Tony Morris, a Scalaz contributor, writes about functional programming, Scala, Haskell and Java, often in a combative style.
HN commenters link his exercises on Haskell lifting and applicative functors as learning material for functional programming concepts.
I don't think you can refer to function composition as a design pattern. The syntax for function composition in Haskell is so light that most of the time it's more effort to write in all the arguments explicitly than it is to use composition. Consider
lineLengths = map (length . words) . lines
as compared to
lineLengths text = map length (map words (lines text))
I don't think that monads are a design pattern either (in this I agree with Tony Morris [1]). Monads are a unified method of doing contextual computations. They are far too general to be a design pattern in themselves (how many design patterns do you know that encompass failure, error handling, nondeterminism, probabilistic computation, logging, backtracking search, mutable state, asynchronous computation, continuations, I/O...)
Monads should be more accurately thought of as an interface that is implemented by many types (in Haskell terminology, a class that many types are instances of).
I am not saying that there aren't any design patterns in Haskell - just that function composition and monads are not examples of design patterns. Instead, common design patterns include
* Writing tail-recursive, accumulating helper functions where you'd use a for loop in an imperative language:
sum xs = go 0 xs
where
go result [] = result
go result (x:xs) = go (result + x) xs
* Using strict left folds to accumulate values
sum = foldl' (+) 0
* Using runStateT and its cousins to tame…
I recently (well, a few years ago) went through functional programming in schools. They don't really teach you functional programming, as much as why you shouldn't program imperatively. Even when they're teaching functional programming, the consistent emphasis on only x% effective really cuts out student interest. It's almost like saying, "yeah we have a method for preventing destructive assignment, but it doesn't really work." While it might seem like a good idea at first, I found it to quickly invoke the I'm not listening anymore response.
Next, is the issue of effectiveness. Personally, I've been shown way so many gross images of imperative spaghetti code, that I won't even open vim without knowing I have scala. Unfortunately, this doesn't follow through for a lot of other kids who went through the same education as I did. "I love ruby", "what about python", "it doesn't feel as good as C++", and "it's just too much work" are all (yes I know it's sad) frequently cited responses among people I know.
Thirdly, and most troublesome of all, some people don't care that they're spreading nasty interoperability impedance mismatching in their non-scalaz libraries since they haven't realized that variance annotations are not worth their use in the context of Scala’s partial support for Hindley Milner type-inferencing.
. I recently found out someone I knew was receiving treatment for coding in C. I asked her when she found out, believing this to be a recent development. "I've been…
Most of the complaints I see from Java programmers amount to this:
http://blog.tmorris.net/anti-intellectual-euphemisms/
Specifically:
> using the word complex, unnatural, academic, “your world” or unintuitive to mean “I am not able nor am I willing to invest the effort to come to to understand this.”
Other than those people:
The blog author I quote above is one of the many "PL gurus" you speak of that rip into Scala because of its various deficiencies when compared to the likes of Haskell. The ones I am smart enough to understand mostly revolve around the type inference and type erasure problems. You mentioned those but I have already run into issues where I did care about them so I don't think its fair to dismiss them as you did.
The amount of hyperbole that comes from elements of the Scala community on actors I think is a cause of a fair amount of vitriol, mostly because actors are not a silver bullet and come with their own host of problems. Akka is trying to solve some of those problems of course :)
And of course the lack of tools. It's hard for me to talk about this because I loathe IDEs. So far I have been writing my medium sized project entirely in vim + NERDTree and it's been great. I imagine with enterprise scale projects I would start to miss Eclipse though.
> Your wording sounds like it implies that Lisp "got stuck" somewhere in the past, no?
Pretty much. See pg's famous "Blub Paradox" where he sees Lisp as the top of a tower of lesser languages. He doesn't recognize that Lisp might at best be called a limit ordinal, to use math jargon. That is, Lisp is just another Blub, and the Lisp zealots haven't figured that out.
You don't necessarily want to keep going further and further up, of course. Lisp still has fascination. But e.g., in Common Lisp (I mean just the stuff in the CL spec, no ad-hoc extensions allowed) you can't write anything resembling an OS. You can in Scheme, using continuations to handle process switching.
Going further up, Lisp doesn't make it easy to ensure the absence of particular behaviours in a program, what TAPL calls the purpose of a type system. Tony Morrison has a semi-realistic example of what static types can get you:
http://blog.tmorris.net/posts/understanding-practical-api-design-static-typing-and-functional-programming/
Link still works but TLS certificate expired in 2025, tsk tsk.
> That said, it isn't hard or long to learn monads.
I am not sure any definition does that justice. It's similar with concept of recursion - it's easy to define (function calls itself), but to put it into programming practice (writing all loops as recursion), that's a lot harder.
I read "Learn Yourself a Haskell" as a tutorial (which is in my opinion great) and still it was a lot of work to figure out this: http://blog.tmorris.net/posts/20-intermediate-haskell-exercises/
Then I started reading http://www.haskell.org/haskellwiki/All_About_Monads but didn't finish it yet (I was playing with Haskell, just figuring out how to structure the application). IMHO, unless you understand all that, how to put monad concept into practice, you don't really know monads.
You can have a type-safe fluent Builder, but it requires having one or more static nested classes with private constructors. The outer class will not have a build() method, but rather that method will live in one of the nested classes. You use the type system to control what parameters have already been set, and what parameters need to be set.
Obviously, this can apply to many sorts of fluent API. This is at least part of what Tony Morris is alluding to in his essay on API design [1].
[1] http://blog.tmorris.net/posts/understanding-practical-api-design-static-typing-and-functional-programming/index.html