\documentclass[]{article}
\usepackage{amsmath,graphicx,supertabular,hyperref,tabularx,ifthen}
\title{TIP \#133: Extending [expr] Operators}
\date{April 08, 2003}
\author{Richard Suchenwirth}
\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 \#133}&\textbf{Extending [expr] Operators}\\\hline
Author&

Richard Suchenwirth \tipmail{Richard.Suchenwirth-Bauersachs}{siemens.com}
\\
Created&Tuesday, \(\text{8}^{\text{th}}\) April 2003\\
Type&Project\\
Tcl Version&\(8.7\)\\
State&Draft\\
Vote&Pending\\
Version&\tipversion$Revision: 1.6 $\\
Post History&\\
\hline\end{tabularx}\end{center}
\thispagestyle{empty}\pagestyle{empty}
\begin{tipabstract}

This TIP proposes a way to define new operators for conditions and the \textbf{expr} command. It also includes demonstrations of how it might work in the examples: \textbf{in} tests inclusion in a list, and \textbf{and}, \textbf{or}, and \textbf{not} are aliases for ``\textbf{\&\&}'', ``\textbf{\tipbar{}\tipbar{}}'', ``\textbf{!}''.
\end{tipabstract}
\tableofcontents\setcounter{page}{0}\clearpage\pagestyle{plain}

\section{Rationale}

Inclusion of a value in a list is frequently tested with the construct
\begingroup\small\begin{verbatim}
   if {[lsearch -exact $list $value] >= 0} {...}
\end{verbatim}
\endgroup

The proposal, first brought by Reinhard Max in the Tcl Chatroom, is to allow an \textit{in} operator in the language understood by \textbf{expr}, and the condition parts of \textbf{for}, \textbf{if} and \textbf{while}, so that the above can be written as
\begingroup\small\begin{verbatim}
   if {$value in $list} {...}
\end{verbatim}
\endgroup

This is shorter to type and much better to read.

In the same vein, I propose to allow operators ``\textbf{and}'', ``\textbf{or}'', ``\textbf{not}'' to be resolved exactly like the current ``\textbf{\&\&}'', ``\textbf{\tipbar{}\tipbar{}}'' resp ``\textbf{!}'' The new ``operator aliases'' are not shorter than the original operators, but definitely better readable --- and easier typed too, as no Shift (or Alt-Gr on German keyboards) key is needed.

When Tcl was young, almost all users knew C, so the C style operators were a good choice. In recent years, there is tendency that Tcl is used by persons who have no or less experience with C, but come from other languages (etc. BASIC variants have the AND, OR, NOT operators) or have Tcl as a first language. For all these, the option of natural-language operators will make the learning just a little bit easier.

\section{Implementation Proposals}

Donal K. Fellows remarked (on an earlier proposal relating to just an \textbf{in} operator) in the Tcl Chatroom: ``On the plus side, it shouldn't be hard to implement (might need an extra opcode for \textbf{lsearch}, but that's pretty straightforward.)''

Pascal Scheffers proposed an extension mechanism for \textbf{expr} and conditions, so the proposed extensions to the expression language can be done in Tcl, with the commands:
\begingroup\small\begin{verbatim}
 expr_register_operator in  {val list} {expr {[lsearch -exact $list $val]>=0}}
 expr_register_operator and {p q}      {expr {$p && $q}}
 expr_register_operator or  {p q}      {expr {$p || $q}}
 expr_register_operator not {p}        {expr {!$p}}
\end{verbatim}
\endgroup

Such operator registrations can have one or two arguments (for unary and binary operators, respective) in the second argument. The third argument is a body that is evaluated, with local variables from the argument list substituted, and returns the resulting value, to be substituted for the operator and its operands.

Alternatively, one could stipulate that \textbf{expr} interprets its arguments in the above sense when called like this:
\begingroup\small\begin{verbatim}
 expr operator in  {val list} {expr {[lsearch -exact $list $val]>=0}}
 expr operator and {p q}      {expr {$p && $q}}
\end{verbatim}
\endgroup

This would currently raise an error, hence cannot break existing code.

For a simple start, it shall be an error to define an operator both as unary and binary.

Rules for operator precedence, and a way of specifying the precedence level, will still be needed.

A feature sometimes discussed in \url{news:comp.lang.tcl}, an assignment operator, could in the same way easily be added by users who so want:
\begingroup\small\begin{verbatim}
 expr operator = {varName value} {upvar 1 $varName var; set var $value}
\end{verbatim}
\endgroup

Reinhard Max has also proposed a unary \textbf{empty} operator:
\begingroup\small\begin{verbatim}
  expr operator empty {list} {expr {[llength $list]==0}}
\end{verbatim}
\endgroup

\section{Copyright}

This document has been placed in the public domain.

\section{Colophon}

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