Reputation: 41617
Just for fun, I have written the following piece of code:
proc "bake a cake" {"number_of_people" {number_of_children}} {
set fmt "Take %d pounds of flour and %d bags of marshmallows."
puts [format $fmt "${number_of_people}" ${number_of_children}]
puts "Put them into the oven and hope for the best."
}
"bake a cake" 3 3
{bake a cake} 5 0
I found it funny that the proc names may include whitespace. I thought that combining this with essentially unused arguments would make it possible to make Tcl programs look very similar to spoken natural language, in a similar way Smalltalk does with its bakeACake forPeople: 3 andChildren: 3
, just without the strange colon disturbing the sentences and the unnatural word order.
To explore this idea further, I tried the same pattern for the parameters of the proc, by replacing each _
with a simple space. The tclsh8.6 didn't like it:
too many fields in argument specifier "number of people"
(creating proc "bake a cake")
invoked from within
"proc "bake a cake" {"number of people" {number of children}} {
set fmt "Take %d pounds of flour and %d bags of marshmallows."
puts [format $fmt "${n..."
(file "bake.tcl" line 1)
This raised the following questions:
proc
?spaceproc
that allows this syntactic variant?Upvotes: 2
Views: 276
Reputation: 246764
Have a close read at the proc
documentation: each of the args in the arg list is itself a list, that must have 1 or 2 elements: the mandatory argument name and the optional default value. "number of people"
has too many elements. You can get what you want with just another layer of braces:
% proc "bake a cake" {{"for people"} {"and children"}} {
puts "baking a cake for [set {for people}] people and [set {and children}] children"
}
% "bake a cake" 1 2
baking a cake for 1 people and 2 children
% "bake a cake"
wrong # args: should be "{bake a cake} {for people} {and children}"
I don't see the benefit of pursuing this experiment: the awkward variable names preclude the $
syntactic sugar.
Note that it's not that difficult to get Smalltalk-looking code
% proc bakeACake {forPeople: nPeople andChildren: nChildren} {
if {[set forPeople:] ne "forPeople:" || [set andChildren:] ne "andChildren:"} {
error {should be "bakeACake forPeople: nPeople andChildren: nChildren"}
}
puts "baking a cake for $nPeople people and $nChildren children"
}
% bakeACake
wrong # args: should be "bakeACake forPeople: nPeople andChildren: nChildren"
% bakeACake foo 1 bar 2
should be "bakeACake forPeople: nPeople andChildren: nChildren"
% bakeACake forPeople: 3 andChildren: 4
baking a cake for 3 people and 4 children
Although unlike Smalltalk, you can't have other commands starting with "bakeACake" (unless you dig into "namespace ensembles")
Upvotes: 3