tag:blogger.com,1999:blog-1777990983847811806.post7399908678496201769..comments2024-03-16T16:29:29.582-07:00Comments on Haskell for all: Scalable program architecturesGabriella Gonzalezhttp://www.blogger.com/profile/01917800488530923694noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-1777990983847811806.post-15649797316823533452018-02-12T11:31:37.452-08:002018-02-12T11:31:37.452-08:00I think https://github.com/elixir-plug/plug is a g...I think https://github.com/elixir-plug/plug is a great application of this idea in the elixir communityAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-76881420427629837072015-12-11T01:51:16.011-08:002015-12-11T01:51:16.011-08:00It recalls me OSGI white board pattern (www.osgi.o...It recalls me OSGI white board pattern (www.osgi.org/wp-content/uploads/whiteboard1.pdf)adolgarevhttps://www.blogger.com/profile/15391327834309772808noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-14394104059804133902014-07-31T06:30:14.977-07:002014-07-31T06:30:14.977-07:00Fixed (months later, sorry!)Fixed (months later, sorry!)Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-2623489099195386502014-07-31T06:27:18.270-07:002014-07-31T06:27:18.270-07:00You're welcome!
You're right that this is...You're welcome!<br /><br />You're right that this is not Haskell-specific. I didn't mean to imply that only Haskell programmers can do this.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-5665920848441405902014-07-31T06:26:12.080-07:002014-07-31T06:26:12.080-07:00It's hard for me to say without knowing more a...It's hard for me to say without knowing more about your code.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-55883836701132866562014-07-31T02:35:11.078-07:002014-07-31T02:35:11.078-07:00So you decompose `f` in order to preserve the scal...So you decompose `f` in order to preserve the scalability property with `h`, correct?<br /><br />Even so, I can’t apply this decomposition to my original question. What am I missing?Anonymoushttps://www.blogger.com/profile/00228703528223893180noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-27428387878149629412014-07-28T21:13:20.017-07:002014-07-28T21:13:20.017-07:00Sorry for the late reply. So if I have a function...Sorry for the late reply. So if I have a function of the shape:<br /><br />f :: A -> A -> B<br /><br />... what I will usually do is see if I can decompose `f` into two functions, like this:<br /><br />g :: A -> B<br /><br />h :: B -> B -> B<br /><br />f a1 a2 = h (g a1) (g a2)Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-84189140279875466252014-07-02T07:36:26.167-07:002014-07-02T07:36:26.167-07:00Following the addition intuition. When you add som...Following the addition intuition. When you add some numbers you can’t go back to the addends.<br /><br />Do you know of any situation where this is not desirable, i.e., where a “foldable/unfoldable” (sorry for the sloppy terminology) structure is needed?Anonymoushttps://www.blogger.com/profile/00228703528223893180noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-9898779974689570372014-04-27T09:58:56.427-07:002014-04-27T09:58:56.427-07:00I have to come to Gabriel's defense. I am deep...I have to come to Gabriel's defense. I am deeply embedded in the C++ community and I can testify to how difficult it is to express and justify certain ideas about composability in that language. I keep pointing out these patterns, like monoid or monad, but since there is not generic workable expression for them in C++, it just sounds like abstract nonsense. And if you try to abstract them, you run into template hell and/or performance issues. In Haskell these ideas are first class citizens at the level of typeclasses. Haskell programmers think in terms of monads. C++ programmers don't recognize a monad when it hits them in the head (the std::future monad being a recent example I had to justify to the C++ Standard Committee).<br />Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-32848160544975558542014-04-25T23:54:49.720-07:002014-04-25T23:54:49.720-07:00This comment has been removed by the author.somedudehttps://www.blogger.com/profile/17768571657587131663noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-11005532849441305352014-04-24T01:45:33.059-07:002014-04-24T01:45:33.059-07:00Clearly many "Haskell concepts" would ap...Clearly many "Haskell concepts" would apply to languages like Agda and Idris, since those languages are heavily influenced by (and implemented in) Haskell, so it would be more justified to call them "FP concepts".<br /><br />However, Haskell's laziness and typeclasses ('being lazy with class') make some idioms particularly suitable which may be regarded as 'advanced topics' or 'second-class citizens' in other FP languages (eg. ML, Scheme or Scala).<br /><br />Monads spring to mind as as such a "Haskell concept"; even though they're now spreading into other languages, they were brought into programming specifically to model lazy IO, and were implemented as a typeclass in Haskell. The same can be said of Applicative and Arrow. Using these concepts in other languages could arguably be called 'writing Haskell-style code'.<br /><br />Of course there are languages like Clean, Curry and Idris which are, or can be, 'lazy with class', but Haskell's age and popularity will make it the posterchild of this feature-set for some time to come. Hence it's fine for introductory, thought-provoking articles like this to focus on it. Those of us who care about languages like Agda and Idris, or even know that they exist, are not the intended audience.Warbohttps://www.blogger.com/profile/11167936627543971536noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-69631514631750658532014-04-19T13:24:41.624-07:002014-04-19T13:24:41.624-07:00Alright, I'll try not to beat the Haskell-spec...Alright, I'll try not to beat the Haskell-specific drum when talking about theory so much.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-83691473988023282772014-04-19T12:35:02.893-07:002014-04-19T12:35:02.893-07:00You probably should't generalize in this way a...You probably should't generalize in this way about language communities you aren't actively involved with.<br /><br />Your comment about having to justify FP in other languages is not relevant. Even if that were so (which it's not in general), that doesn't make functors, categories, monoids, and other aspects of FP Haskell-specific concepts. Is a 'functor' or monoid a Haskell concept? An Idris concept? An Agda concept? None of the above! Just say that the concepts are useful / important for writing software, and use Haskell or as the vehicle for communicating that. Pretending that a general concept is Haskell-specific is not the way to advocate for Haskell, if that's what you're trying to do!Paul Chiusanohttps://www.blogger.com/profile/04844651950877109501noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-45595233637217992412014-04-15T08:37:11.849-07:002014-04-15T08:37:11.849-07:00Yes, that definitely helps, too.
An example I lov...Yes, that definitely helps, too.<br /><br />An example I love to use is concurrent streams. Suppose we model a concurrent stream of `a`s as:<br /><br /> Input a<br /><br />Then let's assume that `Input a` forms a `Monoid` where mappend interleaves two streams and mempty is the empty stream. Now we can combine multiple streams of the same type of value.<br /><br />Now suppose we want to combine two streams of different types of values:<br /><br /> sA :: Input A<br /> sB :: Input B<br /><br />We can do this if `Input` is a `Functor`, too:<br /><br /> sBoth :: Input (Either A B)<br /> sBoth = mappend (fmap Left sA) (fmap Right sB)<br /><br />This shows how algebraic data types and functors make it easy to get things to agree on a common type so that you can combine them.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-21121056354222867662014-04-15T08:28:08.931-07:002014-04-15T08:28:08.931-07:00Yeah, the terms are a bit vague and I was hoping t...Yeah, the terms are a bit vague and I was hoping the type signatures would clear things up.<br /><br />Monads let you combine nested functors, like this<br /><br /> m (m (m (m x))) -> m x<br /><br />Applicatives let you combine tuples of functors like this:<br /><br /> (f a, f b, f c, f d) -> f (a, b, c, d)<br /><br />Does that help?Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-63441794359250451592014-04-15T08:24:01.748-07:002014-04-15T08:24:01.748-07:00That's a class constraint. It is more clear i...That's a class constraint. It is more clear if you parenthesize it:<br /><br /> class (Functor m) => Monad m where ...<br /><br />That means that anything that anything that implements `Monad` must also implement `Functor`. The real `Monad` class does not have this constraint, but it should and it will be added soon (indirectly, via an `Applicative` constraint, which is even more useful).Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-68272616527461413692014-04-15T08:20:14.254-07:002014-04-15T08:20:14.254-07:00Compositional programming (in the category sense o...Compositional programming (in the category sense of the word composition) still feels like a second class citizen in other programming languages, including other functional languages. When I say second-class I mean that you have to justify its use because there is another prevailing way to solve the problem (typically involving objects or mutation). I don't enjoy having to justify this compositional style to others so I would prefer to advocate stridently for a language where this style is the default and pragmatic choice.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-5281742943241856302014-04-15T01:31:13.908-07:002014-04-15T01:31:13.908-07:00To me, it seems that this composability of what yo...To me, it seems that this composability of what you call Haskell design patterns stems (at least also) from its algebraic types and how easily (in terms of syntax and memory management) one value is transformed into another.Unknownhttps://www.blogger.com/profile/03735878191641605824noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-72910977660433041792014-04-14T19:25:36.010-07:002014-04-14T19:25:36.010-07:00If you insert enough weasel words, "for all p...If you insert enough weasel words, "for all practical purposes", "idiomatic", etc, then I can't exactly disprove what you're saying, but I don't agree with your characterization, and I know a lot of functional programmers in other languages would also take issue with it.<br /><br />I am happy that you have discovered good programming ideas via Haskell and like blogging about them, but please don't assume Haskell has a monopoly on these ideas. It really doesn't, and if it think so, I'd say you have not spent enough time in other language communities. IMO, posts like this contribute to unhelpful language tribalism that I'd really like to see go away.Paul Chiusanohttps://www.blogger.com/profile/04844651950877109501noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-17380597502225660982014-04-14T14:05:52.616-07:002014-04-14T14:05:52.616-07:00I don't know. Regular OO languages allow this ...I don't know. Regular OO languages allow this as well. In fact some patterns are even more natural in that setting. You can put various combinator methods in a superclass and then have subclasses implement their own special versions of those methods while still remaining in the same class hierarchy.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-81656496913501027022014-04-14T14:02:40.240-07:002014-04-14T14:02:40.240-07:00Parser combinators are a good real world example o...Parser combinators are a good real world example of such combinability.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-51781783061572350572014-04-14T13:35:29.870-07:002014-04-14T13:35:29.870-07:00For all practical purposes Haskell does have a mon...For all practical purposes Haskell does have a monopoly on this in the programming world. Haskell is the only language where this style of programming is idiomatic.Gabriella Gonzalezhttps://www.blogger.com/profile/01917800488530923694noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-33983714644863790982014-04-14T12:35:18.954-07:002014-04-14T12:35:18.954-07:00This is a very nice observation (and explanation)....This is a very nice observation (and explanation). Actually it makes a lot of sense even outside of the Haskell world. Thanks for sharing!nekhttps://www.blogger.com/profile/17618702265623423602noreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-41160831738525401862014-04-14T11:39:39.262-07:002014-04-14T11:39:39.262-07:00I don't get what you mean by "Functor&quo...I don't get what you mean by "Functor" and combine horizontally vs. vertically, or how this applies to architecture. I'd love to see this line of thought expanded.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-1777990983847811806.post-6339784697365044872014-04-14T11:34:34.138-07:002014-04-14T11:34:34.138-07:00On the contrary; I usually think of a monoid as a ...On the contrary; I usually think of a monoid as a set with a not-necessarily-invertible binary operation (eg, addition of natural numbers), and it just so happens that there's a funny trick for realizing these structures as categories. (As a category with a single object and a bunch of arrows which become the 'elements' of the monoid, under the operation of function composition.) This has almost nothing to do with how category theory is normally actually used, though: one-object categories are a pretty degenerate case.<br /><br />In Sage (sagemath.org) we have a notion of category explicitly because we're building, well, actual categories. The great thing about categories is that they also contain information about the mappings between objects, which is structure not encompassed by the usual object-oriented programming paradigm. That and, yeah, functors.<br /><br />Sage is written mainly in Python, but, like Haskell, makes functions first-class objects. Good ideas deserve to spread!tomhttps://www.blogger.com/profile/01947882733112567381noreply@blogger.com