6 ms·
> Functional architecture makes extensive use of advanced abstraction, to implement reusable components, and, more importantly, supple domain models that antici
by jasim 3y ago
> Functional architecture makes extensive use of advanced abstraction, to implement reusable components, and, more importantly, supple domain models that anticipate the future.
I believe Mike Sperber is talking about Haskell when he says "advanced abstraction", but most regular line-of-business software can reap significant benefits with just simple FP principles: mostly immutable data, record types, sum types, and a vocabulary of small decomposed functions that can parse, transform, and combine this data, together building to larger wholes.
You do need a language with types and first-class functions, and the most common vehicle for that currently is TypeScript. Combine that with a book like Grokking Simplicity by Eric Normand, especially the fundamental idea of separating data, computation, and action, and you have a software system that is supple, simple, and amenable to continuous growth and refactoring over a long period of time.
Grokking Simplicity, IMO, is a severely under-discussed book when it comes to FP. Its only sticking point for me is its lack of static types, but otherwise it is the first and only book that I've seen that distils the functional way of thinking for the working programmer in an accessible way, without having to resort to the all-or-nothing proposition of completely pure FP.
- pharmakom 3y agoI think you need do-notation for true simplicity. This is because handling results, optionals etc without this is really hard to read, maybe more so than the imperative code equivalent. I hope TypeScript gets this but not holding my breath!
- falafel 3y agodo-notation can be easily implemented using delimited continuations (ie. generators). Generators compose well and flatten tail calls so you don't need TCO or trampolines. The only notable issue is that one-shot delimited continuations like generators don't work with non-deterministic monads (ie. List). Multi-shot can be emulated by keeping a cache of past values and replaying the generator, but performance will suffer. See burrido [1] for a JavaScript do-notation implementation. [1] https://github.com/pelotom/burrido https://github.com/pelotom/burrido
- gizmo686 3y agoIn a sufficiently expressive language, do-notation isn't that important. Consider the following pieces of (equivelent haskell) f1 = do fd <- openFile "/file/path" contents <- readFile fd let result = process contents closeFile fd return result f2 = openFile "/file/path" >>= \fd -> readFile_ fd >>= \contents -> let result = process contents in closeFile fd >> return result Sure, the code for f1 is easier to read, but not by that much. You have a bit more noise in each line with the explicit operators being added. The only big readability difference I see is that you have moved to bound variable to the end of lines instead of the start. I've never actually worked in a codebase that regularly did this, but I suspect you would get used to it frequently. The inconsitency with let statements putting the bound variable on the left would be a readability drawback; but I can easily imagine a language that allows for putting the bound variable on the right hand side of an assignment, such as (not Haskell): let process contents -> result in
- daveguy 3y agoI believe it is possible to implement effective and fundamentally sound functional programming without types. Types just make it easier to avoid mistakes in functional programming. Like object oriented paradigms can be implemented in procedural languages like C, but they are easier in languages with built-in object oriented tools. First class functions are definitely a must.
- DonaldPShimoda 3y ago> I believe it is possible to implement effective and fundamentally sound functional programming without types. I prefer working in statically typed languages, but I agree with you (though only if we use a colloquial definition of "sound"). And, what's more, I think the correspondent in the article would agree also. Michael Sperber is very familiar with Scheme, as evidenced by his publication history. I think your point actually connects with a line from the article: > Components in functional programming are essentially just data types and functions, and these functions work without mutable state, [Sperber] said. Even in a dynamically typed language, the data still "has a type" — but now we're talking about the "shape of the data" rather than a formal type system. Reasoning about data-shapes is perfectly valid, and still supports the style of code that Sperber talks about throughout the interview. This also connects to the "Design Recipe" from the textbook How to Design Programs, which is an introductory CS text based on Racket, a derivative of Scheme. In the Design Recipe, students are told that they should write down the contract of their function before implementing the body of the function, and part of this is the specification of the "types" of the inputs and the output. Again, since the language is untyped, this has much more to do with conveying a sense of the "shape" of the data to the programmer, but it is still highly effective in guiding the design and implementation of a functioning software system.
- marcosdumay 3y ago> Types just make it easier to avoid mistakes If you look at a language like Haskell, types are there to provide polymorphism and allow you to rearrange the language in convenient ways. It's impossible to say what is the single main use of types there, but this is certainly one of the most important ones. Another main use of types there is documenting interfaces. People only get to say that types provide nothing else but correction if they decide that all the other uses are non-important and should be ignored. But then, that's a pretty trivial and useless information.
- deleted 3y ago[deleted]