Context madness bugs?

Notices and updates
Locked
m35
Posts: 171
Joined: Wed Feb 14, 2007 12:54 pm
Location: Carifornia

Context madness bugs?

Post by m35 »

Code: Select all

newLISP v.9.9.94 on Win32 IPv4, execute 'newlisp -h' for more info.

> (setq FISH:test 10)
10
> (delete FISH)
true
> (setq FISH:test 20)

ERR: context expected in function setf : FISH
Can you only create a context that way once? Also note the "setf" in the error.

Code: Select all

newLISP v.9.9.94 on Win32 IPv4, execute 'newlisp -h' for more info.

> (setq FISH:FISH FISH)
FISH
> (delete 'FISH:FISH)
This crashes with a segment fault.

newBert
Posts: 156
Joined: Fri Oct 28, 2005 5:33 pm
Location: France

Post by newBert »

m35 wrote:Also note the "setf" in the error.
It's because 'setf' = 'setq'

Code: Select all

newLISP v.9.9.94 on Win32 IPv4, execute 'newlisp -h' for more info.

> setq
setq <40802D>
> setf
setf <40802D>
>
May be the explanation is in the newLISP Manual and Reference at 'delete'
;; in contexts, the quote may be omitted
(delete foo) → foo:x, foo:y deleted

In the last example only the symbols inside context foo will be deleted but not the context symbol foo itself. It will be converted to a normal unprotected symbol and contain nil.

Note that deleting a symbol that is part of a function which is currently executing can crash the system or have other unforeseen effects.
:-)
BertrandnewLISP v.10.7.6 64-bit on Linux (Linux Mint 20.1)

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

Post by Lutz »

The first example is correctly explained by newBert: When deleting a context, then all symbols in it get deleted, and the context symbol is demoted to a normal symbol.

Only this way it is possible to have variables holding contexts:

Code: Select all

(setq FISH:test 10) => 10
(setq FOO FISH) => FISH

FOO:test => 10
FOO is now a variable holding a context. FOO:test and FISH:test point to the same piece of memory. If I do:

Code: Select all

(set 'FOO:test 1234) => 1234

FISH:test => 1234
then FOO and FISH point to the same context. When the interpreter sees: CCC:xxx, it checks first if CCC exists as a context or a normal variable. If neither has been seen before, CCC will be created as a context. If CCC exists already as a normal variable, the interpreter expects CCC to hold a context else will throw an error.

The only way to to elevate a normal symbol back to a context symbol is using the 'context' primitive itself.

Demoting context symbols to normal symbols after deletion was introduced in version 9.1.6 to make it possible to create a context from a local variable in a function. Jeff requested this to be able to create transient contexts, which do only exist during the life of the function execution:

Code: Select all

(define (foo x) 
    (let (ctx 999) 
        (println "ctx:" ctx)
        (context 'ctx) ; create a context from local variable
        (set 'ctx:x 123) 
        (println "current context:" (context))
        (println "symbols in ctx: " (symbols ctx))
        (println "ctx:x: " ctx:x)
        (println "x:" x)
        (delete 'ctx)
))

> (foo 10)
ctx:999
current context:ctx
symbols in ctx: (x)
ctx:x: 123
x:10
true
> 
This construct is only possible using that demotion feature, because we cannot delete the local 'ctx' , which is part of the function defined. I don't think that transient contexts are a necessary feature, but Jeff felt very strong about this and came up with some interesting examples.

It is this new 'demotion' feature introduced in 9.1.6 which causes the crash observed in the second self-referential m35 example, when doing (setq C:C C) (delete 'C:C), or also when doing (set 'C:test C) (delete 'C:test). The deletion of C:test deletes at first the contents of it which is C itself.

'delete' is a low level newLISP function which has no usage in normal newLISP programming, but I will see if this special case can be taken care of without impact on code size or performance.

ps: fixed in 9.9.95, will delete without crash.

m35
Posts: 171
Joined: Wed Feb 14, 2007 12:54 pm
Location: Carifornia

Post by m35 »

Ah ok, thanks for the detailed explanations guys. I probably should have mentioned I was just trying to remove symbols out of contexts. Now that I understand better what's going on, I see I could have used workarounds.

Code: Select all

newLISP v.9.9.94 on Win32 IPv4, execute 'newlisp -h' for more info.

> (setf FISH:test 100)
100
> (delete 'FISH)
true
> (delete 'FISH)
true
> (setf FISH:test 100)
100
The first delete demotes the context symbol to a normal symbol, and the second delete removes the symbol. Of course as you mentioned Lutz, using (context FISH) after the first delete would work as well.

Code: Select all

newLISP v.9.9.94 on Win32 IPv4, execute 'newlisp -h' for more info.

> (setf FISH:test FISH)
FISH
> (setf FISH:test 123)
123
> (delete 'FISH:test)
true
> (symbols FISH)
()
First set the symbol to a non-context value, then delete the symbol.
Thanks for fixing the crash in my first post Lutz. I think it's good to have the same behavior regardless of whether the symbol points to a context or not.

Locked