为什么Tcl允许带有空格的proc名称,而不允许带空格的参数?

问题描述 投票:2回答:1

只是为了好玩,我写了下面这段代码:

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

我觉得有趣的是,proc名称可能包含空格。我认为将它与基本上未使用的参数结合起来可以使Tcl程序看起来非常类似于口语自然语言,就像Smalltalk使用bakeACake forPeople: 3 andChildren: 3一样,只是没有奇怪的冒号扰乱句子和不自然的词序。

为了进一步探索这个想法,我尝试使用相同的模式来处理proc的参数,方法是用一个简单的空格替换每个_。 tclsh8.6不喜欢它:

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)

这提出了以下问题:

  • 有没有令人信服的理由为什么proc名称可能包含空格但参数名称不能?
  • 它只是proc的实现细节吗?
  • 是否有可能编写允许这种语法变体的spaceproc
arguments tcl whitespace
1个回答
3
投票

仔细阅读proc文档:arg列表中的每个args本身都是一个列表,必须有1或2个元素:强制参数名称和可选的默认值。 "number of people"有太多的元素。你可以用另一层大括号得到你想要的东西:

% 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}"

我没有看到追求这个实验的好处:尴尬的变量名称排除了$语法糖。

请注意,获取Smalltalk外观代码并不困难

% 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

虽然与Smalltalk不同,但你不能拥有以“bakeACake”开头的其他命令(除非你深入研究“命名空间集合”)

© www.soinside.com 2019 - 2024. All rights reserved.