\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#288: Allow "args" Anywhere in Procedure Formal Arguments}
\date{October 03, 2006}
\author{Peter Spjuth, Andreas Leitgeb, Peter Spjuth}
\urlstyle{sf}
\setlength{\parskip}{1ex}
\setlength{\parindent}{0pt}
\def\tipversion$#1${\texttt{\$#1\$}}
\def\tiplangle#1{\ensuremath{<}}
\def\tiprangle#1{\ensuremath{>}}
\def\tipbar#1{\ensuremath{|}}
\def\tipmail#1#2{\(\langle\){\small\expandafter\url{#1@#2}}\(\rangle\)}
\ifx\pdfoutput\undefined
\newcommand{\tipimage}[2]{\typeout{Make sure you download #1.eps}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.eps}}{\includegraphics[width=0.8\textwidth]{#1.eps}}}
\newcommand{\tipxref}[1]{}
\newcommand{\tipxrefend}{}
\else
\newcommand{\tipimage}[2]{\typeout{Make sure you create #1.pdf}\ifthenelse{\lengthtest{0.8\textwidth>#2}\and\lengthtest{0pt<#2}}{\includegraphics{#1.pdf}}{\includegraphics[width=0.8\textwidth]{#1.pdf}}}
\pdfcatalog{/PageMode /UseOutlines}
\newcommand{\tipxref}[1]{\pdfannotlink attr {/C [0.5 0.5 1.0] /Border [0 0 1]} goto name {#1}}
\newcommand{\tipxrefend}{\pdfendlink}
\fi
\newenvironment{tipabstract}{\begin{abstract}}{\end{abstract}}
\begin{document}\maketitle
\begin{center}\begin{tabularx}{\linewidth}{|r@{: }X|}\hline
\textbf{TIP \#288}&\textbf{Allow "args" Anywhere in Procedure Formal Arguments}\\\hline
Author&

Peter Spjuth \tipmail{peter.spjuth}{space.se}
\par
Andreas Leitgeb \tipmail{avl}{logic.at}
\par
Peter Spjuth \tipmail{peter.spjuth}{gmail.com}
\\
Created&Tuesday, \(\text{3}^{\text{rd}}\) October 2006\\
Type&Project\\
Tcl Version&\(8.7\)\\
State&Draft\\
Vote&Pending\\
Version&\tipversion$Revision: 1.14 $\\
Keywords&Tcl, proc\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes to make \textit{args} have its special meaning as a formal \textbf{proc}edure argument anywhere in the argument list.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

Many commands, specially many of Tcl's built in commands, have their variadic arguments in the beginning of the argument list and their required arguments at the end. An example is [\textbf{lsearch} ?\textit{options}? \textit{list string}].

Writing tcl procedures in that style is currently a bit cumbersome since you need to do you own argument counting and assignment to variables from ``args''.

If ``args'' had its special meaning at any location in the argument list, it would help with such a task, and it would make things more consistent.

To get simple semantics, optional arguments are not allowed after ``args''. Optional arguments that precede ``args'' will be handled as before. This TIP does not, as of now, specify defaulted arguments directly preceding non-defaulte ones. This should be addressed in a separate TIP.

\section{Specification}

At most one proc argument may be named ``args'' and can be anywhere in the argument list. Arguments after ``args'' may not be optional. Arguments are assigned in the following order:
\begin{enumerate}
\item{}
Assign arguments right of ``args'' from the right.
\setcounter{enumi}{1}
\item{}
Assign arguments left of ``args'' from the left. Handling of defaulted parameters preceding ``args'' remains as it was (but disregarding the non-defaulted ones after ``args'').
\setcounter{enumi}{2}
\item{}
Remaining arguments are assigned to ``args''.
\end{enumerate}

\section{Compatiblity}

Currently ``args'' is allowed anywhere in the argument list, and becomes a normal variable if not last. Most scripts probably don't use this since it would be rather confusing, but it might exist.

All such occurrances would need to be fixed.

Detecting such scripts in an automated way would be simple and fixing them is trivial.

\section{Examples}

New style:
\begingroup\small\begin{verbatim}
proc lgurka {args list item} {
    array set opts {-apa 1 -bepa "" -cepa 0}
    foreach {arg val} $args {
        set opts([prefix match {-apa -bepa -cepa} $arg]) $val
    }
    # Do real stuff
}
\end{verbatim}
\endgroup

Old style:
\begingroup\small\begin{verbatim}
proc lgurka {args} {
    if {[llength $args] < 2} {
        return -code error "wrong # args: should be \"lgurka ?args? list item\""
    }
    set item [lindex $args end]
    set list [lindex $args end-1]
    set args [lrange $args 0 end-2]

    array set opts {-apa 1 -bepa "" -cepa 0}
    foreach {arg val} $args {
        set opts([prefix match {-apa -bepa -cepa} $arg]) $val
    }
    # Do real stuff
 }
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
proc x {a args b} { puts "a=$a, args=$args, b=$b" }
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
x 1 2  ;# ->   a=1, args=, b=2
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
x 1 2 3 ;# ->  a=1, args=2, b=3
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
x 1 ;# -> error: wrong # args: should be "x a ?args? b"
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
proc y {a {b x} args c} { ... }
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
y 1 2 3 ;#   a=1 b=2 c=3  args is empty
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
proc z {a {b x} c args} { ... }
\end{verbatim}
\endgroup
\begingroup\small\begin{verbatim}
z 1 2  ;# -> error: wrong # args: should be "z a ?b? c ..."
\end{verbatim}
\endgroup

To change ``z'' is not covered by this TIP.

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

\textit{TIP AutoGenerator --- written by Donal K. Fellows}
\end{document}
