为什么 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
如果我打开 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