Richard Suchenwirth - When coding for Graph theory in Tcl, I noticed I had to translate mathematical formulations from the book to procedural Tcl code. Routine, yes, but on second look I thought it could be nice to add some sugar (see Salt and sugar) to typical situations: for instance, returning a truth value can be done with a call to expr:
proc isPositive x {expr {$x>0}} but as this is the required condition, one could use requires as alias for expr, so it could look like this:
proc isPositive x {requires {$x>0}} More typing, but somehow reads nicer... And once started with that, I wanted to factor out testing loops like in isEulerian, which break and return false when the test fails once, or return true after looping over all cases, so I could write:
proc arePositive list {requires all i in $list {isPositive $i}}Pretty neat for Tcl, huh? And in place for "all", you could place other logical quantifiers like "any, none"... well, just see for yourself:
proc requires {what args} {
if ![llength $args] {
uplevel 1 expr $what
} else {
foreach {_var "in" list body} $args break
switch -- $what {
each - all {set fail 0; set not !}
one - any {set fail 1; set not ""}
no - none {set fail 0; set not ""}
default {error "usage: requires Q Var in List Body"}
}
upvar 1 $_var var
foreach var $list {
if $not[uplevel 1 $body] {return $fail}
}
expr !$fail
}
}# Here are usage examples for the single and set form, and test code:
proc isEven x {requires {$x%2 == 0}}
proc isOdd x {requires ![isEven $x] }
proc areEven list {requires all i in $list {isEven $i}}
proc hasEven list {requires any i in $list {isEven $i}}
proc areEven2 list {requires no i in $list {isOdd $i}}
foreach test {
{isEven 2} {isEven 4711}
{areEven {2 4 6}} {areEven {2 4 5}} {areEven {}}
{hasEven {1 3 5}} {hasEven {1 4 5}} {hasEven {}}
{areEven2 {2 4 6}} {areEven2 {2 4 5}} {areEven2 {}}
} {
puts "$test:[eval $test]"
}
# The behavior on empty lists leaves something to be wished, though...Sugared assignment: this version evolved in the Tcl chatroom:
proc let {varName "=" args} {
upvar 1 $varName v
set v [uplevel 1 expr $args]
} ;# dkfSee also Let's assign with Let
gold 10/11/2020. Added appendix below, but original source code and text above was unchanged.
Please place any comments here, Thanks.
| Category Numerical Analysis | Category Toys | Category Calculator | Category Mathematics | Category Example | Toys and Games | Category Games | Category Application |