Maxima/函数
对于数学函数,始终使用
define()
而不是
:=
它们之间只有一个微小的差异
"函数定义运算符。f(x_1, ..., x_n) := expr 定义了一个名为 f 的函数,它具有参数 x_1, …, x_n 和函数体 expr。 := 从不评估函数体(除非通过引号-引号 '' 显式评估)。"
"定义一个名为 f 的函数,它具有参数 x_1, …, x_n 和函数体 expr。define 始终评估其第二个参数(除非显式引号)。 "[1]
"return 在 Maxima 中的含义与在其他编程语言中的含义不同。它只意味着从块中返回一个值;对于您在这里需要的内容来说,这还不够。" Robert Dodier[2]
如果您希望从函数内部的某个表达式中返回,那么您必须使用块和返回。
block ([], expr1, ..., if (a > 10) then return(a), ..., exprn)
本身就是一个表达式,因此可以代替函数定义的右侧。这里可能发生的是,返回发生在最后一个表达式之前。
block ([x], expr1, ..., exprn)
块中的第一个 [],可以包含变量和变量赋值列表,例如 [a: 3, b, c: []],这会导致三个变量 a、b 和 c 不引用其全局值,而是具有这些特殊值,只要代码在块内部执行,或者在从块内部调用的函数中执行。这称为动态绑定,因为变量从块开始到退出时有效。从块返回或退出块后,将恢复变量的旧值(如果有)。用这种方式保护您的变量肯定是一个好主意。请注意,块变量中的赋值是并行完成的。这意味着,如果您在上面使用了 c: a,则 c 的值将是您刚刚进入块时 a 的值,但在 a 绑定之前。因此,执行类似的操作
block ([a: a], expr1, ... a: a+3, ..., exprn)
将保护 a 的外部值不被更改,但可以让您访问该值是什么。因此,赋值的右侧在进入上下文之前进行评估,在任何绑定发生之前。仅使用 block ([x], ...) 会导致 x 具有其自身的值,就像您进入一个新的 Maxima 会话一样。
另请参见 Darren Irvine 的描述[3]
- "modedeclare 语句对于编译代码很重要
- 编译可以极大地提高数值代码的速度;对于大多数符号代码来说,速度提高并不大。
- 编译代码和未编译代码之间存在一些差异 - 请小心。" Barton Willis[4]
"mode_declare 告诉编译器编译后的代码不需要通用到足以处理所有类型的对象。如果您的函数只接受浮点数,而不是符号参数,则编译后的代码可能会运行得快得多。" Gunter Königsmann