Tcl Source Code

View Ticket
Login
Ticket UUID: 35fdc88036489d43b4dd1b326527dc0bd7762bf7
Title: proc: disallow duplicated parameter names in arg spec
Type: Patch Version: 8.7a0
Submitter: mr_calvin Created on: 2017-02-23 12:52:19
Subsystem: 22. [proc] and [uplevel] Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Open Last Modified: 2017-04-03 18:27:42
Resolution: None Closed By: nobody
    Closed on:
Description:
% proc foo {a a a} {return [concat [info local] $a]}; foo 1 2 3
a a a 1

To quote KBK from IRC yesterday :)

"Arguably, that's a bug. It surely doesn't do anything useful, and we probably should detect it as an error."

"The fact that Tcl has been around for 27 years, and nobody's noticed [proc x {a a a} { ... }] until now indicates that it's low-worry, especially if it doesn't cause a crash. (I expect that it'll just discard the first two args at run time.)"

Low-worry, indeed, but potentially irritating ([info]) and kind of puzzling after so many years.

In the attached patch, I gave it a shot. Tests were added to proc.test, two tests fixed in trace.test (actually using repeated names!). The above one liner will now result in a proper TCL_ERROR:

arg list contains a duplicate entry "a"

Stefan
User Comments: dgp added on 2017-04-03 18:27:42:
The data structures at work here are deeply confused
and convoluted, failing to distinguish between lists
of argument names and lists of local variables.  They've
been obfuscated and optimized to the point of
incomprehensibility and interbred with unholy extensions
like Itcl and tbcload.  It's unfixable. Only winning
move is not to play.  Nuke it from orbit; only way
to be sure.

dgp added on 2017-03-29 20:28:10:
The contributed patch doesn't restore Tcl 7 handling.

Instead it considers duplicate parameter names to be
an error.

Key trouble with this is:

proc ::tk::EventMotifBindings {n1 dummy dummy} { ... }

and

proc ttk::entry::LineSelect {w _ _} {...}

Since Tk breaks this proposed rule, it's a pretty safe
bet other scripts and packages do as well.

Given that, I'd consider this fix only for 8.7 and later,
and might possibly consider it a Tcl 9 change.

I'd like to see a patch bringing back Tcl 7 behavior to
see how its different compat concerns would play out.

dgp added on 2017-02-23 16:04:16:

FWIW....

dgp	% info patch
	7.5p1
	% proc foo {a a a} {puts stderr [info local]-$a}; foo 1 2 3
	a-3

dgp	% info patch
	8.0.3
	% proc foo {a a a} {puts stderr [info local]-$a}; foo 1 2 3
	a a a-1

Also

dah	% proc foo {a a a} {unset a; puts [info local]; puts $a}
	% foo 1 2 3
	a a
	can't read "a": no such variable

Seems to me Tcl 7 had the better idea of proper behavior.

mr_calvin added on 2017-02-23 13:30:49:
hi,

As for "your expectation": This wasn't mine, but KBK's (is part of the quote).

stefan

avl42 (claiming to be It was noticed, but so far inertia won...) added on 2017-02-23 13:15:12:
Interestingly, while Tcl 8.6 was changed to disallow non-optional arguments following optional arguments, it didn't address non-unique names in the same wash.

Btw., your expectation ("it'll just discard the first two args at run time") is not the right one, because instead it only uses the first one of the values.

Attachments: