Mathematica是一种无类型的语言吗?

时间:2010-12-29 23:20:45

标签: types wolfram-mathematica

与大多数编程语言不同,Mathematica中的每个值都是一个表达式。对任何表达式应用任何操作总会产生另一个表达式因此,Mathematica实际上只有一种类型。 Mathematica没有静态类型检查,可以说,甚至不动态检查类型(在运行时)。

例如,将整数表达式1添加到Mathematica中的字符串表达式"foo"会导致(无意义)表达式1 + "foo"但没有错误。在其他情况下,Mathematica提供有关无意义输入的反馈,但生成此反馈的检查必须由程序员明确执行。

因此,将Mathematica描述为无类型语言而不是静态或动态类型语言是否公平?

5 个答案:

答案 0 :(得分:17)

而不是“类型”, Mathematica 具有的是“头部”的概念,其中任何 Mathematica 表达式都拥有一个。这符合他们的"everything is an expression" paradigm

可以通过函数FullForm[]Head[]来查看 Mathematica 表达式的结构。例如,Head[3]返回IntegerHead[2/3]返回RationalHead[I]返回ComplexHead[.3]返回RealHead[a]返回Symbol(假设您尚未将任何分配给a),Head["a"]会返回String,{{1 }}返回Head[{2}] ...我相信你已经明白了这个想法。

这样做的好处在于,人们可以编写函数,使得他们只能接受特定头部的参数。例如:

List

discussion模式应该为您提供有关如何设置函数的建议,使其仅适用于具有特定磁头或磁头组的对象。

答案 1 :(得分:6)

如果我们将短语“静态类型化”和“动态类型化”视为术语,指的是当语言检查操作对类型的有效性时,那么我认为使用术语“无类型”来表征Mathematica是公平的。感觉它“从不”检查操作是否对某个类型有效。

然而,我确实喜欢Belisarius使用术语“类型不可知”。我这样说是因为虽然语言中的几乎所有类型检查都是惯用的(即由程序员而不是语言实现),但是将操作符应用于键入的操作数的概念也是如此!

考虑1 + "foo"的“荒谬”示例。我认为可以公平地说,所有Mathematica用户的很大一部分(接近统一)会因为他们第一次学习语言而绊倒这样的案例。当一个人用C语言编写代码时,这个问题就特别明显了。在Mathematica圈子里,有很多关于如何处理这些情况的讨论。

另一方面,这种弱点也是Mathematica最大的优势。 Mathematica针对创建新标记进行了优化。很多很多符号都有+的概念,其行为与基本算术中的加法非常相似。在构建这样的符号时,如果Mathematica介入并抱怨+的操作数不是数字,那将非常不方便。在Mathematica的这种更高级别的应用中,“荒谬”的例子不仅“感性”,而且实际上至关重要。

因此,考虑到这一点,类型问题经常没有实际意义。因此,我喜欢Belisarius'“类型不可知”的表征。向我推荐,我做了;)

修改

在区分“无类型”和“类型不可知”时,我会尝试澄清我的想法。

阅读各种答案和评论,我试图弄清楚Mathematica和LISP之间的区别。后者通常被视为“动态类型”的一个例子,尽管核心LISP评估器非常像Mathematica,几乎没有任何类型检查。我们在LISP程序中看到的类型错误主要由(通常是内置的)函数中的硬编码检查发出。例如,+只会接受数字参数,即使评估者本身也不会关心这种方式。话虽如此,LISP编程的“感觉”与Mathematica的“感觉”(至少对我而言)有很大不同。 1 + "foo"示例确实捕获了这种差异。

虽然我普遍同意“无类型”作为Mathematica的特征,但我仍然觉得缺少了某些东西。汇编程序对我来说似乎是无类型的,就像早期的FORTRAN和ANSI之前的版本一样。在这些情况下,参数的位模式都是重要的,如果我传递一个需要整数的字符串参数,程序将继续轻快地继续。 Mathematica肯定会分享这种无关紧要的行为。但是有一个区别:在汇编程序和FORTRAN和C中,缺乏类型检查导致良好结果的情况极为罕见。正如我上面提到的,在Mathematica中,依靠这种行为是可能的,有时甚至是常见的。

输入“类型不可知”。我喜欢它的非承诺立场,听起来不像“无类型”那样激烈。我觉得它反映了Mathematica的基本无类型特性,但为那些能够支持LISP惯用类型检查的语言特征,动态风格(即“头部”习语和支持功能)留下了一些摆动空间。

因此,简而言之,我觉得Mathematica在完全无类型和动态类型之间徘徊。 “类型不可知”为我捕获了这种情绪。 YMMV:)

我欣然承认,没有人可能只是通过检查短语“无类型”和“类型不可知”来重建我在此回复中所写的任何内容。我再次强调,我认为“无类型”是对Mathematica的公平表征,但我也喜欢这样一个事实,即“类型不可知”引发了对这个SO问题的各种回答所解决的许多问题。

答案 2 :(得分:5)

Mathematica确实有一些类型,它是动态的。您有StringIntegerRealComplexListSymbol类型。您可以通过执行类似

的操作来创建仅在一种类型上运行的函数

f[x_Integer]:=x+1

创建一个只对整数运算的函数。

Mathematica严重依赖于模式和替代;这些类型在我看来似乎是另一种帮助你开发模式的方法。在1 + "foo"的情况下,没有模式来评估添加到字符串的数字,因此结果只是表达式本身。在1 + 2的情况下,有一种模式可以添加数字并进行评估。 Mathematica的模式和替换规则可能要复杂得多,如果您感兴趣,最好阅读一本书。

答案 3 :(得分:4)

更多来自实际的,而不是理论方面的东西,我相信你可能会说Mathematica比无类型更类型无关。

此外,您可以使用类似(非常基本的示例如下)之类的内容轻松构建类型化的子语言:

Unprotect[Set]; 

Set[a, x_] := If[Element[x, Integers], x, 0, 0];  

然后尝试:

a = 1; (*runs ok*) 

a = "caca"  (*assigns zero to a*)

修改

此外,您可以将用户定义的类型构造为命名模式,并在重新定义上面的设置时使用它们,而不是整数。
类型组合应该以相同的方式工作。

答案 4 :(得分:4)

答案简短:无类型或无类型。这就是Wolfram Research自己描述产品的方式。 See here.

答案很长: 乔恩,我认为你的问题真的取决于你的无名的意思。为了吸引Wikipedia的权威资源“相反,无类型语言(如大多数汇编语言)允许对任何数据执行任何操作,这些数据通常被认为是各种长度的位序列。 “

阅读之前的答案,辩论的核心似乎是类型检查器在遇到错误时应该怎么做。通常的答案是停止评估并报告某种错误。从Stackoverflow上的几个早期问题(1)(2),我们可以看到Mathematica没有一种优雅的内置方法。 (我想补充一点,在版本8中更加强调编译为C,可以编写类型检查代码,但我不确定这是否应该算作主要语言的一部分。)