Page 1 of 1
Macro version of define that prints args when func is called
Posted: Sun Oct 21, 2007 2:38 pm
by cormullion
Hi. I'm trying to make a new version of define, such that when the function it defines is called, it prints its arguments (eg to a log file). I think it should be possible.
Here's how far I've got:
Code: Select all
(define-macro (my-define)
(set (args 0 0)
(append (lambda)
(list
(rest (first (args))))
(println {call } (first (args)))
(rest (args)))))
(my-define (p2 a1 a2)
(println a1)
(println a2)
)
(p2 "bill" "bob")
But this prints the arguments when the function is first defined, not when it's subsequently called. Is there a way of delaying that 'print' till later on?
Posted: Sun Oct 21, 2007 6:35 pm
by Fanda
'define' creates a lambda function/list. You need to include your 'print' functions into the newly created function:
Try if this works:
Code: Select all
(define-macro (my-define @farg)
(set (@farg 0)
(letex (@arg (rest @farg)
@arg-p (cons 'list (map (fn (@x) (if (list? @x) (first @x) @x)) (rest @farg)))
@body (args))
(append (lambda @arg
(println "params: " @arg-p)
(println "args: " (args)))
'@body))))
(constant (global 'define) my-define)
Example:
Code: Select all
> (define (f x) (+ x x))
(lambda (x) (println "params: " (list x)) (println "args: " (args))
(+ x x))
> f
(lambda (x) (println "params: " (list x)) (println "args: " (args))
(+ x x))
> (f 2)
params: (2)
args: ()
4
> (f 2 3 4)
params: (2)
args: (3 4)
4
> (define (f (x 10)) (+ x x))
(lambda ((x 10)) (println "params: " (list x)) (println "args: "
(args))
(+ x x))
> f
(lambda ((x 10)) (println "params: " (list x)) (println "args: "
(args))
(+ x x))
> (f)
params: (10)
args: ()
20
> (f 3)
params: (3)
args: ()
6
> (f 3 4 5)
params: (3)
args: (4 5)
6
Enjoy, Fanda
Posted: Sun Oct 21, 2007 7:46 pm
by Lutz
Fanda wrote:(constant (global 'define) my-define)
nice idea, this way a Cormullion style trace module can be written and can be used with any exisiting code by simply including a (load "trace.lsp") at the beginning of a program.
Lutz
Posted: Sun Oct 21, 2007 8:33 pm
by cormullion
Wicked cool, Fanda! You've done the clever bit for me...
I might change those @ signs to something else - I find them visually distracting... Underscores appear to work...
thanks!
Posted: Sun Oct 21, 2007 10:13 pm
by cormullion
Could this be easily modified so that the function name is also printed?
Edit: oh yes, i see:
Code: Select all
(define-macro (my-define @farg)
(set @fn (@farg 0)) ; that's the function name
(set (@farg 0)
(letex....
Edit 2: Ah, that doesn't work properly because it's global... Hmm
Posted: Mon Oct 22, 2007 9:40 am
by Fanda
Again, you need to put the function name inside the 'println' inside the 'lambda fn'.
Code: Select all
(define-macro (my-define @farg)
(set (@farg 0)
(letex (@fn (@farg 0)
@arg (rest @farg)
@arg-p (cons 'list (map (fn (@x) (if (list? @x) (first @x) @x)) (rest @farg)))
@body (args))
(append
(lambda @arg (println "[" '@fn "] params: " @arg-p " args: " (args)))
'@body))))
(constant (global 'define) my-define)
Example:
Code: Select all
> (define (f x) (+ x x))
(lambda (x) (println "[" 'f "] params: " (list x) " args: " (args))
(+ x x))
> f
(lambda (x) (println "[" 'f "] params: " (list x) " args: " (args))
(+ x x))
> (f 2)
[f] params: (2) args: ()
4
> (define (f (x 10) y) (+ x y))
(lambda ((x 10) y) (println "[" 'f "] params: " (list x y) " args: "
(args))
(+ x y))
> (f 2 3)
[f] params: (2 3) args: ()
5
> (f 2 3 4 5)
[f] params: (2 3) args: (4 5)
5
PS: I am using @ sign as an other-than-underscore sign, because some functions can be macro-like and use underscores for their variables.
Posted: Mon Oct 22, 2007 10:04 am
by Fanda
One more version returning result of a function:
Code: Select all
(define-macro (my-define @farg)
(set (@farg 0)
(letex (@fn (@farg 0)
@arg (rest @farg)
@arg-p (cons 'list (map (fn (@x) (if (list? @x) (first @x) @x)) (rest @farg)))
@body (cons 'begin (args)))
(lambda @arg
(println "[" '@fn "] params: " @arg-p " args: " (args))
(println "[" '@fn "] result: " @body)))))
(constant (global 'define) my-define)
Example:
Code: Select all
> (define (f (x 10) y) (+ x y))
(lambda ((x 10) y) (println "[" 'f "] params: " (list x y) " args: "
(args))
(println "[" 'f "] result: "
(begin
(+ x y))))
> (f 2 3)
[f] params: (2 3) args: ()
[f] result: 5
5
> (f 2 3 4 5)
[f] params: (2 3) args: (4 5)
[f] result: 5
5
Posted: Mon Oct 22, 2007 10:27 am
by cormullion
Aha - that looks like the one.
I find these constructions really difficult to conjure up, and so I'm really glad for your help. Perhap's it's something to do with the hypothetical nature of things that are going to be evaluated sometime in the future but now now...
thanks!