Hellu! >> Yes, you're right. >> I even went a little further with that and now I also capture lexical >> environment: >> (use-modules (system syntax) (ice-9 local-eval)) >> >> (define-macro (function args . body) >> `(let ((environment (the-environment)) >> (lexical-names (lexical-names)) >> (procedure (lambda ,args ,@body))) >> (set-procedure-property! procedure 'source '(function ,args ,@body)) >> (set-procedure-property! procedure 'environment environment) >> (set-procedure-property! procedure 'lexical-names lexical-names) >> procedure)) >> >> (where ``lexical-names'' returns the car-s of ``lexicals'', as defined >> at the bottom of >> http://www.gnu.org/software/guile/manual/html_node/Syntax-Transformer-Helpers.html#Syntax-Transformer-Helpers >> ) >> >> So in addition to the source of the procedure, the lexical environment >> can also be retrieved: >> >> (define (procedure-lexicals proc) >> (map (lambda(symbol) >> (cons symbol >> (local-eval symbol (procedure-property proc 'environment)))) >> (procedure-property proc 'lexical-names))) > > I don’t want to sound too dogmatic, but I think you really don’t want to > take that route. ;-) > > The issues with ‘local-eval’ have been discussed at length a year ago or > so on guile-devel. Basically, the problem is that it plays badly with > compilation, and there are usually nicer way to achieve what you want.
Fortunately, calling local-eval isn't strictly necessary, as long as the exciting and powerful `lexicals' macro is allowed. Then, the `function' macro can be defined easily as: (define-syntax function (lambda (x) (syntax-case x () ((function args body ...) #'(let ((procedure (lambda args body ...)) (get-lexicals (lambda()(lexicals function)))) (set-procedure-property! procedure 'source '(function args body ...)) (set-procedure-property! procedure 'get-lexicals get-lexicals) procedure))))) (define (procedure-lexicals proc) ((procedure-property proc 'get-lexicals))) I don't fully understand why it works, as syntax-case is still a mystery to me, but I wrote it and it works perfectly, not to mention that the expanded code is much cleaner now, without the-environment.