Hopefully Idris will become production-ready and I'll have the best of all worlds, but that's a way away.
- I don’t like lazy
- ocaml is like Haskell but strict
- I want higher kinded types
(note this is a feature you can turn on in Haskell but ocaml does not have it[1]. The commenter is implying that ocaml is therefore not a sufficient strict Haskell)
- you say that higher kinded types are an option, which is true for Haskell but not for ocaml which is being proposed.
[1] there are ways to sort-of do higher kinder types in ocaml but they are not ergonomic and feel a bit hacky to me.
It's also a surprise to me that you seem to say that OCaml is Haskell without the lazy eval being the default, mind expanding on that? Quite interesting.
* Haskell is pure whereas Ocaml is not
* Haskell has a great story for parallelism whereas Ocaml does not
* Haskell has ad-hoc polymorphism (via typeclasses) whereas Ocaml does not
* Ocaml has an exceptionally powerful module system whereas Haskell does not
That said, the notion of purity is a bit BS. At some point in your program you are definitely going to invoke the world-at-large. Whether you do it through IO(), tap your nose and call it "pure" or you do it other way is all down to semantics (not in the PLT sense of the word - the PLT term to use would be "pragmatics"). The core of both Ocaml and Haskell are pure functions.
Also, Ocaml doesn't really need typeclasses. Modules. Modules are everything
But I worry that by chasing backwards compatibility and not just saying "guys, you need to modernise your libraries to do X and Y, otherwise you will never be Multicore OCaml-friendly" the maintainers will invite a lot of legacy cruft -- which will now be subtly broken -- that they will either have to fix themselves or just concede that it's impossible.
Then again, I suppose they don't want the Python 2 vs. Python 3 split (or Perl 5 vs. Perl 6 / Raiku; EDIT: It's actually "Raku" as a commenter below clarified). But I fear it will happen anyway due to the reasons above.
I very quickly fell in love with OCaml but eventually settled at Rust for these, and a few other reasons. It's an otherwise excellent language and has one of the most underrated compilers on the planet. It's a shame that it's moving so slowly... :(
EDIT: As for safe parallelism, here's what one of the maintainers said soon ago: https://news.ycombinator.com/item?id=22735176
It looks like they prefer to do the lowest level possible so people can build their own abstractions on top. Completely fair though, not criticising.
But algebraic data types, exhaustive pattern matching, and modules make it the next best thing, I think.
I get it, you want to work on interesting scientific problems and/or you work for Jane Street (a huge financial company); but the lack of desire to circle back to certain basics and nail them once and for all sends a hostile message to me as a programmer looking to add OCaml to his tool-belt. It tells me "we don't care".
But the problem is that strings must be a built-in feature in any programming language that wants to be taken seriously (with an exemption for specialized ones that don't need strings, like GLSL). What would you think of a hotel that doesn't have mattresses but allows guests to bring their own?
Haskell gets twice as many as Python (say) because of the desire to have strict and lazy versions.
Multiple moderately bad string types, with strict typing that exacerbates interoperability problems, are worse than one really bad string type (like char pointers in C) or nothing at all.
See also the insightful comment of plinkplonk on that thread.
"Purity is more important than, and quite independent of, laziness
"The next ML will be pure, with effects only via monads. The next Haskell will be strict, but still pure.
"Still unclear exactly how to add laziness to a strict language. For example, do we want a type distinction between (say) a lazy Int and a strict Int?"
From plinkplonk:
"It is through insisting on laziness as default and solving some of the problems encountered (via monads for e.g) that he arrived at the position that "the next Haskell will be strict". He also notes some open problems with adding laziness into a statically typed strict language (slide 40 "Still unclear exactly how to add laziness to a strict language. For example, do we want a type distinction between (say) a lazy Int and a strict Int?")."
Which has already been proven wrong, by the way, by F#, which appeared in 2005 ("Wearing the hair shirt" was from 2003), so I think the comment is not to be taken too literally.
https://www.microsoft.com/en-us/research/publication/wearing...
Laziness enforced purity in the beginning. Now that we collectively know that reasoning about effects is a good thing we can remove laziness but keep that part.
I'd say it was a happy little mistake.
FTFY
- GHC can do less unpacking (moving heap allocations to registers)because of laziness
- laziness as an implementation detail is slow
To implement laziness, GHC puts a closure with it's environment on the heap. When the value is used for the first time, the closure is called. Then the result is put on the heap, the closure is replaced with an indirection to the result, and the program continues.
But this also has some advantages:
- For values that might be used zeor or multiple times, this often actually saves time on average over both strict or call-by-name evaluation
- This is faster than any equivalent code you can write by hand because compiler and runtime system heavily optimize around it
- This gives you mutation through the backdoor which allows asymptotic improvements over strict pure languages in some cases
But the main thing is that laziness allows runtime dead code elimination - if you have an unpacked vector of pairs and only use the left element of each pair, only those values will be allocated - still in a dense bytearray.