For the Compleat Fan
cormullion
Posts: 2038 Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:
Post
by cormullion » Sun Oct 21, 2007 2:38 pm
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?
Fanda
Posts: 253 Joined: Tue Aug 02, 2005 6:40 am
Contact:
Post
by Fanda » Sun Oct 21, 2007 6:35 pm
'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
Lutz
Posts: 5289 Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:
Post
by Lutz » Sun Oct 21, 2007 7:46 pm
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
cormullion
Posts: 2038 Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:
Post
by cormullion » Sun Oct 21, 2007 8:33 pm
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!
cormullion
Posts: 2038 Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:
Post
by cormullion » Sun Oct 21, 2007 10:13 pm
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
Fanda
Posts: 253 Joined: Tue Aug 02, 2005 6:40 am
Contact:
Post
by Fanda » Mon Oct 22, 2007 9:40 am
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.
Fanda
Posts: 253 Joined: Tue Aug 02, 2005 6:40 am
Contact:
Post
by Fanda » Mon Oct 22, 2007 10:04 am
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
cormullion
Posts: 2038 Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:
Post
by cormullion » Mon Oct 22, 2007 10:27 am
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!