Page 1 of 1

Nested contexts

Posted: Wed May 09, 2007 2:22 am
by Jeff
How do I access a variable in a nested context? Ie,

Code: Select all

(context 'FOO)
(define (FOO:create c some-value)
  (new FOO c)
  (set 'ctx (eval c))
  (set 'ctx:some-value some-value))
(context 'MAIN)

(context 'BAR)
(define (BAR:create c foo-instance)
  (new BAR c)
  (set 'ctx (eval c))
  (set 'ctx:foo (eval foo-instance)))
(context 'MAIN)

(FOO:create 'a-foo "Why the heck does he need nested contexts?")
(BAR:create 'a-bar 'a-foo)

(println a-foo:some-value) ; => "Why the heck does he need nested contexts?"
(println a-bar:foo) ; => a-foo
(println a-bar:foo:some-value) ; => symbol expected : " a-bar:foo:some-value)\n"
How can I get at a member of a nested context?

Posted: Wed May 09, 2007 10:50 pm
by Lutz
nested contexts are not supported, all contexts are children of MAIN

Lutz

Posted: Fri May 11, 2007 4:36 pm
by m35
Hi Jeff

You're not alone. I ran into the same problem when working on a newlisp object system inspired by Python.

It would be really nice to be able to simply write a-bar:foo:some-value. Since I couldn't, I wrote this macro to handle cases when I had contexts inside contexts.

Usage:
To get a value
(eval (nest-ctx a-bar foo some-value))
To do assignment
(set (nest-ctx a-bar foo some-value) 100)
To call a method
((eval (nest-ctx a-bar foo some-function)) arg1 arg2)

Code: Select all

(define-macro (nest-ctx)
	(let (_args (args)  _ctx nil)
		(case (length _args)
			(0 nil)
			(1 (first _args))
			(2 (sym (_args 1) (_args 0)))
			(true
				(set '_ctx (pop _args))
				(while (and (not (empty? _args)) (not (nil? _ctx)))
					(set '_ctx (sym (pop _args) _ctx))
				)
			)
		)
	)
)
Note that I had to separate the symbols in the arguments, because even passing a-bar:foo:some-value as an argument to a macro causes the error.

An alternative would be to use periods (".") in place of the colons (":"), but of course that could cause problems if any of the symbols contained a period.

Another option would be to pass [a-bar:foo:some-value], and parse the different parts out of the symbol.

Then of course you could just pass the string "a-bar:foo:some-value".

Unfortunately none of these other options seemed very elegant to me, which is why I just kept the arguments separate.

Posted: Sat May 12, 2007 10:19 am
by newdep
Yes nested contexts are a realy 'nice to have' but as it is not default
I create a pointer/index values and store those in a list as reference,
nesting lists is possible so finaly i have a 'semi' nested context with the
nested lists.

Norman.

Posted: Sat May 12, 2007 12:56 pm
by Jeff
I guess I just don't understand the reasoning behind it. Why have the ability to manually create and store a local scope if you can't nest them? I have no problem with dynamic scoping (a good programmer should aim for side-effect-free programming anyway, and let allows you to cheat), but even Lutz uses contexts for modules, and modules should be able to nest. To me, that's the one part of the language that doesn't really fit.

Posted: Sat May 12, 2007 1:07 pm
by newdep
There is somewhere an older thread in this forum regarding this too where Lutz
explains why its not inside newlisp. It was an issue regarding 'namespaces', As
im used to nest those too in tcl...

Perhpas if we provide Lutz with international-beer supply's
he's willing to rethink it ? ;-)

Posted: Sat May 12, 2007 1:44 pm
by cormullion
You mean - Lutz is bribe-able??

Right, where's my wish list... What could I get for a crate of English ale...?

Posted: Sat May 12, 2007 4:35 pm
by newdep
well..Sort of...but he's descides if he is ;-)