aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
diff options
context:
space:
mode:
authorGravatar Peter McGoron 2025-08-31 20:38:05 -0400
committerGravatar Peter McGoron 2025-08-31 20:38:05 -0400
commita1cb2ba03ce8d39bc0bcfd8d54ecc878670ca4ee (patch)
tree1fe5aebe4443cfbe6f1b083d3a8c7f14235d4d47 /README.md
hascheme init -- figured out some space leak issues
Diffstat (limited to 'README.md')
-rw-r--r--README.md47
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.