-
Notifications
You must be signed in to change notification settings - Fork 468
move Lazy module to Stdlib #7399
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't seem necessary to keep deprecated methods here. They were introduced in v12-alpha.1. =) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @namenu they were moved in v12-alpha.1 but they were already in a |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/*** | ||
This module provides a type `Lazy.t` and functions to create and | ||
manipulate lazy values. A lazy value is a value that is not | ||
computed until it is needed. This is useful for deferring | ||
computations that may be expensive or unnecessary. | ||
*/ | ||
|
||
/** | ||
The type of a lazy value. `Lazy.t<'a>` represents a lazy value | ||
that will eventually yield a value of type `'a` when accessed. | ||
The value is computed only once, and the result is cached for | ||
subsequent accesses. If the computation raises an exception, | ||
the same exception is raised again on subsequent accesses. | ||
*/ | ||
type t<'a> = lazy_t<'a> | ||
|
||
/** | ||
`Lazy.make(f)` creates a lazy value from `f` which is the | ||
computation to be deferred of type `unit => 'a`. | ||
The function returns a lazy value of type `Lazy.t<'a>`. | ||
The computation is not executed until the lazy value is accessed. | ||
|
||
## Examples | ||
```rescript | ||
let lazyValue = Lazy.make(() => { | ||
// Some expensive computation | ||
Console.log("Computing...") | ||
42 | ||
}); | ||
lazyValue->Lazy.get->assertEqual(42) | ||
``` | ||
*/ | ||
let make: (unit => 'a) => t<'a> | ||
|
||
/** | ||
`Lazy.get(x)` forces the suspension `x` and returns its result. | ||
If `x` has already been forced, `Lazy.get(x)` returns the | ||
same value again without recomputing it. If it raised an | ||
exception, the same exception is raised again. | ||
Raise `Undefined` if the forcing of `x` tries to force `x` itself | ||
recursively. This is a runtime error. | ||
*/ | ||
let get: t<'a> => 'a | ||
|
||
/** | ||
`Lazy.isEvaluated(x)` returns `true` if the suspension `x` has | ||
already been forced and did not raise an exception. Otherwise, | ||
it returns `false`. This is useful for checking if a lazy value | ||
has been computed before accessing it. | ||
|
||
## Examples | ||
```rescript | ||
let lazyValue = Lazy.make(() => { | ||
// Some expensive computation | ||
Console.log("Computing...") | ||
42 | ||
}) | ||
Lazy.isEvaluated(lazyValue)->assertEqual(false) | ||
lazyValue->Lazy.get->assertEqual(42) | ||
lazyValue->Lazy.isEvaluated->assertEqual(true) | ||
``` | ||
*/ | ||
let isEvaluated: t<'a> => bool | ||
|
||
exception Undefined | ||
|
||
/** | ||
`force(x)` forces the suspension `x` and returns its result. | ||
If `x` has already been forced, `Lazy.force(x)` returns the | ||
same value again without recomputing it. If it raised an exception, | ||
the same exception is raised again. | ||
Raise `Undefined` if the forcing of `x` tries to force `x` itself | ||
recursively. | ||
*/ | ||
@deprecated("Use `Lazy.get` instead") | ||
let force: t<'a> => 'a | ||
|
||
/** | ||
`force_val(x)` forces the suspension `x` and returns its | ||
result. If `x` has already been forced, `force_val(x)` | ||
returns the same value again without recomputing it. | ||
Raise `Undefined` if the forcing of `x` tries to force `x` itself | ||
recursively. | ||
If the computation of `x` raises an exception, it is unspecified | ||
whether `force_val(x)` raises the same exception or `Undefined`. | ||
*/ | ||
@deprecated("Use `Lazy.get` instead") | ||
let force_val: t<'a> => 'a | ||
|
||
/** | ||
`Lazy.from_fun(f)` creates a lazy value from `f` which is the | ||
computation to be deferred of type `unit => 'a`. | ||
The function returns a lazy value of type `Lazy.t<'a>`. | ||
The computation is not executed until the lazy value is accessed. | ||
*/ | ||
@deprecated("Use `Lazy.make` instead") | ||
let from_fun: (unit => 'a) => t<'a> | ||
|
||
/** | ||
`from_val(v)` returns an already-forced suspension of `v`. | ||
This is for special purposes only. | ||
*/ | ||
@deprecated("Use `Lazy.make` instead") | ||
let from_val: 'a => t<'a> | ||
|
||
/** | ||
`is_val(x)` returns `true` if `x has already been forced and | ||
did not raise an exception. | ||
*/ | ||
@deprecated("Use `Lazy.isEvaluated` instead") | ||
let is_val: t<'a> => bool |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -1,26 +1,26 @@ | ||||||||
// Generated by ReScript, PLEASE EDIT WITH CARE | ||||||||
|
||||||||
import * as Lazy from "rescript/lib/es6/Lazy.js"; | ||||||||
import * as Stdlib_Lazy from "rescript/lib/es6/Stdlib_Lazy.js"; | ||||||||
|
||||||||
function fix() { | ||||||||
return { | ||||||||
TAG: "Fix", | ||||||||
_0: Lazy.from_fun(fix) | ||||||||
_0: Stdlib_Lazy.from_fun(fix) | ||||||||
}; | ||||||||
Comment on lines
+8
to
9
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stdlib_Lazy.from_fun is used here, but the new API exports the lazy function creation as 'make'. Replace 'Stdlib_Lazy.from_fun' with 'Stdlib_Lazy.make' to avoid potential runtime errors.
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point from Copilot, but this test file is a bit weird anyway, as it doesn't actually run any code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes those are the tests I don't fully understand ^^ |
||||||||
} | ||||||||
|
||||||||
function unfixLeak(_f) { | ||||||||
while (true) { | ||||||||
let f = _f; | ||||||||
_f = Lazy.force(f._0); | ||||||||
_f = Stdlib_Lazy.force(f._0); | ||||||||
continue; | ||||||||
}; | ||||||||
} | ||||||||
|
||||||||
function unfix(p) { | ||||||||
while (true) { | ||||||||
let h = p.contents; | ||||||||
p.contents = Lazy.force(h._0); | ||||||||
p.contents = Stdlib_Lazy.force(h._0); | ||||||||
}; | ||||||||
} | ||||||||
|
||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in scope of this PR, but once all "lazy" magic is removed from the compiler (see also #6960), this could just be an abstract type here (instead of a predefined type
lazy_t
from predef.ml).