Re: Perform calculations at compile time and load the result

From: Adam Warner (usenet_at_consulting.net.nz)
Date: 10/28/04


Date: Thu, 28 Oct 2004 11:44:20 +1300

Hi Marco Baringer,

>> I've realised I can simply compute the result at macro expansion time:
>>
>> (defmacro macro-time-value (&body body)
>> (eval `(progn ,@body)))
>
> you could also check out load-time-value

Thanks. That's what I modelled the name of my macro on.

This demonstrates that load-time-value reevaluates the form at load time
(if it didn't it would only return 3, not print 1 and 3. Which means it
will not save me any load time computation):

(eval-when (:compile-toplevel :load-toplevel :execute)
  (defvar *variable* (load-time-value (print (+ (progn (print 1)) 2)))))

My macro time evaluation was unsuccessful for two reasons:

(a) Some implementations (CLISP, ABCL) don't cope well with huge fas
files. CLISP appeared to freeze for minutes but it eventually managed to
write out a 10MB file. ABCL bombed.

CLISP couldn't read a hash table of string literals back in without
setting an appropriate string encoding when loading the file. This appears
to preclude treating strings as arbitrary octet sequences.

(b) I'm creating multiple EQ hash tables of strings. I do not see there is
any portable way to ensure that all references to the same string literal
are coalesced to the same pointer. This means I must postpone creating the
hash tables until load time.

I was most impressed by SBCL's performance. Macro time evaluation wasn't
any slower than run time evaluation and the loading of the fasl file was
acceptably fast. CMUCL would have been using its interpreter (perhaps I
should wrap macro-time-value in a compile form!)

Regards,
Adam