macro to create default functions

For the Compleat Fan
Locked
cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

macro to create default functions

Post by cormullion »

Getting stuck again - please help!

Code: Select all

(define-macro (create-function)
	(letex 
 	 ((f1 (sym (first (args))))) 
	(define (f1) 
		(println  { args are } (args))) 
	)
)
(create-function foo)
(foo 1)
 args are (1)
(foo)
 args are ()
works as expected. But if I replace (define (f1) with (define (f1:f1)) it doesn't:

Code: Select all

(define-macro (create-function)
	(letex 
 	 ((f1 (sym (first (args))))) 
	(define (f1:f1) 
		(println  { args are } (args))) 
	)
)

(create-function foo)
context expected in function define : f1
But I thought you didn't need to quote the symbol when defining a default function...

thanks for any help!

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

you have to put f1:f1 in both places, f1 and f1:f1 are diferent animals

Code: Select all

(define-macro (create-function) 
   (letex 
     ((f1:f1 (sym (first (args))))) 
   (define (f1:f1) 
      (println  { args are } (args))) 
   ) 
) 
But in a function call situation (f1 ...) when newLISP sees that f1 is a context symbol (they are global too) it will use f1:f1 instead. f1 than defaults to f1:f1. Thats why its called a default symbol/function.

But in (letex (f1 ...)..) it is not a function call, just an assignment.

Lutz

ps: but in your case you are just using it as a temporary variable, and in this siutation it is not really necessary, you could just use any normal symbol.

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

OK, thanks. I see that now.

In this:

Code: Select all

(define-macro (create-functions group-name) 
(letex 
 ((f1 (sym (append (name group-name) "1"))) 
  (f2 (sym (append (name group-name) "2")))) 
 (define (f1 arg) (+ arg 1)) 
 (define (f2 arg) (+ arg 2)))) 
 
(create-functions foo) 
There's presumably no way to write the 'f1' and 'f2' function definitions to use (args) rather than the arg, since (args) is still part of the macro definition, rather than the f1/f2 function definition?

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

Not sure what your mean. Isn't that exactly what you did before? And it worked! The (args) in the (define (f1:f1) ... (args) ...) doesn't get evaluated until the function created bye (create-functions ...) is used. Only the (args) in the letex assignment gets evaluated:

Code: Select all

(define-macro (create-function) 
   (letex 
     ((f1:f1 (sym (first (args))))) ;<- evaluated during create-function
   (define (f1:f1) 
      (println  { args are } (args))) ;<- not evaluated during create-function
   ) 
) 
Lutz

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Post by Lutz »

I didn't pay attention earlier to the title of this thread: "macro to create default functions". None of the example really creates default functions. They use default symbols during the creation process, but all just return a lambda expression living in the same name space as the caller.

I believe what you want to do is described here:

http://newlisp.org/downloads/newlisp_ma ... al_scoping

The example creates a function 'acc:acc' where all of its symbols live in a namespace 'acc', including a symbol 'acc:sum' which keeps state when accumulating numbers over various invocations of calls to (acc ...).

Lutz

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

What I'm trying to investigate (to see if it's possible and to give me a task to try and solve using some of these more advanced topics ;-)) is to create a macro that provides a modified/enhanced version of an existing function:

Code: Select all

(define-macro (enhance-function)
...)

(enhance-function add)
;-> my-add

(my-add 1 2 3)
;-> 6

(my-add 2 2)
;-> 4

(my-add:total)
;-> 10

(enhance-function sin)  ; possibly different macro
;-> my-sin

(my-sin 1)
;-> 0.8414709838

(my-sin (div pi 2))
;-> 1

(my-sin:acc)
;-> 1.841470938

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

This is as close as I've got so far:

Code: Select all

(define-macro (enhance-function)
    (let 
    	((fname  (args 0 0))
    	 (fname1 (string "my>" (args 0 0)))
    	 (fbody (append 
    	 		(lambda) 
    	 		 (list
    	 		   (1 (args 0)) 
    	 		   (args 1)))))
    (def-new 'fbody (sym fname1 (context (sym fname1))))))

(enhance-function (add)
	(if invocations
		(inc 'invocations)
		(set 'invocations 0)))
The big problem with this is that the new function that gets created (my>add:my>add) doesn't do the adding as well as keep count of its invocations, so it's not exactly enhanced. :-( But I can't work out where to put the add (presumably (apply add (args)) in the lambda list...

Locked