
Sharing a private conversation, with the permission of Jerzy. On Sat, Jan 09, 2016 at 11:45:00AM +0100, Jerzy Karczmarczuk wrote:
Again: *exps = 1 + integral exps*
I said that if RHS exps is evaluated, it cannot work.
But if it evaluates to a thunk ... Then, on which premises you call the language "strict"?
Why not?
A thunk could either be a delayed function call, or it could be a memoised thunk, such as OCaml (a strict language) provides
http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lazy.html [...] But in the original expression with exps, you don't delay anything. You don't construct *exps()*, or equivalent. This variable is just variable, lexical atom, and either you evaluate it or not. If not, don't call the language strict. If there is a delay form introduced by the compiler, the language is not strict.
If you don't agree, I suggest that instead of asking "why this doesn't work, it should!" , simply implement it.
Oleg has already provided most of the solution http://okmij.org/ftp/ML/powser.ml The aim is exps = 1 + integral exps In Oleg's framework the answer is let exps = I.fix (fun e -> int 1 +% integ e) In a hypothetical OCaml with typeclasses, this becomes let exps = I.fix (fun e -> 1 + integ e) The remaining objection is the presence of the fix. The solution here is to allow the language to support recursive bindings of lazy values[1], not just of function values. The we could write let rec exps = 1 + integ exps If you still do not agree I would appreciate it if you could explain why such a language a) could not exist, or b) would not be called "strict" If you're still not convinced, consider a lazy language, Haskell--, which doesn't allow recursive bindings of non-function types. In Haskell-- you *cannot* write exps = 1 + integral exps but you have to write exps = I.fix (\e -> 1 + integral e) So we see that the nice syntax "exps = 1 + integral exps" is not due to laziness (since Haskell-- is lazy, but you cannot write that). Instead the nice syntax is due to lazy recursive bindings, and this sugar can exist as well in a strict language as it can in a lazy one. Tom [1] Note that recursive bindings are anyway just syntactic sugar for a fixed point. The definition sum = \x -> case x of [] -> 0 (x:xs) = x + sum xs is (essentially) sugar for sum = fix (\sum' x -> case x of [] -> 0 (x:xs) = x + sum' xs) so adding additional sugar for binding lazy values can hardly spoil anything.