web-dev-qa-db-fra.com

Quelle langue apprendre après Haskell?

En tant que premier langage de programmation, j'ai décidé d'apprendre Haskell. Je suis majeur en philosophie analytique, et Haskell m'a permis de créer rapidement et correctement des programmes d'intérêt, par exemple, des transducteurs pour l'analyse syntaxique du langage naturel, des prouveurs de théorèmes et des interprètes. Bien que je ne programme que depuis deux mois et demi, j'ai trouvé la sémantique et la syntaxe de Haskell beaucoup plus faciles à apprendre que les langages impératifs plus traditionnels, et je me sens à l'aise (maintenant) avec la majorité de ses constructions.

La programmation à Haskell, c'est comme de la sorcellerie, et j'aimerais élargir mes connaissances en programmation. Je voudrais choisir un nouveau langage de programmation à apprendre, mais je n'ai pas assez de temps pour choisir un langage arbitraire, le supprimer et répéter. J'ai donc pensé poser la question ici, ainsi que plusieurs stipulations sur le type de langue que je recherche. Certains sont subjectifs, certains sont destinés à faciliter la transition de Haskell.

  • Système de type fort. L'une de mes parties préférées de la programmation dans Haskell est l'écriture de déclarations de type. Cela aide à structurer mes réflexions sur les fonctions individuelles et leur relation avec le programme dans son ensemble. Cela facilite également le raisonnement informel sur l'exactitude de mon programme. Je m'intéresse à l'exactitude, pas à l'efficacité.
  • Accent sur la récursivité plutôt que sur l'itération. J'utilise des constructions itératives dans Haskell, mais les implémente récursivement. Cependant, il est beaucoup plus facile de comprendre la structure d'une fonction récursive qu'une procédure itérative compliquée, en particulier lors de l'utilisation de combinateurs et de fonctions d'ordre supérieur comme les cartes, les plis et la liaison.
  • Récompenser pour apprendre. Haskell est une langue enrichissante dans laquelle travailler. C'est un peu comme lire Kant. Mon expérience il y a plusieurs années avec C, cependant, ne l'était pas. Je ne cherche pas C. Le langage devrait imposer un paradigme conceptuellement intéressant, ce qui, à mon avis entièrement subjectif, ne plaît pas aux C-likes.

Pesant les réponses: Ce ne sont bien sûr que des notes. Je voudrais juste répondre à tous ceux qui ont donné des réponses bien formées. Vous avez été très utile.

1) Plusieurs réponses ont indiqué qu'un langage fort, typé statiquement mettant l'accent sur la récursivité, signifie un autre langage fonctionnel. Bien que je veuille continuer à travailler fortement avec Haskell, camccann et larsmans ont correctement souligné qu'un autre langage de ce type "faciliterait trop la transition". Ces commentaires ont été très utiles, car je ne cherche pas à écrire Haskell in Caml! Parmi les assistants de preuve, Coq et Agda semblent tous les deux intéressants. En particulier, Coq fournirait une solide introduction à la logique constructive et à la théorie des types formels. J'ai passé un peu de temps avec les prédicats de premier ordre et la logique modale (Mendellsohn, Enderton, certains de Hinman), donc je m'amuserais probablement beaucoup avec Coq.

2) D'autres ont fortement favorisé le LISP (LISP commun, Scheme et Clojure). D'après ce que je comprends, Common LISP et Scheme ont un excellent matériel d'introduction ( Sur LISP et The Reasoned Schemer , [~ # ~] sicp [~ # ~] ). Le contenu de [~ # ~] sicp [~ # ~] me fait pencher vers Scheme. En particulier, Scheme through [~ # ~] sicp [~ # ~] couvrirait une stratégie d'évaluation différente, la mise en œuvre de la paresse et une chance de se concentrer sur des sujets comme les continuations, les interprètes, le calcul symbolique, etc. Enfin, comme d'autres l'ont souligné, le traitement par LISP du code/des données serait entièrement nouveau. Par conséquent, je penche fortement vers l'option (2), un LISP.

3) Troisièmement, Prolog. Prolog a une richesse de matériel intéressant, et son domaine principal est exactement celui qui m'intéresse. Il a une syntaxe simple et est facile à lire . Je ne peux pas en dire plus pour le moment, mais après avoir lu un aperçu de Prolog et parcouru du matériel d'introduction, il se classe avec (2). Et il semble que le retour en arrière de Prolog soit toujours piraté dans Haskell!

4) Parmi les langages traditionnels, Python semble le plus intéressant. Tim Yates rend les langues très attrayantes. Apparemment, Python est souvent enseigné en première année) CS majors, donc c'est conceptuellement riche ou facile à apprendre, il faudrait que je fasse plus de recherche.

Merci à tous pour vos recommandations! Il ressemble à un LISP (Scheme, Clojure), Prolog, ou un assistant de preuve comme Coq ou Agda sont les principaux langages recommandés.

85
danportin

J'aimerais élargir mes connaissances en programmation. (...) J'ai pensé poser la question ici, ainsi que plusieurs stipulations sur le type de langue que je recherche. Certains sont subjectifs, certains sont destinés à faciliter la transition de Haskell.

Système de type fort. (...) Cela facilite également le raisonnement informel sur l'exactitude de mon programme. Je m'intéresse à l'exactitude, pas à l'efficacité.

Accent sur la récursivité plutôt que sur l'itération. (...)

Vous pouvez peut-être trop faciliter la transition ici, je le crains. Le système de type très strict et le style purement fonctionnel sont caractéristiques de Haskell et à peu près tout ce qui ressemble à un langage de programmation traditionnel nécessitera des compromis au moins quelque peu sur l'un d'entre eux. Donc, dans cet esprit, voici quelques suggestions générales visant à conserver la plupart de ce que vous semblez aimer à propos de Haskell, mais avec un changement majeur.

  • Ignorez l'aspect pratique et optez pour "plus de Haskell que de Haskell": Le système de type de Haskell est plein de trous, en raison de la non-terminaison et d'autres compromis désordonnés. Nettoyez le gâchis et ajoutez des fonctionnalités plus puissantes et vous obtenez des langues comme Coq et Agda, où le type d'une fonction contient une preuve de son exactitude (vous pouvez même lire la flèche de la fonction -> comme implication logique!). Ces langages ont été utilisés pour les preuves mathématiques et pour les programmes avec des exigences de correction extrêmement élevées. Coq est probablement le langage le plus important du style, mais Agda a une sensation plus Haskell-y (en plus d'être écrit en Haskell lui-même).

  • Ignorez les types, ajoutez plus de magie: Si Haskell est de la sorcellerie, LISP est la magie brute et primitive de la création. Les langages de la famille LISP (incluant également Scheme et Clojure) ont une flexibilité presque sans précédent combinée à un minimalisme extrême. Les langages n'ont essentiellement pas de syntaxe, écrivant du code directement sous la forme d'une structure de données arborescente; la métaprogrammation dans un LISP est plus facile que la programmation non méta dans certains langages.

  • Compromis un peu et rapproche-toi du courant dominant: Haskell appartient à la grande famille des langages fortement influencés par le ML, dont vous pourriez probablement aussi vous passer sans aussi beaucoup de difficulté. Haskell est l'une des plus strictes en ce qui concerne les garanties d'exactitude des types et de l'utilisation du style fonctionnel, où d'autres sont souvent des styles hybrides et/ou font des compromis pragmatiques pour diverses raisons. Si vous souhaitez vous familiariser avec OOP et accéder à de nombreuses plates-formes technologiques traditionnelles, Scala sur la JVM ou F # sur .NET ont beaucoup en commun avec Haskell tout en offrant une interopérabilité facile avec les plates-formes Java et .NET. F # est pris en charge directement par Microsoft, mais a quelques limitations gênantes par rapport à Haskell et les problèmes de portabilité sur les plates-formes non Windows . Scala a des homologues directs à plus du système de type de Haskell et du potentiel multiplateforme de Java, mais a une syntaxe plus lourde et ne dispose pas de la prise en charge première puissante dont bénéficie F #.

La plupart de ces recommandations sont également mentionnées dans d'autres réponses, mais j'espère que ma justification pour celles-ci offre des éclaircissements.

85
C. A. McCann

Je vais être That Guy et suggérer que vous demandez la mauvaise chose.

Vous dites d'abord que vous souhaitez élargir vos horizons. Ensuite, vous décrivez le type de langage que vous voulez, et ses horizons sonnent incroyablement comme les horizons que vous avez déjà. Vous n'allez pas gagner beaucoup en apprenant la même chose encore et encore.

Je vous suggère d'apprendre un LISP - c'est-à-dire LISP commun, Scheme/Racket ou Clojure. Ils sont tous typés dynamiquement par défaut, mais comportent une sorte d'indication de type ou une saisie statique facultative. Raquette et Clojure sont probablement vos meilleurs paris.

Clojure est plus récent et a plus d'haskellismes comme l'immuabilité par défaut et beaucoup d'évaluation paresseuse, mais il est basé sur la machine virtuelle Java Java, ce qui signifie qu'il a des verrues impaires) (Par exemple, la JVM ne prend pas en charge l'élimination des appels de queue, donc la récursivité est une sorte de hack).

Racket est beaucoup plus ancien, mais a pris beaucoup de puissance en cours de route, comme la prise en charge des types statiques et l'accent mis sur la programmation fonctionnelle. Je pense que vous tirerez probablement le meilleur parti de Racket.

Les systèmes de macro de Lisps sont très intéressants et beaucoup plus puissants que tout ce que vous verrez ailleurs. Rien que cela vaut au moins le coup d'oeil.

20
Chuck

Du point de vue de ce qui convient à votre majeur, le choix évident ressemble à un langage logique tel que Prolog ou ses dérivés. La programmation logique peut être effectuée très soigneusement dans un langage fonctionnel (voir, par exemple The Reasoned Schemer ), mais vous pourriez aimer travailler directement avec le paradigme logique.

Un système de preuve de théorème interactif tel que twelf ou coq pourrait également vous intéresser.

19
sclv

Je vous conseille d'apprendre Coq , qui est un assistant de preuve puissant avec une syntaxe qui sera confortable pour le programmeur Haskell. La chose intéressante à propos de Coq est qu'il peut être extrait vers d'autres langages fonctionnels, y compris Haskell. Il y a même un package ( Meldable-Heap ) sur Hackage qui a été écrit en Coq, avait des propriétés prouvées sur son fonctionnement, puis extrait vers Haskell.

Un autre langage populaire qui offre plus de puissance que Haskell est Agda - Je ne connais pas Agda au-delà de savoir qu'il est typé de manière dépendante, sur Hackage, et bien respecté par les gens que je respecte, mais ce sont de bonnes raisons pour moi.

Je ne m'attendrais pas à ce que cela soit facile. Mais si vous connaissez Haskell et souhaitez passer à un langage qui donne plus de puissance que le système de type Haskell, alors ils doivent être pris en considération.

18
Thomas M. DuBuisson

Comme vous n'avez pas mentionné de restrictions en plus de vos intérêts subjectifs et que vous insistez sur `` récompenser pour apprendre '' (eh bien, ok, j'ignorerai la restriction de frappe statique), je suggère d'apprendre quelques langues de différents paradigmes, et de préférence celles qui sont "exemplaires" pour chacun d'eux.

  • Un LISP dialecte pour le code-as-data/homoiconicity et parce qu'ils sont de bons, sinon les meilleurs, exemples de dynamiques (plus ou moins stricts) langages de programmation fonctionnels
  • Prolog comme langage de programmation logique prédominant
  • Smalltalk comme celui vrai OOP langue (également intéressant en raison de son approche généralement extrêmement centrée sur l'image)
  • peut-être Erlang ou Clojure si vous êtes intéressé par les langages forgés pour la programmation simultanée/parallèle/distribuée
  • Forth pour la programmation orientée pile
  • (Haskell pour une programmation paresseuse fonctionnelle strictement typée statiquement)

Surtout Lisps (CL pas autant que Scheme) et Prolog (et Haskell) embrassent la récursivité.

Bien que je ne sois pas un gourou dans aucune de ces langues, j'ai passé du temps avec chacune d'elles, sauf Erlang et Forth, et elles m'ont toutes donné des expériences d'apprentissage intéressantes et révélatrices, car chacune aborde la résolution de problèmes sous un angle différent .

Donc, même s'il peut sembler que j'ai ignoré la partie sur le fait que vous n'ayez pas le temps d'essayer quelques langues, je pense plutôt que le temps passé avec l'une d'entre elles ne sera pas perdu, et vous devriez les regarder toutes.

11
danlei

Si vous voulez un Prolog typé fort (er) ly, Mercury est un choix intéressant. J'y ai essayé par le passé et j'ai aimé la perspective différente que cela m'a donnée. Il a également une modalité (quels paramètres doivent être libres/fixes) et un déterminisme (combien de résultats y a-t-il?) Dans le système de types.

Clean est très similaire à Haskell, mais a un typage d'unicité, qui est utilisé comme une alternative aux monades (plus précisément, la monographie IO). Le typage d'unicité est également intéressant des trucs pour travailler avec des tableaux.

10
yatima2975

Que diriez-vous d'un langage de programmation orienté pile ? Cat atteint vos points forts. C'est:

  • Typé statiquement avec l'inférence de type.
  • Vous fait repenser les concepts courants des langages impératifs comme le bouclage. L'exécution conditionnelle et le bouclage sont gérés avec combinateurs .
  • Récompenser - vous oblige à comprendre un autre modèle de calcul. Vous donne une autre façon de penser et de décomposer les problèmes.

Le Dr Dobbs a publié un court article sur Cat en 2008 bien que la langue ait légèrement changé.

10
Corbin March

Je suis un peu en retard mais je vois que personne n'a mentionné quelques paradigmes et langages apparentés qui peuvent vous intéresser pour leur haut niveau d'abstraction et de généralité:

9
MaD70

Malgré son échec à répondre à l'un de vos grands critères (typage statique *), je vais plaider pour Python. Voici quelques raisons pour lesquelles je pense que vous devriez y jeter un œil:

  • Pour un langage impératif, il est étonnamment fonctionnel. C'était une des choses qui m'ont frappé quand je l'ai appris. Prenez liste des compréhensions , par exemple. Il a des lambdas, des fonctions de première classe et de nombreuses compositions d'inspiration fonctionnelle sur les itérateurs (cartes, plis, zips ...). Il vous donne la possibilité de choisir le paradigme qui convient le mieux au problème.
  • À mon humble avis, il est, comme Haskell, beau à coder. La syntaxe est simple et élégante.
  • Il a une culture qui se concentre sur la façon de faire les choses de manière simple, plutôt que de se concentrer trop minutieusement sur l'efficacité.

Je comprends si vous cherchez autre chose. La programmation logique, par exemple, pourrait vous convenir, comme d'autres l'ont suggéré.


* Je suppose que vous voulez dire ici une saisie statique, car vous voulez déclarer les types. Techniquement, Python est un langage fortement typé, car vous ne pouvez pas interpréter arbitrairement, par exemple, une chaîne comme un Fait intéressant, il existe Python dérivés qui permettent le typage statique, comme Boo .

8
Tim Yates

Compte tenu de votre description, je suggère Ocaml ou F # .

La famille ML est généralement très bonne en termes de système de type fort. L'accent mis sur la récursivité, couplé à la correspondance de motifs, est également clair.

Là où j'hésite un peu, c'est sur la partie gratifiant d'apprendre. Les apprendre a été gratifiant pour moi, sans aucun doute. Mais étant donné vos restrictions et votre description de ce que vous voulez, il semble que vous ne recherchiez pas quelque chose de bien plus différent que Haskell.

Si vous n'aviez pas mis vos restrictions j'aurais suggéré Python ou Erlang , qui vous sortiraient tous deux de votre zone de confort.

8
Muhammad Alkarouri

Je te recommanderais Erlang. Ce n'est pas un langage typé fort et vous devriez l'essayer. C'est une approche très différente de la programmation et vous pouvez trouver qu'il y a des problèmes où la frappe forte n'est pas le meilleur outil (TM). Quoi qu'il en soit, Erlang vous fournit des outils pour la vérification de type statique (typer, dialyseur) et vous pouvez utiliser une frappe forte sur les pièces où vous en tirez des avantages. Cela peut être une expérience intéressante pour vous mais préparez-vous, ce sera un sentiment très différent. Si vous recherchez un "paradigme conceptuellement intéressant", vous pouvez les trouver dans Erlang, le passage de messages, la séparation de mémoire au lieu du partage, la distribution, OTP, la gestion des erreurs et la propagation des erreurs au lieu de la "prévention" des erreurs et ainsi de suite. Erlang peut être loin de votre expérience actuelle, mais vous pouvez toujours chatouiller le cerveau si vous avez de l'expérience avec C et Haskell.

8

D'après mon expérience, une forte frappe + accent sur la récursivité signifie un autre langage de programmation fonctionnel. Là encore, je me demande si c'est très gratifiant, étant donné qu'aucun d'entre eux ne sera aussi "pur" que Haskell.

Comme d'autres affiches l'ont suggéré, Prolog et LISP/Scheme sont sympas, même si les deux sont typés dynamiquement. Beaucoup de grands livres avec un fort "goût" théorique ont été publiés sur Scheme en particulier. Jetez un oeil à SICP , qui transmet également beaucoup de sagesse informatique générale (interprètes méta-circulaires et similaires).

6
Fred Foo

Factor sera un bon choix.

6
leolao

Si vous décidez de vous éloigner de votre préférence pour un système de type, vous pourriez être intéressé par le langage de programmation J. Il est remarquable pour la façon dont il met l'accent sur la composition des fonctions. Si vous aimez le style sans point à Haskell, la forme tacite de J sera enrichissante. Je l'ai trouvé extrêmement stimulant, surtout en ce qui concerne la sémantique.

Certes, cela ne correspond pas à vos idées préconçues sur ce que vous aimeriez, mais donnez-lui un coup d'œil. Le simple fait de savoir que c'est là-bas mérite d'être découvert. La seule source d'implémentations complètes est J Software, jsoftware.com.

5
kaleidic

Vous pouvez commencer à chercher LISP .

Prolog est aussi un langage cool.

5
user454497

Excellente question - je l'ai posée moi-même récemment après avoir passé plusieurs mois à profiter pleinement de Haskell, bien que mon expérience soit très différente (chimie organique).

Comme vous, C et ses semblables sont hors de question.

J'ai oscillé entre Python et Ruby comme les deux langages de script pratiques d'aujourd'hui (mules?)) Qui ont tous deux des composants fonctionnels pour me garder Sans commencer aucun débat Rubyist/Pythonist ici, mais ma réponse pragmatique personnelle à cette question est:

Apprenez celui (Python ou Ruby) que vous obtenez d'abord une excuse à appliquer.

0
jdo

Allez avec l'un des principaux flux. Compte tenu des ressources disponibles, de la commercialisation future de vos compétences, d'un riche écosystème de développeurs, je pense que vous devriez commencer par Java ou C #.

0
Angkor Wat