:TITLE: Adding new commands to Tcl - proc ;# ;# RCSID: $Header: /cvsroot/tcl/tcltutorial/original/Tcl11.lsn,v 1.1 2004/11/04 16:01:13 davidw 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 while, for, set, puts, etc.

The proc command adds a new procedure to the list of known commands. The syntax for the proc command is:

proc name args body

When proc is invoked, it creates a structure to define the procedure, and adds that structure and name 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.

Args is a list of arguments which will be passed to name. When name is invoked, local variables with these names will be created, and the values to be passed to name will be copied to the local variables.

Body is a body of code to execute when name is called.

The value that the body of a proc returns can be defined with the return command. The return command will return its argument to the calling program. If there is no return, then body 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 while, for, set, puts, etc.

The proc command adds a new procedure to the list of known commands. The syntax for the proc command is:

proc name args body

When proc is invoked, it creates a structure to define the procedure, and adds that structure and name 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.

Args is a list of arguments which will be passed to name. When name is invoked, local variables with these names will be created, and the values to be passed to name will be copied to the local variables.

Body is a body of code to execute when name is called.

The value that the body of a proc returns can be defined with the return command. The return command will return its argument to the calling program. If there is no return, then body 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.

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 while, for, set, puts, etc.

The proc command adds a new procedure to the list of known commands. The syntax for the proc command is:

proc name args body

When proc is invoked, it creates a structure to define the procedure, and adds that structure and name 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.

Args is a list of arguments which will be passed to name. When name is invoked, local variables with these names will be created, and the values to be passed to name will be copied to the local variables.

Body is a body of code to execute when name is called.

The value that the body of a proc returns can be defined with the return command. The return command will return its argument to the calling program. If there is no return, then body 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.

Digression on programming style.

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.

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.

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.

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.

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: