News for hackers. Stuff that matters.
Re:PureScript and Haskell by yoneda on Friday February 26, 2021 @08:32PM (#26281862)
This is a great writeup, and I just want to offer a counterpoint regarding the eager vs. lazy trade-offs.

I found this article really helpful for explaining why laziness is important: http://augustss.blogspot.com/2011/05/more-points-for-lazy-ev...

In particular, scroll down to the "Reuse" section. Lazy evaluation enables you to compose functions to build new functions with the right performance characteristics (constant factors aside), as in:

  any :: (a -> Bool) -> [a] -> Bool
  any p = or . map p
In an eager language, predicate `p` would have to be evaluated on every element in the list, even if the predicate is already satisfied after the first element. So instead you'd have to write this function in an ad hoc way with explicit recursion/looping, without being able to reuse the more primitive functions.

Of course, in an impure language, laziness can't be the default because you wouldn't be able to reason about when your side effects occur. But in my mind that's an argument for purity rather than an argument for eagerness.

BTW, comparing "strict" vs. "lazy" is a category error. The proper comparison would be either "strict" vs. "non-strict" or "eager" vs. "lazy". The former is in reference to the denotational semantics, whereas the latter characterizes the operational semantics.

Re:PureScript and Haskell by jeeeb on Friday February 26, 2021 @09:20PM (#26282092)
Your example relates to the properties of lazy sequences, which are generally acknowledge as a good idea and implemented as part of the standard libraries of most major languages (e.g. Java, C#, Python 3).

For example, the following Python code has the same evaluation semantics.

  def any_predicate(predicate, iterable):
      return any(map(predicate, iterable))
What's less clear is whether using lazy evaluation everywhere is a good idea. Certainly it has some really nice properties - for example it blurs the distinction between macros and functions by allowing arguments to be lazily evaluated.

However, It can lead to hard to debug errors (as the error will not necessarily surface at the call site), and make it hard to reason about the performance and memory usage of code.

Re:PureScript and Haskell by wyager on Saturday February 27, 2021 @01:09AM (#26283060)
> the error will not necessarily surface at the call site

One of the positive side effects of this fact is that Haskellers have been forced to figure out proper error handling strategies, for the exact same reason Haskellers were forced to figure out proper effect management strategies (e.g. monadic IO). In fact, errors and effects are part of the same problem.

In imperative languages, the temptation to use evaluation sequencing as a hack for handling errors and effects has proven too tempting for every pre-Haskell language I'm aware of.

Re:PureScript and Haskell by jiyinyiyong on Sunday February 28, 2021 @10:58PM (#26299563)
> However, It can lead to hard to debug errors (as the error will not necessarily surface at the call site), and make it hard to reason about the performance and memory usage of code.

Agreed. Clojure uses lazy sequence by default. After ClojureScript is compiled to js, sometimes it's crazily hard to figure out why the error happened due to the obscure call site in the code.

Re:PureScript and Haskell by mietek on Saturday February 27, 2021 @05:32AM (#26283910)
> [laziness] blurs the distinction between macros and functions by allowing arguments to be lazily evaluated.

Good point. Interestingly, there doesn’t seem to be a commonly known notion of evaluation that would blur the distinction between FEXPRs and functions — that is, one that would allow “functions” access to the unevaluated syntactic form of the arguments.

Re:PureScript and Haskell by dunham on Saturday February 27, 2021 @01:05PM (#26286714)
Doesn't "vau" in the kernel language do this? Or does that not qualify as commonly known?
Re:PureScript and Haskell by mietek on Saturday February 27, 2021 @06:00PM (#26288977)
Indeed, FEXPRs are Kernel’s entire thing. However, vau is a language primitive, not a notion of evaluation, such as eager or lazy.