[TCLCORE] TIP#457 - Add Support for Named Arguments

4 views
Skip to first unread message

Mathieu Lafon

unread,
Apr 23, 2017, 6:58:44 PM4/23/17
to Tcl Core Mailing List
Hello,

TIP #457 and its implementation have just been updated. The main
modifications are :
- Modification of the behaviour of the -required specifier ;
- Updated implementation in the tip-457 branch, which also include the
updated documentation of info and proc ;
- Updated section on performance.

Related links :
- http://www.tcl.tk/cgi-bin/tct/tip/457.html
- http://core.tcl.tk/tcl/timeline?r=tip-457

As usual, feedback and comments are welcomed.

-- Mathieu

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Tcl-Core mailing list
Tcl-...@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tcl-core

Alexandre Ferrieux

unread,
Apr 23, 2017, 8:04:18 PM4/23/17
to Mathieu Lafon, Tcl Core Mailing List
On Mon, Apr 24, 2017 at 12:58 AM, Mathieu Lafon <mla...@gmail.com> wrote:
>
> TIP #457 and its implementation have just been updated.
> [...]
> As usual, feedback and comments are welcomed.

Thanks for committing all the doc changes.
With this, the nifty fossil-diff to trunk at

http://core.tcl.tk/tcl/vdiff?from=0ca94b41a13ea375&to=e722c70aad11a12a&sbs=1

gives a very good view of the volume of additions to code, tests, and docs.

Which leads me to the following observation: this is a big piece
(meaning some code maintenance work) with rich semantics and syntax
(meaning a large extra doc section).
In other words, this departs from the usual "Tcl is a simple language"
rather drastically, by increasing the cognitive entry cost to proc.n.
In addition, this move is done in support of a specific style that's
fashionable in other languages but not really a game-changer in Tcl.
Also, unless I've missed part of the discussion, it is not completely
neutral in terms of perf, as much work on the BC optimizer is still
due before named args can be morphed into positional at compile time.

For this reason, my current position is to vote NO regarding the TIP
itself (meaning core inclusion); but all this work should not be lost
and could very well live in an extension (with the only difference
that input arglist parsing should be explicitly requested by calling a
helper function).

-Alex

Peter da Silva

unread,
Apr 24, 2017, 8:40:51 AM4/24/17
to Alexandre Ferrieux, Mathieu Lafon, Tcl Core Mailing List
We consider this a major game changer in Tcl. Positional parameters make maintenance of large Tcl applications dangerously complex, but the verbosity of handcrafting named parameters and the significant overhead for using named parameters in small Tcl functions strongly discourages this idiom.

In addition, I would argue that named parameters and flags are a common and popular style in Tcl itself, but only in built-in commands and in extensions, where they are implemented in C. This change brings Tcl procs into parity with the core of the language.

The original rough design implied by the FlightAware bounty was much simpler, but it was argued that it wasn’t sufficiently Tcl-ish. Would you consider something closer to the original more acceptable?

Andreas Leitgeb

unread,
Apr 24, 2017, 12:57:26 PM4/24/17
to tcl-...@lists.sourceforge.net
Mathieu Lafon <mla...@gmail.com>
> TIP #457 and its implementation have just been updated. The main
> modifications are :
> - Modification of the behaviour of the -required specifier ;
> - Updated implementation in the tip-457 branch, which also include the
> updated documentation of info and proc ;
> - Updated section on performance.
> As usual, feedback and comments are welcomed.

Two points I'm rather unhappy about in version 1.19 of the TIP:

*) separation of -upvar <varname> into -upvar <bool> and -varname <varname>

This one was suggested by kbk. A few days later I asked him on tkchat about
his motivation. In a nutshell, it was that Kevin didn't like the idea
of the empty string meaning "I don't care for outer name" and that the
empty string would not have been a usable <varname> to hold the outer
variable's name, then. Given that :: and () are already "characters non
grata" for formal argument names and that therefore argument names are
already not "any string"s, then the idea of using the empty string for
the outer name doesn't seem all that precious to me to make upvar use
so much more verbose.

It may be inopportune to criticize kbk's ideas (with all his other contri-
butions being as awesome as they are), but here that's exactly what I
feel like doing.

I wish that this matter caught more attention. If all others decide to go
with kbk on this point, then obviously I'm going to have to live with it...

*) -required <bool> (with this option's default depending on namedness of
options).

Apart from that I principally dislike having formal arguments being
initially unset, I even more dislike, that for named arguments this
would even be the default behaviour unless "-required 1" is explicitly
spelled out.

I do understand the usecase of some "out-of-band" state for unspecified
optional arguments (e.g. lsort -command) and suggested an approach with
"-list" to address this not-quite-that-common usecase.

But even if unsetting optional arguments (that aren't passed a value) is so
much preferred, the requiredness behaviour should at least be same for all
types of parameters, and it should be named for what it means: something
along -defaultunset <bool>. It's about what happens to unspecified params,
not about actual requiredness, because for the latter the -default option
also plays a role.

Well, agree or disagree, that's my feedback, just as asked for. :-)

Kevin Kenny

unread,
Apr 24, 2017, 1:32:35 PM4/24/17
to a...@logic.at, Tcl Core Mailing List
On Mon, Apr 24, 2017 at 12:56 PM, Andreas Leitgeb <a...@logic.at> wrote:
*) separation of -upvar <varname> into -upvar <bool> and -varname <varname>

   This one was suggested by kbk. A few days later I asked him on tkchat about
      his motivation. In a nutshell, it was that Kevin didn't like the idea
      of the empty string meaning "I don't care for outer name" and that the
      empty string would not have been a usable <varname> to hold the outer
      variable's name, then.  Given that :: and () are already "characters non
      grata" for formal argument names and that therefore argument names are
      already not "any string"s, then the idea of using the empty string for
      the outer name doesn't seem all that precious to me to make upvar use
      so much more verbose.

   It may be inopportune to criticize kbk's ideas (with all his other contri-
      butions being as awesome as they are), but here that's exactly what I
      feel like doing.

I didn't worry that much about the verbosity, because it struck me that
actually wanting the name was the exceptional case. I surely
understand that we should not have information that cannot be
introspected, but had trouble seeing an actual use case for
-varname.

I'm by no means always right, and to the extent that my contributions
are 'awesome' (I'd consider simply 'workmanlike' to be high praise)
they got that way by the input of the whole community. 

I'm not wedded
to this, either way. Since we already forbid {} as the name of a procedure
argument (for reasons unknown), I suppose that it's acceptable to
forbid it for a -varname as well.
 
  *) -required <bool> (with this option's default depending on namedness of
   options).

   Apart from that I principally dislike having formal arguments being
   initially unset, I even more dislike, that for named arguments this
   would even be the default behaviour unless "-required 1" is explicitly
   spelled out.

   I do understand the usecase of some "out-of-band" state for unspecified
   optional arguments (e.g. lsort -command) and suggested an approach with
   "-list" to address this not-quite-that-common usecase.

   But even if unsetting optional arguments (that aren't passed a value) is so
   much preferred, the requiredness behaviour should at least be same for all
   types of parameters, and it should be named for what it means: something
   along -defaultunset <bool>. It's about what happens to unspecified params,
   not about actual requiredness, because for the latter the -default option
   also plays a role.

I appreciate that sentiment - uniformity is a Very Good Thing to
have in interfaces. Sometimes, to my way of thinking,
having sensible defaults trumps uniformity. Positional parameters
cannot be optional, except for some contiguous block of them,
without introducing ambiguity. By contrast, named parameters
are optional more often than not:. Look at the profusion of -flags
anywhere in Tk, or the growth of -options on [lsearch] or [regexp]
or anything with a programming interface that's at all complicated.
It strikes me as a bit odd that such options would be required
by default. It's not an uncommon use case at all. It's the usual
situation for most commands I've seen that accept named args.


Andreas Leitgeb

unread,
Apr 24, 2017, 1:38:38 PM4/24/17
to tcl-...@lists.sourceforge.net
Alexandre Ferrieux <alexandre...@gmail.com> wrote:
> On Mon, Apr 24, 2017 at 12:58 AM, Mathieu Lafon <mla...@gmail.com> wrote:
> > TIP #457 and its implementation have just been updated.
> Thanks for committing all the doc changes.
> With this, the nifty fossil-diff to trunk at
> http://core.tcl.tk/tcl/vdiff?from=0ca94b41a13ea375&to=e722c70aad11a12a&sbs=1
> gives a very good view of the volume of additions to code, tests, and docs.
>
> Which leads me to the following observation: this is a big piece
> (meaning some code maintenance work) with rich semantics and syntax
> (meaning a large extra doc section).
> In other words, this departs from the usual "Tcl is a simple language"
> rather drastically, by increasing the cognitive entry cost to proc.n.

Despite the two points in my previous mail that kind of spoil it for
me almost to the point of rather not having it at all, I don't think
that the complexity as such should be the blocker.

Also, I think that the new proc.n is well structured, leaving the simple
old syntax to the front (with just some "teasers" for the fancy stuff),
and the fancy new stuff in its own section.

Kevin Kenny

unread,
Apr 24, 2017, 1:46:33 PM4/24/17
to Alexandre Ferrieux, Tcl Core Mailing List
On Sun, Apr 23, 2017 at 8:03 PM, Alexandre Ferrieux <alexandre...@gmail.com> wrote:
On Mon, Apr 24, 2017 at 12:58 AM, Mathieu Lafon <mla...@gmail.com> wrote:
>
> TIP #457 and its implementation have just been updated.
> [...]
> As usual, feedback and comments are welcomed.

Thanks for committing all the doc changes.
With this, the nifty fossil-diff to trunk at

 http://core.tcl.tk/tcl/vdiff?from=0ca94b41a13ea375&to=e722c70aad11a12a&sbs=1

gives a very good view of the volume of additions to code, tests, and docs.

Which leads me to the following observation:  this is a big piece
(meaning some code maintenance work) with rich semantics and syntax
(meaning a large extra doc section).
In other words, this departs from the usual "Tcl is a simple language"
rather drastically, by increasing the cognitive entry cost to proc.n.
In addition, this move is done in support of a specific style that's
fashionable in other languages but not really a game-changer in Tcl.
Also, unless I've missed part of the discussion, it is not completely
neutral in terms of perf, as much work on the BC optimizer is still
due before named args can be morphed into positional at compile time.

For this reason, my current position is to vote NO regarding the TIP
itself (meaning core inclusion); but all this work should not be lost
and could very well live in an extension (with the only difference
that input arglist parsing should be explicitly requested by calling a
helper function).

If we bundle this with the core as an extension, it will either become
popular or it will not.

To the extent that it becomes popular, being able to deal with it will become
part of what is required to have a competent reading knowledge of Tcl.

To the extent that it does not become popular, it will have failed to supply
people with much-requested functionality, because it will become much
harder to support when packaging to run in strange places.

The simple, performant interface to [proc] will still be there, and we can
draft the manual page, if necessary, to discuss that first.

I don't think that the bytecoding is a showstopper. For an initial implementation,
as long as we have enough compile-time machinery to get all the variables
that represent positional parameters into the LVT (this doesn't look impossible;
I think I can sign up to do it if the TIP passes), we can get decent, if not
ideal, performance by adding a single bytecode instruction that unpacks
objc/objv into the local variables, taking some representation of the
argument specifications as aux data.

If we can get that far, we're up to "at least the new way is representable
in bytecode, and the old way is still performant." We can proceed at
greater leisure from there; I'm comfortable with having named parameters
be, for a while, only a little faster than interpreted code. To me, the
biggest benefit is that we will have introduced a uniform way to implement
them, rather than a large number of ad hoc hacks that programmers have
introduced over the last couple of decades. It's the number and
quirkiness of the implementations that tends to convince me that this
really needs to be, if not "Core" functionality, at the very least a bundled
extension that can be depended on to be universally available. Since
we have no mechanisms for bundled extensions to do their own BCC,
it really needs to be Core unless that problem is addressed as well.

If you can't bring yourself to support it, or stand aside, I'll just have to hope
that fewer than a third of our colleagues agree with you.

Andreas Leitgeb

unread,
Apr 24, 2017, 2:40:02 PM4/24/17
to Kevin Kenny, Tcl Core Mailing List
On Mon, Apr 24, 2017 at 01:32:06PM -0400, Kevin Kenny wrote:
> On Mon, Apr 24, 2017 at 12:56 PM, Andreas Leitgeb <a...@logic.at> wrote:
> > *) separation of -upvar <varname> into -upvar <bool> and -varname <varname>
> > [...] Given that :: and () are already "characters non grata" for
> > formal argument names and that therefore argument names are already
> > not "any string"s, then the idea of using the empty string for the
> > outer name doesn't seem all that precious to me to make upvar use
> > so much more verbose.

> I didn't worry that much about the verbosity, because it struck me that
> actually wanting the name was the exceptional case. I surely
> understand that we should not have information that cannot be
> introspected, but had trouble seeing an actual use case for
> -varname.

Suppose a procedure with some "incr"-like behaviour, then if the supplied
variable contained a non-numeric argument, then it would be useful if
the procedure could mention the outer name in its error-message.

So, I think any procedure that isn't entirely tolerant about what the
link points to (even if array or scalar) ought to know the outer name
and produce an error for the outer name, rather than for its local name.

> I'm not wedded
> to this, either way. Since we already forbid {} as the name of a procedure
> argument (for reasons unknown), I suppose that it's acceptable to
> forbid it for a -varname as well.

My intention here is to get rid of the -varname option altogether and
thereby simplify the TIP a bit -- unless there is any prospect of another
use for -varname apart from -upvar.

> > *) -required <bool> (with this option's default depending on namedness of
> > options).
> I appreciate that sentiment - uniformity is a Very Good Thing to
> have in interfaces. Sometimes, to my way of thinking, having sensible
> defaults trumps uniformity.

I do understand the power of sensible defaults over uniformity, but
I don't think, that this is such a case.

If one wants to add "yet another option" (and actually *use* it),
then at some point they'd have to write:
if {[info exists optvar]} { ... }

My point is, that having them just add a numeric default and value to
the arg-spec and then write:
if {$optvar} { ... }
is the Right'er Thing(tm).

And serendipitously it makes the whole thing easier to describe.


PS: in my own "procx" I've added (after a suggestion on the chat) a
-boolean {id identifier ...} argspec option, that will implicitly
set the default to 0 and the value for any of the given identifiers
(name-aliases) to 1. -- it complains at proc declaration time if
it is used together with an explicit -default and a value ne "0".

> Positional parameters
> cannot be optional, except for some contiguous block of them,
> without introducing ambiguity.

That's something that I believe to have disproven in my procx, too.

Peter da Silva

unread,
Apr 24, 2017, 2:53:52 PM4/24/17
to a...@logic.at, Kevin Kenny, Tcl Core Mailing List
On 4/24/17, 1:39 PM, "Andreas Leitgeb" <a...@logic.at> wrote:
> If one wants to add "yet another option" (and actually *use* it), then at some point they'd have to write:
> if {[info exists optvar]} { ... }

> My point is, that having them just add a numeric default and value to the arg-spec and then write:
> if {$optvar} { ... }
> is the Right'er Thing(tm).

Unless 0 is a valid value for optvar. Sometimes you have an optional value that has no special value you can use as a sentinel. Also known as the “how do you store arbitrary binary data in null-terminated strings” problem.

Alexandre Ferrieux

unread,
Apr 24, 2017, 4:53:54 PM4/24/17
to Kevin Kenny, Tcl Core Mailing List
You're convincingly outlining a way of driving an unwinking effort to
make it fast, assuming it (the feature itself, not the speed) is worth
it. I seriously am unsure about the latter.

> If you can't bring yourself to support it, or stand aside, I'll just have to
> hope that fewer than a third of our colleagues agree with you.

The key is "Tcl is a small language". Think about stuff like
Tcl-in-JS. Today's procs can reasonably be transliterated to JS
functions on the fly, due to the similarity of styles (positional +
dynamically typed). Named args make this harder. Moreover, the
extended argspec syntax completely departs from the usual "no-brainer"
left-to-right mapping. This means lowering readability (meaning the
speed at which human eyeballs scan and validate a proc signature).
Yeah you may tag me as too old for innovation, factor of inertia, etc.
But I'd rather see efforts aimed at letting Tcl live on in an
all-superfast-JS era than for the sake of a specific idiom supporting
a very specific workload (behemoth applications with ubiquitous option
processing that for some reason cannot be done with "proc f args
{helper $args;...}"). Last, the Two Thirds rule makes it perfectly
reasonable for the TIP to pass despite my concern if I'm wrong alone,
so I'm not really stabbing anything in the back. That's why I'm
respectfully suggesting that we agree to disagree.

Andreas Leitgeb

unread,
Apr 24, 2017, 5:20:17 PM4/24/17
to Peter da Silva, Tcl Core Mailing List
On Mon, Apr 24, 2017 at 06:53:29PM +0000, Peter da Silva wrote:
> On 4/24/17, 1:39 PM, "Andreas Leitgeb" <a...@logic.at> wrote:
>> If one wants to add "yet another option" (and actually *use* it),
>> then at some point they'd have to write:
>> if {[info exists optvar]} { ... }
>> My point is, that having them just add a numeric default and value to
>> the arg-spec and then write:
>> if {$optvar} { ... }
>> is the Right'er Thing(tm).
> Unless 0 is a valid value for optvar. Sometimes you have an optional
> value that has no special value you can use as a sentinel.

Yes, we all know the [lsort -command ...] example.
It's just not all that common.


PS: with my procx I could do it this way:
procx lsort {{cmd {} -l 1 -n command -fv {xx {extra 1} yy {extra 2}}} list} {
...
if {[llength $cmd]==1} {
# a -command has been given, namely: [lindex $cmd 0] because
# the -list 1 wraps the argument in a list, but not the default
# value or values associated to flags with -flagvals option.
} else { ... }
...
}
lsort -xx {foo bar}
lsort -yy {foo bar}
lsort {foo bar}
lsort -command {string compare} {foo bar}

Peter da Silva

unread,
Apr 24, 2017, 6:11:55 PM4/24/17
to a...@logic.at, Tcl Core Mailing List
On 4/24/17, 4:19 PM, "Andreas Leitgeb" <a...@logic.at> wrote:
> It's just not all that common.

It’s common enough that I’ve been occasionally annoyed by the lack of a way to distinguish unambiguously between a missing argument and an argument that matches the sentinel with the existing proc positional/default semantics.

And the “info exists” idiom is natural in Tcl. I use it all over the place, even (especially) in this case:

proc init {args} {
array set opts $args; # I know this is slack as anything but we don’t have TIP457 yet...

variable build_root

# ...

if {[info exists opts(-dir)]} {
set build_root $opts(-dir)
}

# ...

if {[info exists opts(-mode)]} {
catch {exec chmod $opts(-mode) $build_root}
}

# ... etc etc etc

Andreas Leitgeb

unread,
Apr 24, 2017, 7:20:29 PM4/24/17
to Peter da Silva, Tcl Core Mailing List
On Mon, Apr 24, 2017 at 10:11:30PM +0000, Peter da Silva wrote:
> On 4/24/17, 4:19 PM, "Andreas Leitgeb" <a...@logic.at> wrote:
> > It's just not all that common.
> It’s common enough that I’ve been occasionally annoyed by the
> lack of a way to distinguish unambiguously between a missing
> argument and an argument that matches the sentinel with the
> existing proc positional/default semantics.

I said: "not all that common", not: "doesn't exist".

The examples you gave (-dir, -mode) both look pretty much like as if the
empty string would be a fine default not getting in the way of useful values.
Even for lsort, an empty -command could have been singled out as a default
that would be equivalent to not specifying a -command option. I wouldn't call
foreach i {a b c d e f g} {
proc $i x {puts [info level 0]; string compare {*}[info level 0] }
}; lsort -command {} {g f e d c b a}
a worthy usecase for an empty command.

The only real undefaultable case presented so far in the whole discussion
is [set]'s second argument.

PS: if you shared two or three of your *really undefaultable* optional
params, that you come across occasionally, it might even make me shut up
about their marginality.

Peter da Silva

unread,
Apr 25, 2017, 7:52:09 AM4/25/17
to Tcl Core Mailing List
On 4/24/17, 6:19 PM, "Andreas Leitgeb" <a...@logic.at> wrote:
> The examples you gave (-dir, -mode) both look pretty much like as if the empty string would be a fine default not getting in the way of useful values.

You wrote:

>> My point is, that having them just add a numeric default and value to
>> the arg-spec and then write:
>> if {$optvar} { ... }
>> is the Right'er Thing(tm).

That _only_ works if you can use zero as a sentinel.

The examples I gave all require an explicit test against the sentinel, which is just as verbose as “[info exists...]”, and “[info exists...]” does a better job of self-documenting that you are explicitly testing whether the argument has been provided.

But OK, here’s a more straightforward class of keyword arguments where any value is legal and the presence or absence of the option makes a difference. Any filter-style option in a proc that performs a search or comparison against a value that may be empty. Not comparing against the value is not the same as looking for empty fields. For examples: -name, -school, -flight-id, -registration, -ident, -email, -city, -title, ...

This kind of thing is super common, and workarounds are clumsy.

Donald G Porter

unread,
Apr 25, 2017, 9:28:49 AM4/25/17
to tcl-...@lists.sourceforge.net
On 04/24/2017 01:46 PM, Kevin Kenny wrote:
> The simple, performant interface to [proc] will still be there, and we can
> draft the manual page, if necessary, to discuss that first.

Just on this point, you can take a look at how [return] documentation
was restructured when it grew several complicating options.

--
| Don Porter Applied and Computational Mathematics Division |
| donald...@nist.gov Information Technology Laboratory |
| http://math.nist.gov/~DPorter/ NIST |
|______________________________________________________________________|

Colin McCormack

unread,
Apr 25, 2017, 12:11:50 PM4/25/17
to Tcl Core List
Not sure what I am missing here, but I tend to use args as dicts to extract named arguments.  Obviously arrays would work as well.  One benefit is no pesky leading dashes.  I understand that this approach precludes singleton flags whose mere presence signifies something.  My response would be "then don't do that."  It's not like my opinion counts especially, but as a long-time tcl programmer, I haven't felt the need for named arguments beyond what can be rolled out of what's already there, and speaking personally I would be loathe to see simple command invocation slowed even an iota for a facility which (although reportedly clamoured for, although in who knows what closed rooms) seems to me to have little actual benefit.

Donal K. Fellows

unread,
Apr 25, 2017, 2:47:23 PM4/25/17
to tcl-...@lists.sourceforge.net
On 25/04/2017 17:11, Colin McCormack wrote:
> reportedly clamoured for, although in who knows what closed rooms

The conference room in the hotel in Houston was closed, IIRC, but just
to prevent draughts. :-)

I'm definitely in several minds about this whole area. I really don't
want to see command invocation slowed down, as it is one of the real hot
spots in many people's Tcl code; I'm mindful of the people who are not
complaining. I'm also concerned about the longer-term pickle that you
can get yourself into with named arguments (I've seen a lot of really
messy Python over the past 6 months or so). On the other hand, it'd also
be nice to make it easier for people to do these styles of call, since
we would provide one mechanism that does its task rapidly. Though that
really does need to be opt-in; programmers who wish to take advantage
really need to modify their code to do so, as we don't have the luxury
of being able to say “we break your code for our convenience” very often.

However, the TIP as it stands is much better than its initial version.
(Only the “-switch”-related options seem odd to me. Not bad, just odd.)
I particularly like that this is functionality that people will need to
“buy into” so it won't surprise anyone's existing codebase. The only
confusing thing is the interaction with the “args” magic; the conditions
under which “--” is supported should be more explicitly described. Also,
I assume that it is the intention that lambda terms and TclOO methods
(plus perhaps also methods in other object systems) will support the
same sorts of argument handling? It'd be worth also calling that out.

Donal.
donal_k_fellows.vcf

Mathieu Lafon

unread,
Apr 25, 2017, 3:31:16 PM4/25/17
to Donal K. Fellows, Tcl Core Mailing List
Hello,

On Tue, Apr 25, 2017 at 8:46 PM, Donal K. Fellows
<donal.k...@manchester.ac.uk> wrote:
> I'm definitely in several minds about this whole area. I really don't want
> to see command invocation slowed down, as it is one of the real hot spots in
> many people's Tcl code;

Perhaps the performance section in the TIP has confused readers but
there is really *no* performance issue :

- existing code (and code not using extended argspec) is not impacted
by the change, the current initialisation code is still available and
used ;
- code using extended argspec *may* be impacted because we're using a
different code path which loop on each argument and may handle named
arguments but initial testing does not show a significant slowdown.

On Tue, Apr 25, 2017 at 6:11 PM, Colin McCormack <mcc...@gmail.com> wrote:
> Not sure what I am missing here, but I tend to use args as dicts to extract
> named arguments. [...], and speaking personally I would be loathe to see simple
> command invocation slowed even an iota for a facility which (although reportedly
> clamoured for, although in who knows what closed rooms) seems to me to have
> little actual benefit.

On the other side, performance testing has showed that named argument using
tip-457 is 8 time faster than doing it in Tcl-pure code (using a dict
built from 'args').

On Tue, Apr 25, 2017 at 8:46 PM, Donal K. Fellows
<donal.k...@manchester.ac.uk> wrote:
> [...]. Also, I assume that
> it is the intention that lambda terms and TclOO methods (plus perhaps also
> methods in other object systems) will support the same sorts of argument
> handling? It'd be worth also calling that out.

Yes, lambda and TclOO methods/constructor are handled. There are related
subcommands for 'info argspec' (mentionned in TIP) and dedicated tests in
tip-457 branch. I will made it more clear in TIP if that's your point.

-- Mathieu

Mathieu Lafon

unread,
Apr 25, 2017, 3:45:07 PM4/25/17
to Andreas Leitgeb, Tcl Core Mailing List
On Mon, Apr 24, 2017 at 6:56 PM, Andreas Leitgeb <a...@logic.at> wrote:

> Two points I'm rather unhappy about in version 1.19 of the TIP:
>
> *) separation of -upvar <varname> into -upvar <bool> and -varname <varname>
> [...]
> *) -required <bool> (with this option's default depending on namedness of
> options).
> [...]

Thanks for your feedback. I understand your points Andreas but
whatever choice is chosen, someone will be unhappy with it. Of course,
this can still change if there is a large consensus on a different
solution.

In the current solution, I don't see why using '-upvar 1 -varname var'
instead of '-upvar var' and '-name foo -required 1' instead of '-name
foo' is a major problem.

-- Mathieu

Andreas Leitgeb

unread,
Apr 26, 2017, 10:01:15 AM4/26/17
to Mathieu Lafon, Tcl Core Mailing List
On Tue, Apr 25, 2017 at 09:44:20PM +0200, Mathieu Lafon wrote:
> On Mon, Apr 24, 2017 at 6:56 PM, Andreas Leitgeb <a...@logic.at> wrote:
> > Two points I'm rather unhappy about in version 1.19 of the TIP:
> > *) separation of -upvar <varname> into -upvar <bool> and -varname <varname>
> > [...]
> > *) -required <bool> (with this option's default depending on namedness of
> > options).
> > [...]
> Thanks for your feedback. I understand your points Andreas but
> whatever choice is chosen, someone will be unhappy with it.
> In the current solution, I don't see why using '-upvar 1 -varname var'
> instead of '-upvar var' ... [is a major problem]

The principle here is to make the Right Thing(tm) the easier (or at
least almost equally easy) option.

The Right Thing(tm) here would be procedures that complain about the
outer name of a variable that they're not happy with, rather than about
the internal name.

The likeliness, that someone will capture the outer name with -upvar vname
option (instead of using -upvar {}) and then use it in an error message is
just ways higher, than if they need to type out -upvar 1 -varname vname.

> [and why] '-name foo -required 1' instead of '-name foo' is a major problem.

Meanwhile Peter has provided one usecase (namely specifying filters) for
undefaultable options.

I also have to agree with Kevin, that for named arguments, not needing to
specify them on call site is indeed the much more common case, so breaking
the uniformity is indeed justified.

I still dislike unset formal params, but I have to admit it seems to be
the most general thing to do, where no explicit -default is provided.
In particular, it avoids an arbitrary choice of a "default default".


Nutshell: case -upvar still pending, case -required dropped. :-}

Peter da Silva

unread,
Apr 26, 2017, 10:09:53 AM4/26/17
to a...@logic.at, Mathieu Lafon, Tcl Core Mailing List
On 4/26/17, 9:00 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
> Nutshell: case -upvar still pending, case -required dropped. :-}

Originally I was inclined to support the simpler upvar syntax, but after sleeping on it... it does seem a bit potentially confusing. Will someone reading “{foo -upvar bar}” automatically assume that means “the upper variable name is in bar and the value is in foo” or “the upper variable name is in foo...” (since every other variable the named variable contains exactly what was on the command line) “... and the value is in bar” (since that’s after the upvar). {foo -upvar 1 -varname bar} is unambiguous.

Peter da Silva

unread,
Apr 26, 2017, 10:41:41 AM4/26/17
to Brian Griffin, Tcl Core Mailing List, a...@logic.at
On April 26, 2017 at 9:31 AM, Brian Griffin <bria...@easystreet.net> wrote:
> It seems to me the real mistake here is having 2 arbitrary names involved with an upvar argument.  It would be more straight forward to have an accessor mechanisms applied to a single name.  Something where the argument spec  {foo -upvar}  defines $foo for accessing the upper variable's value and ${&foo} accessing the name of the upper variable.  (or using command style: [nameof foo], for example)

Perhaps ${-foo}? To avoid inventing additional metacharacters?

I sort of like it but on the other hand it also seems a bit precious. Hmmm...

Donal K. Fellows

unread,
Apr 26, 2017, 11:05:17 AM4/26/17
to tcl-...@lists.sourceforge.net
On 26/04/2017 15:41, Peter da Silva wrote:
> Perhaps ${-foo}? To avoid inventing additional metacharacters?
>
> I sort of like it but on the other hand it also seems a bit precious.

I quite like something like that. It makes the actual value available,
but only in an awkward way, yet that'll do as most of the time people
don't need the upvar'd variable and its name in the same procedure. So
we handle the 95% case easily and make the 5% case possible; that'll do.

Donal.
donal_k_fellows.vcf

Andreas Leitgeb

unread,
Apr 26, 2017, 11:30:27 AM4/26/17
to Peter da Silva, Tcl Core Mailing List
On Wed, Apr 26, 2017 at 02:09:23PM +0000, Peter da Silva wrote:
> On 4/26/17, 9:00 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
> > case -upvar still pending

> Originally I was inclined to support the simpler upvar syntax, but
> after sleeping on it... it does seem a bit potentially confusing.

The hazards of sleeping ;)

> Will someone reading “{foo -upvar bar}” automatically assume that
> means “the upper variable name is in bar and the value is in foo”
> or “the upper variable name is in foo...” (since every other
> variable the named variable contains exactly what was on the
> command line) “... and the value is in bar” (since that’s after
> the upvar).

I agree, that the option name "-upvar" doesn't really make this clear,...

> {foo -upvar 1 -varname bar} is unambiguous.

... but I think that the extra option fails to make it any clearer.


Maybe, the even more natural thing would be: {varname -upvarto var} afterall.
And yes, it would indeed force the user to define two varnames (or just add
a & or * to the formal arg name). That would also avoid the {} special case ;)


A separate -varname option only makes sense if it would capture the exact
part of the call-time arguments that affected this argument. But then its
assigned value would need to be always a list, to allow for option and value
or flag or empty(if defaulted). Iirc, that was one issue raised a while ago:
passing on all the options from a wrapper to the original command.


Brian's approach (allowing to query the link target lateron without extra
verbosity in the argspec -- not the ${&/-\$} incompatible line noise) also
looks fine to me.

Peter da Silva

unread,
Apr 26, 2017, 11:38:08 AM4/26/17
to a...@logic.at, Tcl Core Mailing List


On 4/26/17, 10:29 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
> A separate -varname option only makes sense if it would capture the exact part of the call-time arguments that affected this argument. But then its assigned value would need to be always a list, to allow for option and value or flag or empty(if defaulted). Iirc, that was one issue raised a while ago: passing on all the options from a wrapper to the original command.

I’m not sure I understand that. The varname contains the outer variable name for error reporting and similar stuff. It may not (usually won’t, I suspect) even be a parameter to the outer proc, and thus won’t have any of that metadata associated with it.

proc fiddle {{foo -upvar 1 -varname -foo}} {
if {![string length $foo]} {
error “Expected non-empty foo in ${-foo}”
}
}

> Brian's approach (allowing to query the link target lateron without extra verbosity in the argspec -- not the ${&/-\$} incompatible line noise) also looks fine to me.

What incompatible line noise? Variable names can contain arbitrary metacharacters already.

% set -foo babble
babble
% echo ${-foo}
babble

Andreas Leitgeb

unread,
Apr 26, 2017, 12:26:28 PM4/26/17
to Peter da Silva, Tcl Core Mailing List
On Wed, Apr 26, 2017 at 03:37:47PM +0000, Peter da Silva wrote:
> On 4/26/17, 10:29 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
>> A separate -varname option only makes sense if it would capture the
>> exact part of the call-time arguments that affected this argument.

> I’m not sure I understand that. The varname contains the outer variable


> name for error reporting and similar stuff.

Slightly different thing. In that suggestion, the variable named to "-varname"
would not be specific to those argspecs with -upvar.
e.g.:
proc foo {
{arg1 -upvar 1 -varname arg1v}
{arg2 -name x -switch y -varname arg2v}
{arg3 -default "def" -varname arg3v}
} { list $arg1 $arg1v -- $arg2 $arg2v -- $arg3 $arg3v }

arg1 requires an argument, so $argv1 will always be [list <outername>]
$arg2v might be equal to {} or "-y" or [list -x $arg2], depending on
how it was called.
$arg3v is either empty (if defaulted) or a singleton list of $arg3

[concat $arg1v $arg2v $arg3v] would be pretty close to
[lrange [info level 0] 1 end] except that duplicate call options
and "--" would be weeded out. foo -x v1 -y -x bar ---> $arg3v eq "-x bar"

If this proc foo was to be wrapped by a proc bar with same arg-spec,
then proc bar could safely tailcall foo {*}$arg1v {*}$arg2v -- {*}$arg3v
from its body. Not saying this is comfortable. But the ability to do it
was once asked for, quite a while ago.

> proc fiddle {{foo -upvar 1 -varname -foo}} {
> if {![string length $foo]} {
> error “Expected non-empty foo in ${-foo}”
> }
> }

The extra list level might even be beneficial here, for vars where
it is even visible.

> > Brian's approach (allowing to query the link target lateron without extra verbosity in the argspec -- not the ${&/-\$} incompatible line noise) also looks fine to me.
> What incompatible line noise? Variable names can contain arbitrary metacharacters already.

That's exactly why it's incompatible.

How I understood the ${&foo} thing, it was suggested such, that in your
proc fiddle you'd omit the -varname -foo from the argspec, but still
have ${&foo} contain (magically) the outer name for foo. This I don't
like. Instead something like [info linktarget foo] would be fine, but
that needs a way to also deal with other linked vars - probably out of
scope for this TIP.

Peter da Silva

unread,
Apr 26, 2017, 12:31:41 PM4/26/17
to a...@logic.at, Tcl Core Mailing List
On 4/26/17, 11:26 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
> Slightly different thing. In that suggestion, the variable named to "-varname" would not be specific to those argspecs with -upvar.

I don’t see the value of that.

>>> Brian's approach (allowing to query the link target lateron without extra verbosity in the argspec -- not the ${&/-\$} incompatible line noise) also looks fine to me.
>> What incompatible line noise? Variable names can contain arbitrary metacharacters already.
>That's exactly why it's incompatible.

But it’s not. It can’t possibly conflict with any existing variables with the same name, because there is no way that variables with that name can exist in scope, because the name {-foo} would only be inserted into scope in new code that is using the new argument syntax. There’s no magic, just an implicitly created actual variable.

Brian Griffin

unread,
Apr 26, 2017, 1:04:47 PM4/26/17
to Peter da Silva, Tcl Core Mailing List, a...@logic.at
On Apr 26, 2017, at 7:09 AM, Peter da Silva <peter....@flightaware.com> wrote:

On 4/26/17, 9:00 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
Nutshell: case -upvar still pending, case -required dropped. :-}

Originally I was inclined to support the simpler upvar syntax, but after sleeping on it... it does seem a bit potentially confusing. Will someone reading “{foo -upvar bar}” automatically assume that means “the upper variable name is in bar and the value is in foo” or “the upper variable name is in foo...” (since every other variable the named variable contains exactly what was on the command line) “... and the value is in bar” (since that’s after the upvar). {foo -upvar 1 -varname bar} is unambiguous.

It seems to me the real mistake here is having 2 arbitrary names involved with an upvar argument.  It would be more straight forward to have an accessor mechanisms applied to a single name.  Something where the argument spec  {foo -upvar}  defines $foo for accessing the upper variable's value and ${&foo} accessing the name of the upper variable.  (or using command style: [nameof foo], for example)

-Brian


Donald Arseneau

unread,
Apr 26, 2017, 7:46:19 PM4/26/17
to tcl-...@lists.sourceforge.net
Peter da Silva <peter....@flightaware.com> wrote:
> {foo -upvar 1 -varname bar} is unambiguous.

If that "1" is a boolean, I find it kinda clunky, but if it
is a level, then it can add a lot! Could it be used like
{foo -upvar #0 -varname bar}?

(Just a silly example in lieu of global.)


Donald Arseneau, TRIUMF CMMS, as...@triumf.ca

Peter da Silva

unread,
Apr 27, 2017, 8:27:04 AM4/27/17
to Donald Arseneau, tcl-...@lists.sourceforge.net
On 4/26/17, 6:15 PM, "Donald Arseneau" <as...@triumf.ca> wrote:
> Peter da Silva <peter....@flightaware.com> wrote:
>> {foo -upvar 1 -varname bar} is unambiguous.
>
> If that "1" is a boolean, I find it kinda clunky, but if it is a level, then it can add a lot! Could it be used like {foo -upvar #0 -varname bar}?

I am pretty sure it was a boolean, for key/value syntax reasons, but making it a level is a big improvement.

Andreas Leitgeb

unread,
Apr 27, 2017, 12:40:24 PM4/27/17
to tcl-...@lists.sourceforge.net
"Donald Arseneau" <as...@triumf.ca> wrote:
> > {foo -upvar 1 -varname bar} is unambiguous.
> If that "1" is a boolean, I find it kinda clunky, but if it
> is a level, then it can add a lot! Could it be used like
> {foo -upvar #0 -varname bar}?

A case could be made about #0, as in vwait and some tk-widgets' -variable
or -textvariable option the argument refers to the name of a global
variable (which can still be namespaced, if specified by caller).

I had a use where I used upvar with a variable level that depended
on recursion depth of a custom loop structure, but I'm sure that any
other value than 1 or #0 makes no sense at all in the arg-spec.

How often would you specify a procedure to which a caller would need
to pass a variable's name of its own caller's scope? (and that's only
at level 2)

If the arg to upvar were destined to be a boolean (as it is in current
state of TIP), then I'd agree that 1 or #0 would be a more useful choice,
but unless there is a command (or auto-named variable) to retrieve the
outer var name lateron, I'd strongly urge to make it the laziest choice
for the programmer to specify a variable for the outer name, e.g. like:
proc x {{yn -upvarto y}} { list name $yn val $y }.

Peter da Silva

unread,
Apr 27, 2017, 1:13:29 PM4/27/17
to a...@logic.at, tcl-...@lists.sourceforge.net
On 4/27/17, 11:39 AM, "Andreas Leitgeb" <a...@logic.at> wrote:
> How often would you specify a procedure to which a caller would need to pass a variable's name of its own caller's scope? (and that's only at level 2)

To avoid chaining upvars when passing a name to an internal helper function used by a published API that takes a variable name.

proc foo {name val} {
...
foosetter $name [something something $val]
...
}

proc foosetter {{name -upvar 2} val} {
set $name [something else $val]

Peter da Silva

unread,
Apr 27, 2017, 1:18:30 PM4/27/17
to a...@logic.at, tcl-...@lists.sourceforge.net
That should of course be “set name [something else $val]”.

Mathieu Lafon

unread,
Apr 27, 2017, 1:49:36 PM4/27/17
to tcl-...@lists.sourceforge.net, Donald Arseneau
On Wed, Apr 26, 2017 at 4:31 PM, Brian Griffin <bria...@easystreet.net> wrote:
> It seems to me the real mistake here is having 2 arbitrary names involved
> with an upvar argument. It would be more straight forward to have an
> accessor mechanisms applied to a single name. Something where the argument
> spec {foo -upvar} defines $foo for accessing the upper variable's value
> and ${&foo} accessing the name of the upper variable. (or using command
> style: [nameof foo], for example)

I'm 100% in favor of removing -varname and adding a method to get the
variable name. I prefer the addition of an introspection command which
will simplify the tip-457 code (part of complexity is related to the
variables added by -varname) and will be usable for other link
variables (those created with [upvar] for example).

The variable name is not directly accessible but should be easy to get
by searching in upper call frames.

On Thu, Apr 27, 2017 at 2:26 PM, Peter da Silva
<peter....@flightaware.com> wrote:
> On 4/26/17, 6:15 PM, "Donald Arseneau" <as...@triumf.ca> wrote:
>> Peter da Silva <peter....@flightaware.com> wrote:
>>> {foo -upvar 1 -varname bar} is unambiguous.
>>
>> If that "1" is a boolean, I find it kinda clunky, but if it is a level, then it can add a lot! Could it be used like {foo -upvar #0 -varname bar}?
>
> I am pretty sure it was a boolean, for key/value syntax reasons, but making it a level is a big improvement.

That's a simple modification to do, will add that later.

-- Mathieu

Peter da Silva

unread,
Apr 27, 2017, 1:55:41 PM4/27/17
to Mathieu Lafon, tcl-...@lists.sourceforge.net, Donald Arseneau
On 4/27/17, 12:48 PM, "Mathieu Lafon" <mla...@gmail.com> wrote:
> I'm 100% in favor of removing -varname and adding a method to get the variable name. I prefer the addition of an introspection command which will simplify the tip-457 code (part of complexity is related to the variables added by -varname) and will be usable for other link variables (those created with [upvar] for example).
>
> The variable name is not directly accessible but should be easy to get by searching in upper call frames.

That’s a pretty compelling reason to do it and abandon all the discussion about the alternate syntaxes.

Dipl. Ing. Sergey G. Brester

unread,
Apr 27, 2017, 2:35:40 PM4/27/17
to Mathieu Lafon, Donald Arseneau, tcl-...@lists.sourceforge.net
> The variable name is not directly accessible but should be easy to get by searching in upper call frames.

I miss some point here? 
The variable name is suplied to the proc directly as argument, so here it an example on instruction level:
```
(0) push1 0         # "upvar"
(2) push1 1         # "lev"
(4) loadStk
(5) push1 2         # "x"
(7) loadStk
(8) push1 2         # "x"
(10) invokeStk1 4
```
That would be equivalent to {upvar $lev $x x} in first compiled body of `proc some { {x -upvar 1} ...}`.


Actually I guess, that implementing of the new INST for upvar would be more favored.
Something like:
```
push1 0         # "lev"
push1 1        # "x"
upvarStk 2
```
Or if var and value should be differently (e. g. via option `-variable`):
```
push1 0         # "lev"
push1 1        # "x"
push1 2        # "y"
upvarStk 3
```

But I don't see it as beneficial, because if someone need it, then he can just use `upvar $x y` instead.
 

Regards,
sebres

Kevin Kenny

unread,
Apr 27, 2017, 6:03:18 PM4/27/17
to Dipl. Ing. Sergey G. Brester, Donald Arseneau, Tcl Core Mailing List
[uplevel #1] is also useful when there are coroutines about. It's a place where coroutine-local variables can be created. 

Donald Arseneau

unread,
Apr 27, 2017, 8:37:33 PM4/27/17
to tcl-...@lists.sourceforge.net
Mathieu Lafon <mla...@gmail.com>

> I'm 100% in favor of removing -varname and adding a method to get the
> variable name. I prefer the addition of an introspection command which
> will simplify the tip-457 code (part of complexity is related to the
> variables added by -varname) and will be usable for other link
> variables (those created with [upvar] for example).

I agree, just not 100%. Since this is basically a cleaner path
to upvar, it would be good to simplify the proc TIP (even if the
-upvar <boolean> gets changed to -upvar <level>) and let people
use upvar for any cases beyond the most basic, thus making it
clearer in the code that something a bit beyond the basic is
happening. A new introspection command ([info linkedvar foo] ??)
would nicely handle most of the cases that are otherwise beyond
basic.

I'm fine with automatically creating two variables though (like
foo and &foo); starting to question my proposed -upvar <level>,
worrying that it introduces too much tangle; still think -upvar
<bool> is confusing, but it could be improved with minor tweaks
like -byname <bool> (default 0) or, better, flags without arguments
-byvalue & -byname (default -byvalue).


Donald Arseneau, TRIUMF CMMS, as...@triumf.ca


Peter da Silva

unread,
Apr 28, 2017, 9:25:42 AM4/28/17
to Donald Arseneau, tcl-...@lists.sourceforge.net
On 4/27/17, 7:37 PM, "Donald Arseneau" <as...@triumf.ca> wrote:
> I'm fine with automatically creating two variables though (like foo and &foo); starting to question my proposed -upvar <level>, worrying that it introduces too much tangle; still think -upvar <bool> is confusing, but it could be improved with minor tweaks like -byname <bool> (default 0) or, better, flags without arguments -byvalue & -byname (default -byvalue).

All the flags have arguments to guarantee that any new-style definition will have a list length of three in its extended arguments, so they won’t conflict with the {varname defaultvalue} syntax of the classic proc API.

Donal K. Fellows

unread,
Apr 28, 2017, 10:54:46 AM4/28/17
to tcl-...@lists.sourceforge.net
On 24/04/2017 13:40, Peter da Silva wrote:
> We consider this a major game changer in Tcl. Positional parameters make maintenance of large Tcl applications dangerously complex, but the verbosity of handcrafting named parameters and the significant overhead for using named parameters in small Tcl functions strongly discourages this idiom.
>
> In addition, I would argue that named parameters and flags are a common and popular style in Tcl itself, but only in built-in commands and in extensions, where they are implemented in C. This change brings Tcl procs into parity with the core of the language.

Looking at this (which would be a headline feature if accepted) a little
more broadly, I'm wondering about what the maximal set of features that
the named parameter configuration system would support would be. It's
pretty obvious that we can conceive of more than are currently listed,
but does that mean we should have lots more TIPs to allow each new
extension idea to be bolted on? Perhaps instead there ought to be a
minimum set and the other options will instead get converted into some
kind of call of potentially-user-defined Tcl commands to enable them to
do the extra behaviours. (Tcl commands because how else would you do
something complex in Tcl?)

This is speculation spurred by discussions on the Tcler's Chat last
night, and might be just too complex. :-) But it's worth getting this
discussion out where everyone can see it.

If this was a route we might consider, it would also give us a way to
get on with doing named parameters: we can just have this TIP do the
absolute most basic thing that could possibly work (i.e., handling named
parameter parsing itself, with no interpretation of the values received)
which we could then move forward on relatively easily, while doing
another TIP to add that general extension mechanism (which would also be
the thing to add automatic upvar, type assumptions, docs, etc.) That
would be good as it would mean that we wouldn't have to block the basic
TIP while we think of every possible good idea ever. ;-)

So… can we do less now with an eye to doing more, more flexibly, in the
future?

> The original rough design implied by the FlightAware bounty was much simpler, but it was argued that it wasn’t sufficiently Tcl-ish. Would you consider something closer to the original more acceptable?

The most Tclish thing I can think of is to do as little as possible
while making provision for mixing in cool ideas in as many ways as
possible through running code in smart ways.

Donal.
donal_k_fellows.vcf

Peter da Silva

unread,
Apr 28, 2017, 11:01:14 AM4/28/17
to Donal K. Fellows, tcl-...@lists.sourceforge.net
On 4/28/17, 9:54 AM, "Donal K. Fellows" <donal.k...@manchester.ac.uk> wrote:
> Looking at this (which would be a headline feature if accepted) a little more broadly, I'm wondering about what the maximal set of features that the named parameter configuration system would support would be. It's pretty obvious that we can conceive of more than are currently listed, but does that mean we should have lots more TIPs to allow each new extension idea to be bolted on?

Possibly, but that was one of the things we were trying to accomplish. The extended parameter syntax we’re using here is open-ended so additional features from other systems could be considered for addition in the future without a lot of additional effort and without breaking compatibility.

Certainly the -upvar part could be split out into its own tip, but once you’ve done that the result is very close to the minimal extension already. What other aspects do you think are really optional?

Mathieu Lafon

unread,
May 5, 2017, 7:44:09 PM5/5/17
to Donal K. Fellows, Tcl Core Mailing List
I have removed the -varname specifier and created an introspection
command (currently named [info linkedname]) which can be used to
retrieve the name of the variable linked to. A new TIP has been
proposed for this command to simplify TIP#457, implementation is in
the info-linkedname branch.

I have also changed the -upvar argument from a boolean to a level
value (same forms than the [upvar] command).

TIP and implementation have been updated.

On Fri, Apr 28, 2017 at 4:54 PM, Donal K. Fellows
<donal.k...@manchester.ac.uk> wrote:
> If this was a route we might consider, it would also give us a way to get on
> with doing named parameters: we can just have this TIP do the absolute most
> basic thing that could possibly work (i.e., handling named parameter parsing
> itself, with no interpretation of the values received) which we could then
> move forward on relatively easily, while doing another TIP to add that
> general extension mechanism (which would also be the thing to add automatic
> upvar, type assumptions, docs, etc.)

The remaining specifiers (-default, -name, -switch, -required, -upvar)
are core specifiers of this proposal and have already been discussed
so I would prefer keeping them together.

-- Mathieu

Mathieu Lafon

unread,
May 18, 2017, 5:26:57 PM5/18/17
to Tcl Core Mailing List
Hello,

I personally consider TIP#457 to be in its final form and ready for a
vote, so if a TCT member agree with me, I would favor a CFV.

Regards.

-- Mathieu

On Sat, May 6, 2017 at 1:43 AM, Mathieu Lafon <mla...@gmail.com> wrote:
> I have removed the -varname specifier and created an introspection
> command (currently named [info linkedname]) which can be used to
> retrieve the name of the variable linked to. A new TIP has been
> proposed for this command to simplify TIP#457, implementation is in
> the info-linkedname branch.
>
> I have also changed the -upvar argument from a boolean to a level
> value (same forms than the [upvar] command).
>
> TIP and implementation have been updated.

Christian Gollwitzer

unread,
May 19, 2017, 2:56:55 AM5/19/17
to tcl-...@lists.sourceforge.net
Am 18.05.17 um 23:26 schrieb Mathieu Lafon:
> I personally consider TIP#457 to be in its final form and ready for a
> vote, so if a TCT member agree with me, I would favor a CFV.

First of all, thanks for the big work that you have undertaken,
especially in destilling the compromise out of all the opinions
prevalent here.

I am still concerned about the actual assignment of actual arguments to
formal parameters. Especially this last paragraph:
"The handling of a group of contiguous named arguments (which can be
only one argument) is ended on the first argument which is either a
multi-elements list, a parameter not starting with a dash or the special
-- end-of-options marker. Remaining arguments will then be assigned to
following positional arguments."

It implies, that the assignment is based on the *content* of the actual
parameter - if it starts with a dash - which is IMHO a big mistake.
Andreas Leitgeb and Kevin Kenny have expressed reasonable ways to handle
the assignment in many cases without inspecting the content. I strongly
recommend to adapt this to one of their proposals in order to avoid
data-driven bugs. I don't have it ready now, but it was along the lines:

"The positional args are assigned first from the start, then from the
end, the remaining to the named and the rest to args" or similar. I
think it was Kevin Kenny who formulated it in a very reasonable way in
the chatroom.


Otherwise, I am quite pleased wit hthe compromise that came out of the
discussion.

Best regards,

Christian

Mathieu Lafon

unread,
May 19, 2017, 5:07:59 AM5/19/17
to Christian Gollwitzer, Tcl Core Mailing List
On Fri, May 19, 2017 at 8:56 AM, Christian Gollwitzer <auri...@gmx.de> wrote:
> I am still concerned about the actual assignment of actual arguments to
> formal parameters. [...]
>
> It implies, that the assignment is based on the *content* of the actual
> parameter - if it starts with a dash - which is IMHO a big mistake.

Following latest discussions, the parameter is only "stringified" if
it is not a multi-elements object. This was added to avoid unnecessary
conversion of big array objects.

Why do you think it is a big mistake? Do you see any possible issues?

> "The positional args are assigned first from the start, then from the
> end, the remaining to the named and the rest to args" or similar. I
> think it was Kevin Kenny who formulated it in a very reasonable way in
> the chatroom.

I don't understand how the 'args' case is handled as we don't know how
many arguments should go there.

I personally think thas assigning arguments from the end is
counter-intuitive and error-prone. On the user side, it is not easy to
spot where the name arguments stop.

Unless there is a majority of feedback which support that request, I
prefer to leave it as-is.

> Otherwise, I am quite pleased wit hthe compromise that came out of the
> discussion.

Thanks for your support.

Regards.

-- Mathieu

Andreas Leitgeb

unread,
May 19, 2017, 6:16:32 AM5/19/17
to tcl-...@lists.sourceforge.net
Christian Gollwitzer <auri...@gmx.de> wrote:
> I am still concerned about the actual assignment of actual arguments to
> formal parameters. Especially this last paragraph:
> "The handling of a group of contiguous named arguments (which can be
> only one argument) is ended on the first argument which is either a
> multi-elements list, a parameter not starting with a dash or the special
> -- end-of-options marker. Remaining arguments will then be assigned to
> following positional arguments."
> It implies, that the assignment is based on the *content* of the actual
> parameter

It's *not* like content of an argument was *forbidden* to make a change in
interpretation of an argument. It is merely *necessary*, for the caller to
be *able* to arrange "context" such that particular arguments can be "any"
value barring "special" interpretation - see [if ... then else], (and
anti-see [exec ... "<..."]).

with these options: if you know that the next argument after the options is
definitely not an option, then you can save the boilerplate of "--"
Otoh., if the next argument after options is not known ahead of time, then
use the "--" and it's once again unambiguous.

> Andreas Leitgeb and Kevin Kenny have expressed reasonable ways to handle
> the assignment in many cases without inspecting the content.

My procx differs in a small way, but not in the way you indicated.
My procx is actually even further away from your expectation, in
that an unknown option starting with dash is used as next positional
arg, (rather than raise an error (unknown option), as mlafon's more
correctly does).

> "The positional args are assigned first from the start, then from the
> end, the remaining to the named and the rest to args" or similar. I
> think it was Kevin Kenny who formulated it in a very reasonable way in
> the chatroom.

The spec in TIP 457 feels ways more natural to me, than any "start from
first ones, then do the last ones and finally do the middle ones..."

Even my procx doesn't work like that. It merely "reserves" arguments
for yet-to-assign positional parameters, but strictly assigns from
first to last in order.


And one more:

Harald Oehlmann <harald....@elmicron.de>
> I personally don't see the use-case of the command expect to find out if
> a variable is a link in general.
> The returned name has no practical use, as the upvar level is not
> returned. It is not known, if the target variable is in the stack of a
> caller or a global variable. And other introspection commands may not be
> executed, as this requires the level information.

This other TIP about link(ed?)name seems to have some discussion yet to
do.

Your diagnose is correct: The original (i.e. real) variable's name as
returned by the proposed info-subcommand is pretty useless without at
least it's level. If more cannot be obtained, the command could just
as well return a boolean (to not even need a catch). Inside a proc-body
this result could also be deduced from [info locals] versus [info vars].

But even if the level gets added, then it still is *no substitute* for
the "-varname" option in the named-arguments TIP. It just doesn't
cover that particular usecase *at all*!

If a command that retrieves the immediately upvar'ed name is not
possible, then we need to step back to either add "-varname" back to
TIP 457, or define some auto-named local varname like "&<param>"
for the respective "-upvar"-tagged <param>.

Mathieu Lafon

unread,
May 19, 2017, 7:33:53 AM5/19/17
to Andreas Leitgeb, Tcl Core Mailing List
On Fri, May 19, 2017 at 12:16 PM, Andreas Leitgeb <a...@logic.at> wrote:
> If a command that retrieves the immediately upvar'ed name is not
> possible, then we need to step back to either add "-varname" back to
> TIP 457, or define some auto-named local varname like "&<param>"
> for the respective "-upvar"-tagged <param>.

The dedicated introspection command (now) seems the most logical
option to me. And tip-457 implementation is way simpler without
-varname.

I will do some testing to keep intermediate link variables.

Regards.

-- Mathieu

Peter da Silva

unread,
May 19, 2017, 8:27:51 AM5/19/17
to Christian Gollwitzer, tcl-...@lists.sourceforge.net
On 5/19/17, 1:56 AM, "Christian Gollwitzer" <auri...@gmx.de> wrote:
> "The handling of a group of contiguous named arguments (which can be only one argument) is ended on the first argument which is either a multi-elements list, a parameter not starting with a dash or the special -- end-of-options marker. Remaining arguments will then be assigned to following positional arguments."

> It implies, that the assignment is based on the *content* of the actual parameter - if it starts with a dash - which is IMHO a big mistake.

I think you’re misinterpreting this text.

Can you provide an example of what you think this means? maybe it needs to be clarified, I see it as saying that if a parameter doesn’t start with a dash then it’s not a “name” indicating that a named argument is present.

OH, if you’re expecting:

foo ?-opt1 value? ?-opt2 value? ?-opt3 value? param4 param5

And you pass it:

foo -opt1 this -opt2 that blah

Then blah is not a “name” and it won’t look for “-opt3” after it.

If there is a possibility that “blah” might be “-blah”, then you need to explicitly put a “--“ in there, just as you would with (for example) the “switch” command.
Reply all
Reply to author
Forward
0 new messages