wduquette / molt

Embeddable TCL Interpreter for Rust applications
BSD 3-Clause "New" or "Revised" License
103 stars 12 forks source link

TCL 8 Namespaces #97

Open jtremesay opened 4 years ago

jtremesay commented 4 years ago

Hi, I was trying to access $::env and I found this behavior:

$ moltsh shell
Molt 0.3.0
% set ::foo(bar) spam
spam
% puts $::foo(bar)
$::foo(bar)
% puts ${::foo(bar)}
spam
wduquette commented 4 years ago

Syntactically, Molt is based on the TCL 7.6 version of the language, with a few TCL 8.x additions (dictionaries, the "eq" and "ne" operators, "return" with options, "throw", and like that.) As such it doesn't (at this time) support namespaces; and so "::" is not recognized as part of a bare variable number. Namespaces is probably the next big item for me to work on, so I've renamed this issue accordingly.

And then, as you've no doubt noticed, there is no "env" array. That's much more easily fixed; see issue #98.

jtremesay commented 4 years ago

I didn't realized that the :: is for namespace. I thought it was a special prefix for avoiding accidental  overwriting of the variable or something like that ^^' (I don't know much about TCL).

May 11, 2020 03:29:12 Will Duquette notifications@github.com:

Syntactically, Molt is based on the TCL 7.6 version of the language, with a few TCL 8.x additions (dictionaries, the "eq" and "ne" operators, "return" with options, "throw", and like that.) As such it doesn't (at this time) support namespaces; and so "::" is not recognized as part of a bare variable number. Namespaces is probably the next big item for me to work on, so I've renamed this issue accordingly. And then, as you've no doubt noticed, there is no "env" array. That's much more easily fixed; see issue #98[https://github.com/wduquette/molt/issues/98]. — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub[https://github.com/wduquette/molt/issues/97#issuecomment-626423959], or unsubscribe[https://github.com/notifications/unsubscribe-auth/AADCKMOF3LLOTHHDHKNRVMLRQ5HTVANCNFSM4M5IZGSA]. [https://github.com/notifications/beacon/AADCKMK4RET5WXG6ZKPCASTRQ5HTVA5CNFSM4M5IZGSKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEVLHRFY.gif]

wduquette commented 4 years ago

Yup. "::" is the namespace operator; and by calling the variable ::env you're referring to the variable called env in the global namespace. But as I say, Molt doesn't have namespaces yet; so if you want to reference env in a proc you need to call global env in the proc.

dbohdan commented 4 years ago

I have a suggestion, since replicating the feature set of Tcl 8 namespaces is a pretty daunting task. You don't have to implement full support for namespaces right away to get many (most?) of the benefits and reach practical compatibility with mainline Tcl. Look at the design of Jim Tcl's simplified "implicit" namespaces. The namespaces in Jim Tcl are less suitable for implementing OOP than those of Tcl 8, but they work well enough for organizing code.

https://github.com/msteveb/jimtcl/blob/master/README.namespaces

The design allows you to write code that is compatible with both implicit and "real" namespaces. (For example, I've written a somewhat complex library that uses namespaces and works in both Jim Tcl and Tcl 8. You could similarly write code that worked in Tcl 8 and implicit-namespace Molt.)

wduquette commented 4 years ago

That's an excellent idea. I'll read it carefully before I proceed.

wduquette commented 4 years ago

If I understand the Jim Tcl design, there's a single dictionary for non-local variable names and a single dictionary for commands; and the names of those variables and commands include the implicit namespace. Thus, at the shell if I type proc foo {} {...} it goes in as ::foo. And in proc ::test::myproc, the command variable myvar has exactly the same effect as global ::test::myvar. There's no magic going on.

Do I have that right?

dbohdan commented 4 years ago

If I understand the Jim Tcl design, there's a single dictionary for non-local variable names and a single dictionary for commands; and the names of those variables and commands include the implicit namespace.

Yes.

the command variable myvar has exactly the same effect as global ::test::myvar.

Yes, it has the same effect as global ::test::myvar in Tcl 8 (but global ::test::myvar does not work in Jim Tcl; you must use variable.)

Take a look at the commit that added namespaces to Jim Tcl: https://github.com/msteveb/jimtcl/commit/7f383c6726fd71c23d622753152faf749124ca22. While it is large, the core changes are fairly small and clear. Jim Tcl's C API is close to that of Tcl 8, and I think you can understand the code just fine with only knowledge of Tcl 8's internals.