Rocksolid Light

Welcome to Rocksolid Light

mail  files  register  newsreader  groups  login

Message-ID:  

You're already carrying the sphere!


devel / comp.lang.tcl / dicts vs. namespaces - who wins?

SubjectAuthor
* dicts vs. namespaces - who wins?Luc
`* dicts vs. namespaces - who wins?Rich
 `* dicts vs. namespaces - who wins?Luc
  `* dicts vs. namespaces - who wins?Rich
   +* dicts vs. namespaces - who wins?Luc
   |`- dicts vs. namespaces - who wins?Rich
   `- dicts vs. namespaces - who wins?Luc

1
dicts vs. namespaces - who wins?

<20240107013803.5887d79c@lud1.home>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13107&group=comp.lang.tcl#13107

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: dicts vs. namespaces - who wins?
Date: Sun, 7 Jan 2024 01:38:03 -0300
Organization: A noiseless patient Spider
Lines: 73
Message-ID: <20240107013803.5887d79c@lud1.home>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: dont-email.me; posting-host="5ad61530f9796c8e4620a64da94f6b8e";
logging-data="1025843"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/+8bvtCfrjX2KFcK1a94hXGxcAWlS3jKA="
Cancel-Lock: sha1:df1YxTcCqDvbL8bJeWnBIe726ww=
 by: Luc - Sun, 7 Jan 2024 04:38 UTC

I am keeping tabs on my tabs (erm, sorry) with a dict:

set ::TabControl [dict create]

Then for example::

set tabID [clock milliseconds]
dict set ::TabControl $tabID "
[list TCTabPosition $position]
[list TCDirectory $dir]
[list TCViewMode $::GUIoptions_DefaultLayout]
"

etc.

Querying: set tabdir [dict get $tabID TCDirectory]

I don't have any problem with it. It works.

But it's occurred to me that maybe I could also do it all using
namespaces:

set tabID [clock milliseconds]
namespace eval $tabID {
set TCTabPosition $position
set TCDirectory $dir
set TCViewMode $::GUIoptions_DefaultLayout
}

Querying: set dir $tabID::TCDirectory

Now I wonder if there would be any benefit in using namespaces instead
of the dict. Shorter/less cluttered code maybe? Looks like it.

What do you think? Any particular reason for one or another?

Bonus questions if you are in the mood:

1. Now that I think of it, what is the point of dicts anyway? What can
you ever do with them that you can't do with namespaces? You know what
you can do with a namespace that you can't do with a dict? Store an
array in it:

% array set aa {item1 a}
% set dd [dict create]
% dict set dd "array1 $aa"
can't read "aa": variable is array
% dict set dd "array1 [array get aa]"
wrong # args: should be "dict set dictVarName key ?key ...? value"

% namespace eval nn {}
% array set nn::array1 [array get aa]
% parray nn::array1
nn::array1(item1) = a

2. I vaguely remember reading somewhere that we can't trace a dict.
Is that bad?

3. Can we trace a namespace? I mean, name a namespace and have Tcl
detect any changes that happen to variables and commands within that
entire namespace?

--
Luc
>>

Re: dicts vs. namespaces - who wins?

<undi16$10c48$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13110&group=comp.lang.tcl#13110

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: dicts vs. namespaces - who wins?
Date: Sun, 7 Jan 2024 06:57:43 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 112
Message-ID: <undi16$10c48$1@dont-email.me>
References: <20240107013803.5887d79c@lud1.home>
Injection-Date: Sun, 7 Jan 2024 06:57:43 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="848de04a1cc71e1163f22940425b1b88";
logging-data="1061000"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18sMxjnHvEMgmkmFDOaWBt0"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:wiROy3sutwp1G5ZxblefXrpnfGg=
 by: Rich - Sun, 7 Jan 2024 06:57 UTC

Luc <luc@sep.invalid> wrote:
> I am keeping tabs on my tabs (erm, sorry) with a dict:
>
> set ::TabControl [dict create]
>
> Then for example::
>
> set tabID [clock milliseconds]
> dict set ::TabControl $tabID "
> [list TCTabPosition $position]
> [list TCDirectory $dir]
> [list TCViewMode $::GUIoptions_DefaultLayout]
> "

Is there a reason why you don't use dict create above?

dict set ::TabControl $tabID [dict create TCTabPosition $position TCDirectory $dir TCViewMode $::GUIoptions_DefaultLayout]

Or if you want the 'alignment layout':

dict set ::TabControl $tabID [dict create TCTabPosition $position \
TCDirectory $dir \
TCViewMode $::GUIoptions_DefaultLayout]

> Querying: set tabdir [dict get $tabID TCDirectory]
>
>
> I don't have any problem with it. It works.
>
> But it's occurred to me that maybe I could also do it all using
> namespaces:
>
> set tabID [clock milliseconds]
> namespace eval $tabID {
> set TCTabPosition $position
> set TCDirectory $dir
> set TCViewMode $::GUIoptions_DefaultLayout
> }
>
> Querying: set dir $tabID::TCDirectory

You could, although this really isn't the /intended/ use of namespaces.
Their intended use is for organizing sets of related procs and those
procs associated variables, and for avoiding name conflicts with
modules/packages.

> Now I wonder if there would be any benefit in using namespaces
> instead of the dict. Shorter/less cluttered code maybe? Looks like
> it.

Unless you plan to also have specific procs for given tabs there's not
likely any benefit, and in reality the dict access will likely be
marginally faster.

Plus, if you wanted to eventually save your state across exits and
reload where you were, the dict method gives you that single data
structure to save/restore. The plural namespaces means you need extra
work to extract and serialize to disk the namespaces and later restore
them all upon reload.

> Bonus questions if you are in the mood:
>
> 1. Now that I think of it, what is the point of dicts anyway? What can
> you ever do with them that you can't do with namespaces? You know what
> you can do with a namespace that you can't do with a dict? Store an
> array in it:

Bzzt, please try again.

>
> % array set aa {item1 a}
> % set dd [dict create]
> % dict set dd "array1 $aa"
> can't read "aa": variable is array
> % dict set dd "array1 [array get aa]"
> wrong # args: should be "dict set dictVarName key ?key ...? value"

That is because you tried to do string interpolation to store the
array. Don't do that. This works just fine:

$ rlwrap tclsh
% array set aa {item1 a}
% set dd [dict create]
% dict set dd array1 [array get aa]
array1 {item1 a}
% dict get $dd array1
item1 a

Granted, what is stored is the string representation of the array, but
once stored, you can then 'dict get' against it:

% dict get $dd array1 item1
a

> 2. I vaguely remember reading somewhere that we can't trace a dict.
> Is that bad?

Traces work on dicts, what they don't let you target is traces on a
single dict key, you have to write a bit of code to do that as part of
a trace on the dict itself.

In any case, if you are not using traces, the subtle distinction
hardly matters.

> 3. Can we trace a namespace? I mean, name a namespace and have Tcl
> detect any changes that happen to variables and commands within that
> entire namespace?

No, not the namespace itself. You can apply traces to the variables
and the procs in the namespace, but you can also apply traces to a
variable holding a dict just as well.

Re: dicts vs. namespaces - who wins?

<20240107133504.334aa11d@lud1.home>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13112&group=comp.lang.tcl#13112

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!news.hispagatos.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: dicts vs. namespaces - who wins?
Date: Sun, 7 Jan 2024 13:35:04 -0300
Organization: A noiseless patient Spider
Lines: 82
Message-ID: <20240107133504.334aa11d@lud1.home>
References: <20240107013803.5887d79c@lud1.home>
<undi16$10c48$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: dont-email.me; posting-host="e1f22bbaa75b22e4f62b98738f7e55d1";
logging-data="1194093"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/St6bk0V/6J5FAyN+chKRYgmgpQAnao48="
Cancel-Lock: sha1:mPT4BmJJ2T4kVJsScX9uZAcMtiQ=
 by: Luc - Sun, 7 Jan 2024 16:35 UTC

On Sun, 7 Jan 2024 06:57:43 -0000 (UTC), Rich wrote:

>Is there a reason why you don't use dict create above?

Yes, just code cleanliness. I declare all global variables at the
beginning of the whole thing including four or five dicts that will be
populated later on.

>Or if you want the 'alignment layout':

I like alignment layout for debug printing, but I've found out it all
goes away as soon as the dict is updated. I had to make a proc that
"beautifies" the printing of the main dict. It wasn't very easy to
write and it's only good for that one dict and its own unique structure.
Doing the same with namespaces would be a lot easier and it would work
with all dict-replacing namespaces.

>Plus, if you wanted to eventually save your state across exits and
>reload where you were, the dict method gives you that single data
>structure to save/restore. The plural namespaces means you need extra
>work to extract and serialize to disk the namespaces and later restore
>them all upon reload.

That is a good point, but

1. I feel that coding with dicts is by itself a lot of "extra work"
because their structure is trickier. The command lines are longer and
look a bit too fragmented to me, and inserting lists and sublists is a
pretty good minefield so it's very easy to make a mistake and I have
to be printing and checking them all the time. I feel very tempted to
rewrite everything with namespaces now because it will be a lot easier
to manage. There is still a lot to be done. I've barely done the basics
because I am spending a lot of time coding around that text widget and
image create limitation. That one problem alone is requiring a lot of
management that is no fun at all. I had to introduce some stupid nesting
to handle it and that too should be easier to manage with namespaces.

2. Saving and restoring with namespaces is easy enough:
foreach fe [info vars $::namespace::Config_*] {
do something with $fe
}

>Bzzt, please try again.
>
>That is because you tried to do string interpolation to store the
>array. Don't do that. This works just fine:
>
> $ rlwrap tclsh
> % array set aa {item1 a}
> % set dd [dict create]
> % dict set dd array1 [array get aa]
> array1 {item1 a}
> % dict get $dd array1
> item1 a
>
>Granted, what is stored is the string representation of the array, but
>once stored, you can then 'dict get' against it:
>
> % dict get $dd array1 item1
> a

Thank you for the lesson, but I find that a little too convoluted. It
seems to me that you in fact did not store an array in the dict but
rather converted it into a list so it would be admitted by the dict's
doorman/bouncer.

>In any case, if you are not using traces, the subtle distinction
>hardly matters.

Not yet.

Thank you.

--
Luc
>>

Re: dicts vs. namespaces - who wins?

<unf3dl$1759e$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13115&group=comp.lang.tcl#13115

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: dicts vs. namespaces - who wins?
Date: Sun, 7 Jan 2024 21:00:37 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 187
Message-ID: <unf3dl$1759e$1@dont-email.me>
References: <20240107013803.5887d79c@lud1.home> <undi16$10c48$1@dont-email.me> <20240107133504.334aa11d@lud1.home>
Injection-Date: Sun, 7 Jan 2024 21:00:37 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="848de04a1cc71e1163f22940425b1b88";
logging-data="1283374"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/bTsZUrhniOTLuSYTcwhZX"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:iPsFH5ccY5OwJ1Q4n9Y4o9qCrFE=
 by: Rich - Sun, 7 Jan 2024 21:00 UTC

Luc <luc@sep.invalid> wrote:
> On Sun, 7 Jan 2024 06:57:43 -0000 (UTC), Rich wrote:
>
>>Is there a reason why you don't use dict create above?
>
> Yes, just code cleanliness. I declare all global variables at the
> beginning of the whole thing including four or five dicts that will
> be populated later on.

But, if you are going for cleanliness, then using dict create is:

1) cleaner

2) more meaningful. The code declares exactly what it is doing. This
can be esp. good if you sit this aside for a while and return in six or
nine months. Seeing

set x [dict create key1 value1 \
key2 value2]

clearly says a [dict] is being created.

While

set x "key1 value1
key2 value2"

Is just a string, that /could/ be a list, or /could/ be a dict, or
/could/ eventually be turned into an array. Less overtly meaningful
without first investigating how "x" is used later.

3) safer.

Doing "set x [dict create key1 $somevariable]" will always succeed.

Doing "set x " key1 $somevariable" will /appear/ to also always
succeed, until that fateful day, months or years in the future, where
the string inside "$somevariable" happens to contain a character that
is meaningful to Tcl's implicit list/dict conversion parser, at which
point, the use of x as a dict will blow up with a very non-meaningful
error message. And this will be made worse by the fact that you'll be
left wondering: "it has been working for X time so far, what
happened?".

Watch:

$ rlwrap tclsh
% set somevar "a string"
a string
% set dict "key1 $somevar"
key1 a string
% dict get $dict key1
missing value to go with key
%
vs:
% set dict [dict create key1 $somevar]
key1 {a string}
% dict get $dict key1
a string
%

Unless you have very good reason to be assembling dicts or lists by
concatenating plain strings, and are "very careful" when doing so, it
is best to *always* use the proper constructor procs:

[dict create ...] for dicts
[list ...] for lists

Both take care of making sure the result is proper as a dict/list and
for handing those special edge cases that are easily forgotten when
doing "$a $b $c $d $e" to assemble what will be used as a dict/list.

>>Or if you want the 'alignment layout':
>
> I like alignment layout for debug printing, but I've found out it all
> goes away as soon as the dict is updated.

Because as soon as you update the dict, your pretty string is parsed,
converted into a proper dict data structure, and then the next time you
'puts' it, you get back the default string representation of a dict
data structure, not the original string you began with.

> I had to make a proc that "beautifies" the printing of the main dict.

https://wiki.tcl-lang.org/page/pdict%3A+Pretty+print+a+dict?R=0&O=pdict

> It wasn't very easy to write and it's only good for that one dict and
> its own unique structure. Doing the same with namespaces would be a
> lot easier and it would work with all dict-replacing namespaces.

>>Plus, if you wanted to eventually save your state across exits and
>>reload where you were, the dict method gives you that single data
>>structure to save/restore. The plural namespaces means you need extra
>>work to extract and serialize to disk the namespaces and later restore
>>them all upon reload.
>
> That is a good point, but
>
> 1. I feel that coding with dicts is by itself a lot of "extra work"
> because their structure is trickier.

Not if you use the proper "create" procs (i.e., [dict create]). Then
there's nothing 'tricky' at all.

> The command lines are longer and look a bit too fragmented to me,

This is true, but you realize this is Tcl, you can 'adjust' that fact
if you like:

% dict get $dict key1
a string
% interp alias {} dget {} dict get
dget
% dget $dict key1
a string
%

> and inserting lists and sublists is a pretty good minefield so it's
> very easy to make a mistake

If you use the creation procs, and the setting procs, instead of trying
to create strings that are proper as dicts, then it is almost
impossible to "make a mistake", and usually those mistakes that are
made are immediate syntax errors just after making a code change, not
hidden mines waiting to blow up a week from now.

> and I have to be printing and checking them all the time.

Use the proper creation and update procs and you won't have to be
"printing and checking them all the time".

> I feel very tempted to rewrite everything with namespaces now because
> it will be a lot easier to manage.

That's up to you, and you can certianly do so. But you'll likely
encounter some other issue with that path that brings back the
complexity issues you think you are avoiding, just wearing a different
hat this time.

>>Bzzt, please try again.
>>
>>That is because you tried to do string interpolation to store the
>>array. Don't do that. This works just fine:
>>
>> $ rlwrap tclsh
>> % array set aa {item1 a}
>> % set dd [dict create]
>> % dict set dd array1 [array get aa]
>> array1 {item1 a}
>> % dict get $dd array1
>> item1 a
>>
>>Granted, what is stored is the string representation of the array, but
>>once stored, you can then 'dict get' against it:
>>
>> % dict get $dd array1 item1
>> a
>
> Thank you for the lesson, but I find that a little too convoluted. It
> seems to me that you in fact did not store an array in the dict but
> rather converted it into a list so it would be admitted by the dict's
> doorman/bouncer.

Yes, I said so in the "Granted, what is stored is the string
representation of the array," statement. You can't physically store
"an array" in a dict, for the same reason why you can't actually pass
an array to a proc as a parameter. A design decision with how array's
were handled way back in Tcl's very early days resulted in array's
being 'oddball' that way.

But you'll note I stored the array using the proper dict update proc,
not by trying to do 'set dd "$dd array1 [array get aa]"' via string
interpolation. If you have lots of those throughout your code, you
have a minefield just waiting to be stepped on some day.

>>In any case, if you are not using traces, the subtle distinction
>>hardly matters.
>
> Not yet.

The question of course is, do you plan to use traces?

Re: dicts vs. namespaces - who wins?

<20240107192027.79c666d8@lud1.home>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13116&group=comp.lang.tcl#13116

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: dicts vs. namespaces - who wins?
Date: Sun, 7 Jan 2024 19:20:27 -0300
Organization: A noiseless patient Spider
Lines: 109
Message-ID: <20240107192027.79c666d8@lud1.home>
References: <20240107013803.5887d79c@lud1.home>
<undi16$10c48$1@dont-email.me>
<20240107133504.334aa11d@lud1.home>
<unf3dl$1759e$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: dont-email.me; posting-host="e1f22bbaa75b22e4f62b98738f7e55d1";
logging-data="1286830"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/yJuIA1vpVhjeUbc/UdD6qC5/fi5QQPdc="
Cancel-Lock: sha1:Qafmj9MGOcXqvIK6o+4lfDh7sCQ=
 by: Luc - Sun, 7 Jan 2024 22:20 UTC

On Sun, 7 Jan 2024 21:00:37 -0000 (UTC), Rich wrote:

>Watch:
>
> $ rlwrap tclsh
> % set somevar "a string"
> a string
> % set dict "key1 $somevar"
> key1 a string
> % dict get $dict key1
> missing value to go with key
> %
>vs:
> % set dict [dict create key1 $somevar]
> key1 {a string}
> % dict get $dict key1
> a string
> %

Well, yes, but I read the upper part of your example, found it strange
and did it differently:

% set somevar "a string"
% dict create dict {}
% dict set dict key1 $somevar
key1 {a string}
% dict get $dict key1
a string

That would be my way of doing it.

>[dict create ...] for dicts
>[list ...] for lists

I make mistakes with lists often and with dicts too because dicts are
(or may be) lists of lists. And the [list] construct doesn't always
help in my case. PEBKAC.

>> I feel very tempted to rewrite everything with namespaces now because
>> it will be a lot easier to manage.
>
>That's up to you, and you can certianly do so. But you'll likely
>encounter some other issue with that path that brings back the
>complexity issues you think you are avoiding, just wearing a different
>hat this time.

I've done it already and I like it so far. I think things look cleaner
and simpler already. There is one particular section that changed
radically for the better, very neat, so I am even more optimistic about
it. Let's see.

Either way, I really appreciate your input because you are a lot more
experienced than me (not exactly a challenge anyway) and this is a
"public" project, i.e. something that will be freely available and may
have to be maintained by someone else in the future. I hope I am not
leaving a legacy of very horrible code to whoever decides to pick it up.

>The question of course is, do you plan to use traces?

Maybe. Some idea crossed my mind. If one tab is displaying a directory
and the user opens another tab for the same directory and makes changes
in it (e.g. create a new directory) I thought that maybe I should let
all tabs that display that one directory know about it immediately. But

1. I keep control of everything by tabID not by path and there are no
variables concerning the content of directories except one array that
is also identified by tabID. The idea behind that is, for example, when
selecting an entry (for deletion for example) I used to identify the
entry's path with [$widget get $currentline.0 "$currentline.0 lineend]
but I scrapped that for cosmetic reasons. I am giving the user the
option to list empty directories as such, for example:

somedir
anotherdir
thisother (empty)
someother

So I am using an array of line numbers and filenames instead so the
displayed entry doesn't have to be exactly the same as the actual
filename.

Yes, I realize it is dangerous, but unless the tab display "refreshes"
between the user's selection and the delete operation, the selection
and the operation are safe, and "getting" the filename from the widget
display wasn't terribly safe either.

2. When I create files and directories in my application, other file
managers pick them up and display them immediately. They are really
fast so I'm guessing they keep monitoring the current tab's directory
every so many milliseconds and I should probably do the same. But then
my "selection" is not safe anymore because the listing and line numbers
may change under the user's feet during a delete operation. I still
don't know how to avoid that possibility. Ideas are very welcome.

I still haven't written any of that. I will think harder about it and
test it extensively. What I already have is a "sandbox" mode that lets
me choose a directory and the app will refuse to do anything potentially
"regrettable" outside of the sandbox.

TL;DR: no, I probably won't need traces. Probably.

--
Luc
>>

Re: dicts vs. namespaces - who wins?

<unfb1m$186al$1@dont-email.me>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13117&group=comp.lang.tcl#13117

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: dicts vs. namespaces - who wins?
Date: Sun, 7 Jan 2024 23:10:47 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 125
Message-ID: <unfb1m$186al$1@dont-email.me>
References: <20240107013803.5887d79c@lud1.home> <undi16$10c48$1@dont-email.me> <20240107133504.334aa11d@lud1.home> <unf3dl$1759e$1@dont-email.me> <20240107192027.79c666d8@lud1.home>
Injection-Date: Sun, 7 Jan 2024 23:10:47 -0000 (UTC)
Injection-Info: dont-email.me; posting-host="362e4ed0701982492d30bdaa94481307";
logging-data="1317205"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18lH2XL6jBBWCqxRF+eUd2d"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:ojq1JAA4PydWFsk+k7o7K3izNDQ=
 by: Rich - Sun, 7 Jan 2024 23:10 UTC

Luc <luc@sep.invalid> wrote:
> On Sun, 7 Jan 2024 21:00:37 -0000 (UTC), Rich wrote:
>
>>Watch:
>>
>> $ rlwrap tclsh
>> % set somevar "a string"
>> a string
>> % set dict "key1 $somevar"
>> key1 a string
>> % dict get $dict key1
>> missing value to go with key
>> %
>>vs:
>> % set dict [dict create key1 $somevar]
>> key1 {a string}
>> % dict get $dict key1
>> a string
>> %
>
> Well, yes, but I read the upper part of your example, found it strange
> and did it differently:
>
> % set somevar "a string"
> % dict create dict {}
> % dict set dict key1 $somevar
> key1 {a string}
> % dict get $dict key1
> a string
>
> That would be my way of doing it.

Except that is not what you posted at the start of this thread:

> dict set ::TabControl $tabID "
> [list TCTabPosition $position]
> [list TCDirectory $dir]
> [list TCViewMode $::GUIoptions_DefaultLayout]
> "

You are trying to set the key in $tabID to a string created by
concatenating lists through string interpretation. Which is the point
I'm trying to make:

Don't create a dict, or a list, by beginning with a double quoted
string: " ... "

Doing so can often get you a quick ride to quoting hell:
https://wiki.tcl-lang.org/page/Quoting+hell

>>[dict create ...] for dicts
>>[list ...] for lists
>
> I make mistakes with lists often and with dicts too because dicts are
> (or may be) lists of lists. And the [list] construct doesn't always
> help in my case. PEBKAC.

If you try to use [list ...] inside double quoted strings to
concatenate things, then sometimes it works, sometimes it will blow up.

Don't try to create a list by beginning something with double quote
("). When you find yourself doing so, take a step back and work out
how to use [list] (nested if necesssary) or [dict create] (nested if
necessary) to create the list of dict, without needing to surround it
with double quotes.

>>The question of course is, do you plan to use traces?
>
> Maybe. Some idea crossed my mind. If one tab is displaying a directory
> and the user opens another tab for the same directory and makes changes
> in it (e.g. create a new directory) I thought that maybe I should let
> all tabs that display that one directory know about it immediately. But
>
> 1. I keep control of everything by tabID not by path and there are no
> variables concerning the content of directories except one array that
> is also identified by tabID. The idea behind that is, for example, when
> selecting an entry (for deletion for example) I used to identify the
> entry's path with [$widget get $currentline.0 "$currentline.0 lineend]
> but I scrapped that for cosmetic reasons. I am giving the user the
> option to list empty directories as such, for example:
>
> somedir
> anotherdir
> thisother (empty)
> someother
>
> So I am using an array of line numbers and filenames instead so the
> displayed entry doesn't have to be exactly the same as the actual
> filename.
>
> Yes, I realize it is dangerous, but unless the tab display "refreshes"
> between the user's selection and the delete operation, the selection
> and the operation are safe, and "getting" the filename from the widget
> display wasn't terribly safe either.
>
> 2. When I create files and directories in my application, other file
> managers pick them up and display them immediately. They are really
> fast so I'm guessing they keep monitoring the current tab's directory
> every so many milliseconds and I should probably do the same.

Unlikely. More likely they are using the kernel inotify event api:

https://wiki.tcl-lang.org/page/tcl%2Dinotify

Polling every few ms is a great way to burn battery on a laptop/phone
when the same is not plugged into a charger.

You, of course, still have to know what to change in the UI based on
what the kernel tells you was updated.

None of this (so far) needs Tcl's traces.

> But then my "selection" is not safe anymore because the listing and
> line numbers may change under the user's feet during a delete
> operation. I still don't know how to avoid that possibility. Ideas
> are very welcome.

One possibility might be to have the active 'tab' broadcast a change
event via [event generate] and have the tabs all watching that event
stream, and making appropriate updates to their own displays based
upon the changes broadcast via the events.

Another possibility is for the active tab to update all the underlying
data of all the other tabs, but that feels more complex than having
each tab do its own updates from a "something changed" message.

Re: dicts vs. namespaces - who wins?

<20240108044512.53a7d1b5@lud1.home>

  copy mid

https://news.novabbs.org/devel/article-flat.php?id=13118&group=comp.lang.tcl#13118

  copy link   Newsgroups: comp.lang.tcl
Path: i2pn2.org!i2pn.org!paganini.bofh.team!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: dicts vs. namespaces - who wins?
Date: Mon, 8 Jan 2024 04:45:12 -0300
Organization: A noiseless patient Spider
Lines: 41
Message-ID: <20240108044512.53a7d1b5@lud1.home>
References: <20240107013803.5887d79c@lud1.home>
<undi16$10c48$1@dont-email.me>
<20240107133504.334aa11d@lud1.home>
<unf3dl$1759e$1@dont-email.me>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Info: dont-email.me; posting-host="526ce00c118fd91fb99b7c6baf8e17a8";
logging-data="1547276"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18CmpxGJRTPmJ3S3yEG7xXG+cQtZCBA93k="
Cancel-Lock: sha1:SPFUMUshc9W3EJAkj7r2VKQJnYc=
 by: Luc - Mon, 8 Jan 2024 07:45 UTC

I forgot to comment on this:

>> The command lines are longer and look a bit too fragmented to me,
>
>This is true, but you realize this is Tcl, you can 'adjust' that fact
>if you like:
>
> % dict get $dict key1
> a string
> % interp alias {} dget {} dict get
> dget
> % dget $dict key1
> a string
> %

I find this a bad idea. A long time ago, when I had just learned Tcl,
I loved that idea and used it a lot. I made a long script that I always
sourced in my scripts and I still source in Tkcon (which is of course
both my Tcl testing ground and my trusty pocket calculator thanks to
'unknown') with a ton of such abbreviations and enough syntax sugar to
have diabetes.

It took a while but I eventually realized that I was conditioning myself
to speak a Tcl dialect that others would likely understand but with some
considerablle effort, and that would certainly annoy the hell out of a
lot of people if I ever shared any code in that pidgin Tcl. I was
basically writing in Perl.

I may still use my sugary syntax on Tkcon once in a while, but I've
acquired the habit of avoiding those tricks so I don't alienate myself
from The Elements of Style. As this is a "public" project that others
may have to maintain someday, I will most certainly do my best to speak
The King's Tcl.

But my best is MY best, you know...

--
Luc
>>

1
server_pubkey.txt

rocksolid light 0.9.8
clearnet tor