Osc*_*Ryz 21 oop programming-languages functional-programming smalltalk
随着对函数式编程语言的兴趣,我看到了Smalltalk和FPL之间的一些相似之处,即闭包(Smalltalk中的BlockClosures)然而,Smalltalk不是FPL?
需要考虑什么呢?
mis*_*tor 27
功能编程语言没有公认的定义.
如果将函数语言定义为支持第一类函数的语言,那么是的,Smalltalk*是一种函数式语言.
如果您还考虑支持不变性,代数数据类型,模式匹配,部分应用等因素,那么不,Smalltalk*不是*函数式语言.
我建议您阅读以下相关博客文章(以及下面的评论):
Fra*_*rar 22
Smalltalk可能不是一种"纯粹的功能语言"(无论可能是什么).但是,Smalltalk的自然使用通常会产生功能代码.(我猜Scala人会称之为"对象功能".)
例如,Squeak的Point类有一个功能API:像1@1 translateBy: 1@1返回新状态的方法,而不是改变内部状态.(这使得Point几乎不可变,因为改变对象内部状态的唯一方法是通过#instVarAt:等反射机制.)
在Smalltalk中使用更高阶函数(如地图,滤镜,折叠等)是很正常的.鉴于将这些内容融入Collections API,编写以功能性方式使用Collections的代码通常更容易.
很多人对"函数式编程语言"的定义如此之多,以至于"Foo a FPL"这个问题就像"Foo是面向对象的语言"一样无用.
话虽如此,这是我的两分钱:函数式编程语言是一种使用函数技术自然而惯用的语言:一流函数,避免可变状态,无副作用函数,高阶函数.
通过该描述,Smalltalk是一种函数式编程语言.它根据是否命名或匿名调用一阶函数"方法"或"块".对象在实例变量中存储状态.高阶函数是将块作为参数的简单方法.
话虽如此,是的,你可以用非功能性方式编写Smalltalk.它确实允许可变状态.这会阻止Smalltalk被称为功能语言吗?如果是这样,这些语言都不起作用:Common Lisp,Erlang(通过进程字典共享状态,ets/dets).
因此,简而言之,Smalltalk是一个FPL,因为:
和Smalltalk不是FPL,因为:
(有些Smalltalks显然支持不可变对象.我的经验仅限于Squeak,它不支持VM级别的不变性.)
编辑:除了通过在对象上定义方法之外,我不理解igouy对命名函数定义的需求.但无论如何,我们走了:
Smalltalk at: #func put: [:x | x + 1].
func value: 1.
Run Code Online (Sandbox Code Playgroud)
小智 13
使用面向对象的范例进行编程是通过识别问题域实体并将其建模为对象来创建程序,然后使它们在它们之间协作以解决每个问题实例.使用Functional范例进行编程是将问题建模为一个数学问题,并创建一个数学函数(通过编写其他函数),为每个问题实例计算问题解决方案.
在我看来,函数式编程语言是一种语言,它为使用函数式编程范例解决的问题提供了解决方案,该语言可以完全按照它的想法表达该解决方案.如果您需要"转换"解决方案的某些部分以使其适合语言可以表达的内容,那么它并不完全支持您用于思考解决方案的范例.
Smalltalk在大多数情况下可以表达使用面向对象编程范例创建的所有解决方案,但它无法原始地表达使用功能编程范例创建的许多解决方案.这就是为什么我不认为它是一个FPL.尽管不能原始地表达FPL可以提供的每个解决方案,但Smalltalk极其可扩展,您可以扩展它以表达FPL可以提供的所有解决方案.
Smalltalk是一种纯粹的面向对象语言,几乎所有代码基本上都是交换消息的对象.函数式编程面向函数调用,以及函数之间的组合以创建更复杂的行为(避免数据的状态,而不是对象在任何面向对象语言中具有的内部状态).
通过命名函数,语言不会成为函数式语言 - 按照这个定义,C将是有用的!更重要的是数学意义上的功能语义,结果仅取决于参数(特别是:没有副作用).通过这个定义,可以通过setter修改的对象与函数式编程风格相反.但是,正如已经指出的那样,如果禁止副作用,偶数对象也可以用于函数样式(Rectangle示例).而且,顺便说一句.在具有方法的对象和一组函数之间存在二元性,这些函数在私有状态的闭包中定义(有关详细信息,请参阅SICP).他们可以相互模拟:
(def (make_foo initVal1 ... initValN)
(let ((instVar1 initVal1) ... (instVarN initValN))
(define (method1 args) ...)
...
(define (methodN args) ...)
(define (lookup selector)
(cond ((eq? selector 'method1) method1)
...
((eq? selector 'methodN) methodN)
(true doesNotUnderstandCode)))
lookup)) ; returns the lookup function (provides "access into the closure") !
(defMacro (method1 receiver.args)
((receiver selector) args))
(define foo (make_foo 1 2 ...))
(method1 foo ...)
Run Code Online (Sandbox Code Playgroud)
以上是模拟"纯"功能对象,并且在语义上与很多Smalltalk代码相同!但是,要实现setter方法,必须添加一个方法(set!instVar newValue).并且,因为设置!是无功能的,打破了该计划的"功能".
总结:看看语义,而不是源,卢克!