为什么smalltalk不是函数式编程语言?

Osc*_*Ryz 21 oop programming-languages functional-programming smalltalk

随着对函数式编程语言的兴趣,我看到了Smalltalk和FPL之间的一些相似之处,即闭包(Smalltalk中的BlockClosures)然而,Smalltalk不是FPL?

需要考虑什么呢?

mis*_*tor 27

功能编程语言没有公认的定义.

如果将函数语言定义为支持第一类函数的语言,那么是的,Smalltalk*是一种函数式语言.

如果您还考虑支持不变性,代数数据类型,模式匹配,部分应用等因素,那么不,Smalltalk*不是*函数式语言.


我建议您阅读以下相关博客文章(以及下面的评论):

  • 实际上,Smalltalk是一种几乎功能齐全的语言.Smalltalk有一些扩展,提供功能模式匹配,例如http://map.squeak.org/package/3772b420-ba02-4fbd-ae30-8eadfc323b7b.此外,Newspeak(http://newspeaklanguage.org/)是Self和Smalltalk传统中的一种编程语言,它支持不可变性作为其核心概念之一. (3认同)
  • @ AngelO'Sphere,我非常熟悉一流的功能.(Scala和Haskell是我的主要语言.)感谢您对该术语的无端解释.现在:拥有顶级课程是*正交*具有一流的功能.Scala,Smalltalk和许多其他人都有这两个特征.或者你现在要用"必须支持顶级功能定义"来修改你的定义吗? (3认同)

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中 - 准确地说是CompiledMethods或BlockClosures).
  • Smalltalk支持闭包(它称为块).
  • Smalltalk允许用户以自然,惯用的方式进行功能性写作.

Smalltalk不是FPL,因为:

  • 作为程序员,您必须确保您的数据结构(对象)是不可变的(通过让setter/mutators返回具有变异状态的对象的副本).
  • 作为程序员,您必须确保您的方法(函数)没有副作用.

(有些Smalltalks显然支持不可变对象.我的经验仅限于Squeak,它不支持VM级别的不变性.)

编辑:除了通过在对象上定义方法之外,我不理解igouy对命名函数定义的需求.但无论如何,我们走了:

Smalltalk at: #func put: [:x | x + 1].
func value: 1.
Run Code Online (Sandbox Code Playgroud)

  • 在Smalltalk中,程序被组织成对象,但是在函数式编程语言中,程序被组织成函数.我们在OOP和FP中如何构建程序有一个很好理解和根本的区别.有关示例,请参阅"合成面向对象和功能设计以促进重用"http://www.cs.brown.edu/~sk/Publications/Papers/Published/kff-synth-fp-oo/ (3认同)
  • @igouy:"组织成对象"并不是反对Smalltalk不是函数式语言的论据.请参阅Common Lisp(特别是CLOS).你说"对象",我说"一组函数在同一种结构上工作,在它们自己的命名空间中." (2认同)

小智 13

使用面向对象的范例进行编程是通过识别问题域实体并将其建模为对象来创建程序,然后使它们在它们之间协作以解决每个问题实例.使用Functional范例进行编程是将问题建模为一个数学问题,并创建一个数学函数(通过编写其他函数),为每个问题实例计算问题解决方案.

在我看来,函数式编程语言是一种语言,它为使用函数式编程范例解决的问题提供了解决方案,该语言可以完全按照它的想法表达该解决方案.如果您需要"转换"解决方案的某些部分以使其适合语言可以表达的内容,那么它并不完全支持您用于思考解决方案的范例.

Smalltalk在大多数情况下可以表达使用面向对象编程范例创建的所有解决方案,但它无法原始地表达使用功能编程范例创建的许多解决方案.这就是为什么我不认为它是一个FPL.尽管不能原始地表达FPL可以提供的每个解决方案,但Smalltalk极其可扩展,您可以扩展它以表达FPL可以提供的所有解决方案.

  • 虽然这是一个旧线程,但我对这里提出的OO的定义提出异议.OO只是以交换消息和封装状态的实体形式表达程序; 直接"建模"问题域,因为对象不进入定义,而是 - IMO - 是一种工具甚至是技巧.从这个意义上说,功能程序可以看作是封装零状态的实体,并通过非常简单的消息进行交互("应用").这将使功能模型成为OO的子集. (5认同)
  • 您能列举一些Smalltalk无法“原始”表达的FPL例子吗? (2认同)

Man*_*áoz 7

Smalltalk是一种纯粹的面向对象语言,几乎所有代码基本上都是交换消息的对象.函数式编程面向函数调用,以及函数之间的组合以创建更复杂的行为(避免数据的状态,而不是对象在任何面向对象语言中具有的内部状态).

  • 好吧,"几乎所有"都不是"1"或"a:= b"之类的表达.此外,功能的组合正是我所说的"小型自然在Smalltalk中功能性写入".内部状态(实例变量的集合)与外部定义的结构相同.就像CONS细胞一样.或者一个清单.或者是一个hashmap.(重要的条件:你实际上已经以函数的方式在类上编写了方法,比如我给出的Point类示例.) (3认同)

Mat*_*kel 5

纯函数式语言通常具有不可变变量,使它们更像数学意义上的变量.


bla*_*999 5

通过命名函数,语言不会成为函数式语言 - 按照这个定义,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).并且,因为设置!是无功能的,打破了该计划的"功能".

总结:看看语义,而不是源,卢克!

  • 冷静下来:让我们尝试定义一些我们都同意的共同基础:1)功能风格是使用无副作用的功能; 2)功能语言是功能风格是最自然或首选的做事方式.这使得lisp成为一种功能语言,虽然它支持非功能操作(例如set!)和对象(clos或类似).这也使Smalltalk成为一种非功能性语言,尽管它也支持所有功能性的东西.3)你可以用lisp编程oo风格,也可以用smalltalk编写功能风格 (3认同)