先上张代码的图吧!
FriCAS 虽然是从 AXIOM 这门古董级语言中 fork 出来的一个分支,目前仍处在活跃开发期,但是很多功能仍然缺失,尤其是:调试的功能基!本!没!有!
有些时候,这门语言很灵活,例如:变量没有声明类型也可以使用;有些时候又严格得要命,例如:函数的参数必须是指定类型,你一个函数,
以 Expression(Integer)
为参数,给它传个 Integer
类型的变量,就不认了!必须要先转换成 Expression(Integer)
才可以。
所以,写个程序非常蛋疼。。。
编写程序的时候出了不少问题,错误信息有时候非常令人迷惑,例如:
-
这个错误信息:
Error detected within library code: (1 . failed) cannot be coerced to mode (Expression (Integer))
不是说你传递的参数类型有问题,而八成是你的代码中对类型的处理不够谨慎:例如 Ring
中的 exquo
运算
(消去运算),会返回一个 Union
类型的变量:要么成功了,得到这个环中的元素,要么失败了,返回一个
字符串 “failed”
。所以,不要以为消去一下,就直接可以用了,还要顾及到有可能返回的是字符串,这时候
需要这样:
(a exquo b) case "failed" => "failed"
表示直接返回字符串 “failed”
. 或者,
(a exquo b) case "failed" => error "Through some error message..."
哦,会报这个错误的另一个原因就是这个 exquo
函数,在命令行中你可以写
exquo(a,b)
但在 spad
文件中却不行,必须要写成二元运算的样子
(a exquo b)
-
这样的错误:
******** Spad syntax error detected ******** Expected: BACKTAB The prior line was: 129> “^":(%,I) -> Union(%, “failed”) The current line is: 136> fracStream (%, R, I, NNI, %) -> SC
出错原因,一定是你 129 附近的哪行类型处理不当,或者少写括号了等等。了如,我在这里犯下的错误就是 fracStream
后面少了冒号
- 最后,貌似一切的错误,类型转换都已经处理到了,但是还是不行,一运行就死在那了,原因是:我在 delay 里用了这样的递归调用:假设
foo: (param1,...) -> Stream(R)
在函数体里面,用了延迟运算和递归:
delay
concat(foo(param1,...),b)
这里的问题是:每次函数被调用的时候,都会先去运行 foo
,然后在 foo
返回 Stream(R)
类型的值后,再和元素 b
合并。可是 foo
并没有终止条件,每次先运行 foo
, 就算已经用延迟计算 delay
了,也会陷入无休止的循环。正确的做法(我不知道为什么这样),只要把 b
放前面就行了 (囧)。。。
好吧!无论如何经过两天的努力,耐心的在命令行里逐步运行代码,所有的错误都已经基本解决了。当然还有一些细节需要处理,但总算是迈出了里程碑式的一步!