New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comparing lazy values #7021
Comments
Comment author: @garrigue Well, I'm afraid Pervasives.compare makes assumptions about values not moving around while it's comparing them, such that you cannot call ocaml code inside it. What about just defining a normalizing function, that forces all lazy values in your data structure? Then you could just use the standard comparison function after normalizing. |
Comment author: bouaziz That's unfortunate, the point of having lazy values is to avoid forcing them whenever it's not needed. At least when there is no side-effect, the ideal semantics for lazy values would be to behave like non-lazy values, i.e., shouldn't depend on them having been forced or not. Fortunately forced lazy values behave as non-lazy values (except for lazy float).
|
Comment author: @garrigue I agree that the handling of lazy values in ocaml could be more transparent. Damien, do you have something to add here? |
Comment author: @alainfrisch Making lazy more transparent is dangerous in OCaml, since forcing can cause arbitrary side effects, including exceptions and non termination. It's a rather nice property that forcing is always marked by some local-enough syntax (Lazy.force, lazy pattern). |
Comment author: lavi The solution is parhaps to add a Lazy.compare function, preventing all user to be slowed with Pervasive.compare. |
Comment author: bouaziz Yes, worst cases are what they are :) Of course, there can be side-effects, and I understand it can surprising if an exception was thrown from Pervasives.compare; but... it's already the case with non-forced lazy values (I personally think lazy values should have no side-effects). If it had to slow down every compare, it's not worth it, but would there be a cheap way to enter the "slow" mode only when lazy values are encountered? (worst case could be: found Lazy_tag -> start over with the lazy-safe version) Whatever your choice is, it's probably worth adding documentation on lazy with compare/marshal/hash. |
Comment author: @damiendoligez I agree it would be nice to have hashing/comparison/marshaling force the lazy values as needed, but it would be a large amount of difficult work to implement it correctly. In the meantime, it would be good to have the generic functions (especially hashing) throw an exception when they encounter an unforced lazy value. And of course this problem should be mentioned in the documentation of the generic functions. |
Comment author: @yallop I think the correct behaviour is to fail when comparing two unforced lazy values. Having comparison perform forcing doesn't give the right notion of equality. For example, these two lazy values shouldn't be considered equal, just because they both return unit lazy (print_endline "foo") any more than these two functions should be considered equal: fun () -> print_endline "foo" Treating lazy values as run-once computations fits better with how they actually behave in OCaml than treating them as values that have not yet been reduced. |
This issue has been open one year with no activity. Consequently, it is being marked with the "stale" label. What this means is that the issue will be automatically closed in 30 days unless more comments are added or the "stale" label is removed. Comments that provide new information on the issue are especially welcome: is it still reproducible? did it appear in other contexts? how critical is it? etc. |
Original bug ID: 7021
Reporter: bouaziz
Assigned to: @garrigue
Status: assigned (set by bouaziz on 2015-10-16T02:52:34Z)
Resolution: open
Priority: normal
Severity: minor
Platform: x64
OS: Ubuntu
OS Version: 14.04
Version: 4.02.3
Category: standard library
Monitored by: @gasche
Bug description
Comparing lazy values either
I changed a little type in a big data type to be lazy and I got the exception, which seems reasonable knowing how lazy values are represented.
Trying to reproduce on a small example, I didn't get the exception but just wrong results.
Since I am very lazy and I don't want to add compare functions everywhere in my Pervasives.compare-safe data structure, I would love lazy values to be forced when compared.
Steps to reproduce
For (2):
compare (lazy (1+1)) (lazy 2)
returns 1
The text was updated successfully, but these errors were encountered: