Calculating positions along the edges of a rectangle I had the following three Tcl procedures, which calculate positions along three edges of a rectangle:

#---- Numbered pins at the top ---------------------------------------
# Given a list of triplets (number, name, index), place the pins for the
# signals "name&lt;index&gt;" along the top edge, positioned vertically at 'y'
# and horizontally at 'number' times a constant space left of 'xRight'
# (plus an arbitrary offset of 2).
proc setNumberedTopPins {xRight y pins} {
    set padWidth 95
    foreach {number name index} $pins {
        set xOffset [expr $number * $padWidth + 2]
        setPin $name [expr $xRight-$xOffset] $y Top $index
    }
}
#---- Numbered pins at the right -------------------------------------
# The same for the right edge.
proc setNumberedRightPins {x yTop pins} {
    set padWidth 95
    foreach {number name index} $pins {
        set yOffset [expr max(0, $number * $padWidth - 2.5)]
        setPin $name $x [expr $yTop-$yOffset] Right $index
    }
}
#---- Numbered pins at the bottom ------------------------------------
# The same for the bottom edge.
proc setNumberedBottomPins {xRight y pins} {
    set padWidth 95
    foreach {number name index} $pins {
        set xOffset [expr $number * $padWidth + 2]
        setPin $name [expr $xRight-$xOffset] $y Bottom $index
    }
}


Since the code for each of the procedures is almost identical, I decided to write a single generalized procedure and three specializations of it.

I had some difficulties with generalizing the fact that the offset is sometimes applied to the second (x) and sometimes to the third (y) argument of setPin. I wanted to make sure that this decision is only taken once, outside the foreach loop.

Here is the solution I came up with:

#---- Numbered pins at the top ---------------------------------------
proc setNumberedTopPins {xRight y pins} {
    setNumberedPins Top 2 $xRight $y $pins
}
#---- Numbered pins at the right -------------------------------------
proc setNumberedRightPins {x yTop pins} {
    setNumberedPins Right -2.5 $x $yTop $pins
}
#---- Numbered pins at the bottom ------------------------------------
proc setNumberedBottomPins {xRight y pins} {
    setNumberedPins Bottom 2 $xRight $y $pins
}
#---- Generic numbered pins ------------------------------------------
proc setNumberedPins {side offsetPin0 x y pins} {
    set padWidth 95
    switch $side {
        Top - Bottom {set coords {list [expr $x-$offset] $y}}
        Right {set coords {list $x [expr $y-$offset]}}
    }
    foreach {number name index} $pins {
        set offset [expr max(0, $number * $padWidth + $offsetPin0)]
        setPin $name {*}[eval $coords] $side $index
    }
}


I'm not an experienced Tcl programmer and I wonder if there is a better way to solve this. Particularly, there is still some amount of code duplication left (almost identical definition of auxiliary variable coords inside switch) and I would like to eliminate that (while keeping the code reasonably readable).
I would suggest that since only 2 of the procs are close enough to identical, just "combine" those:

set padWidth 95

proc setNumberedRightPins {x yTop pins} {
    foreach {number name index} $pins {
        set yOffset [expr {max(0, $number * $::padWidth - 2.5)}]
        setPin $name $x [expr {$yTop-$yOffset}] Right $index
    }
}

proc setNumberedTopPins {args} {
    setNumberedTopOrBottomPins {*}$args Top
}

proc setNumberedBottomPins {args} {
    setNumberedTopOrBottomPins {*}$args Bottom
}

proc setNumberedTopOrBottomPins {xRight y pins side} {
    foreach {number name index} $pins {
        set xOffset [expr {$number * $::padWidth + 2}]
        setPin $name [expr {$xRight-$xOffset}] $y $side $index
    }
}


Notes:


always brace your expressions, gain a big performance boost
constants can live in the global namespace, and you access them with a fully qualified variable name