Pourquoi smalltalk n'est-il pas un langage de programmation fonctionnel?

Avec l'intérêt renouvelé pour les langages de programmation fonctionnels, j'ai vu des similitudes entre Smalltalk et FPL, à savoir des fermetures ( BlockClosures dans Smalltalk ) encore, Smalltalk n'est pas un FPL?

Que faudrait-il pour le considérer comme tel?

21
demandé sur OscarRyz 2010-08-20 06:26:23

9 réponses

La programmation avec le paradigme orienté objet crée un programme en identifiant et en modélisant les entités de domaine problématiques en tant qu'objets, puis en les faisant collaborer entre elles pour résoudre chaque instance de problème. La programmation avec le paradigme fonctionnel modélise le problème en tant que problème mathématique et crée une fonction mathématique (en composant d'autres fonctions) qui, pour chaque instance de problème, calcule la solution du problème.

, À mon avis, une programmation fonctionnelle le langage est un langage qui a donné une solution à un problème résolu en utilisant le paradigme de programmation fonctionnelle, le langage peut exprimer cette solution exactement comme on le pensait. Si vous avez besoin de" transformer " une partie de votre solution afin qu'elle corresponde à ce que le langage peut exprimer, alors il ne supporte pas complètement le paradigme que vous avez utilisé pour penser la solution.

Smalltalk peut exprimer dans la plupart des cas toutes les solutions créées en utilisant le paradigme de programmation orienté objet, mais il ne peut pas exprimer primitivement beaucoup de solutions créées en utilisant le paradigme de programmation fonctionnelle. C'est pourquoi je ne le considère pas comme un FPL. Bien que ne pas être primitivement capable d'exprimer chaque solution qu'un FPL peut, Smalltalk est extrêmement extensible, et vous pouvez l'étendre pour être en mesure d'exprimer toutes les solutions QU'un FPL peut.

12
répondu Diego Geffner 2010-08-20 13:41:00

Il n'y a pas de définition acceptée du langage de programmation fonctionnel.

Si vous définissez le langage fonctionnel comme le langage qui prend en charge les fonctions de première classe, alors oui, Smalltalk *est* un langage fonctionnel.

Si vous considérez également les facteurs comme le support de l'immuabilité, les types de données algébriques, la correspondance de modèles, l'application partielle, etc. alors non, Smalltalk *n'est pas* un langage fonctionnel.


Je vous encourage à lire les articles de blog connexes suivants (et aussi les commentaires ci-dessous):

27
répondu missingfaktor 2010-08-20 05:08:09

Smalltalk pourrait ne pas être un "langage fonctionnel pur" (quoi que ce soit). Cependant, l'utilisation naturelle de Smalltalk entraîne souvent un code fonctionnel. (Ce que je suppose que les gens de Scala appelleraient "objet-fonctionnel".)

Par exemple, la classe point de Squeak a une API fonctionnelle: des méthodes comme 1@1 translateBy: 1@1 renvoient de nouveaux Points avec le nouvel état, au lieu de muter l'état interne. (Cela rend le Point pratiquement immuable, puisque la seule façon de changer l'état interne de l'objet est à travers mécanismes de réflexion comme # instVarAt:.)

Il est tout à fait normal d'utiliser des fonctions d'ordre supérieur dans Smalltalk comme des cartes, des filtres, des plis, etc. Étant donné que ceux-ci sont intégrés dans L'API Collections, il est souvent plus facile d'écrire du code qui utilise des Collections de manière fonctionnelle qu'autrement.

Tant de gens ont tellement de définitions de "langage de programmation fonctionnel" que la question "est Foo un FPL" est aussi inutile qu'une question à poser que "est Foo un objet orienté langue".

Cela dit, Voici mes deux cents: un langage de programmation fonctionnel est un langage dans lequel il est naturel et idiomatique d'employer des techniques fonctionnelles: fonctions de première classe, évitement de l'état mutable, fonctions libres d'effets secondaires, fonctions d'ordre supérieur.

Par cette description, Smalltalk est un langage de programmation fonctionnel. Il appelle les fonctions de premier ordre "méthodes" ou "blocs" selon qu'elles sont nommées ou anonymes. Objet stocker l'état dans les variables d'instance. Les fonctions d'ordre supérieur sont simplement des méthodes qui prennent des blocs comme paramètres.

Cela dit, oui, vous pouvez écrire Smalltalk d'une manière non fonctionnelle. Il permet un état mutable. Est-ce que cela empêche Smalltalk d'être appelé un langage fonctionnel? Si c'est le cas, ces langages ne sont pas non plus fonctionnels: Common Lisp, Erlang (état partagé via le dictionnaire de processus, ets/dets).

Donc, en bref, Smalltalk est un FPL parce que:

  • les fonctions sont des entités de première classe (objets, dans Smalltalk-CompiledMethods ou BlockClosures, pour être précis).
  • Smalltalk supporte les fermetures (il les appelle des blocs).
  • Smalltalk permet d'écrire fonctionnellement de manière naturelle et idiomatique.

Et Smalltalk n'est pas un FPL parce que:

  • en tant que programmeur, vous devez vous assurer que vos structures de données (objets) sont immuables (en faisant renvoyer des copies par des setters / mutators de l'objet avec l'état muté).
  • en tant que programmeur, vous devez vous assurer que vos méthodes (fonctions) sont sans effet secondaire.

(Certains Smalltalks supportent apparemment des objets immuables. Mon expérience est limitée à Squeak, qui ne prend pas en charge l'immuabilité au niveau de la machine virtuelle.)

Edit: Je ne comprends pas le besoin d'igouy pour des définitions de fonctions nommées autres que par la définition de méthodes sur un objet. Mais de toute façon, nous y voilà:

Smalltalk at: #func put: [:x | x + 1].
func value: 1.
22
répondu Frank Shearar 2010-08-24 10:43:15

Smalltalk est un langage purement orienté objet, où presque tout le code est essentiellement des objets échangeant des messages. La programmation fonctionnelle est orientée vers les appels de fonction, et les compositions entre les fonctions pour créer un comportement plus complexe (en évitant l'État pour les données, par opposition aux États internes que les objets ont dans n'importe quel langage orienté objet).

7
répondu Manuel Aráoz 2010-08-20 02:31:07

Les langages purement fonctionnels ont généralement des variables immuables, ce qui les rend plus semblables aux variables dans un sens mathématique.

5
répondu Matthew Schinckel 2010-08-20 02:36:31

Une langue ne devient pas un langage fonctionnel en ayant des fonctions nommées par cette définition, C serait fonctionnel ! Plus important est la sémantique fonctionnelle au sens mathématique, que le résultat dépend des arguments seuls (en particulier: pas d'effets secondaires). Par cette définition, les objets qui peuvent être modifiés par des setters sont contraires à un style de programmation fonctionnel. Cependant, comme déjà souligné, même les objets peuvent être utilisés dans un style fonctionnel (exemple de Rectangle) si vous interdire effets secondaires. Et, btw. il y a une dualité entre les objets avec des méthodes et un ensemble de fonctions qui sont définies dans une fermeture sur un État privé (voir SICP pour plus de détails). Ils peuvent se simuler mutuellement:

(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 ...)

Ce qui précède est une simulation d'objets fonctionnels "purs", et sémantiquement le même que beaucoup de code Smalltalk! Cependant, pour implémenter une méthode setter, vous devez ajouter une méthode qui fait un (set! instVar newValue). Et, parce que mis en! est non fonctionnel, casse le "fonctionnalité" du régime.

Résumé: regardez la sémantique, pas la source, luke !

5
répondu blabla999 2010-08-23 12:25:41

Merci à tous pour toutes les réponses.

Je vais ajouter le mien ici qui est fondamentalement ma (probablement manquer) compréhension de la vôtre.

Je pense que le critère pour appeler quelque chose OO ou FP est qu'ils "stuff" est construit en utilisant le langage; pas comment facile ou difficile est de le faire, je veux dire, le paradigme mental utilisé.

Par exemple, comme le montrent les liens, il peut être plus difficile de taper quelque chose dans Scala que dans OCaml, mais cela ne le rend pas moins FPL (peut-être incomplet ou impur, mais définitivement fonctionnel); parce que le but de Scala est d'utiliser des fonctions comme blocs de construction primaires, plutôt que des objets.

D'un autre côté, faciliter l'écriture d'une fonction dans une langue ne la rend pas fonctionnelle, si le style ou le but est d'utiliser d'autres artefacts. Smalltalk par exemple, il est très facile d'écrire un bloc anonyme ou de fournir un comparateur de tri enfichable, mais cela ne le rend pas fonctionnel du tout, car l'objectif est d'utiliser des objets et de transmettre des messages. Les Blockclosures sont juste un mécanisme pour encoder ces messages ( pas des fonctions ) même s'ils ressemblent à des fonctions.

La confusion vient, parce que OO et FP sont orthogonaux ( comme Rahul a déclaré via twitter ) , donc, ce qu'il ressemble à un message codé dans Smalltalk, ressemble à peu près à une fonction anonyme dans Scala. Mais faire quelque chose de similaire ne convertit pas un langage d'un paradigme en un autre.

Pour le rendre pire, Scala utilise également le OO paradigme, pour le rendre plus facile pour les programmeurs traditionnels ( Java, C++, C#) de donner le saut, et si vous voyez, il a eu beaucoup plus de succès que n'importe lequel des autres FPL. Et bien sûr, cela a été merci à Java (à mon humble avis Si Clojure a un succès sera exactement pour la même raison, la JVM)

En conclusion: un langage de programmation peut être classé par le paradigme qu'il utilise pour construire des "choses". Il y a des langages qui sont purs comme [Smalltalk : OO, Haskell: Functional, C: Procédure], ou hybrides, comme Scala ou multi-paradigme , comme C++, Ruby, Python.

Le fait que vous puissiez écrire un style avec l'autre langue n'en fait pas la langue de ce style. Comme Simuler des objets avec Lisp ne le rend pas OO, ni l'utilisation de fonctions avec Java le rend fonctionnel.

Pour répondre à la question, pour être considéré comme fonctionnel, Smalltalk devrait utiliser des fonctions comme blocs de construction, ce qui n'est pas le cas car il utilise des objets.

2
répondu OscarRyz 2017-05-23 12:17:36

J'ai vu quelques similitudes entre Smalltalk et FPL, à savoir les fermetures

Il y a une similitude plus basique - chaque message Smalltalk renvoie toujours une valeur.

Mais maintenant, regardez les principes de conception derrière Smalltalk

[Smalltalk] envoie le nom du opération désirée, avec tout arguments, comme un message au numéro, avec la compréhension que l' récepteur sait mieux comment effectuer souhaité opération.

Est-ce que cela décrit ce que vous pensez de la programmation fonctionnelle?

@ Frank Shearar-qui décrit Erlang trop. Erlang est-il maintenant non fonctionnel?

Erlang est quelque chose d'une chimère-la programmation séquentielle est basée sur des fonctions, mais la programmation simultanée est basée sur le passage de messages entre les processus. Donc Erlang n'est pas multi paradigme ou hybride de la manière dont d'autres langages permettent d'utiliser des styles différents pour atteindre le même objectif - il utilise différents styles à des fins différentes.

1
répondu igouy 2010-08-25 01:20:40

Qu'est-ce qui serait nécessaire pour le considérer comme de cette façon?

  • Un moyen de déclarer des fonctions plutôt qu'un moyen de déclarer des méthodes dans une classe

  • Une façon de structurer un programme autour des fonctions plutôt qu'autour des objets

@ Missing Faktor - mais func dans cet exemple n'est-il pas nommé la fonction?

|func v|
func := [:x | x + 1].
v := func value: 5.

Pas de func est une variable locale. Vous avez lié une fonction anonyme à la variable locale func.

|func v|
func := [:x | x + 1].
func := 2.
v := func value: 5.

Pour voir la différence, regardez cet exemple D'Erlang qui montre à la fois une fonction anonyme et une fonction nommée.

0
répondu igouy 2010-08-22 17:30:56