Io 语言解释器和文件执行之间的不同行为

Io language different behavior between interpreter and file execution

我正在尝试用 Io 语言创建一个新的运算符,但是当我检查我使用解释器和文件执行的工作时,我注意到了不同的行为:

## Executing nand.io
##########################
OperatorTable addOperator("nand", 10)
true nand := method(bool, if(bool, false, true))
false nand := method(bool, true)

true nand false println        # => false
true nand true println         # => true
false nand false println       # => false
false nand true println        # => true

# Why does this print 'true' (it should be 'false')?
(true nand true) println      # => true

# I noticed that the argument to nand is always printed
true nand "not" println        # => not
true nand "what" println       # => what
false nand "I" println         # => I
false nand "expected" println  # => expected

# Another sanity check. I thought this might have to do with println behaving
# oddly, but this conditional really does return true
if(true nand true, "This should not print" println, "This should print" println)
# => This should not print

# More unexpected behavior
false nand := method(arg, "foo")
false nand "bar" println       # => "bar"

true nand := method(arg, "foo")
true nand "bar" println        # => "bar"

false nand := "Why is this not returned?"
false nand "aaaaahhhh" println # => "aaaaahhhh"



## Ran in the io interpreter
###############################
OperatorTable addOperator("nand", 10)
true nand := method(bool, if(bool, false, true))
false nand := method(bool, true)

# Same as file execution when sent to println
true nand false println   # => false
true nand true println    # => true
false nand false println  # => false
false nand true println   # => true

# It acually does what's expected here
true nand false           # => true
true nand true            # => false    -- It works here!!!
false nand false          # => true
false nand true           # => true

if(true nand true, "This should not print" println, "This should print" println)
# => This should print

也许这需要编译和解释?这实际上是预期的行为吗,也许我遗漏了有关该语言的一些基本知识(我今天才开始学习 Io)?

好的,这与 VM 解析运算符的方式有关。文件的第一遍将遍历并重写它已经知道的任何运算符,重写与作为优先级提供的数字相关的消息。然后第二遍将执行修改后的消息树。因此,当您在稍后通过 VM 传递的文件中将新运算符添加到运算符 table 时,您的新运算符将仅可用于之后加载的任何文件或模块。对于从该文件生成的消息树的生命周期,您的操作员不存在。

基本上这里的经验法则是维护一个单独的 operators.io 文件,和你的主 io 文件分开;然后确保 operators.io 在 main.io 之前加载,您就大功告成了。

CLI 没有这个问题的原因是它会一条一条地评估消息。也就是说,您输入的下一条消息将具有新的运算符 st