:TITLE: Adding new commands to Tcl - proc
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_English/Tcl_English11.lsn,v 1.1 2008/08/02 12:37:17 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# See file "NOTICE" for licensing terms.
;#
:LESSON_TEXT_START_LEVEL 0:
In Tcl there is actually no distinction between functions and commands. 
There are no reserved words as exist in C, BASIC, FORTRAN, etc.  When
the Tcl interpreter starts up there is a list of known functions in the
table that the interpreter uses to parse a line.  These are the commands
that Tcl knows about by default.  These commands include <CODE>while,
for, set, puts,</CODE> etc. 
<P>
The <CODE>proc</CODE> command adds a new procedure to the list of known
commands.  The syntax for the <CODE>proc</CODE> command is:
<P><B>proc</B> <I>name args body</I>
<P>
When <CODE>proc</CODE> is invoked, it creates a structure to define the
procedure, and adds that structure and <I>name</I> to the tables 
used when parsing commands.  If the command already existed, then it
will be replaced by the new command with the same name.
<P>
<I>Args</I> is a list of arguments which will be passed to <I>name</I>.  When
<I>name</I> is invoked, local variables with these names will be created,
and the values to be passed to <I>name</I> will be copied to the local
variables.
<P>
<I>Body</I> is a body of code to execute when <I>name</I> is called.
<P>
The value that the <I>body</I> of a proc returns can be defined with the
<CODE>return</CODE> command.  The <CODE>return</CODE> command will return
its argument to the calling program.  If there is no return, then <I>body</I>
will return to the caller when the last closing brace has been reached, and
the proc will return the value of the last command to be executed.
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
In Tcl there is actually no distinction between functions and commands. 
There are no reserved words as exist in C, BASIC, FORTRAN, etc.  When
the Tcl interpreter starts up there is a list of known functions in the
table that the interpreter uses to parse a line.  These are the commands
that Tcl knows about by default.  These commands include <CODE>while,
for, set, puts,</CODE> etc. 
<P>
The <CODE>proc</CODE> command adds a new procedure to the list of known
commands.  The syntax for the <CODE>proc</CODE> command is:
<P><B>proc</B> <I>name args body</I>
<P>
When <CODE>proc</CODE> is invoked, it creates a structure to define the
procedure, and adds that structure and <I>name</I> to the tables 
used when parsing commands.  If the command already existed, then it
will be replaced by the new command with the same name.
<P>
<I>Args</I> is a list of arguments which will be passed to <I>name</I>.  When
<I>name</I> is invoked, local variables with these names will be created,
and the values to be passed to <I>name</I> will be copied to the local
variables.
<P>
<I>Body</I> is a body of code to execute when <I>name</I> is called.
<P>
The value that the <I>body</I> of a proc returns can be defined with the
<CODE>return</CODE> command.  The <CODE>return</CODE> command will return
its argument to the calling program.  If there is no return, then <I>body</I>
will return to the caller when the last closing brace has been reached, and
the proc will return the value of the last command to be executed.
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
In most programming languages there are a set of core commands that the
compiler knows about, and a set of functions that a user writes as parts
of their program.  The commands that the compiler knows are coded into
the compiler, and you can't use those words for anything except what
they were intended for.  The code to implement these commands may be
added as function calls, or as in-line assembler.  The code for the users
functions are always added as function calls.
<P>
In Tcl there is no distinction between functions and commands. 
There are no reserved words as exist in C, BASIC, FORTRAN, etc.  When
the Tcl interpreter starts up there is a list of known functions in the
table that the interpreter uses to parse a line.  These are the commands
that Tcl knows about by default.  These commands include <CODE>while,
for, set, puts,</CODE> etc. 
<P>
The <CODE>proc</CODE> command adds a new procedure to the list of known
commands.  The syntax for the <CODE>proc</CODE> command is:
<P><B>proc</B> <I>name args body</I>
<P>
When <CODE>proc</CODE> is invoked, it creates a structure to define the
procedure, and adds that structure and <I>name</I> to the tables 
used when parsing commands.  If the command already existed, then it
will be replaced by the new command with the same name.
<P>
<I>Args</I> is a list of arguments which will be passed to <I>name</I>.  When
<I>name</I> is invoked, local variables with these names will be created,
and the values to be passed to <I>name</I> will be copied to the local
variables.
<P>
<I>Body</I> is a body of code to execute when <I>name</I> is called.
<P>
The value that the <I>body</I> of a proc returns can be defined with the
<CODE>return</CODE> command.  The <CODE>return</CODE> command will return
its argument to the calling program.  If there is no return, then <I>body</I>
will return to the caller when the last closing brace has been reached, and
the proc will return the value of the last command to be executed.
<P>
Digression on programming style.
<P>
Use procs.  Use them often.  A tcl program (or any other program) should 
consist of a very little glue in the main routine, and most of the processing
should be done in the procs.  If you design your procs well, you'll be able
to extract them later and use them in a different piece of code without 
rewriting them.  Mainline code tends to be harder to pick up pieces and move.
You end up learning suddenly that a variable was initialized several hundred 
lines earlier, or something else unpleasant.  
<P>
Dividing code into procs also makes each individual module smaller.  The smaller
a module is, the fewer interactions there are, and the less likelihood there
is that one of these interactions will bite you.  Small modules are also 
easier to comprehend and modify safely.  
<P>
Since Tcl is an ideal language for rapid prototype style development, the
odds are very good that as a project progresses you will change the behavior
of procs, usually by adding more functionality to them.  If they 
start out fairly small, they will end up medium sized.  If they started out 
large, they'll end up too large and unwieldy.  
<P>
Design procs with the idea that they'll be used elsewhere and will be 
modified over time.  If that doesn't happen, you'll be stuck with well designed
procs.  If it does happen, you'll be glad you put the extra effort into doing
the task well the first time.
<P>
The fact that a proc will return the return value from the last command
executed within the proc by default can be used to save yourself typing
several characters.  Don't give in to that temptation.  If you intend to
make use of a proc's return value, then set it explicitly.  Otherwise,
you'll make a 'harmless' change at some point in the future, unintentionally 
change the return, and break your code in unpleasant and hard to fathom
ways. 
:TEXT_END:

:CODE_START:
proc sum {arg1 arg2} {
  set x [expr $arg1+$arg2];
  return $x
  }

puts " The sum of 2 + 3 is: [sum 2 3]\n\n"

proc for {a b c} {
	puts "The for command has been replaced by a puts";
	puts "The arguments were: $a\n$b\n$c\n"
	}

for {set i 1} {$i < 10} {incr i}
:TEXT_END:

