7 ms·
Type Driven Domain Modelling, Part 2: Evolving Models with F#
- fowlerpower 10y agoF# is a beautiful language. You always want to use the right tool for the job but honestly F# is so right for so many jobs. I know a lot of people don't want to hear this but these types of languages, functional first, are the future of our industry. (In the sense that in the 2000s Java like laguanges were the future of our industry). I might be reaching here, but in my opinion, these are the right languages for the Cloud and that's why they are getting so popular.
- aryehof 10y agoFuture of our industry? Such languages are popular and suited to certain types of projects and solutions certainly. Particularly for systems in computing, and information and data science. However, for complex representational systems, including both transactional and continuous systems in business, commerce and industry, other languages and paradigms can remain better suited.
- KurtMueller 10y ago> However, for complex representational systems, including both transactional and continuous systems in business, commerce and industry, other languages and paradigms can remain better suited. Hello. Respectfully, what is a complex representational system? Why are other languages/paradigms better suited over a language like F#?
- twblalock 10y ago> Respectfully, what is a complex representational system? A database is one example. A database is also global mutable state for the programs that write to it, and that significantly compromises the advantages of using functional programming languages for such programs. You might start with some nice pure functional code, but the database adds massive side effects.
- yawaramin 10y agoActually, the benefits of pure functional programming are even more clearly exposed if you're doing complex IO operations like disk access and mutability. The ability to capture the effectful operations (read a table, write a row) as statically-typed action containers is invaluable because it lets you sequence the effects in a correct order with very little effort.
- staticassertion 10y agoThis is the #1 misconception I see surrounding pure functional programming - that once you run into mutable state, you run into problems. It is entirely the opposite. PFP exposes the murky aspects of mutability, provides abstractions around it, and ensures that you're not tripping over yourself in regards to mutability.
- jpalomaki 10y agoMaybe we should get rid of databases (or limit them to reporting). Back in the days they were mandatory since memory was expensive and you simply had to access stuff from disk and needed something that made it reasonably efficient. Now memory is so cheap and for quite many business applications it would be feasible to keep everything in memory. SSDs with GB/s level read speeds would enable restoring the stuff back to memory in reasonable time in case the cluster goes down. I think the whole database thing also caused major issues on the object oriented side and actually stopped people from really using OO (or getting benefits out of it). Instead of building intelligent and smart objects it is easy to end up with objects that are just containers for data. Probably there has been thoughts on how to do this, one old project I remember is Prevayler[1]. [1] http://prevayler.org/ http://prevayler.org/
- olavk 10y agoPersistent objects does not mean you get rid of the database. It just means the database is a lot harder to query.
- throwawayish 10y ago
- aryehof 10y ago> "What is a complex representational system" 1. Representational systems a. Transactional systems [1], based around actions that need to be recorded, typically for commercial or legal reasons, like software used to record your purchases, payments, reservations, participation, interactions, obligations, results, commitments, plans, and significant events. b. Non-transactional continuous systems, like software controlling an elevator, warehouse conveyor system, or a vehicle engine management system. See http://aryehoffman.com/entry/project-types http://aryehoffman.com/entry/project-types
- yawaramin 10y agoThe Tezos project is writing a new safety-focused blockchain implementation in OCaml. Would you classify that as a representational system or otherwise?
- aryehof 10y agoI don't know anything about Tezos or blockchain implementations sorry, but I suspect that it is primarily focused on the processing of data, rather than the modeling of the concepts in a domain – a specific area of activity or knowledge. As such it is more of a Type 2B project - "Information, data science and analysis projects, systems often focused on the processing of data." (http://aryehoffman.com/entry/project-types http://aryehoffman.com/entry/project-types)
- willtim 10y agoMost mainstream languages don't even have sum types, but have to encode them via other means (enums, tags, inheritance). They are not necessarily the best choice for modelling data, just your preferred choice.
- yawaramin 10y agoFrom the description, 2(b) sounds like a strict superset of 1(a). In fact, it sounds like the most generic possible description of an IT system. I mean, what computer system is not focused on the processing of data? Anyway, I asked you about a blockchain technology because it fits perfectly into your description of a representational technology. In fact it's a breakthrough in the space, and I'm finding it hard to believe that an IT professional doesn't have even a basic idea about about it.
- willtim 10y agoThere's not enough detail here to really comment. I can say that Haskell has the best software transactional memory implementation out there, thanks to purity and controlled side-effects. Haskell's explicit handling of state also helps provenance and keeping state managed / in the database.
- shados 10y agoFacebook is betting pretty hard on ML via ReasonML (even on the client with BuckleScript), and F# is similar as an ML derivative. We'll hear about these more and more for sure.
- pjmlp 10y agoSure, but the majority of companies in the world with IT department, don't have software as business, rather as a cost center for support their actual business. Companies like Facebook aren't what the majority of us works on. So when selling languages to management "look Facebook does it" usually doesn't help at all, what one needs are how that adoption will help those IT costs go down.
- lucasmreis 10y agoFrom my research and experiments, I think that ML languages help a lot "getting the specs right". That means that you have more confidence that the code does what you want it to do. I can see a lot of value for that in non-tech companies that correctness is crucial, like finance, insurance, health...
- pjmlp 10y agoI love ML languages, my first was Caml Light, OCaml wasn't yet born. Also share your opinion, and go even further, for me personally IT projects should be accountable just like in many industries. However my experience in enterprise consulting, with applications written in Excel, or languages that allow for "replaceable programmers", is that business doesn't care if software is the same quality of 1 € shop items, as long it generates the desired output.
- shados 10y agoit trickles down, slowly. Facebook does it, then SV companies do it, then tech companies globally do it, then everyone else. Always goes that way.
- 10y ago
- twblalock 10y ago> I know a lot of people don't want to hear this but these types of languages, functional first, are the future of our industry. Mainstream languages will incorporate functional features and remain popular, and they will not be superseded by pure functional languages. Java and C# are already doing this.
- smoothdeveloper 10y agoThey will still remain generally more painful and more exposed to their issues and choices: * mutable by default * OO by default * null by default * structural equality a pain to implement * immutable types a pain to implement * verbose syntax / failing at the DRY principle * statement based rather than expression based * large codebase following those idioms I don't think they'll not remain popular, but I think a more important share of people will eventually "get it" that there are alternative approaches which are sound, same or greater potential to achieve and thriving eco-system.
- pjmlp 10y agoManagers don't care about those bullet points. If you want to sell a language to the upper layers, you need a list of business reasons, not language features.
- smoothdeveloper 10y agoSee if testimonials help: http://fsharp.org/testimonials/ http://fsharp.org/testimonials/ As for me, I also use the awareness of manager to the developer needs to be productive, give best ROI and would definitely use that to select a job.
- pjmlp 10y agoI am aware of them, my comment was more a kind of heads up, because I have been in too many meetings about technology adoption, whose presenters though an endless list of features was the best approach.
- staticassertion 10y agoI would agree if I felt that the industry were moving towards "better" software - as in, as an industry, we said "Wow, we need to seriously take a step back and start writing systems more reliably, more securely, etc". I do not think we're going in this direction, necessarily.
- rubber_duck 10y agoI honestly wish this was true but I doubt it. F# is different enough to have a big curve, and yet the benefits aren't immediately tangible, it's just a bunch of small things that add up - but try selling that to someone. Meanwhile mainstream languages are picking up features from it (eg. C# will eventually have record types and pattern matching). I think languages like this will influence the mainstream but I don't see them being mainstream in the future.
- vivainio 10y agoHuh, the benefits are immediately tangible, the biggest one being less code to do the same thing while remaining typesafe. In the meantime, you probably need slightly, but not massively, better developers.
- jackmott 10y agoI don't think you need better developers. I've had one college intern so far that I've had work with some F# and she liked it better than C#. Lots of stuff that is easier to do. Not much that is harder.
- rubber_duck 10y agoWhen you don't know a lot learning something different is actually easier than when you're already proficient in C#. You expect an intern to take x ammount of time before he can be productive, so if he spends it on learning how to do it with F# or C# it won't change the x much. But when you have a senior who knows how to do something with C# he will not want to invest ammount similar to x, even a 1/2 of the time, because he can get it done with what he knows. Like I said to OP F# doesn't have that "hard sell", it's just a bunch of incremental improvements that end up being a big deal together, but each one on it's own is unimpressive.
- vivainio 10y agoYou rarely have Tabula Rasa developers - average developer is probably proficient in Java and/or C#. I would say HM type inference is a non-incremental "hard sell" improvement, but it depends on the target audience :).
- cmoscoso 10y agoI agree with functional first for backend programs. I don't see functional programming become popular on the front-end thought.
- christophilus 10y agoI disagree. It is the frontend that made me want to learn functional programming in earnest. Redux and ImmutableJs were the catalysts. I'm currently learning a couple of LISP variants (Closure and LFE). With ClojureScript, Elm, PureScript, BuckleScript, and even plain ole ES6, functional on the frontend is more compelling than ever.
- lucasmreis 10y agoI disagree too. Frontend is getting more complex each day, and I find that functional programming languages help a lot with large projects. Frontend SPA's are crying for help with the exploding complexity :)
- cmoscoso 10y agoGood point on the complexity of today web apps. I'm not really into web front-end and my comment was more about native frontend development, where you need to add/remove things from screen, run animations, you know, those sort of things that are inherently non-functional. Sorry for not being clearer.
- lucasmreis 10y agoIt's ok! :) So, if we only want to call a couple of animations and submit a form, I agree that a small script with three jQuery-style functions can do the job. But that's rarely the case nowadays, in my experience. Almost every frontend project I came across professionally became a full application at some point. There's the need of dealing with concurrent user interactions, online data requests to the server, non-traditional form behaviors, different routes...
- 10y ago
- willtim 10y agoAgreed. Objects for everything results in code that is riddled with hidden mutable state and side-effects (state is not encapsulated). It's impossible to reason globally about such systems, even before threads are added. Objects can be used as a reasonable module system, which is why many still advocate them, although IMHO better module systems do exist (e.g. in OCaml).
- kough 10y agoI think there's a typo in the createQty function: shouldn't it return (uint16 0) if n is less than 0, not greater? Otherwise, great article. This is exactly how I learned to program with Scheme: mosel the domain carefully, slowly building up helper functions, and conposing at the end.
- lucasmreis 10y agoThank you! I actually just removed createQty from the code. not only it had a typo, it was not being used anywhere beside the tests. And, as some commenter on Disqus said, probably the right thing to do would be returning an Qty option from the function, and treating it properly. I have no experience with Scheme, but already worked with Clojure - it was actually my "gateway" to functional programming languages, hehe!
- daxfohl 10y agoI call this RSLDD: Red Squiggly Line Driven Development.
- lucasmreis 10y agoAmazing - I'm gonna use this in the future :)
- daxfohl 10y agoIt'd be especially nice if database schemas mapped to F# types more readily. JSON db's kinda do it, but with no defined schema and no joins. It seems like it'd be not terribly difficult to augment regular SQL databases with something akin to the F# type system to define table schemas, rather than just flat data in columns. Then "SQL" could be extended to include `match` expressions.
- jackmott 10y agohave you seen sqlprovider and sqlcommandprovider?
- tejasv 10y agoI've taken the approach of converting my models to XML, mostly because they map 1:1 from F#-land to XML-land, and I can use SQL Server's XML Indices, but most importantly, I can use XSLT to evolve my persisted models upon change change to F# code. Then using a bit of F# Quotations, I can convert most match queries to XPath queries and query SQL Server directly (still work-in-progress). But running into performance problems, so it's not 100% done. http://stackoverflow.com/questions/41949177/f-data-types-sql-server-persistence-using-no-sql-techniques http://stackoverflow.com/questions/41949177/f-data-types-sql...
- daxfohl 10y agoYeah, I did the first part a couple years ago too. I also put the whole thing behind a VCS so we'd have version-controlled data. But, yeah, it didn't scale well enough and I ended up dropping that for mongodb, and later for postgres.
- kazinator 10y agoTXR Lisp: (defstruct product nil sku price) (defstruct event nil) (defstruct add-to-basket event product quantity) (defstruct line nil product-sku quantity line-total) (defstruct basket nil lines total (:postinit (me) (set me.total [reduce-left + me.lines 0 (usl line-total)]))) (defvarl empty-basket (new basket)) (defun build-line (product quantity) (new line product-sku product.sku quantity quantity line-total (* quantity product.price))) (defmeth basket add-to (me product quantity) (flet ((transform-line (line) (if (equal line.product-sku product.sku) (build-line product (+ line.quantity quantity)) line))) (let* ((transformed-lines [mapcar transform-line me.lines]) (product-already-in-basket (nequal transformed-lines me.lines))) (if product-already-in-basket (new basket lines transformed-lines) (new basket lines (cons (build-line product quantity) me.lines)))))) (defmeth basket update (me event) event.(add-to me)) (defmeth add-to-basket add-to (me basket) basket.(add-to me.product me.quantity)) REPL: $ txr -i typemodel.tl 1> (new add-to-basket product (new product sku 42 price 5) quantity 4) #S(add-to-basket product #S(product sku 42 price 5) quantity 4) 2> (new basket) #S(basket lines nil total 0) 3> *1.(add-to *2) #S(basket lines (#S(line product-sku 42 quantity 4 line-total 20)) total 20) (The silly implementation of the product-already-in-basket is a literal transliteration of the original.) If you see me designing programs like this in real life, just whack me on the head, please!
- kazinator 10y agoHere is a version of basket add-to with a recursive local function for doing the insert, avoiding the clumsy mapcar and "did we insert or not" check copied from the F# code. (defmeth basket add-to (me product quantity) (labels ((insert (lines) (tree-case lines ((line . rest) (if (equal line.product-sku product.sku) (cons (build-line product (+ line.quantity quantity)) rest) (cons line (insert rest)))) (() (list (build-line product quantity)))))) (new basket lines (insert me.lines))))