与大多数编程语言不同,Mathematica中的每个值都是一个表达式。对任何表达式应用任何操作总会产生另一个表达式因此,Mathematica实际上只有一种类型。 Mathematica没有静态类型检查,可以说,甚至不动态检查类型(在运行时)。
例如,将整数表达式1
添加到Mathematica中的字符串表达式"foo"
会导致(无意义)表达式1 + "foo"
但没有错误。在其他情况下,Mathematica提供有关无意义输入的反馈,但生成此反馈的检查必须由程序员明确执行。
因此,将Mathematica描述为无类型语言而不是静态或动态类型语言是否公平?
答案 0 :(得分:17)
而不是“类型”, Mathematica 具有的是“头部”的概念,其中任何 Mathematica 表达式都拥有一个。这符合他们的"everything is an expression" paradigm。
可以通过函数FullForm[]
和Head[]
来查看 Mathematica 表达式的结构。例如,Head[3]
返回Integer
,Head[2/3]
返回Rational
,Head[I]
返回Complex
,Head[.3]
返回Real
,Head[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确实有一些类型,它是动态的。您有String
,Integer
,Real
,Complex
,List
和Symbol
类型。您可以通过执行类似
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,可以编写类型检查代码,但我不确定这是否应该算作主要语言的一部分。)