This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Attached is an experimental patch to Kawa to better support a lazy evaluation style, including multi-threaded futures.
We already have: (future EXP) - Evaluate EXP in a new thread. Return a "future" object, which is a wrapper for the *eventual* result of EXP. (delay EXP) - Return a promise for the value of EXP. (force LAZY) - Where LAZY is the result of future or delay. Waits until EXP is evaluated and returns the value.
delay and force enable "lazy evaluation" and future enables a convenient way to evaluate using multiple threads. But having to sprinkle force all over the code makes for ugly code.
The patch implements "auto-forcing" - force is called automatically "when needed", which roughly means when the specific value is needed for a core operations, like arithmetic or comparisons.
(define (squares start end) (if (= start end) '() (cons (* start start) (future (begin (sleep 1) (squares (+ start 1) end))))))
(define (print-list l) ::void (cond ((eqv? l '())) (else (display (car l)) (newline) (print-list (cdr l)))))
Combining auto-forcing with type-declarations raises the question how those interact: Should the type "integer" be an immediate (already-forced) gnu.math.IntNum, or should it be a value that evaluates to an IntNum *after forcing*? A type declaration in a pure functional language like Haskell chooses the latter: An "integer" value is one that when forced is an integer. However, for a hybrid language like Kawa it seems better to make "integer" mean an immediate forced IntNum:
integer - an immediate gnu.math.IntNum value lazy[integer] - a value that evaluates to an IntNum. Maps to the Java type gnu.mapping.Lazy<gnu.math.IntNum>.
This way of doing it provides (I think) better control and less surprise to programmers. More importantly (for Kawa) is it makes it easier to write high-performance code with less overhead: Auto-forcing happens during type-conversion, and not on each operation, as long as we have the necessary type information. For example:
(define (square i::integer) (* i i)) (define x::object 4) (square x) ;; implicit force (define y::integer 5) (square y) ;; no force needed
In this example there is no forcing code in the square method, and no forcing needed if a known-non-lazy value is passed to a known function with a non-lazy parameter.
(It would probably be feasible to invert the convention, so that you have a type integer that eventually evaluates to an IntNum and a type eager[integer] that is forced. However, that seems more difficult and is incompatible with existing code.)
eq? is low-level and does not do auto-forcing eqv? equal? = do auto-forcing instanceof tests are TDB - currently does not do auto-forcing. display does auto-forcing; write does not.
Please try it out and let me know what you think. I'm sure there are bugs, most likely places where force is missing. -- --Per Bothner per@bothner.com http://per.bothner.com/
Attachment:
lazy.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |