Tmac - a Tcl macro processor package

Tmac is a macro facility for Tcl. A copy is still available here .

Description

I created the Tmac package to make Tcl coding go easier. Tmac lets you leverage the base language to make your specific application issues easier to solve.

Tmac version 1.0 released 9-December-2003

Purpose of this page is to offer a brief introduction and rationale for Tmac and to solicit feedback and comments for improvements.

WHAT IS IT?

Tmac is a pure Tcl package that helps automate the creation of Tcl code or data. It does this automation by implementing named macros. One way to create a macro is to give Tmac a template or block of code that you want replicated. For example:

 MAC-BLOCK max a b {[expr {$@a > $@b ? $@a : $@b}]}

Gives you a 2 parameter macro to find the maximum value stored between two variables. In this case the benefit would be to run slightly faster than the equivalent procedure call since there would be no proc call overhead in the code.

The second kind of macro is called a filter:

 proc dovarset args {
   set out ""
   foreach {var val} $args {append out "set $var $val \n"}
   return $out
 }
 MAC-FILTER varset dovarset

Now we can write

 <:varset a 0 b 0 c 10 d 50 :>

to generate

 set a 0
 set b 0
 set c 10
 set d 50

A filter macro , by contrast to block macros, does not use a template or block of code. Instead it calls a proc which computes and returns the code to be inserted. Notice how the filter macro did not need to declare parameters.

WHAT IS TMAC GOOD FOR?

Tmac provides new avenues to create and structure Tcl code. This capability can address all of the following areas:

  1. Code reuse - An alternative method. Macros offer code reuse as per eval but lets the parameters be enumerated and is more efficient because the code is compilable.
  2. Flexibility - A way of keeping options open longer. Macros are easily defined and used at the same point in the code. Thus, correcting, tuning, and enhancing of the macro code is often easier than if the code had been factored out into a procedure.
  3. Mental Overhead - reduce the programmers workload. The process of coding involves a very large number of concerns, judgments, decisions, and inventions that tax the mental capacity. In particular, defining a procedure is taxing because it requires a shift in attention from the coding problem onto a packaging and naming problem. Defining and using a macro can be mentally easier than defining and using a procedure because there are generally fewer mental steps involved. The macro can then be easily converted to a proc at a later time.
  4. Performance improvements. Macros offer a way to increase performance and preserve maintainability. Macros can increase speed in several ways, the principal way is to avoid proc call overhead. The value of this depends on the criticality of the procedure in question. How often is it called, is it called in event processing? Is there a big overhead in getting parameters and data in/out of the proc?
  5. Shorter and more concise coding. Certain applications and application modules can be tedious and repetitive to code because of nested commands and lengthy option names (widgets formats). Macros can easily reduce this error-prone situation by encoding the common idioms into macro invocations. So if your app needed to look at a lot of string suffixes:
           MAC-BLOCK tail s i {[string range @s end-[expr {@i-1}] end]}
           set last2 <:tail $s 2:>
           # Or if you used back-quote as the macro delimiter:
           # set last2 `tail $s 2`

by Roy Terry