This may be a dumb thing to do:
(define-macro (foo1 ctx1 arg1)
(context ctx1)
(define (foo1 arg1)
(setq var1 arg1)))
(foo1 fooctx1 "hello1")
And it crashes newLISP.exe.
Quote
> (debug (foo1 fooctxt1 "hello1"))
-----
(define-macro (foo1 ctx1 arg1)
#(context ctx1)#
(define (foo1 arg1)
(setq var1 arg1)))
[-> 3 ] s|tep n|ext c|ont q|uit > ctx1
fooctxt1
[-> 3 ] s|tep n|ext c|ont q|uit > s
-----
(define-macro (MAIN:foo1 MAIN:ctx1 MAIN:arg1)
#(context MAIN:ctx1)#
(define (MAIN:foo1 MAIN:arg1)
(setq MAIN:var1 MAIN:arg1)))
RESULT: fooctxt1
[<3> s
-----
(define-macro (MAIN:foo1 MAIN:ctx1 MAIN:arg1)
(context MAIN:ctx1)
#(define (MAIN:foo1 MAIN:arg1)
(setq MAIN:var1 MAIN:arg1))#)
[-> 3 fooctxt1] s|tep n|ext c|ont q|uit > s
***newLISP Crashes here *****
C:Documents and SettingsOwner>
Another thing is that I wanted to create foo1 in foo1 context. But I guess while running the macro in MAIN context, creating context inside the running macro and defining new function does not make the new ones go into the newly created context -- they instead go to MAIN. But still that crashes, so I don't know.
But the following seems to work a little better:
(define-macro (foo1 ctx1 arg1)
(setq FOO1 (context ctx1))
(define (FOO1:foo1 FOO1:arg1)
(setq FOO1:var1 FOO1:arg1)))
Basically I want to be able to create a context and a function and call that function in one expression.
Modifying a function while running it, will always crash the system.
Lutz
Thanks.
I realize that it has turned out to be that way - modifying the function while running it. But it was due to my lack of understanding. I was intending to do the same kind of thing as I do from the interpreter prompt.
(context 'FOO1)
(define (foo1) (setq var1 123))
This works from the repl.
So I thought I could do the same inside a macro.
(define-macro (make-foo1)
(context 'FOO1)
(define (foo1) (setq var1 123)))
So when I run what I expect (perhaps wrongly) is that foo1 created will be inside FOO1 context. But foo1 gets created inside MAIN.
Is there a way to create a function and variables in a new context from inside another function or macro? I would like to be able to do that and eval the function on the fly.
I can't figure out how to do that in newLISP.
yes there is a way, but let me first explain what is going on here:
(define-macro (make-foo1)
(context 'FOO1)
(define (foo1) (setq var1 123)))
The context statement switches the context during runtime executing 'make-foo1', but at this time all other symbols in 'make-foo1' are already created as symbols in MAIN when reading the source from the program file. So at this time the context switch doesn't do anything anymore. newLISP reads a toplevel expression then evaluates it then reads the next toplevel expressin etc. While rading all symbols are created for the current context swithced to with a top level context statement.
'context' changes the context only for subsequent source code translation. When switching the context during runtime of 'make-foo1' it would only change the subsequent behaviour of an 'eval-string' or a 'sym' statement (if they don't have a context specified).
To create a function for a different context and that context at the same time you can use the following function described here:
http://newlisp.org/downloads/newlisp_manual.html#lexical_scoping
;; define static functions (use only in context MAIN)
;;
;; Example:
;;
;; (def-static (foo x) (+ x x))
;;
;; foo:foo ? (lambda (foo:x) (+ foo:x foo:x))
;;
;; (foo 10) ? 20
;;
(define-macro (def-static)
(let (temp (append (lambda) (list (1 (args 0)) (args 1))))
(def-new 'temp (sym (args 0 0) (args 0 0)))))
It is defined as a hygienic macro. Easier to understand perhaps this older version from the 8.7.1 manual, which does the same:
(define (def-static s contents)
(def-new 'contents (sym s s)))
(def-static 'acc (fn (x) (if sum (inc 'sum x) (set 'sum x))))
(acc 5) => 5
(acc 5) => 10
(acc 2) => 12
acc:sum => 12
acc:x => nil
The current definition from the link just mentioned lets you use 'def-static' like 'define'.
So the link and the older previous example show how to define a function (actually the default function) for another context.
Doing a function define for the same current context is much more streight forward:
(define-macro (make-func func body)
(set func body))
(make-func foo (fn (x) (+ x x)))
(foo 10) => 20
You just do an assignment of a lambda/fn expression to a symbol, which is the same as a 'define'.
If you are more interested in code to write functions in newLISP you should definitely also look into:
http://newlisp.org/downloads/newlisp_manual.html#expand
and
http://newlisp.org/downloads/newlisp_manual.html#letex
In newLISP variable expansion is something you do explicitly with 'expand' or 'letex'. You can use both to fill in function templates, which I think is what you want to do.
'define-macro' alone is just a 'define' without argument evaluation.
Lutz
Thanks.
I think def-new is definitely something I can use!