Live data from Hacker News

Show HN: I built a poker site with Haskell

github.com

31–40 of 121 posts

Re: Show HN: I built a poker site with Haskell

#31
post #8

Earlier quoted context omitted.

Haskell is dense. I'm picking it up now[0], so this project was very useful for me to see how some "real world" Haskell is written. But yes, take for example this function getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort return defaultPort Just port -> maybe (return defaultPort) return (readMaybe port) It gets a port from an environment variable, if it can, otherwise a default port. Co…

Ouch. That function is actually written in a pretty convoluted and redundant way. getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort >= readMaybe That's starting to border on over-terse, so you could expand the bind operator into do notation if you wanted to spread it out a bit further. On the other hand, it's also starting to feel over-verbose, using do notation for only a single IO act…

I feel like I'm in a unique place of learning Haskell, so I'll try to translate the last line of your first function:

  return . fromMaybe defaultPort $ maybeEnvPort >>= readMaybe
Basically this is composing a function out of "return" and "fromMaybe" (using the composition operator "."), then partially applying defaultPort to that composed function, so you now have a function that takes one argument. The resulting function is then applied (using $) to the result of "maybeEnvPort >>= readMaybe".

In "maybeEnvPort >>= readMaybe", ">>=" is an infix function that takes maybeEnvPort as its first argument (which is a Maybe Monad), "unpacks" it, applies "readMaybe" to the unpacked result. readMaybe returns another Maybe Monad.

The result of everything after the $ is a Maybe Monad that contains the port from the environment, or a failure condition. The result of applying the composed-and-partially-applied function (from before the $) to it is that the port from the environment is chosen if it didn't fail, otherwise the defaultPort is used, and then the whole thing is wrapped in an IO Monad.

Re: Show HN: I built a poker site with Haskell

#33

What would be the best IDE/editor for Haskell?

I tried spacemacs with intero for a while, but I'm now using https://github.com/haskell/haskell-ide-engine + vscode + vimmode. Mostly because I'm using vscode in my work and I don't want to invest more into emacs.

Re: Show HN: I built a poker site with Haskell

#34
post #8

Earlier quoted context omitted.

Haskell is dense. I'm picking it up now[0], so this project was very useful for me to see how some "real world" Haskell is written. But yes, take for example this function getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort return defaultPort Just port -> maybe (return defaultPort) return (readMaybe port) It gets a port from an environment variable, if it can, otherwise a default port. Co…

Ouch. That function is actually written in a pretty convoluted and redundant way. getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort >= readMaybe That's starting to border on over-terse, so you could expand the bind operator into do notation if you wanted to spread it out a bit further. On the other hand, it's also starting to feel over-verbose, using do notation for only a single IO act…

[deleted]

Re: Show HN: I built a poker site with Haskell

#35

Earlier quoted context omitted.

Well, non-programmers are even more helpless in understanding the code, but that's just not the point I'm making. Let's not require everyone to couch every statement in disclaimers, especially such an ancillary one. And you surely can understand that code is trying to read a port or use a default one.

> And you surely can understand that code is trying to read a port or use a default one. In programming languages which use paradigms I'm more familiar with, yes. In Haskell, not so much, which is the entire point of this thread.

> In Haskell, not so much, which is the entire point of this thread.

Yes, that's my point, too. I'm not sure what you're arguing with.

That you don't understand even the most trivial snippet in the code base is only a point in my favor. You're picking beef with an irrelevant detail and confusing it for disagreement.

Remember, I was replying to someone who is trying to show that Haskell isn't so hard once you break down a snippet. I pointed out that the snippet was the most trivial selection they could have picked, that the rest of the code is even harder so it's not a very big consolation. You chimed in that even the simplest snippet was still alien to you.

Re: Show HN: I built a poker site with Haskell

#36

Earlier quoted context omitted.

Ouch. That function is actually written in a pretty convoluted and redundant way. getSocketAPIPort :: Int -> IO Int getSocketAPIPort defaultPort = do maybeEnvPort >= readMaybe That's starting to border on over-terse, so you could expand the bind operator into do notation if you wanted to spread it out a bit further. On the other hand, it's also starting to feel over-verbose, using do notation for only a single IO act…

tbf, I (as a person with some very basic haskell understanding) can more or less read the parent's code, but can't make heads or tails out of yours. "Convoluted and redundant" is in the eye of the beholder I guess

Is it?

There's no part of you that looks and that and wonders why it's stuffing return into every leaf of a branching structure instead of just leaving it at the root? That's just objectively redundant.

And there's no part of you that's wondering why it's using nested branches to implement the railway oriented programming pattern? That's just objectively more convoluted than using the combinators that abstract that out and coalesce all the failure branches into one spot.

My second version has an extra really nice property. It consists of three subexpressions that can be understood in totality in isolation from the rest of the code. It is compositional code of the sort we all claim we want to work with.

What my code does have as a real downside is a much higher burden of knowledge to understand. You have to know much more of the contents of the base library. You have to be familiar with how idioms like the aforementioned railway oriented programming work.

But that knowledge has its rewards. You get to reduce manual plumbing in your own code, replacing it with standard library plumbing. When you know Haskell, the standard plumbing fades into the background. I guess it's like what lispers talk about with their parenthesis.

So yes, there is an additional burden in understanding my versions of the code. But that burden amortizes very nicely over a lifetime of getting the advantages of having all that plumbing just there when you need it.

Re: Show HN: I built a poker site with Haskell

#37
post #2

So, I know literally nothing about Haskell, and I would rate my knowledge of functional programming theory as 'beginner' at best, but I still get baffled every time when reading Haskell code that implements anything other than something trivial like a fibonacci sequence. The poker server code looks extremely tidy and well engineered, so that can't be the problem, but to me it's utterly incomprehensible. It seems like…

Game servers aren’t typical. Texas Hold’Em especially.

Like a chat application is also multi-user real-time. It’s obvious that when a chat participant disconnects you hold onto the messages to deliver to them for later. When you disconnect from a Texas Hold’em online and you were small blind, what should you do? Wait? Shift the blinds over? The next player in line gets big or small? Copy the leading product’s behavior? It’s hard to reproduce all the states in someone else’s live, production game.

It’s not at all obvious and this logic has to live somewhere. It touches a bajillion things, like the raw connection state, timers, transient and long-term persistent state. Your programming language isn’t going to make it simpler for you. It can’t just hide in your database’s conflict resolution or some AWS service.

This is a great Haskell demo because it shows that you can’t hide this code anywhere. It stares back at you with all its ugliness.

Re: Show HN: I built a poker site with Haskell

#39

Earlier quoted context omitted.

> And you surely can understand that code is trying to read a port or use a default one. In programming languages which use paradigms I'm more familiar with, yes. In Haskell, not so much, which is the entire point of this thread.

> In Haskell, not so much, which is the entire point of this thread. Yes, that's my point, too. I'm not sure what you're arguing with. That you don't understand even the most trivial snippet in the code base is only a point in my favor. You're picking beef with an irrelevant detail and confusing it for disagreement. Remember, I was replying to someone who is trying to show that Haskell isn't so hard once you break do…

>Remember, I was replying to someone who is trying to show that Haskell isn't so hard once you break down a snippet.

That's not what I was trying to show, and I'm not sure how you got that sense. I was trying to show that even the most simple snippet requires a lot of background knowledge to understand.

Post reply on HN