newLISP Fan Club

Forum => Anything else we might add? => Topic started by: cormullion on July 14, 2007, 09:56:36 AM

Title: macro to create default functions
Post by: cormullion on July 14, 2007, 09:56:36 AM
Getting stuck again - please help!


(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:


(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!
Title:
Post by: Lutz on July 14, 2007, 11:45:35 AM
you have to put f1:f1 in both places, f1 and f1:f1 are diferent animals



(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.
Title:
Post by: cormullion on July 14, 2007, 03:24:46 PM
OK, thanks. I see that now.



In this:


(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?
Title:
Post by: Lutz on July 14, 2007, 04:04:47 PM
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:


(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
Title:
Post by: Lutz on July 14, 2007, 05:15:00 PM
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_manual.html#lexical_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
Title:
Post by: cormullion on July 15, 2007, 01:49:07 AM
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:


(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
Title:
Post by: cormullion on July 16, 2007, 04:49:40 AM
This is as close as I've got so far:


(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...