Hacker News new | past | comments | ask | show | jobs | submit login

It doesn't do that. The one in the post composes a bunch of other Behaviors, see the lowPower one further down in the article for an example, it's not polling a bunch of variables. Then it is all wired up to react to events.



I think that, while the lack of type annotations on every variable is great since hiding boilerplate is great, it could be confusing to the uninitiated.

To elaborate, lowpower etc. on this line are Behaviors, which emit values by time:

    react <$> lowpower <*> fridgepowerchange <*> wifiusers
while lowpower, fridgepowerchange, wifiusers in the react function bind to the values that are emitted by the Behaviors. (Just by looking at the code we can infer that their types are Bool, (Num a, Ord a) => a, and PowerChange respectively.)

    react lowpower fridgepowerchange wifiusers
            | lowpower = Just PowerOff
            | wifiusers > 0 = Just PowerOn
            | otherwise = fridgepowerchange
None of these are simply state variables!

Although this might have confused GP, I think this is nice since we can associate the name 'lowpower' for its semantics (The low power signal) and not have to worry about "this lowpower is a Behavior while that lowpower is a Bool".


So is it confusing or obvious? Pick one


The code behavior is obvious once you know Haskell. The code simplicity confuses people that don't know the language and think it is something much less powerful than it actually is.


In that case, why not just write everything in perl?


We actually did for a long time. It wasn't so bad, I guess? Certainly not worse than Python, to me.

But the value of writing this kind of code in Haskell is that Haskell makes code that couples very abstract interfaces VERY easily. This is really hard to explain without some examples, so I'm going to give you an example.

Here, let me show you from real code. I'm going to tweak some endpoint names, but this is real code I'm going to ship next week: https://gist.github.com/KirinDave/9b4380376f9f748bcf0f8440de...

What's cool about this code is that I'm describing a "generic" radAPI service with a bunch of endpoints stripped out. Everything is parameterized around 3 generic ideas: "p", the Storage service. "Patchable", a strategy for applying patches to a storage service (exposing runPatch), and "CanValidate", a strategy for authenticating requests based on some sort of stored string, auth headers, and body contents.

This is even better than mocking, because instead of deeply coupling the structure of my code to my tests, I only couple the capabilities.


The joy of Perl!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: