Live data from Hacker News

Grain: A strongly-typed functional programming language for the modern web

grain-lang.org

151–156 of 156 posts

Re: Grain: A strongly-typed functional programming language for the modern web

#151

Earlier quoted context omitted.

Are you asking how they are implemented? You'll have to read the compiler code for that. But the documentation does tell you... "No runtime type errors, ever. Every bit of Grain you write is thoroughly sifted for type errors, with no need for any type annotations." So you never write them, but you get all the benefits as if you did.

Reading the compiler code... well, I think I'll wait they write the documentation. But how's that possible in general? Example, JSON parsing of data from a HTTP request. This is pseudo code # request.data is # {"a":1, "b":2, "c":"a string"} data = parse(request.data) total = data["a"] + data["b"] # 3 total = total + data["c"] # ops! The last line is either a compiler error (how? forbidding input is not an option) or…

I imagine the result here would be the same as in Javascript. This is not an error in Javascript. It would concatenate them and convert to a string. So, you would get the string "3a string". I do see your point though and now agree there should be more documentation covering these cases

Re: Grain: A strongly-typed functional programming language for the modern web

#152
post #142
post #9

Earlier quoted context omitted.

Grain is quite different. Grain is more functional (no classes or context, tuples). Dart compiles to Javascript. Grain compiles to web assembly. Dart requires you to define types. Grain provides type safety and zero runtime errors without ever defining types manually.

So it's more like elm then?

More like elm than Dart, but elm also compiles (transpiles?) to javascript and Grain compiles to web assembly

Re: Grain: A strongly-typed functional programming language for the modern web

#153

Earlier quoted context omitted.

How is "there was a JavaScript error on this page" informational icon any worse than an order total of "undefined" or that the page just doesn't seem to be reacting to clicks? I'd argue that the former is much better UX -- at least the user isn't confused whether it's them that's doing something wrong or it's the page that just shoddily implemented.

> at least the user isn't confused whether it's them that's doing something wrong or it's the page that just shoddily implemented Users generally ignore all messages coming from their computers. They routinely blame their computers for doing things that the computers are not doing at all. Like, oh I can’t find the document I wrote three weeks ago -> obviously my computer is being disobedient. Anyway, I don’t blame th…

Did you read what I said at all?

"Order total: undefined" is hugely different from "There was an error -- maybe just leave the page, yeah?".

Re: Grain: A strongly-typed functional programming language for the modern web

#154

Earlier quoted context omitted.

Yeah in general it’s good to avoid sometimes returning a value and sometimes undefined. There’s an equivalence you can make between a type and a mathematical set, where you say that the type is the set of all possible values for that type. In both JavaScript and math, multiplication of numbers is an operation that has a special property called closure, which means that the return type is the same as the input types.…

Closure is only good in programming if the answers it gives are always useful. Otherwise, you run into the same non local error problem that plagues nulls: the error still happens, but now it happens at some distant usage site, far away from the cause.

Good point. This is exactly what JavaScript does with NaN and the set of numbers, and errors are harder to track down because of it.

Computer numbers in general have all sorts of issues like this where clean mathematical theory is broken. NaN, Infinity and -Infinity, for example, are all similar to absorbing elements[1] under multiplication in the sense that once you get that as a result, you can't do the inverse operation (division) to get back to your original inputs.

Re: Grain: A strongly-typed functional programming language for the modern web

#155

The main page doesn't do a great job of showing what's interesting about Grain vs. JavaScript. The only hint is this: "No runtime exceptions, ever. Every bit of Grain you write is thoroughly sifted for type errors, with no need for any type annotations." Maybe show some examples of errors Grain would catch that JavaScript wouldn't, like Elm does: http://elm-lang.org/

> No runtime exceptions, ever. This is something I wonder about JS: there are a lot of places that exceptions happen in (say) Python that just return `NaN` or `undefined` in javascript. Is it intentional? Is it a good idea? Examples: the multiplication operator essentially never throws. Out-of-bounds (or "not found") lookups don't throw. I suspect the logic is "only throw if you have the wrong type for that operation…

NaN is property of the floating point specification.

https://en.wikipedia.org/wiki/NaN

The purpose of silent propagation is for the expression to be checked at the end of the overall expression rather then have every operation itself be checked. It's a speed optimization. It is by far more user friendly for an invalid operation to throw an error.

For example

for this following operation

(100/2/2/0/2)

without NaNs the system must check 4 operations 100/2, 50/2, 25/2, 12.5/0 for an error. Every arithmetic operation whether it has a division by zero or not will have to have additional checks.

With NaNs the computer just runs through the entire operation with no checks and the user just explicitly does a check for a single NaN at the end. The Maybe Monad operates under the same concept when used as an output type for a division operation.

The same logic applies for javascript "undefined".

Re: Grain: A strongly-typed functional programming language for the modern web

#156
post #124

Earlier quoted context omitted.

They did. The elm-style version is in the standard libraries as: listToMaybe :: [a] -> Maybe a ( http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-M... )

That's a lengthy name for the simple operation of getting the first element of a list if there is one. I would have preferred 'car' :-)

It's a bit verbose, but this kind of thing is far less prevalent in Haskell anyway; most of the time you destructure a list through pattern matching, not explicit head/tail functions.
Post reply on HN