适合Lisp和Haskell。
我是认真的。
=============
下面认真答题。
首先我认为这个问题没有意思。因为,学会一门语言不是目标,计算机语言只是实现我们想法的手段。所以,没有适合学哪一门语言,只有我们需要哪一门语言。所以,这个问题就相当于,我是广东人,适合学俄语还是法语,答案是,看你想去俄国还是法国。
所以我回答的问题,其实是“数学好在学哪一门语言时更有优势”或者“哪一门语言中数学比较重要”。这里我没有限定在Java和C++,因为可能是题主暂时只知道Java和C++,但其实应该不介意了解更多语言。
当然,如果题中数学好指的是高中数学成绩好,或者说“初等代数”好,那确实“学程序语言和数学没关系”。但这样也至少说明对数学有兴趣,很有可能对抽象代数继续有兴趣,那也还是有意义的。
那么,我的答案是Lisp和Haskell,当然还包括其他functional语言。我这里保留的functional的英文,没有说是“函数式语言”,不是装逼,是因为这个词,在数学里有另外一个广为人知名字:“泛函”。(不过下面我直接说函数式语言了跟顺口一点。。。。)
之所以说数学好学函数式语言更有优势。是因为1)相较其他语言,函数式语言和数学“更像”,2)函数式语言更依赖数学。
说函数式语言和数学更像,最基本的就是“函数”。要注意,虽然都叫函数,但是其实二者是完全不一样的。数学中的函数是一个从定义域到值域的映射,而计算机语言中的“函数”至少包括两个意思:procedure和function(Pascal中就是分开的两个概念,呃。。。说出Pascal是不是就等于暴露了OI历史。。。),function还可以粗略的等于从参数的空间到返回值的空间的映射关系,但procedure完全就是程序跳转到另一个位置去执行,和“函数”这个东西基本没有任何关系。而在学C的时候,我们叫着函数,却基本都把它理解成procedure。既是是有输入有输出的函数,还有和数学中函数的一个最大的不同:确定性,或者说,副作用。
一般来说,数学中的函数是一个从定义域到值域的确定的映射关系。换言之,确定的输入总产生确定的输出。但是过程式语言中这一点完全无法保证,例如允许对函数外的变量进行修改。而纯函数式语言中通常要求函数保证无副作用(比如通过强制变量不可变),这样保证了语言中函数和数学中的函数的一致性。
再举个可能不太恰当的例子:在纯函数语言中,通常变量不可变。于是,困惑了无数小白的诸如“a=a+1”这样违背数学常识的语句也不太可能出现了。
因为语言中的函数和数学中的函数统一了,递归这个概念也好理解多了。因为递归不再是“一段代码调用本身”这么拗口的概念,就是数学中的递归定义或者递推公式而已。
再者,配合函数式语言中常见的模式匹配,函数式语言仅仅是“看上去”,也更像数学。比如Erlang中实现斐波那契数列:
fib(0)->1;
fib(1)->1;
fib(N)->fib(N-1)+fib(N-2)
基本就是数学定义。
然后,泛函。数学上,泛函通常是指定义域为函数的函数,而函数式语言中,函数是first-class的,即和普通变量一样,函数可以操作函数。看,又和数学统一了。使用函数式语言,完全就是从数学的角度看问题了。这种操作在C和Java中不能直接实现。当然,C可以使用指向函数的指针,Java通常借助一个接口。但这样,都是从机器的角度思考,或者从面向对象的角度思考,而不是从数学的角度思考。
另外,学习函数式语言也确实需要数学基础。
过程式语言,包面向对象语言等等,都可以用图灵机来理解,但是函数式编程则不然,理解好函数式编程你需要理解lambda演算,然后不可避免需要形式系统的推理和证明,这些还真的需要数学基础。而Haskell更进一步,即使不碰monad,至少需要集合论的知识甚至部分泛函(向量空间)的知识,而如果涉及到monad,没有抽象代数和范畴论的概念基本很难真正理解。(是的我要承认我还没有真正理解)
综上,如果数学好,“适合”学函数式语言,而我所举的,是其中两个典型。另外有人提到clojure,我认为clojure可以视为Lisp的一种方言。其他推荐学习的函数式语言包括Erlang和OCaml。
然后再来回答一下原来的问题,如果以后会搞计算机,那这两门语言都跳不过去,但是两者选其一,建议先学Java,因为C++太复杂(抱歉我是C++黑,不争论)。但是,更建议C和Lisp。
学C,推荐的教程只有一本:《C程序设计语言》,作者K&R,不要去看任何其他的书。
学Lisp,推荐的教程也不用多说:《计算机程序的构造和解释》。
然后,虽然我大部分时间会使用Python,但我坚决不同意一个专业的程序员从Python入门。虽然Python上手很快,但是无益于理解计算机的运作方式,也无益于理解程序的数学本质。当然,Python是个好语言,(Perl?哈哈哈哈,逃~)。
说这么多,不是表达Lisp和Haskell比Java和C++高端,或者Java和C++是inferior languages。C/Java/C++应用比函数式语言广泛毋庸置疑,而函数式语言学习的更大好处其实是学习其中的思想不是为了工程应用(大多数情况下,Lisp在人工智能领域应用很广)。数学和机器都是计算机的一部分,对机器感兴趣,就去学C,学体系,对数学感兴趣,就去学Lisp,学计算理论,最后会发现,殊途同归。只不过,选择一样的时候,记得对另一样保持好奇心。
计算机很好玩的!!!!!我们不要再(让别人乱)黑了好不好!!!!!
最后,也别全信《黑客与画家》,那就是一本Lisp软文集。。
嗯哼~
— 完 —
本文作者:tefx
【知乎日报】
你都看到这啦,快来点我嘛 Σ(▼□▼メ)
此问题还有 8 个回答,查看全部。
延伸阅读:
零基础学编程,VB / Java / C / C# / C++ 等哪个更容易上手?
2012 年的年度编程语言会是 C#、Java,还是 Objective-C ?为什么?