Problem using "context alias"?

Notices and updates
Locked
ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Problem using "context alias"?

Post by ale870 »

Hello,

I notice a strange behavior.
Look at the following code:

Code: Select all

(context 'PIPPO)
(define (init)
	(println (string "PIPPO: " (context)))
)

(context 'PLUTO)
(println (string "A1: " (context)))
(PIPPO:init)
(println (string "A2: " (context)))
I obtain:

Code: Select all

A1: PLUTO
PIPPO: PIPPO
A2: PLUTO
It works well. Now I want to use a variable to refer to a context, so I have:

Code: Select all

(context 'PIPPO)
(define (init)
	(println (string "PIPPO: " (context)))
)

(context 'PLUTO)

(setq ctxPippo PIPPO)

(println (string "A1: " (context)))
(ctxPippo:init)
(println (string "A2: " (context)))
I got:

Code: Select all

A1: PLUTO
PIPPO: PLUTO
A2: PLUTO
Ops... something is wrong! In fact, as you can see, in this case the context inside the function "init" seems wrong!

Assigning a context to a variable is useful to create a kind of alias (usually I use full-qualified context names, and they become enough long!).

Can you tell me what's wrong? Can you find a work-around?

Thank you!
--

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

Another important point about this: sometimes I use a variable to maintain a reference to a specific context. For example:

Code: Select all

(context 'C1)
(define (f1)(println "Context C1"))

(context 'C2)
(define (f1)(println "Context C2"))

(context MAIN)

(setq ctxChoice C2) ; or... (setq ctxChoice C1)
(ctxChoice:f1)
In this case I could use the variable ctxChoice to switch between the contexts.
--

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

Hello again!

I found a workaround, but it seems ugly! (but it works...)

Code: Select all

(context 'ThisIsMyContext)

(define (f1)
	(println (string "Context C1d: " (context) ) )
)
(setq get-f1 (f1))

(context MAIN)
(context ThisIsMyContext "get-f1")

(setq Alias ThisIsMyContext)
(context Alias "get-f1")
Basically, I used a variable defined inside the context in order to get the value of the required function. It means it is recalled from inside the context self, and the result is correct (I used a similar concept of GETTERS/SETTERS).

But I don't like it.... :-(
--

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

This is the best solution I found. Here a "clean" example:

Code: Select all

(context 'PersonalData)

(setq _myname nil)

(define (my-name (argName nil) )
	(println (string "Context 3: " (context)))
	(if argName
		(setq _myname argName)
		_myname
	)
)

(define (get-name)
	(println (string "Context 1: " (context)))
	(my-name)
)

(define (set-name argName)
	(println (string "Context 2: " (context)))
	(my-name argName)
)

(context MAIN)

(setq ctxAlias PersonalData)

(ctxAlias:set-name "Alessandro")
(println (ctxAlias:get-name))
It seems in this way it works correctly. See the results:

Code: Select all

Context 2: MAIN
Context 3: PersonalData
Context 1: MAIN
Context 3: PersonalData
Alessandro
As you can see, even if get-name and set-name are executed in the "wrong" context, the function inside the context my-name is running in the right context.

However I think this should be fixed, since it seems an incoherent behavior.

If I'm wrong, or if you have better idea, you are welcome! :-)
--

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

One optimiziation more:

thank to newLisp and its flexibility, we can do this simple operation. Let's take this original code:

Code: Select all

(define (do-sum val1 val2)
	(println (string "Somma valori: " (+ val1 val2)))
	(+ val1 val2)
);define

(println (string "10+20=" (do-sum 10 20)))
In order to modify it to avoid context problems we can simply do this:

1) add the new function:

Code: Select all

(define (do-sum val1 val2)(_do-sum val1 val2))
2) modify the original function by adding an "_" in front of the function name. It will become:

Code: Select all

(define (_do-sum val1 val2)
	(println (string "Somma valori: " (+ val1 val2)))
	(+ val1 val2)
);define
Then the new full code will be:

Code: Select all

(define (_do-sum val1 val2)
	(println (string "Somma valori: " (+ val1 val2)))
	(+ val1 val2)
);define

(define (do-sum val1 val2)(_do-sum val1 val2))

(println (string "10+20=" (do-sum 10 20)))
Very easy.

Maybe some of you made a question: why should I have to assign a context to a variable (like an alias)? Well, there are at least two good reasons:

1) I can use a single alias to refer to different contexts (if we talk about OOP programming, we could think to "polymorphisms")

2) When I create big programs, I could find more contexts with the same name. So it means I could have some naming conflicts. In order to avoid it, I could call the contexts with a domain-specific name. For example (talking about a theorical context module to perform database access).
Basically I have "odbc.lsp" -> ODBC context.
But what happen if I will find another useful module to access to ODBC too? So I could rename original context (ODBC) as: ale870.database.odbc
(ale870 is obviously my name!).
The other module could be called:
mister.database.odbc

Well, in order to avoid to type these long context names, I need to create an alias. So:

Code: Select all

(ale870.database.odbc:connect ... )
(ale870.database.odbc:query ... )
or is better...

Code: Select all

(setq ctxODBC ale870.database.odbc)
(ctxODBC:connect ... )
(ctxODBC:query ... )
;-)
--

cormullion
Posts: 2038
Joined: Tue Nov 29, 2005 8:28 pm
Location: latiitude 50N longitude 3W
Contact:

Post by cormullion »

A good thread you have here! I'm not too skilled with contexts to be able to contribute, but your explorations are very interesting...

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

Thank you! My explorations were caused by some problems I found during the development of a complex application, using CGI, for a barcode reader!
Furthermore, I like to study the different faces of a programming language, and newLISP has a lot of faces!!! :-)
--

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

Post by Lutz »

I notice a strange behavior.
The context switch always goes by context of the calling symbol, which explains the behavior you are seeing. Only for the default symbol the context switch will also work, when using an alias for the context:

Code: Select all

(define (foo:foo) (context))

(setq ctx foo)

(ctx) => foo

; but

(ctx:foo) => MAIN
The context as returned above really only is important when using the functions 'eval-string' or 'sym'. For implementig any kind of OO- polymorphism this effect has no significance and when using 'eval-string' or 'sym' it is always better to specifiy the context anyway.

For implementing polymorphism you better see the chapter "17. Object-Oriented Programming in newLISP" specifically the subchapter about the : colon operator.

Lutz

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

Thank you Lutz, now everything is more clear for me!
--

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

Post by Lutz »

In any case in version 9.3.2 the behavior is changed to:

Code: Select all

(define (foo:foo) (context)) 
(setq ctx foo) ; alias

(ctx:foo) => foo
(ctx) => foo 
which is more intuitive, and this change also gave a slight speed increase (~ 5%) when using aliases this way.

Lutz

ale870
Posts: 297
Joined: Mon Nov 26, 2007 8:01 pm
Location: Italy

Post by ale870 »

GREAT!!!!! I think this is the most coherent way and intuitive solution!
Thank you again!!! :-) :-) :-)
--

Locked