Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

I want to know the pros and cons of TCL....

602 views
Skip to first unread message

Anil A Kumar

unread,
Sep 30, 2009, 11:58:51 AM9/30/09
to
Hi all,

I just wanted to know the pros and cons of TCL. Just now I tried to
return an array from proc it is not returning. Even I had a doubt, as
we have array concept in TCL what is the need of keylist? and We can
return a keyList fron proc but we cannot return array. So, I thought I
better to know the pros and cons of TCL...

Thanks in advance!

-Anil A Kumar

Bryan Oakley

unread,
Sep 30, 2009, 12:16:45 PM9/30/09
to

Asking for pros and cons of Tcl is like asking which notes in a song
are too loud or too soft. Without knowing what you consider "loud" or
"soft" we can't give a good answer. And what is too loud for one type
of song (lullaby, for example) might be too soft for another (heavy
metal rock). Similarly with software, what you call a pro might be a
con for someone else, and what is a pro for one type of application
might be a con for another.

What you need to know about Tcl is this: it is different. Don't expect
it to work like other languages. This isn't a bad thing, it's what
gives Tcl its strength. There are things you can do in Tcl that are
virtually impossible in other languages. Of course, the opposite is
true as well, there are things you can do in other languages that you
can't easily do in Tcl.

schlenk

unread,
Sep 30, 2009, 12:28:26 PM9/30/09
to
key value lists can have duplicate keys..., arrays cannot

About pros and cons, it depends on what you want to do and with what
you compare.

Lets try a comparision of the mainstream Python 2.6 with the upcoming
Tcl 8.6.

Tcl's pro points there (compared to Python)
- Nicer Unicode and encoding support
- Better Threading support (especially for Embedding in multithreaded
C/C++ code)
- Nicer event based programming (unless you add the Twisted package to
Python)
- Better Metaprogramming abilities / write your own DSL stuff
- Better Tk integration
- Better x-platform abilities (e.g. symlinks/reparse points on all big
platforms...)
- Better single file deployment options
- Safe Interpreters
- Better packaging system (but you can argue here)

Tcl's con points (compared to Python)
- More verbose syntax
- fewer 3rd party libraries available
- No good UDP or IPv6 support on all platforms
- Often slower
- No access to much platform specific stuff in the core language
( which is a consquence of better x-platform abstraction, you cannot
have both)
- Not so many books

I guess i forgot a lot of other pro/con things that might interest one
or the other.

Michael

Anil A Kumar

unread,
Sep 30, 2009, 12:47:08 PM9/30/09
to

Sorry, I was supposed to ask limitations....

Anil A Kumar

unread,
Sep 30, 2009, 12:47:48 PM9/30/09
to

Thanks,

tom.rmadilo

unread,
Sep 30, 2009, 1:46:11 PM9/30/09
to
On Sep 30, 9:16 am, Bryan Oakley <oak...@bardo.clearlight.com> wrote:
> What you need to know about Tcl is this: it is different. Don't expect
> it to work like other languages. This isn't a bad thing, it's what
> gives Tcl its strength. There are things you can do in Tcl that are
> virtually impossible in other languages. Of course, the opposite is
> true as well, there are things you can do in other languages that you
> can't easily do in Tcl.

This is something that I have generally agreed with over the years,
but as time goes on, I have found fewer things which fall into the
category of "things you can't easily do in Tcl".

What we have, IMHO, is a lack of evangelism and experimentation in
Tcl, and a general inferiority complex in certain areas: objects,
design patterns, algorithm support, data structure support.

I was forced to revise my own misconceptions when I translated two C
programs into Tcl without understanding either the datamodel or the
algorithm in either program. The first was a brute force sudoku
solver. I used an identical algorithm and data structure. The second
was an exact cover algorithm (dancing links) that used a single non-
recursive compact algorithm with goto jumps. Again, without the
slightest understanding of the algorithm, I had no problem with the
translation. Code lines for each version were similar to the
original.

David Gravereaux

unread,
Sep 30, 2009, 2:08:17 PM9/30/09
to

No one has yet answered your first question on arrays. Yes, you can
return an array from a proc, just not by value.

proc foo {varName} {
upvar $varName local
set value 0
foreach name {a b c d} {set local($name) [incr value]}
}
array set bar {}

% foo bar
% parray bar
bar(a) = 1
bar(b) = 2
bar(c) = 3
bar(d) = 4


If you really want by value, flatten it to a list for the return call
with 'return [array get <name>]'

--


signature.asc

Larry W. Virden

unread,
Sep 30, 2009, 2:20:24 PM9/30/09
to
On Sep 30, 11:58 am, Anil A Kumar <401a...@gmail.com> wrote:

> I just wanted to know the pros and cons of TCL.

They are similar to the pros and cons of any other programming
language.

Cons:
1. you have to learn how to design and implement algorithms in general
to be able to write useful complex programs (in any language)
2. you have to learn the language well not to get bit by language
pecularities
3. you have to learn the language by writing code if you want to be
comfortable writing programs that tend to work.
4. you have to learn where the resources are to look up "how to ..."
and "why did ..." type questions

Pros:
1. you can write all sorts of programs, of all sizes, in Tcl.
2. once you are comfortable reading and writing tcl, as well as how to
design and implement an algorithm, you can expect to get the job done
3. you have access to real-time IRC chat areas, wikis, and web
discussion groups where questions are typically answered without too
much grief.

Larry W. Virden

unread,
Sep 30, 2009, 2:24:57 PM9/30/09
to
On Sep 30, 2:08 pm, David Gravereaux <davyg...@pobox.com> wrote:

> No one has yet answered your first question on arrays.  Yes, you can
> return an array from a proc, just not by value.
>
> proc foo {varName} {
>    upvar $varName local
>    set value 0
>    foreach name {a b c d} {set local($name) [incr value]}}
>
> array set bar {}
>
> % foo bar
> % parray bar
> bar(a) = 1
> bar(b) = 2
> bar(c) = 3
> bar(d) = 4
>
> If you really want by value, flatten it to a list for the return call
> with 'return [array get <name>]'
>


Well, technically speaking, you are not returning an array. Instead,
you are directly modifying the array. And of course, another method of
doing that would be to build the array within a namespace (even if
only the global namespace) and then just modify it directly.

At least in the way you do it, the same proc can easily be used for
multiple arrays - in the case of the global array situation, to make
it "generic" you would have to pass in the array name and then use a
variable holding the name or some such thing.

tom.rmadilo

unread,
Sep 30, 2009, 2:40:00 PM9/30/09
to

Can you return an actual data structure in any language? Probably you
return a pointer to the start of the structure. In Tcl, you usually
pass in the name of the array, the procedure then uses the array name
to create/update the array, but just like in most languages, the
structures created inside a function (local variables, and the
associated storage) disappear once the function returns, so persistent
structures must be created somewhere else.

Anil A Kumar

unread,
Sep 30, 2009, 3:45:49 PM9/30/09
to

Larry,

you are correct. I just wanted to return the array from the proc
directly. And keyed lists are also similar to arrays. As we are using
hash arrays in tcl infact we can use the same facility with
keyedlists. But we can easily return keyedlists from proc. Any I have
few more doubts like we have sleep and after both do the same thing,
they wait by specified by the amount of time mentioned. But difference
is after is in msec but sleep takes seconds. Why do we have these
duplicate commands.

In C we can call procs by references but in TCL we cannot. Just wanted
to list out the things like these.

I will be happy if we can figure out the duplicate commands, or
atleast the main purpose of these kinds of similar commands.

tom.rmadilo

unread,
Sep 30, 2009, 4:58:44 PM9/30/09
to

Basically you are speculating. Do you really think we have two
identical commands?

> In C we can call procs by references but in TCL we cannot. Just wanted
> to list out the things like these.

Not sure what you mean here. You can store a procedure name in a
variable, and then place the variable where a command should go:

% set a puts
% $a hi
hi
% $a $a
puts

Tcl has a more general concept of call by reference, we have named
references which you don't even need to pass around in order to use
(assuming you agree on the name ahead of time). But it seems the same
as with C, if you ask me.

> I will be happy if we can figure out the duplicate commands, or
> atleast the main purpose of these kinds of similar commands.

The main purpose is that they are different commands. One difference
is that [after] works with the event loop and sleep just halts the
execution of the current script for the specified time.

Anil A Kumar

unread,
Sep 30, 2009, 5:28:54 PM9/30/09
to

can u give more details on event loops...

David Gravereaux

unread,
Sep 30, 2009, 6:39:27 PM9/30/09
to
tom.rmadilo wrote:
> On Sep 30, 12:45 pm, Anil A Kumar <401a...@gmail.com> wrote:
...

>> I will be happy if we can figure out the duplicate commands, or
>> atleast the main purpose of these kinds of similar commands.
>
> The main purpose is that they are different commands. One difference
> is that [after] works with the event loop and sleep just halts the
> execution of the current script for the specified time.

Like Tom says, they are different. These two forms do the same thing:

sleep 1
after 1000

But [after] does more when a script is placed at the end.

set count1 0
set count2 100

proc refresh1 {} {
puts [incr ::count1]
after 1000 {refresh1}
}
proc refresh2 {} {
puts [incr ::count2]
if {$::count2 == 120} {set ::done 1; return}
after 1200 {refresh2}
}
refresh1; refresh2
vwait done
puts finished
exit


Paste that into tclsh. In the above, background activity (sockets,
pipes, Tk, etc..) would be allowed due to entering the event loop. A
blocking [sleep] is not the same.

--


signature.asc

tom.rmadilo

unread,
Sep 30, 2009, 6:52:46 PM9/30/09
to
On Sep 30, 2:28 pm, Anil A Kumar <401a...@gmail.com> wrote:

> can u give more details on event loops...

There is an event queue and a loop.

Ralf Fassel

unread,
Oct 1, 2009, 8:32:16 AM10/1/09
to
* Anil A Kumar <401...@gmail.com>

| can u give more details on event loops...

http://wiki.tcl.tk/1527

HTH
R'

Nick Hounsome

unread,
Oct 1, 2009, 11:29:07 AM10/1/09
to

I can't resist having a go too :-)

The con here is that Tcl arrays are not arrays as anyone else
understands the term.

The confusion is between variables and values - an array is a special
sort of variable not a special sort of value.

There are no types in Tcl.
Every VALUE is effectively a string.
An array isn't a value (but it's elements and keys are).

All the things that seem to be types in Tcl such as list, dict,
numbers are best thought of as strings that are optimized for a
particular use and strings can be freely returned from procs.

If the string representation looks like a dictionary then it can be
used as one but that use will be more efficient if you just built it
with the dict command and not the list command.

None of this is really a deficiency of Tcl but just an area of
potential confusion.

I wouldn't bother trying to make detailed list of differences between
C and Tcl because you will get bogged down in trying to make precise
definitions of things that people think that they understand but
actually haven't thought deeply about. You wouldn't try to compare C
to Lisp and you shouldn't try to compare it to Tcl.

tom.rmadilo

unread,
Oct 1, 2009, 1:32:25 PM10/1/09
to
On Oct 1, 8:29 am, Nick Hounsome <nick.houns...@googlemail.com> wrote:
> I wouldn't bother trying to make detailed list of differences between
> C and Tcl because you will get bogged down in trying to make precise
> definitions of things that people think that they understand but
> actually haven't thought deeply about. You wouldn't try to compare C
> to Lisp and you shouldn't try to compare it to Tcl.

Before you can compare two languages, you first have to decide the
purpose of the comparison. Tcl may be unique among general purpose
programming languages in one respect: it was initially designed to
leverage the vast supply of existing operating system/shell commands
and programs (and C library code). The tcl shell, "tclsh" is a safer
and easier to comprehend shell than the typical shells available on
unix-like systems. Whereas Java and C# have been forced to recreate
all the system level and application level tools, Tcl was designed to
use what is already there. Because of that high-level reuse of
existing components, there is very little need or interest in
rewriting libraries and applications in Tcl. I'm just talking about
Tcl, someone else could probably point out the usefulness of Tk to
expose existing command line applications and libraries as GUI
applications.

So, although there may be languages which are faster at the algorithm
level, this is generally not a problem with Tcl, because the focus is
on leveraging everything that is available, not replacing it with a
Tcl only solution.

Donal K. Fellows

unread,
Oct 1, 2009, 6:46:54 PM10/1/09
to
On 1 Oct, 10:32, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> So, although there may be languages which are faster at the algorithm
> level, this is generally not a problem with Tcl, because the focus is
> on leveraging everything that is available, not replacing it with a
> Tcl only solution.

Nicely said. Tcl's specifically intended to be used with components
(err, commands) from other languages. There's no shame in doing just
that.

Donal.

Anil A Kumar

unread,
Oct 2, 2009, 2:11:26 AM10/2/09
to
On Oct 2, 3:46 am, "Donal K. Fellows"

This reply is to Nick.

Nick even keyed lists also have the keys, but still we can return them
from a proc. And I know TCL array are hash arrays, but the concept is
same,isn't it?

And I just raised the issue not to compare TCL with other languages.
Since from 2 years I am working on TCL, I know the beauty of TCL, and
easiness. But my main intention is to let the TCL lovers to know about
the cons, so that if they can get any solution or alternate to that.
And that will be helpful to us. One more thing is, if don't know the
limitations, some times we cannot work properly, eg.: While writing a
script one of my procs I was returning an array, I got an error
message saying "a is not a variable and it is an array". Earlier I
don't know that we cannot return an array, I had spent ;ot of time to
figure it out, so I just want to prepare document, so that we can
share that to all our TCL lovers.

-Anil A Kumar

Nick Hounsome

unread,
Oct 2, 2009, 4:38:17 AM10/2/09
to
> This reply is to Nick.
>
> Nick even keyed lists also have the keys, but still we can return them
> from a proc. And I know TCL array are hash arrays, but the concept is
> same,isn't it?

keys are values not variables.
arrays aren't values they just happen to be implemented using some of
the same C code as for dicts which are values.

> And I just raised the issue not to compare TCL with other languages.
> Since from 2 years I am working on TCL, I know the beauty of TCL, and
> easiness. But my main intention is to let the TCL lovers to know about
> the cons, so that if they can get any solution or alternate to that.

This is what I thought. Whatever you know about Tcl my point was that
I don't think that you will be able to get it across to non-Tcl people
by trying to compare Tcl to C.

> And that will be helpful to us. One more thing is, if don't know the
> limitations, some times we cannot work properly, eg.: While writing a
> script one of my procs I was returning an array, I got an error
> message saying "a is not a variable and it is an array". Earlier I
> don't know that we cannot return an array, I had  spent ;ot of time to
> figure it out, so I just want to prepare document, so that we can
> share that to all our TCL lovers.

Here's my attempt at a simple comparison to C showing why arrays are
as they are.
NB This is not the real Tcl code as that is much more complicated but
hopefully it gives an insight.

struct Tcl_Obj {....}; // All Tcl values really are Tcl_Obj*

struct Tcl_Dict : public Tcl_Obj { Tcl_Obj* keys; Tcl_Obj*
values; } // Not real Tcl but a dict really is a value

// array set aTclArray {}
Tcl_Dict aTclArray;

// proc aTclProc {} {return [dict]}
Tcl_Obj* aTclProc() // All Tcl procs really do return Tcl_Obj* (just
not like this)
{
return new Tcl_Dict();
}

// set aTclVar [aTclProc]
Tcl_Obj* aTclVar = aTclProc(); // OK

// set aTclArray [aTclProc]; # ERROR - aTclArray is not a variable
Tcl_Dict aTclArray = ATclProc(); // ERROR - type mismatch

// proc badTclProc { array set a {}; return $a }; # ERROR because not
returning Tcl_Obj*
Tcl_Dict* badTclProc() // Not valid because all procs must return
Tcl_Obj*
{
return new Tcl_Dict();
}

To be honest I doubt that this is any more helpful than any other
explanation but maybe it will make some sense to C/C++ programmers.

IMHO If there was a clear concise explanation then someone more
articulate than me would have given it by now. If you manage to
succeed where all before you have failed then you will be a hero of
the Tcl community but just saying that you can't return arrays is too
simplistic.

You might like to remind people that one of the pros of arrays
compared to dict values is that you can trace/bind individual array
elements whereas you cant trace/bind values in a dict (or "keylist").

I like to refer people who are getting confused by names/variables and
values to Lewis Carroll (It wont clear up the confusion but it made me
think when my IT Professor first told it):

The name of the song is called "Haddocks' Eyes."'
`Oh, that's the name of the song, is it?' Alice said, trying to
feel interested.
`No, you don't understand,' the Knight said, looking a little
vexed. `That's what the name is called. The name really is "The Aged
Aged Man."'
`Then I ought to have said "That's what the song is called"?'
Alice corrected herself.
`No, you oughtn't: that's quite another thing! The song is called
"Ways and Means": but that's only what it's called, you know!'
`Well, what is the song, then?' said Alice, who was by this time
completely bewildered.
`I was coming to that,' the Knight said. `The song really is "A-
sitting On A Gate": and the tune's my own invention.'

tom.rmadilo

unread,
Oct 2, 2009, 3:20:43 PM10/2/09
to

Can you please name a single language which returns an array? An array
is a type of storage, not a value.

But forget about reality for a minute. It is considered bad design for
a procedure to choose the name of an [upvar]'d variable in Tcl. The
general practice is to pass in the name of the variable to be created
in the current scope. IF you were able to return a local array (does
that phrase have meaning?), it is important to point out that the next
attempt at accessing the array would lead to a serious error since the
array no longer exists.

Anil A Kumar

unread,
Oct 3, 2009, 3:08:52 AM10/3/09
to
I don't know any other language than TCL, Here is a sample script:


senario: returning array
# -----------------------------
package require Tclx

# Set an array
array set anil {a 1 b 2 c 3 d 4}

# proc which returns an array
proc arrayTest {args} {
array set procArray {1 a 2 b 3 c 4 d}
return $procArray
}

# Test the proc

arrayTest

#output:
#C:\Documents and Settings\Advay\Desktop>tclsh85 sample1.tcl
#can't read "procArray": variable is array
# while executing
#"return $procArray"
# (procedure "arrayTest" line 3)
# invoked from within
#"arrayTest"
# (file "sample1.tcl" line 15)

#----------------------------------------

Senario: calling a proc by array.

#---------------------------------------

# -----------------------------
package require Tclx

# Set an array
array set anil {a 1 b 2 c 3 d 4}

# proc which returns an array
proc arrayTest {args} {
array set procArray {1 a 2 b 3 c 4 d}
return $procArray
}

# Test the proc

arrayTest $anil

#output:
#C:\Documents and Settings\Advay\Desktop>tclsh85 sample1.tcl
#can't read "anil": variable is array
# while executing
#"arrayTest $anil"
# (file "sample1.tcl" line 15)

---- This because we can't use an array as a variable directly we can
parse it and use it.

1. I just want to let you guys know that we can't use arrays to return
any arrays from procs, that may lead to tcl crashes. Even while
calling procs we can use parsed arrays, but not entire array.

2. Tom, Nick, Donal, Ralf, David, and Larry can we prepare a document
which gives the limitations of TCL, it is not to hurt TCL lovers but
to help them in scripting, if they know all these issues they they can
use TCL effectively. What do you say. Or else at least we can post all
these thing in blog.

Please let me know your concerns, you can send me an email @---
401...@gmail.com/ you can post your comments here.


-Anil A Kumar

Aric

unread,
Oct 3, 2009, 4:22:34 AM10/3/09
to
> 401a...@gmail.com/ you can post your  comments here.
>
> -Anil A Kumar

You may be interested in this part of the Tcl tutorial, which is part
of the official Tcl documentation: http://www.tcl.tk/man/tcl/tutorial/Tcl23.html

And this page from the Tcl wiki: http://wiki.tcl.tk/3262

You might add some comments about limitations on passing arrays to
this page: http://wiki.tcl.tk/19838

David Gravereaux

unread,
Oct 3, 2009, 4:35:58 AM10/3/09
to
Anil A Kumar wrote:
> I don't know any other language than TCL, Here is a sample script:

Most college programs (used to) start with Pascal. Any document that
you would feel to be helpful would only be from your own perspective,
thus would not be appropriate to cover others point-of-views as they
approach this new paradigm.

We already explained pass-by-reference, but if you can't grasp it now,
let it brew for later until it clicks.

In your script, change 'return $procArray' to be 'return [array get
procArray]'. That is a flattened list. Or return use a dict like so:

proc qwe {} {set foo [dict create one 1 two 2]; return $foo}
qwe

dicts are similar to lists in their storage, but are accessed more like
a structure. Hit the docs to read about them:
http://www.tcl.tk/man/tcl8.5/TclCmd/dict.htm

Or the proc may take a name of an array that it will be modified in the
caller's frame with [upvar] for pass-by-reference.

Arrays not returnable by procs is NOT a limitation. The only limitation
I see is your understanding of Tcl's features.

# Set an array
array set anil {a 1 b 2 c 3 d 4}

# proc which returns an array

proc arrayTest {{arrayName {}}} {
upvar $arrayName local
if {[array exist local]} {
puts "found the array, a=$local(a)"
}
set procDict [dict create 1 a 2 b 3 c 4 d]
return $procDict
}

# Test the proc

arrayTest
arrayTest anil
--


signature.asc

David Gravereaux

unread,
Oct 3, 2009, 4:37:26 AM10/3/09
to
Anil A Kumar wrote:
> Or else at least we can post all
> these thing in blog.

It's all in the wiki already: http://wiki.tcl.tk

--


signature.asc

tom.rmadilo

unread,
Oct 3, 2009, 2:11:08 PM10/3/09
to
On Oct 3, 12:08 am, Anil A Kumar <401a...@gmail.com> wrote:
> I don't know any other language than TCL, Here is a sample script:
>
> senario: returning array
> # -----------------------------
> package require Tclx
>

What does Tclx have to do with anything below? Nothing.

> # Set an array
> array set anil {a 1 b 2 c 3 d 4}

This creates an array at the global level. You can do this in C in a
code file outside of a function:

static char buf[100];

A function defined in that file can refer to this variable and the
variable will continue to exist after the function returns.

If you define an array inside a function in C:

int
NsTclServerObjCmd(ClientData arg, Tcl_Interp *interp, ...)
{
Pool *poolPtr;
char mybuf[100];

...
}

There is no way to return "mybuf" from this function, and the array
will cease to exist after the function returns.

How is this different from Tcl? It isn't.

> # proc which returns an array
> proc arrayTest {args} {
>    array set procArray {1 a 2 b 3 c 4 d}
>    return $procArray
>
> }

If you assumption is invalid, any conclusions you reach based upon the
assumption will be invalid. procArray is created withing the
procedure. You can't return variables which exist in a procedure.

Also, $ "operator" can't be applied to procArray because procArray
isn't a variable. Tcl has several namespaces where it looks up stuff.
Unlike most languages, you can reuse names as long as the things you
are naming exist in different namespaces. One namespace is for
procedure names, another is for variables, still another is for array
names. However, array names can't be used as variable names. I don't
know the reason for this limitation, but if it was possible, debugging
code would be a little more difficult. Anyway, procArray isn't in the
list of variables which exist inside your procedure. But if procArray
was the name of a variable, $procArray would not return the variable,
it would return the value of the variable. A procedure which returned
$procArray would not be returning the storage location, but a value.
The variable procArray, the place in memory where it exists would not
be accessible after your proc returned. No different than any other
language which can define and use local variables.


> # Test the proc
>
> arrayTest
>
> #output:
> #C:\Documents and Settings\Advay\Desktop>tclsh85 sample1.tcl
> #can't read "procArray": variable is array

> 1. I just want to let you guys know that we can't use arrays to return


> any arrays from procs, that may lead to tcl crashes. Even while
> calling procs we can use parsed arrays, but not entire array.

Seriously? No language can "return" an array, since an array is
storage, memory.

If you open a file on disk, can you return the file? No. The file
remains on disk. A file on disk is exactly the same as a char array in
memory. You can't "return" such a thing. And if you create this
storage inside a proc or function, even references to it become
invalid once the proc or function returns.

Andreas Leitgeb

unread,
Oct 3, 2009, 3:27:36 PM10/3/09
to
tom.rmadilo <tom.r...@gmail.com> wrote:
> One namespace is for procedure names, another is for variables, still another
> is for array names. However, array names can't be used as variable names.

Doesn't this exclusion effectively put them in the same namespace?
Or are there really different lookup-tables for variables and arrays
inside each scope or tcl-namespace?

tom.rmadilo

unread,
Oct 3, 2009, 5:17:03 PM10/3/09
to
On Oct 3, 12:27 pm, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:

My guess is that the names are stored in the same hash array. If the
named variable was an array, the associated value would be a pointer
to another hash array which stored the name-value pairs.

The main point is that an array is not a "value", and neither is a
variable. Neither a variable nor an array can be "returned" by a proc.
But this is no different than any other programming language. At most
you can return a reference or a pointer to an array, which in Tcl is
just the name of the array.

Gerald W. Lester

unread,
Oct 3, 2009, 8:35:56 PM10/3/09
to
tom.rmadilo wrote:
> On Sep 30, 12:45 pm, Anil A Kumar <401a...@gmail.com> wrote:
>> On Sep 30, 11:40 pm, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:...

>>
>> you are correct. I just wanted to return the array from the proc
>> directly. And keyed lists are also similar to arrays. As we are using
>> hash arrays in tcl infact we can use the same facility with
>> keyedlists. But we can easily return keyedlists from proc. Any I have
>> few more doubts like we have sleep and after both do the same thing,
>> they wait by specified by the amount of time mentioned. But difference
>> is after is in msec but sleep takes seconds. Why do we have these
>> duplicate commands.

Keyed list and the sleep command are not part of Tcl but rather TclX (an
extension).

Tcl 8.5+ does have dictionaries, which are like keyed list.

>
> Basically you are speculating. Do you really think we have two
> identical commands?
>
>> In C we can call procs by references but in TCL we cannot. Just wanted
>> to list out the things like these.
>
> Not sure what you mean here. You can store a procedure name in a
> variable, and then place the variable where a command should go:
>
> % set a puts
> % $a hi
> hi
> % $a $a
> puts

I *think* he meant pass variables to a procedure by reference -- yes we have
that, as in:

proc AddOne {varName} {
upvar $varName localVar

incr localVar
}
set x 1
AddOne
puts "x = $x"

We also have pass by name via uplevel.

--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Alexandre Ferrieux

unread,
Oct 3, 2009, 9:30:24 PM10/3/09
to
On 4 oct, 02:35, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
>
> [...] pass variables to a procedure by reference -- yes we have
> that, [upvar]

>
> We also have pass by name via uplevel.

Hrm. Without any desire to re-re-launch the boring terminology debate
about "by name vs. by reference", [upvar] is the only name/reference
manipulation primitive. Uplevel is a completely different beast,
actually a variant of [eval] climbing the ladder of call frames.

(Andreas, I know you know this, I just wanted to eliminate what I felt
was a risk of extra, unneeded confusion in our collective response to
Anil)

-Alex

Alexandre Ferrieux

unread,
Oct 3, 2009, 9:32:15 PM10/3/09
to
On 4 oct, 03:30, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
wrote:

>
> (Andreas, I know you know this, I just wanted to eliminate what I felt
> was a risk of extra, unneeded confusion in our collective response to
> Anil)

And I added confusion myself since I'm pretty sure Andreas and Gerald
are two different people ;-)
Sorry guys.

-Alex

tom.rmadilo

unread,
Oct 3, 2009, 9:34:07 PM10/3/09
to
On Oct 3, 5:35 pm, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
> tom.rmadilo wrote:
> > On Sep 30, 12:45 pm, Anil A Kumar <401a...@gmail.com> wrote:
> >> On Sep 30, 11:40 pm, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:...
>
> >> you are correct. I just wanted to return the array from the proc
> >> directly. And keyed lists are also similar to arrays. As we are using
> >> hash arrays in tcl infact we can use the same facility with
> >> keyedlists. But we can easily return keyedlists from proc. Any I have
> >> few more doubts like we have sleep and after both do the same thing,
> >> they wait by specified by the amount of time mentioned. But difference
> >> is after is in msec but sleep takes seconds. Why do we have these
> >> duplicate commands.
>

Note that I didn't author the above statement. Gerald, you are now
almost as sloppy as I am ;-)

> Keyed list and the sleep command are not part of Tcl but rather TclX (an
> extension).

I guess that explains the [package require in the examples]. [sleep]
must be from AOLserver's [ns_sleep], and the keyed lists are probably
from AOLserver's [ns_set].


> Tcl 8.5+ does have dictionaries, which are like keyed list.

AOLserver's [ns_set] has some features not found in [dict]. The most
important is that it maintains the order in which key-value pairs are
added, and keys can appear more than once, with other keys between
identical keys. You can also search for keys in a case-insensitive
way. An example use-case for this is to handle HTTP headers, which can
repeat and contain multiple headers with the same name.

>
> > Basically you are speculating. Do you really think we have two
> > identical commands?
>
> >> In C we can call procs by references but in TCL we cannot. Just wanted
> >> to list out the things like these.
>
> > Not sure what you mean here. You can store a procedure name in a
> > variable, and then place the variable where a command should go:
>
> > % set a puts
> > % $a hi
> > hi
> > % $a $a
> > puts
>
> I *think* he meant pass variables to a procedure by reference -- yes we have
> that, as in:

He talks about variables in other places, I assumed he meant procs
here. Tcl and C can handle both.

tom.rmadilo

unread,
Oct 4, 2009, 1:17:39 AM10/4/09
to
On Oct 3, 6:34 pm, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> On Oct 3, 5:35 pm, "Gerald W. Lester" <Gerald.Les...@cox.net> wrote:
> > Keyed list and the sleep command are not part of Tcl but rather TclX (an
> > extension).
>
> the keyed lists are probably
> from AOLserver's [ns_set].
>
> > Tcl 8.5+ does have dictionaries, which are like keyed list.
>
> AOLserver's [ns_set] has some features not found in [dict].

Oops, TclX's keyed list is much closer to a dict than to ns_set. Seems
like the feature set for [dict] makes it a better choice than the
keyed list.

Andreas Leitgeb

unread,
Oct 4, 2009, 3:33:46 AM10/4/09
to
tom.rmadilo <tom.r...@gmail.com> wrote:
> On Oct 3, 12:27 pm, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> wrote:
>> > One namespace is for procedure names, another is for variables, still another
>> > is for array names. However, array names can't be used as variable names.
>> Doesn't this exclusion effectively put them in the same namespace?
> My guess is that the names are stored in the same hash array.

I think that positively answers my side-question.

> The main point is that an array is not a "value", and neither is a
> variable. Neither a variable nor an array can be "returned" by a proc.

I think this subthread still lacks the statement, that
while it is principially and never possible to actually return
any type of *storage*(variables,arrays), it is easily possible
to return the *content(s)* of those as one value:

return $myLocalVariable
return [array get myLocalArray]

set retVar [myVariableContentReturningProc]
array set retArr [myArrayContentReturningProc]

(In case of reuse of "retArr", do an "array unset retArr", first.)

PS: how about an "array init <arrayName> <list>" that would first
do the clearing of the array, and then go on to "set"?
No big deal, but convenient. Is it worth a TIP?

Andreas Leitgeb

unread,
Oct 4, 2009, 3:40:32 AM10/4/09
to
Alexandre Ferrieux <alexandre...@gmail.com> wrote:
>> (Andreas, I know you know this, I just wanted to eliminate what I felt
>> was a risk of extra, unneeded confusion in our collective response to
>> Anil)
> And I added confusion myself since I'm pretty sure Andreas and Gerald
> are two different people ;-)
> Sorry guys.

It's ok. I was the one who started that debate some time ago.
I'm glad to read, that with respect to upvar/uplevel and pass-by-*
I've now got a follower of my views :-) (you)

tom.rmadilo

unread,
Oct 4, 2009, 4:43:27 AM10/4/09
to
On Oct 4, 12:33 am, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:

> tom.rmadilo <tom.rmad...@gmail.com> wrote:
> > On Oct 3, 12:27 pm, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> > wrote:
> >> > One namespace is for procedure names, another is for variables, still another
> >> > is for array names. However, array names can't be used as variable names.
> >> Doesn't this exclusion effectively put them in the same namespace?
> > My guess is that the names are stored in the same hash array.
>
> I think that positively answers my side-question.
>
> > The main point is that an array is not a "value", and neither is a
> > variable. Neither a variable nor an array can be "returned" by a proc.
>
> I think this subthread still lacks the statement, that
> while it is principially and never possible to actually return
> any type of *storage*(variables,arrays), it is easily possible
> to return the *content(s)* of those as one value:

The OP has been arguing that some other language (maybe C or C++)
actually allows you to return an array (or even just a pointer to an
array) that was defined inside a proc/function, and that Tcl was
uniquely unable to do this. I'm not sure how else to interpret the
statements. Here is the example proc:

# proc which returns an array
proc arrayTest {args} {
array set procArray {1 a 2 b 3 c 4 d}
return $procArray

}

Can anyone think of a language in which something like this would
work? The OP hasn't been very clear about exactly what is intended.
Part of the unclearness is that in C you can't even return a
representation of an array (something equivalent to [array get
myArray]), you could only return a pointer. But if the array was
defined inside the function, the pointer would be invalid once the
function returns...if the code even compiled.

Andreas Leitgeb

unread,
Oct 4, 2009, 6:46:35 AM10/4/09
to
tom.rmadilo <tom.r...@gmail.com> wrote:
> The OP has been arguing that some other language (maybe C or C++)
> actually allows you to return an array (or even just a pointer to an
> array) that was defined inside a proc/function, and that Tcl was
> uniquely unable to do this.

In C++ you can really (syntactically) return e.g. a vector: The compiler
allocates storage in the outer stackframe, and upon return from the inner
function the returned vector is copied byte-for-byte into the outer one's.

vector<int> myFunc() { vector<int> myArr; return myArr; }
...
vector<int> outer=myFunc();


Apart from that, some array could have been *allocated* (e.g. with malloc(),
or the "new"-operator) from inside a procedure/function/method. That doesn't
mean that the array's storage would necessarily be part of the function's
stackframe. I wouldn't bet that people always distinguish between "define"
and "allocate" when talking of objects thusly brought to existence.

Schelte Bron

unread,
Oct 4, 2009, 7:28:02 AM10/4/09
to
tom.rmadilo wrote:
> AOLserver's [ns_set] has some features not found in [dict]. The
> most important is that it maintains the order in which key-value
> pairs are added [...]

You appear to imply here that dicts don't maintain the order of
their keys. Fortunately that is not true, they do.

Schelte

Andreas Leitgeb

unread,
Oct 4, 2009, 9:44:20 AM10/4/09
to

They didn't do that from their beginning. Iow., this feature
was added later than the dicts themselves (iirc).

Anyway, "multiple same keys" is not among the features of dicts
(and most likely this won't change). To get it, one can use
lists of values associated to each key, but then, the insertion
order of keys is no longer maintained (only the order of values
within each key) - or just use lists directly like dicts, but
without the uniqueness and without dict's efficiency of element
access.

Donal K. Fellows

unread,
Oct 4, 2009, 1:14:26 PM10/4/09
to
On 4 Oct, 06:44, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:

> They didn't do that from their beginning.  Iow., this feature
> was added later than the dicts themselves (iirc).

Correct. I realized that by maintaining key ordering in the correct
sense, values would behave like classical string values in a suitable
sense and there would be far fewer weirdnesses involved. (And I
figured out a fairly cheap way to implement it.)

> Anyway, "multiple same keys" is not among the features of dicts
> (and most likely this won't change).

Correct. The fundamental model of dictionaries is that of a value-
>value map, not a multimap.

Donal.

tom.rmadilo

unread,
Oct 4, 2009, 1:26:30 PM10/4/09
to
The full sentence was:

"The most important is that it maintains the order in which key-value
pairs are

added, and keys can appear more than once, with other keys between
identical keys."

That is one feature, of which I then gave an example:

"An example use-case for this is to handle HTTP headers, which can
repeat and contain multiple headers with the same name."

Actually an HTTP header could contain multiple headers with the same
case-insensitive name, which is why ns_set has case insensitive
versions of a number of its subcommands: iunique, ifind, iget, icput.
It also has an isnull subcommand which can actually distinguish NULL
from an empty string.

The con (since this is a pro/con thread) is that ns_sets, like arrays,
are structures, not values. You can pass them around by name, but not
by value. Another minor inconvenience: you have to use AOLserver or
nstclsh, although I have written a tcl only replacement for ns_set
based upon [lsearch] and a simple package API.

Donal K. Fellows

unread,
Oct 4, 2009, 1:26:57 PM10/4/09
to
On 4 Oct, 01:43, "tom.rmadilo" <tom.rmad...@gmail.com> wrote:
> Can anyone think of a language in which something like this would
> work?

There are a good few (e.g. Haskell, Ocaml, ...) and they'd typically
implement it using references and/or copying under the hood. Many
languages don't expose how they manage memory on the program's behalf.

I suppose the key difference is whether the programming language
considers such things to be variables or values. Variables are (by
their very nature) mutable in some way and so have an identity that is
distinct from their current value (and are awkward to move around
unless there's some sort of reference remapping mechanism), whereas
values are (almost[*]) always theoretically constant - 42 is always 42
- and so can be copied around without language-theoretical problems.

Donal.
[* Old versions of Fortran got this wrong, which was a source of
horrible bugs. ]

Alexandre Ferrieux

unread,
Oct 4, 2009, 1:46:06 PM10/4/09
to
On Oct 4, 9:40 am, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:
>

> I'm glad to read, that with respect to upvar/uplevel and pass-by-*
> I've now got a follower of my views :-)   (you)

Uh, no offense intended, but we're just both stating the obvious
truth ;-)

-Alex


tom.rmadilo

unread,
Oct 4, 2009, 1:48:30 PM10/4/09
to
On Oct 4, 6:44 am, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:

> Schelte Bron <nos...@wanadoo.nl> wrote:
> > tom.rmadilo wrote:
> >> AOLserver's [ns_set] has some features not found in [dict]. The
> >> most important is that it maintains the order in which key-value
> >> pairs are added [...]
> > You appear to imply here that dicts don't maintain the order of
> > their keys. Fortunately that is not true, they do.
>
> They didn't do that from their beginning.  Iow., this feature
> was added later than the dicts themselves (iirc).

I remember arguing about the need for [dict] to maintain a fixed order
and was happy to see this feature added.

> Anyway, "multiple same keys" is not among the features of dicts
> (and most likely this won't change).  To get it, one can use
> lists of values associated to each key, but then, the insertion
> order of keys is no longer maintained (only the order of values
> within each key) - or just use lists directly like dicts, but
> without the uniqueness and without dict's efficiency of element
> access.

Personally I recommend that developers create their own specialized
data structures, maintained and accessed via an API to get the feature
set that they need. The base structures: lists, arrays, dicts don't
need to include every possible feature.

Schelte Bron

unread,
Oct 4, 2009, 3:12:27 PM10/4/09
to
tom.rmadilo wrote:
> On Oct 4, 4:28 am, Schelte Bron <nos...@wanadoo.nl> wrote:
>> You appear to imply here that dicts don't maintain the order of
>> their keys. Fortunately that is not true, they do.
> The full sentence was:
>
> "The most important is that it maintains the order in which
> key-value pairs are
> added, and keys can appear more than once, with other keys between
> identical keys."
>
True. And to me that looked like a listing of differences between
the two commands. So for the benefit of people who may run into this
thread in the future I just wanted to clarify that dicts do maintain
the order of their keys. That's all.

Schelte.

tom.rmadilo

unread,
Oct 4, 2009, 4:01:47 PM10/4/09
to

I've never found a compact way to describe this feature of an ns_set.
It does not map to any other internal data structure that I've seen.
Where is shows up is in external representations: HTTP headers, XML
child elements. And if the keys are thought of as column names in an
SQL query, an ns_set also matches the ordered and possibly duplicate
column names.

tom.rmadilo

unread,
Oct 4, 2009, 5:28:21 PM10/4/09
to
On Oct 4, 10:26 am, "Donal K. Fellows"

I guess the main difference is that in Tcl you can't specify what you
expect a procedure to return. You just know it will be a value. The
caller decides what the value means (if anything). The result is that
Tcl doesn't offer any syntactical support that would hint at any
behind the scenes manipulation. (One exception is the new {*} expand
syntax, but I'm not sure if you can apply that to a procedure call.)

Everyone can decide for themselves if this is a deficiency in Tcl, to
me it is just the way Tcl works. The interesting fact is that only
local variables: those created inside and local to a procedure (or
[namespace eval] block) are not available to other code. Every other
"thing" is discoverable and persists. Examples of such things are:
open file handles, global variables (any variable with a value in
the :: namespace), procedure definitions, namespaces and their
contents. Some people complain about this level of introspection. And
in addition to these persistent objects or "things", you can use
[upvar] to access local variables.

The best way to deal with complex structures which are created in one
place and used in another is to provide an interface which creates and
manages the structure.

Andreas Leitgeb

unread,
Oct 5, 2009, 1:55:04 AM10/5/09
to

Ah, yesofcourse! I was just still irritated how others could still
be *blind* about that truth. Or are they just part of a conspi
<transmission interrupted>

Andreas Leitgeb

unread,
Oct 5, 2009, 2:06:23 AM10/5/09
to
tom.rmadilo <tom.r...@gmail.com> wrote:
> (One exception is the new {*} expand syntax, but I'm not sure if
> you can apply that to a procedure call.)

Two clarifications on that:
1.) yes, {*} also works with command substitution
2.) {*} before any subst does not "hint" any more than
usage as an argument of e.g. llength would.

Apart from that, the only language I know of, that really infers
usage-information into the called function is perl. (they talk
about singular and plural contexts, iirc)

Anil A Kumar

unread,
Oct 13, 2009, 1:49:18 AM10/13/09
to
On Oct 4, 12:33 pm, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:

But we can return keyedList.... even it is king of storage..!

0 new messages