Sat Jan 19 20:01:35 CET 2013
Seems not trivial:
- Won't work for expressions: some other "context" is necessary, i.e. let-values.
- Might need separate partial evaluation step to determine # outputs
Function output arity is simple:
;; This one is simpler: all primitive functions are replaced by
;; `void', mapping anything to #void, which yields a (values #void
;; ...) result where only the size is significant.
(define (ai-arity p)
(define eval-void (p void void void))
(define nb-in (procedure-arity eval-void))
(define args (for/list ((i (in-range 0 nb-in))) #f))
(lambda () (apply eval-void args))
(values nb-in nb-out))
However, this raises the issue that inner functions cannot be
abstractly evaluated. It might be best to remove the "poor man's
module" approach now and use a different mechanism for propagating
Anyway, why not use the same approach as in Haskell implementation?
Type classes are implemented by threading the semantics through the
code, passed as a first argument to each function.
A similar approach might work better than units. Somehow it seems
that units are not modular enough..
I.e. using syntax-parameterize.
(define-syntax-parameter ai-prims #f)
(define-syntax-rule (ai-lambda (arg ...) expr)
(lambda (p arg ...)
((ai-prims (lambda _ #'p)))
(define-struct ai (add mul integrate))
(define-syntax-rule (add a b) ((ai-add (ai-prims)) a b))
(define-syntax-rule (mul a b) ((ai-mul (ai-prims)) a b))
(define-syntax-rule (integrate a b) ((ai-integrate (ai-prims)) a b))
Next is how to do this for nesting ai-lambdas? Basically this needs a
re-implementation of %app