Tcl-区分列表/目录和匿名进程
我编写了以下程序,它模拟了Lodash(javascript库)()中的过滤器函数。您可以用3.5基本格式调用它,如示例部分所示。对于后三个调用选项,我想去掉发送-s(速记)的要求。为了做到这一点,我需要区分匿名进程和list/dict/string 我试着查看Tcl-区分列表/目录和匿名进程,tcl,Tcl,我编写了以下程序,它模拟了Lodash(javascript库)()中的过滤器函数。您可以用3.5基本格式调用它,如示例部分所示。对于后三个调用选项,我想去掉发送-s(速记)的要求。为了做到这一点,我需要区分匿名进程和list/dict/string 我试着查看字符串is,但没有字符串is proc。在这里研究:我发现他们建议info complete,但是在大多数情况下,无论参数类型如何,参数都会通过测试 有人知道可靠的测试方法吗?我知道我可以离开它或更改过程定义,但我正试图尽可能真实地对待L
字符串is
,但没有字符串is proc。在这里研究:我发现他们建议info complete
,但是在大多数情况下,无论参数类型如何,参数都会通过测试
有人知道可靠的测试方法吗?我知道我可以离开它或更改过程定义,但我正试图尽可能真实地对待Lodash
示例:
set users [list \
[dict create user barney age 36 active true] \
[dict create user fred age 40 active false] \
]
1. set result [_filter [list 1 2 3 4] {x {return true}}]
2. set result [_filter $users -s [dict create age 36 active true]]
3. set result [_filter $users -s [list age 36]]
4. set result [_filter $users -s "active"]
程序代码:
proc _filter {collection predicate args} {
# They want to use shorthand syntax
if {$predicate=="-s"} {
# They passed a list/dict
if {[_dictIs {*}$args]} {
set predicate {x {
upvar args args
set truthy 1
dict for {k v} {*}$args {
if {[dict get $x $k]!=$v} {
set truthy false
break
}
}
return $truthy
}}
# They passed just an individual string
} else {
set predicate {x {
upvar args args;
if {[dict get $x $args]} {
return true;
}
return false;
}}
}
}
# Start the result list and the index (which may not be used)
set result {}
set i -1
# For each item in collection apply the iteratee.
# Dynamically pass the correct parameters.
set paramLen [llength [lindex $predicate 0]]
foreach item $collection {
set param [list $item]
if {$paramLen>=2} {lappend param [incr i];}
if {$paramLen>=3} {lappend param $collection;}
if {[apply $predicate {*}$param]} {
lappend result $item
}
}
return $result
}
x{return true}
是字符串、列表、字典还是lambda术语(匿名进程的正确名称)
事实上,这可能是他们所有人;可以正确地说,它是上述任何类型的成员的值。你需要更精确、更明确地描述你的意图,而不是把它隐藏在某种类型的魔法中。通过使用像-s
这样的选项或通过不同的主命令名,可以实现更高的精度,但这两种方法都是必需的。你不能正确和安全地做你想做的事
再深入一点… 所有Tcl值都是有效的字符串 列表具有已定义的语法,并且是字符串的正确子类型。(它们在内部的实现方式不同,但您应该忽略这些细节。) 字典的语法相当于具有偶数个元素的列表,其中偶数索引处的元素彼此都是唯一的 Lambda术语是包含两个或三个元素的列表(第三个元素是上下文名称空间的名称,如果没有,则默认为全局名称空间)。列表的第一个元素也必须是有效的列表 两元素列表符合上述所有要求。在Tcl的实际类型逻辑中,它同时满足上述所有要求。一个特定的值实例化可能有一个特定的实现表示,但这是一个暂时的东西,不能反映值的真实类型
Tcl的类型系统与许多其他语言的类型系统不同。没错,我想知道是否有人有一种聪明的方式来表示lambda术语有这个功能,但list/dict/string没有。我看到的唯一的电位差是λlen=2或3。如果是3,我可以假设lambda,因为我实际上只接受dict或string。但是如果它的len=2,我唯一能想到的就是查看第一个组件(args),并检查它是否大于1,如果大于1,则很可能是一个lambda或一个有空格的dict键。最后,我得出了同样的结论,但我想看看是否有人更聪明。。。