It always gives me joy to read about a successful monolith powered by Haskell + Postgres. It’s such a pleasant experience to develop using that approach, it feels like cheating.
I loved this post. Thank you very much Rebecca. I’m looking forward to the book. I would buy it now on beta but it seems that beta only includes the eBooks. I’m a dead-tree kind of person. I’ll keep my eye out for it!
Don’t use Redux. Write your own little framework where you pass messages through something like a stream that leads to something modifying your “state store” and then something rendering your app.
Redux is simple in principle, but somehow accumulates massive complexity and reams of indirection around it. Reducers are too boilerplatey, sometimes you do want nested state, and you want more control over when/how rendering happens.
Avoid all the dependencies you can. Even react-router.
This looks great. I haven’t looked at the source code but are the paths human curated or an algo of some sort? I’m guessing with the amount of topics, it’s unlikely that a person has individually looked at each topic.
I found spacevim throuhgh your search engine, so that’s pretty awesome.
Thank you Steve. Actually all maps were human curated by me up until this point.
However we are moving to a model where anyone can contribute by sending pull requests similar to GitHub awesome lists. We are also moving to D3.js render for smoother viewing and exploring experience.
I hope you will enjoy using the search. It should be getting better and better every day especially with the help of community. :)
Point. I meant in the general “huh, crap, that function didn’t take the happy path with the supplied arguments path” rather than literal PL construct of exceptions. My apologies. :)
I personally enjoyed your post; that’s a very cool language feature. To deflect comments mentioning that this is essentially a specific sub-case of monads and do-notation (which we’ve seen in one form or another many times in many languages), you perhaps could have mentioned this fact in your post and preempted such comments.
While the GP’s post was a bit curt, it’s not wrong, and it’s valuable to the discussion because not everyone will recognize that this is a specific case of a more general concept of interest to the languages community.
For what it’s worth, I meant my comment in the sense of squinting at it and going “oh, nifty”.
I don’t know much about monads by that name, mostly because of the smugness of Haskell weenies and how much I can’t possibly give a shit about whatever they want to say when they fail to put in the effort to educate.
Even if it’d help.
~
In that same spirit, the reason I said “pipeline with structured exception handling” is that your link was the first time it clicked with me what with was doing.
We’d normally write
"foo"
|> bar()
|> baz()
|> quux()
And hope no exceptions/BadMatches occured, or maybe (yuck) wrap the thing in a try/rescue block.
With with, you declare a pipeline, and if a stage fails, it tries matching down in the else clause. That’s really neat.
I don’t know much about monads by that name, mostly because of the smugness of Haskell weenies and how much I can’t possibly give a shit about whatever they want to say when they fail to put in the effort to educate.
Wat? I guess you’re not aware of the glut of monad tutorials? One may not read them or think they are poorly written but given the size of the community there is quite a lot of educational material developed by it.
Alright, let me clarify my English there and I’ll stop derailing the thread:
I am aware there is a glut of monad tutorials–least of all because apparently every time a Haskeller finally groks what a monad is and how they work they immediately write another tutorial on it.
I am also aware that the Haskell community writ large has made lots of efforts to educate.
My assertion is better quoted as:
Whenever I read a post that smugly monad-splains how whatever is being talked about is some inferior version of a concept from Haskell, especially without examples given, I automatically lose interest.
Imagine if every time you were chatting in public about a Haskell concept (say, lifting) that a Javascript developer popped out and said “yeah that’s kinda like currying in Javascript but used by fewer people and nobody gives a shit because we’re busy raising 5M USD seed rounds with Meteor and Mongo and doing cocaine and banging models at our plug-in camp at Burning Man fuck youuuuu”.
Do you see how annoying that is? Not in the least because they didn’t provide any code demonstrating their point, and because they clearly have at least some truth to their statement–not that you’ll ever know, because they didn’t stick around to explain the interesting bits of what they said (like how JS has almost certainly produced more revenue than Haskell, ever)?
Imagine if every time you were chatting in public about a Haskell concept (say, lifting) that a Javascript developer popped out and said “yeah that’s kinda like currying in Javascript but used by fewer people and nobody gives a shit because we’re busy raising 5M USD seed rounds with Meteor and Mongo and doing cocaine and banging models at our plug-in camp at Burning Man fuck youuuuu”.
That’s called “every single day” :)
I can sort of see your point. Where I disagree is that this Elixir concept is literally a less powerful version of monads, so bringing them up, to me, is clearly related.
You can make an instance of Monad that subsumes the baked-into-the-language thing they did here. I don’t know or care what “less powerful” means, but good PL design doesn’t require reifying instantiations of basic patterns in the implementation.
If you don’t care, ok, but I’d like for our industry to be less mired in mediocrity for the next 5 decades.
do
a <- Math.divide 1 0
b <- Math.divide a 4
return ("success: " ++ show b)
The else bit doesn’t translate as nicely, but it also doesn’t generalize as well.
Here’s depth first, exhaustive, lazy search
do
a <- [1 .. 100]
b <- [1 .. 100]
guard (a + b == 50 && a * b > 250)
return (a, b)
Point being that the structure of do subsumes more than just the behavior of with since there’s a somewhat more general pattern you could abstract over. The first example is super useful and if you had to pick just one way to use this pattern it’s a pretty good choice.
Otoh, it’s also very nice to have convenient access to the whole set of similar patterns.
But I’ll say no more. Chris actually thinks very hard about how to talk about all of this and probably will do a much better job.
Oh probably, let me stew on how best to condense the point and why it matters (there are a lot of reasons, but not all of them are obvious if you haven’t been breathing it)
Really? This is what you’re taking away from this?
You make it sound like that’s the wrong message to take away…are you saying it’s not this? It certainly lacks the power of being able to define what “bind” does, so it’s much more limited. There doesn’t really seem to be that much to discuss, to me. It’s sugar for some case statements.
I’ll concede the way I expressed myself might be sub-optimal, but I don’t think that makes with more interesting.
is there a place where middlebrow dismissals are ever the right takeaway? Maybe instead of insulting the language designers for not completely implementing a feature the way you’d like it, you could just go punch a couch pillow and use swear words and stomp around the house for a few hours?
It always gives me joy to read about a successful monolith powered by Haskell + Postgres. It’s such a pleasant experience to develop using that approach, it feels like cheating.
@enobayram - we’re hiring for a Staff Engineer if you are interested in working with us!
I loved this post. Thank you very much Rebecca. I’m looking forward to the book. I would buy it now on beta but it seems that beta only includes the eBooks. I’m a dead-tree kind of person. I’ll keep my eye out for it!
Fantastic post.i had to email the author to let him know how good it was.
Incredible article. This is going to save me so much time, being new to redux and all.
I’ll save you even more!
Don’t use Redux. Write your own little framework where you pass messages through something like a stream that leads to something modifying your “state store” and then something rendering your app.
Redux is simple in principle, but somehow accumulates massive complexity and reams of indirection around it. Reducers are too boilerplatey, sometimes you do want nested state, and you want more control over when/how rendering happens.
Avoid all the dependencies you can. Even react-router.
This looks great. I haven’t looked at the source code but are the paths human curated or an algo of some sort? I’m guessing with the amount of topics, it’s unlikely that a person has individually looked at each topic.
I found spacevim throuhgh your search engine, so that’s pretty awesome.
Thank you Steve. Actually all maps were human curated by me up until this point.
However we are moving to a model where anyone can contribute by sending pull requests similar to GitHub awesome lists. We are also moving to D3.js render for smoother viewing and exploring experience.
I hope you will enjoy using the search. It should be getting better and better every day especially with the help of community. :)
It’s almost like a pipeline with structured exception handling… :P
Those are not exceptions though. It does this on return values that are specific tuples.
Point. I meant in the general “huh, crap, that function didn’t take the happy path with the supplied arguments path” rather than literal PL construct of exceptions. My apologies. :)
It’s almost like a less thought out and less useful attempt at expressing monads.
You know what I like about your post?
Let me show you the problem the tool is trying to solve. Got it? Good. Here’s the tool and how it solves it.
Sooo many posts fail at that first part. Thanks!
I personally enjoyed your post; that’s a very cool language feature. To deflect comments mentioning that this is essentially a specific sub-case of monads and do-notation (which we’ve seen in one form or another many times in many languages), you perhaps could have mentioned this fact in your post and preempted such comments.
While the GP’s post was a bit curt, it’s not wrong, and it’s valuable to the discussion because not everyone will recognize that this is a specific case of a more general concept of interest to the languages community.
For what it’s worth, I meant my comment in the sense of squinting at it and going “oh, nifty”.
I don’t know much about monads by that name, mostly because of the smugness of Haskell weenies and how much I can’t possibly give a shit about whatever they want to say when they fail to put in the effort to educate.
Even if it’d help.
~
In that same spirit, the reason I said “pipeline with structured exception handling” is that your link was the first time it clicked with me what
with
was doing.We’d normally write
And hope no exceptions/BadMatches occured, or maybe (yuck) wrap the thing in a
try/rescue
block.With
with
, you declare a pipeline, and if a stage fails, it tries matching down in the else clause. That’s really neat.Do 3+ years and a thousand pages get me permission to bend your ear?
Well, you did write a book to help teach on it, and you haven’t (here at least) gone with “lol it’s just a monad [git gud]”. So, sure! :)
I save the
git gud
for /r/darksoulsWat? I guess you’re not aware of the glut of monad tutorials? One may not read them or think they are poorly written but given the size of the community there is quite a lot of educational material developed by it.
Alright, let me clarify my English there and I’ll stop derailing the thread:
I am aware there is a glut of monad tutorials–least of all because apparently every time a Haskeller finally groks what a monad is and how they work they immediately write another tutorial on it.
I am also aware that the Haskell community writ large has made lots of efforts to educate.
My assertion is better quoted as:
Imagine if every time you were chatting in public about a Haskell concept (say, lifting) that a Javascript developer popped out and said “yeah that’s kinda like currying in Javascript but used by fewer people and nobody gives a shit because we’re busy raising 5M USD seed rounds with Meteor and Mongo and doing cocaine and banging models at our plug-in camp at Burning Man fuck youuuuu”.
Do you see how annoying that is? Not in the least because they didn’t provide any code demonstrating their point, and because they clearly have at least some truth to their statement–not that you’ll ever know, because they didn’t stick around to explain the interesting bits of what they said (like how JS has almost certainly produced more revenue than Haskell, ever)?
That’s called “every single day” :)
I can sort of see your point. Where I disagree is that this Elixir concept is literally a less powerful version of monads, so bringing them up, to me, is clearly related.
You can make an instance of
Monad
that subsumes the baked-into-the-language thing they did here. I don’t know or care what “less powerful” means, but good PL design doesn’t require reifying instantiations of basic patterns in the implementation.If you don’t care, ok, but I’d like for our industry to be less mired in mediocrity for the next 5 decades.
Could one of you write an example, in Haskell and a vulgar language of your choosing (ideally Elixir), of what you’re getting at?
Especially if you are going to toss around terms like “mired in mediocrity”.
Here’s the example given in the post:
The
else
bit doesn’t translate as nicely, but it also doesn’t generalize as well.Here’s depth first, exhaustive, lazy search
Point being that the structure of
do
subsumes more than just the behavior ofwith
since there’s a somewhat more general pattern you could abstract over. The first example is super useful and if you had to pick just one way to use this pattern it’s a pretty good choice.Otoh, it’s also very nice to have convenient access to the whole set of similar patterns.
But I’ll say no more. Chris actually thinks very hard about how to talk about all of this and probably will do a much better job.
Oh probably, let me stew on how best to condense the point and why it matters (there are a lot of reasons, but not all of them are obvious if you haven’t been breathing it)
You make it sound like that’s the wrong message to take away…are you saying it’s not this? It certainly lacks the power of being able to define what “bind” does, so it’s much more limited. There doesn’t really seem to be that much to discuss, to me. It’s sugar for some case statements.
I’ll concede the way I expressed myself might be sub-optimal, but I don’t think that makes
with
more interesting.is there a place where middlebrow dismissals are ever the right takeaway? Maybe instead of insulting the language designers for not completely implementing a feature the way you’d like it, you could just go punch a couch pillow and use swear words and stomp around the house for a few hours?