TIP 65: Enhanced [info args]

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2017 Conference, Houston/TX, US, Oct 16-20
Send your abstracts to tclconference@googlegroups.com
by Aug 21.
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.

History