From: Jonathan Bromley on
On 11 Sep 2009 16:52:19 GMT, Joe English wrote:

>What you can say is: "A canonical-form list, when parsed as a script,
>will be interpreted as a single command whose words are the elements
>of the list." That's about the only relationship between lists
>and scripts I can think of...

I'm not sure about "single command":

% set L {puts a ; puts b}
% llength $L
=> 5
% eval $L
=> a
b

Prodded into thinking about this more carefully than
I have done before, I've learnt what most of you have
always known: the parsing of a string as a *script*
and the parsing of a string as a *list* are two very
different things. However, they have enough similarities
to confuse me (and, I suspect, others) from time to time.

As Joe's intriguing example with quoted square-
brackets shows, it *must* be like that for Tcl
to work sensibly.

Thanks to everyone for the interesting input.
One day, when I try to understand [subst], I will
be back for more help :-)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley(a)MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
From: Erik Leunissen on
Uwe Klein wrote:
>>>
>>> set newpath [eval [linsert $components 0 file join]]
>> ...

> ...
> you can have it faster even:
>
> set newpath [if true [linsert $components 0 file join]]]
>

That's creative!

As I understand it, both invocations cause an evaluation of the same
body. So, how come that the latter is faster?

Erik.


> uwe


--
leunissen@ nl | Merge the left part of these two lines into one,
e. hccnet. | respecting a character's position in a line.
From: Uwe Klein on
Erik Leunissen wrote:
> Uwe Klein wrote:
>
>>>>set newpath [eval [linsert $components 0 file join]]
>>>
>>>...
>
>
>>...
>>you can have it faster even:
>>
>>set newpath [if true [linsert $components 0 file join]]]
>>
>
>
> That's creative!
>
> As I understand it, both invocations cause an evaluation of the same
> body. So, how come that the latter is faster?
>
> Erik.

[eval] is supposed to shimmer to string to list tokens
while [if] takes the list without further ado.

at least that is the explanation that was given some years ago.

uwe
From: Joe English on
Jonathan Bromley wrote:
> Joe English wrote:
>>What you can say is: "A canonical-form list, when parsed as a script,
>>will be interpreted as a single command whose words are the elements
>>of the list." That's about the only relationship between lists
>>and scripts I can think of...
>
> I'm not sure about "single command":
>
> % set L {puts a ; puts b}
> % llength $L
> => 5
> % eval $L
> => a
> b

Ah, but that's not a *canonical-form* list.

% set L {puts a ; puts b}
% lrange $L 0 end
==> "puts a {;} puts b"
............^^^ note quoting
% eval [lrange $l 0 end]
==> error "wrong # args: ..."

That's why the [eval [linsert ...]] idiom is recommended for
callbacks: [linsert] returns a canonical-form list, so
you don't need to worry about quoting Tcl syntax characters.


--Joe English
From: Andreas Leitgeb on
Uwe Klein <uwe_klein_habertwedt(a)t-online.de> wrote:
>>>>>set newpath [eval [linsert $components 0 file join]]
>>> you can have it faster even:
>>> set newpath [if true [linsert $components 0 file join]]]
>> As I understand it, both invocations cause an evaluation of the same
>> body. So, how come that the latter is faster?
> [eval] is supposed to shimmer to string to list tokens
> while [if] takes the list without further ado.
> at least that is the explanation that was given some years ago.

Also some years ago there was a statement, that eval recognizes list
Tcl_Obj's (internally) and avoids the string/script detour then.