diff options
| author | 2025-08-31 20:38:05 -0400 | |
|---|---|---|
| committer | 2025-08-31 20:38:05 -0400 | |
| commit | a1cb2ba03ce8d39bc0bcfd8d54ecc878670ca4ee (patch) | |
| tree | 1fe5aebe4443cfbe6f1b083d3a8c7f14235d4d47 /README.md | |
hascheme init -- figured out some space leak issues
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..dde64f9 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# HaScheme -- Call By Name Scheme + +This is a library that exports interfaces similar to the R7RS, except +everything is call-by-need and not call-by-value: there is no need to +explictly use `delay` or `delay-force`. Procedures can be written in +ways that look almost identical to regular Scheme. The procedures +return promises which can be forced by non-lazy code. Hence lazy and +non-lazy code can co-exist. + +*Every* procedure in HaScheme is lazy. Values are forced in conditionals, +or explicitly using `!`. + +## Fun (or Pain) with Laziness + +You need to be careful with lazy functions because they can cause +space leaks. This is a problem in general with lazy languages ([like +in Haskell][1]). Here is an example: + +[1]: https://wiki.haskell.org/Foldr_Foldl_Foldl%27 + + (define (list-tail list n) + (if (zero? n) + list + (list-tail (cdr list) (- n 1)))) + +Thunks will build up over time in the list, so it must be forced. + + (define (list-tail list n) + (if (zero? n) + list + (list-tail (force (cdr list)) (- n 1)))) + +Note that `n` is never explicitly forced: it is implicitly forced by the +control flow. + +The first code block has the attractive property that it operates the +same way on finite lists in both Scheme and HaScheme, while the second +one could differ in exotic cases (like promises that return promises). +Instead of writing `force`, the operator `!` is used: + + (define (list-tail list n) + (if (zero? n) + list + (list-tail (! (cdr list)) (- n 1)))) + +where `(! x)` is defined to just be `x` in Scheme. Now the code block +above operates the same in Scheme and HaScheme. |
