creating context inside macro

For the Compleat Fan
Locked
frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

creating context inside macro

Post by frontera000 »

This may be a dumb thing to do:

Code: Select all

(define-macro (foo1 ctx1 arg1)
  (context  ctx1)
  (define (foo1 arg1)
    (setq var1 arg1)))

(foo1 fooctx1 "hello1")
And it crashes newLISP.exe.
> (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 Settings\Owner>

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:

Code: Select all

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

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

Post by Lutz »

Modifying a function while running it, will always crash the system.

Lutz
Last edited by Lutz on Mon Aug 28, 2006 6:20 pm, edited 1 time in total.

frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

Post by frontera000 »

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.

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

Post by Lutz »

yes there is a way, but let me first explain what is going on here:

Code: Select all

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

Code: Select all

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

Code: Select all

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

Code: Select all

(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

frontera000
Posts: 72
Joined: Sun Jun 11, 2006 8:02 pm
Location: berkeley, california
Contact:

Post by frontera000 »

Thanks.

I think def-new is definitely something I can use!

Locked