为什么 Octave 允许重命名函数?

Why does Octave allow renaming of functions?

如果我打开 Octave 并执行以下操作:

a = 1:10;
sum(a)

ans = 55

但如果我这样做:

sum = 30;
sum(a)

我收到一个错误:

error: A(I): index out of bounds; value 10 out of bound 1

Octave 允许我更改单词 "sum" 指向的位置,所以现在它是一个值而不是一个函数。为什么这是允许的,我不应该得到警告 - 这不是非常危险吗?

如果我意识到我已经这样做了,如何在不关闭 Octave 和丢失我的工作区的情况下删除引用?

How, if I realise I've done this, do I remove the reference without closing octave and losing my workspace?

使用命令clear sum清除符号sum的用户定义,恢复为内置含义。 (即内置定义将不再被用户定义遮蔽。)

至于为什么 Octave 会这样工作,就得问这个开源项目的维护者了。也许是因为 Matlab 是这样工作的,而 Octave 力求尽可能兼容。

想象一下Octave不允许变量与函数相同。你在 Octave 中编写了一个程序,你有一个名为 total 的变量,它不是一个函数。一切都好。一个新的 Octave 版本问世并添加了一个名为 total 的函数。您的程序将停止工作,您将不得不重命名您的变量。这种向后不兼容的程度会更糟。而且这个问题不会仅限于新的 Octave 版本。也许您后来决定要使用 Octave 包,它带来了一整套新功能,其中一个可能会与您的变量发生冲突。

但是,在即将发布的 Octave 中,越界错误会提示变量名正在隐藏函数。在 Octave 4.2.1 中:

octave-cli-4.2.0:1> a = 1:10;
octave-cli-4.2.0:2> sum = 30;
octave-cli-4.2.0:3> sum (a)
error: sum(10): out of bound 1

在 4.3.0+ 中(哪一天会变成 4.4):

octave-cli-4.3.0+:1> a = 1:10;
octave-cli-4.3.0+:2> sum = 30;
octave-cli-4.3.0+:3> sum(a)
error: sum(10): out of bound 1 (note: variable 'sum' shadows function)

然而,真正的问题不在于变量可以隐藏函数。真正的问题是语法不允许区分变量和函数。变量索引和函数调用都使用相同的括号 ()(其他语言通常对函数使用 (),对索引变量使用 [])。即使你调用一个没有任何参数的函数,括号也是可选的:

foo(1)  # 1st element of foo?  Or is foo a function?
foo     # Is this a variable or a function call without any arguments?
foo()   # idem

此语法主要是为了实现 Matlab 兼容性,这是 GNU Octave 的目标之一。

为了解决这个缺陷,Octave 编码指南(贡献给 Octave 的代码所需的指南。Octave 解析器并不真正关心)要求函数始终使用括号并在它们和函数名称:

foo (x, y); # there is a space after foo so it must be a function
foo(x, y);  # there is no space, it is indexing a matrix
foo         # this is a variable
foo ();     # this is a function