TIP:            65
Title:          Enhanced [info args]
Version:        $Revision: 1.6 $
Author:         Glenn Jackman <glennj@nortelnetworks.com>
Author:         Don Porter <dgp@users.sf.net>
Author:         Glenn Jackman <glennj@ncf.ca>
State:          Rejected
Type:           Project
Vote:           Done
Created:        18-Sep-2001
Post-History:   
Tcl-Version:    8.5

~ Abstract

This TIP proposes a new subcommand to the [[info]] command be added
that would return the list of arguments, together with any default
values in the same format as the ''args'' parameter to the [[proc]]
command.

~ Introduction

The [[proc]] man page defines ''args'' as:

  > ... the formal arguments to the procedure.  It consists of a list,
    possibly empty, each of whose elements specifies one argument.
    Each argument specifier is also a list with either one or two
    fields.  If there is only a single field in the specifier then it
    is the name of the argument; if there are two fields, then the
    first is the argument name and the second is its default value.

Suppose we define a procedure like this:

|       proc test {one {two 2} {three {3 4 5}} args} {return}

We want to determine the formal arguments for this procedure.  We want
some method to return the list:

|       one {two 2} {three {3 4 5}} args

[[info args]] fails us because it does not return default values, only
the list of argument names {one two three args}.

The [[info default]] command exists, and does partially what we want.
However [[info default]] only operates on a single argument.  To
determine the complete list of arguments with default values, we must
iterate over the arguments returned by [[info args]].  We would define
a procedure like:

|       proc info_args_with_defaults {procname} {
|           set argspec [list]
|           # [info args] throws an error if $procname is not a procedure.
|           foreach arg [info args $procname] {
|               if {[info default $procname $arg value]} {
|                   lappend argspec [list $arg $value]
|               } else {
|                   lappend argspec $arg
|               }
|           }
|           return $argspec
|       }
|       info_args_with_defaults test  ;# ==> returns {one {two 2} {three {3 4 5}} args}

A more sophisticated scripted solution is to overload the [[info]]
command itself, as described in the Wiki at
http://wiki.tcl.tk/wrappingCommands

It would be much more convenient to be able to rely on the [[info]]
command itself to return the desired information, particularly since
it ''almost'' does what we want already.

''This topic was originally raised in the news:comp.lang.tcl newsgroup
in the thread http://groups.google.com/groups?th=4b0d5dba85d2c160''

~ Specification

Add [[info formalargs]] to the set of subcommands for
Tcl's built-in [[info]] command, with syntax:

| info formalargs $procName

This command will raise an error if ''$procName'' is not the
name of a proc.  Otherwise, it will return a list of formal
arguments of the named proc, along with their default values,
if any, in a format suitable for passing to the [[proc]] command
as a second argument.

~ Rationale

With the goal of maintaining backwards compatibility in mind, two
possibilities arise: adding a new switch to the existing [[info args]]
command, and adding a completely new subcommand to [[info]].

Adding a switch to [[info args]] may break backwards compatibility.
If we use the syntax [[info args ''?-withdefaults? procname'']], there
may be trouble with existing scripts containing a procedure named
"-withdefaults".  The syntax [[info args ''procname
?-withdefaults?'']] is completely backwards compatible.  However,
among Tcl commands that take subcommands, there is currently some
inconsistency as to where switches should appear.  [[clock]]
subcommands place these options after required parameters.
[[namespace]] and [[package]] subcommands place these options before
required parameters.  Some [[file]] subcommands put them before, some
after.  Currently, no [[info]] subcommands take switches.

Rather than compound to this inconsistency, creating a new [[info]]
subcommand feels cleaner.  Possible names include:

 argspec, arglist, args_with_defaults:	These all collide with the
    "arg", "ar", "a" shorthands for [[info args ''procname'']].  And
    ''args_with_defaults'' is just *way* too ugly.

 formalargs, fullargs:	Either of these could be used.  This collides
    with the "f" shorthand for [[info functions]]

 parameters:	This collides with the "pa" shorthand for [[info
    patchlevel]]

 prototype:	This collides with the "pro" and "pr" shorthands for
    [[info procs ''?pattern?'']]

 signature:	This could be used, as it does not collide with any
    shorthand for either [[info script]] or [[info sharedlibextension]].

The term "signature" has meaning in the Java and C++ worlds: the
function name and its arguments together comprise the signature.  The
purpose of this TIP is to return only the arguments with any defaults,
so to avoid any potential confusion I will rule out "signature".

Of the remaining possibilities, my choice would be "formalargs".  The
term "formal arguments" is used in the [[proc]] man page.
"formalargs" also incorporates the word "args", indicating a
relationship to [[info args]].

~ Reference Implementation

Refer to the submitted patch, which implements an subcommand named
[[info fullargs]], at:
http://sourceforge.net/tracker/index.php?func=detail&aid=461635&group_id=10894&atid=310894

~ Reasons for Rejection

Those voting against this proposal believed that since the desired
functionality is already possible with a short script of just a few
Tcl commands, it would be unnecessary bloat to add another subcommand.
Some also pointed to [112] as another approach to letting people extend
Tcl built-in commands with their own custom subcommands.

~ Copyright

This document has been placed in the public domain.

