9 ms·
This is a great post. However, there are so many more things that should be on here! If I could suggest just one, it would be lazy evaluation by default, which
by spekcular 6y ago
This is a great post. However, there are so many more things that should be on here!
If I could suggest just one, it would be lazy evaluation by default, which makes it exceedingly hard to reason about time and space complexity.
Also relevant is the author's article on problems using Haskell on Arch Linux: https://dixonary.co.uk/cabal-2020 https://dixonary.co.uk/cabal-2020
- dunefox 6y agoThat's not a pain point, that's a core part of the language. If you don't want that use Ocaml.
- pdimitar 6y agoThen maybe an argument can be made that this should be front-and-center in the docs? (Note that I am not claiming anything though, haven't checked Haskell's docs in a while.) 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.
- dunefox 6y agoFrom what I've seen of Ocaml it's similar but with strict evaluation. Then again, it has no support for unicode strings so I never really looked at it again. But algebraic data types, exhaustive pattern matching, and modules make it the next best thing, I think.
- pdimitar 6y agoYeah, one of the things I dislike in it as well. UTF-8 should be built-in, not relied upon by libraries, even if they are commonly used by everyone.
- HelloNurse 6y agoLack of well-made strings puts the language as a whole in a bad light: if you don't bother supporting fundamental practical needs, asking me to use your experimental, half-engineered proof of concept is arrogant.
- pdimitar 6y agoAbsolutely. I know many engineers hate the word but this is simply extremely bad marketing. 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".
- dunefox 6y agoI even spent two evenings getting the tools set up so that I can install a library that apparently supports unicode. I got nowhere. The core language might be interesting, but everything around it - including unicode strings - is a mess.
- tome 6y agoThere are well-made string types for Haskell! People are just understandably confused that there are so many of them.
- HelloNurse 6y agoI'm sure that very smart people have risen to the challenge of supporting strings in Haskell, and it is therefore possible for a sufficiently motivated user to process text decently after all. 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?
- wk_end 6y agoThey're similar but not really the same. The big differences are: * 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
- spekcular 6y agoNote that multicore OCaml is almost ready: https://discuss.ocaml.org/t/multicore-ocaml-may-2020-update/5898 https://discuss.ocaml.org/t/multicore-ocaml-may-2020-update/...
- vkazanov 6y agoOh-h-h-h... I've heard this so many times before :-)
- yaantc 6y agoThis time is different ;) Look at the end of the GP link on multi-core Ocaml progress report: everything under the "OCaml" title is work on the upstream compiler. It's still limited, but the upstreaming process has started.
- ghostwriter 6y agoHaving an SMP compiler/runtime is half of the story, the other half is safe parallelism. I expect another decade is going to be spent on chasing bugs due to mutable data escape hatches in OCaml world.
- pdimitar 6y agoThis is my main worry about Multicore OCaml. You nailed it. There's a lot of legacy in the ecosystem -- which is not a bad thing at all! Many people appreciate stable environments and learn to circumvent their problems. All completely fine and we all do it. 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 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.
- Gormisdomai 6y agoCan't it be both?
- dunefox 6y agoSure, but I believe that Haskell is great just because it tries stuff that isn't in other languages, like laziness by default. If it's really a pain point you can always switch to Ocaml or others.
- logicchains 6y agoSeems like an overreaction to suggest someone move to another language when there's a very simple solution to laziness in Haskell: the -XStrict language pragma.
- Vosporos 6y ago>If it's really a pain point you can always switch -XStrict on FTFY
- hopia 6y agoIs that flag really ever smart to switch on? I've heard StrictData makes a lot more sense but turning Strict on prevents the compiler from making some quite crucial optimizations, resulting in degraded performance.
- logicchains 6y agoWhich optimisations does it prevent? I've heard laziness prevents a lot of optimisations, because it makes bottom an instance of every type, and the compiler has to account for that.
- Tarean 6y agoThere are two main parts to this: - 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.
- spekcular 6y agoIIRC, even Simon Peyton Jones has stated lazy evaluation was a design mistake.
- dunefox 6y agoI'm gonna need a source for that.
- spekcular 6y agoThe exact quote and source (powerpoint slides) are in this HN comment: https://news.ycombinator.com/item?id=1924061 https://news.ycombinator.com/item?id=1924061. See also the insightful comment of plinkplonk on that thread.
- dunefox 6y agoThat has to be the worst set of slides I have ever seen. Thanks.
- danielscrubs 6y agoComic Sans is arguably an excellent font for learning. It's funny how the world works. https://www.dictionary.com/e/comic-sans-font/ https://www.dictionary.com/e/comic-sans-font/
- deleted 6y ago[deleted]
- danielscrubs 6y agoFrom what I understand of the talk: 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.
- mcguire 6y agoThat's the "Wearing the Hair Shirt" talk, for those that are familiar. "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?")."
- TheOtherHobbes 6y agoRecursive Big O that isn't defined until runtime is not usually considered a good thing.
- lmm 6y agoI want higher-kinded types (heck, I want kind polymorphism) though. Hopefully Idris will become production-ready and I'll have the best of all worlds, but that's a way away.
- dunefox 6y agoIsn't there a compiler extension for hkt?
- dan-robertson 6y agoNot for ocaml
- dunefox 6y agoI meant for Haskell, did you mean for Ocaml originally?
- dan-robertson 6y agoIf you look at the comment chain, you see: - 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.
- saityi 6y agoIn case anyone is curious about [1], there is a paper called Lightweight higher-kinded polymorphism -- http://ocamllabs.io/higher/lightweight-higher-kinded-polymorphism.pdf http://ocamllabs.io/higher/lightweight-higher-kinded-polymor... -- that goes into some of the possible encodings.
- deleted 6y ago[deleted]
- logicchains 6y agoThe -XStrict language extension is a lifesaver here, for when you want a language like Haskell but without lazy evaluation.
- runeks 6y agoExcept it only lets you define your own strict functions and data structures — i.e. you still need to consider laziness when using existing libraries.
- zozbot234 6y agoIt's also not a very principled solution. It would be better to use focusing and/or polarized logic so as to allow both "strict" and "lazy" data and functions on a first-class basis. Then language-level options could be used to manage "defaults" as a matter of language syntax, for the programmer's convenience.
- whateveracct 6y agoPretty much every time I turn -XStrict on for some module I'm trying to optimize, performance gets worse. Laziness gets a lot of flak for being hard to reason about. I disagree - it's just different. But I never hear anyone acknowledge that laziness can bring compositional performance benefits no other language can sniff.
- jose_zap 6y agoThat’s because full laziness is actually an optimization strategy that Haskell uses to make programs faster. You are completely right about laziness being a big plus for composing functions.
- ghostwriter 6y ago> If I could suggest just one, it would be lazy evaluation by default, which makes it exceedingly hard to reason about time and space complexity In what scenarios does it make hard to reason about those complexities? I find GHCs profiler statistics clear and meaningful[1], I lack the efficiency of its reports in other environments I work with, namely Python. [1] https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/profiling.html https://downloads.haskell.org/~ghc/latest/docs/html/users_gu...
- runeks 6y ago> In what scenarios does it make hard to reason about those complexities? I’m guessing OP is referring to reasoning about time/space usage by reading code, rather than by running the program.
- ghostwriter 6y agoThis is not trivial in strict languages either, because implementation details of a particular language/library dictate the rules. For instance: l = list(range(N)) for _ in range(M): x = list(l) CPython will have MxN iterations (allocations?), whereas other languages/libraries where data is immutable may decide to optimise the list() constructor and return a reference to the same object when the input is an instance of a list. In lazy-by-default languages I can at least rely on normal evaluation order.
- foldr 6y agoOf course you need to know the semantics of the programming language you're using. The point is that lazy evaluation introduces additional complexity on top of that.
- ghostwriter 6y agothe point is that it's not semantics of a language alone, it's the semantics of the language + the libraries + the data constructors + the flow order. Lazy evaluation doesn't introduce additional complexity on top of that for no good reason, it actually trades a few of these complexities for one additional abstraction that lets you think about your programs in terms of data flows and transformations (instead of allocation semantics at every individual step), where program boundaries define the actual computations to perform and the complexity of the final algorithm. It's an extremely powerful tool and the complexity is justified.
- weareconvo 6y agoFYI: As of the time of this reply, https://dixonary.co.uk/cabal-2020 https://dixonary.co.uk/cabal-2020 returns a 404.
- johnday 6y agoYeah, sorry, my website got nuked from orbit. Hopefully it'll be back up tomorrow.