guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

The case for a non-copying `eval'


From: Ludovic Courtès
Subject: The case for a non-copying `eval'
Date: Wed, 30 May 2007 14:11:10 +0200
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

Hi,

In a program of mine, large mathematical sexps are evaluated as follows:

  (define %pure-math-module
    ;; A confined math module where only math procedures are available.
    (let ((m (make-module)))
      (module-define! m '+ +)
      (module-define! m '- -)
      (module-define! m '* *)
      (module-define! m '/ /)
      (module-define! m 'expt expt)
      (module-define! m 'let* let*)
      m))

  (define (eval-math-expression sexp binding-alist)
    "Evaluate @var{sexp}, a mathematical expression, with bindings
  @var{binding-alist} (a list of name-value pairs)."

    (eval `(let* ,(append '((+ +) (- -) (* *) (/ /) (expt expt))
                          (map (lambda (name+value)
                                 (list (car name+value) (cdr name+value)))
                               binding-alist))
             ,sexp)
          %pure-math-module))


This turns out to be costly because `primitive-eval' (and `eval') copy
the source expression tree before passing it to the evaluator[*].  In my
case, I wouldn't mind if the source sexp were modified by the
evaluation, and I could even feed the evaluator with a pre-memoized
expression actually.

This calls for an even more primitive version of `eval', say
`primitive-eval!', that just invokes `CEVAL ()' without copying the
source tree.  IOW, `primitive-eval' could be written as follows:

  (define (primitive-eval sexp)
    (primitive-eval! (copy-tree sexp)))

What do you think?

Thanks,
Ludovic.

[*] Writing a custom evaluator (in Scheme) doesn't suffer from this
    problem but still doesn't compete with `primitive-eval'.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]