expand and define-macro

Started by eddier, December 09, 2004, 07:09:12 AM

Previous topic - Next topic

eddier

Lutz,



It would be nice to have expand work on stuff like

(setq a 'r)
(expand (a:a b)  'a ) => (r:r b)

instead of having to do string manipulation like below

(define-macro (def-mac _dm _body)
 (let (_s (string _dm))
  (eval-string
   (format "(context '%s) (define-macro (%s:%s) %s) (context 'MAIN)"
           _s
           _s
           _s
           (string (eval _body)))))


What I would like is to create a macro definition that performs

(context 'my-setq)

(define-macro (my-setq:my-setq x y) (set x (eval y)))  

(context MAIN)

by just typing

(def-mac (my-setq x y) (set x (eval y)))

although I haven't quite figured out how to do the parameters yet.

Note this is almost static scoping for macros  (the variables within the context remain after the macro call). If context variables where deleted on leaving the call we would have static scoping. I wonder if contexts could be used to form a contiunation? Is it possible to make define-macro statically scoped in newLISP?



Eddie

Lutz

#1
Let me first comment on yur last paragraph and example:

(context 'my-setq)
(define-macro (my-setq:my-setq x y) (set x (eval y)))
(context MAIN)

This could also be written as:

(define-macro (my-setq:my-setq my-setq:x my-setq:y) (set my-setq:x (eval my-setq:y)))

>>> Eddie

... the variables within the context remain after the macro call ...

<<<

(my-setq x 123) => 123
x => 123

;; but
my-setq:x => nil
my-setq:y => nil

No they don't, because they are parameters in a lambda expression. Both mys-setq:x and my-setq:y will contain nil after evaluating the function.



But non-parameter variables would be remembered:

(define (acc:acc acc:x) (if (not acc:sum) (set 'acc:sum acc:x) (inc 'acc:sum acc:x)))

(acc 5) => 5
(acc 5) => 10
(acc 3) => 13

;; but
acc:x => nil


So this is effectively a form of static scoping, similar to writing in 'C'

int acc(x)
{
static sum = -1;

if(sum == -1) sum = 0;
else sum += x);
}
 


But main part of your question is, how to avoid bracketing all code with (context ...) ...... (context 'MAIN). Part of the answer may be (?) the other form of writing these by explicetely prefixing every symbol with the context name. But of course this is even more clumsy and laborous in typing. But that form may be easier to convert to with something like 'expand' ?. I have to think about this a little bit longer.



Lutz

Lutz

#2
The whole thing can be done using the function 'def-new' which was introduced in 8.2.5.



'def-new' copies a function fo a different context and creates autmatically the var in the new context (see manual).



Unfortunately 'def-new' has a bug which prevents it working correctly when the source context is MAIN. This is fixed in a development release later today, which also contains a 'do-while', 'do-until' (post condition check versions of 'while' and 'until')



With that  def-new' fix you can create a function  of the form foo:foo (called a default function) in just one statement, effectively defining a statically scoped function.



later today ...



Lutz

eddier

#3
Thanks Lutz!



Is this a regular function definition or macro?



Eddie

Lutz

#4
Either is possible. See the chapter 'Lexical, static scoping in newLISP' subchapter of 'Programming with context objects' in the manual in the just posted development release 8.3.2.



Lutz

eddier

#5
Thanks lutz for all of your good work.



Eddie