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!