5 ms·
> freeing yourself from the arbitrary syntactic boilerplate that most languages have. And coming up against arbitrary three-four-character combinations people
by dmitriid 6y ago
> freeing yourself from the arbitrary syntactic boilerplate that most languages have.
And coming up against arbitrary three-four-character combinations people come up with for their operators.
Terser does not automatically mean better (or J and K would've won that argument a long time ago).
At least mainstream languages are usually consistent. A method call is a method call. A structure is a structure. What is this ungodly mess?
type API = "polls" :> Get '[JSON] [Poll]
:<|> "polls" :> Capture "question_id" Int :> Get '[JSON] Poll
:<|> "polls" :> Capture "question_id" Int :> "results" :> Get '[JSON] PollResults
- masklinn 6y ago> And coming up against arbitrary three-four-character combinations people come up with for their operators. Nothing requires that though, it's more of a debatable community habit, similar to the overly abstract or cutesy names. > At least mainstream languages are usually consistent. A method call is a method call. A structure is a structure. What is this ungodly mess? Haskell is arguably way more consistent there: "mainstream languages" also have operators, often overloadable, you just can't declare your own operators in most of them. Haskell simply allows sigils to be used as infix functions, aka binary operators, and furthermore allows those to be used as prefix functions, as well as prefix binary functions to be used infix.
- kazagistar 6y agoThat makes it more consistent to write, but less consistent when reading.
- TheSmoke 6y agoit might look weird to the foreign eyes but essentially this is just a typed api with 3 routes. /polls returns an array of Poll. /polls/:question_id returns a Poll. /polls/:question_id/results returns a PollResults. the thing you call a mess is the combination of type level operators which helps you describe your API which is the essence of functional programming.
- jraph 6y agoIt does look weird to the foreign eyes, because it looks nothing like what you may encounter in your life when learning a natural language or math. As a consequence, this notation cannot leverage any intuition at all. You need to learn the syntax. Nothing is explicit and helps you guess if you haven't. It is telling that this is "just a typed api with 3 routes". Somebody who haven't learned all the specific bits of Haskell (or, for that matter, specific bits of this program that may be overloading strange operators to define routes) won't even start to guess that it's defining routes. They can guess it is defining an API, thanks to the words used at the beginning of the snippet. And even though you told us that it's defining a route, I cannot figure out what it is really doing. It is just not clear. So, yes, it looks like a mess for the foreign eye. I have no doubt it looks straightforward as soon as you learn Haskell and practice a bit. Mainstream languages also look gibberish for people who haven't learned programming though. That's also something that we have to humbly keep in mind while, as foreigners who practice other programming languages, we discuss the syntax of Haskell.
- dmitriid 6y agoIt's also funny (ironic?) how they defend this syntax while bemoaning mainstream languages' syntax.
- jraph 6y agoMainstream languages probably look very verbose, clunky and ugly to many people who like Haskell-like syntaxes more. I feel this way when looking at a Pascal code. But they have to keep in mind that this verbosity is a feature and they should not act surprised that many people like it. This verbosity makes many things explicit, and I'll not be the first to think that "Explicit is better than implicit". Conciseness is also a feature, though.
- mrkeen 6y ago> What is this ungodly mess? type API = "polls" :> Get '[JSON] [Poll] :<|> "polls" :> Capture "question_id" Int :> Get '[JSON] Poll :<|> "polls" :> Capture "question_id" Int :> "results" :> Get '[JSON] PollResults Delightful :D The API is the route "/polls" accessed via GET, returning a list of Polls in JSON format or the route "/polls/question_id" where question_id is an Int, accessed via GET, returning a Poll in JSON format or the route "/polls/question_id/results" where question_id is an Int, accessed via GET, returning PollResults in JSON format
- runeks 6y agoSince we’re discussing syntax I’d like to question the necessity of the tick preceding [JSON]. Could we leave out this tick given that the kind of this parameter is [*]?
- pyrale 6y agoFor reasons that are not easy to explain, no. [JSON] and '[JSON] have different meanings. Here, '[JSON] does not refer to a list of json files, but to a type-level list of the mimetypes that can be returned. You could see '[JSON, PNG] instead, which would make no sense in the context of a list type declaration. The genius of Servant is that the DSL doesn't require you to know how '[] is implemented and why it's different from [], you just have to know the DSL.
- quickthrower2 6y agoYep as soon as you make it look like natural language, compilers magically become intelligent and context aware readers of prose, not the old-school pedantic expectors of syntax rules.
- pyrale 6y ago> What is this ungodly mess? An eDSL ? Much like every DSL, it requires to invest some time learning, and gives you something if you take that time. It's not really specific to Haskell. Back when I was doing some Java, I had to learn the logic of maven xml files, and it was exactly the same kind of investment-for-future-reward.