417 votes

Est fonctionnelle programmation GUI possible?

J'ai récemment pris la FP bug (en essayant d'apprendre Haskell), et j'ai été vraiment impressionné par ce que j'ai vu jusqu'à présent (le premier de la classe des fonctions, évaluation différée, et tous les autres goodies). Je ne suis pas expert, mais j'ai déjà commencé à trouver plus facile de raison "fonctionnellement" que impérative pour les algorithmes de base (et je vais avoir de la difficulté à aller en arrière, là où j'ai).

Le seul domaine où pc actuel semble tomber à plat, cependant, est la programmation GUI. Le Haskell approche semble être à juste envelopper impératif kits graphiques (tels que GTK+ ou wxWidgets) et d'utiliser "faire" des blocs de simuler un impératif de style. Je n'ai pas utilisé le F#, mais ma compréhension est qu'il fait quelque chose de semblable à l'aide de la programmation orientée objet avec .NET classes. Évidemment, il y a une bonne raison pour cela-courant de la programmation GUI est tout au sujet de IO et des effets secondaires, de manière purement fonctionnelle, la programmation n'est pas possible avec la plupart des cadres actuels.

Ma question est, est-il possible d'avoir une approche fonctionnelle de la programmation GUI? J'ai du mal à imaginer à quoi cela pourrait ressembler dans la pratique. Personne ne sait de cadres, expérimentale ou autre, essayez ce genre de chose (ou même des cadres qui sont conçus à partir du sol pour un langage fonctionnel)? Ou est la solution d'utiliser une approche hybride, avec la programmation orientée objet pour la GUI pièces et FP pour la logique? (Je demande juste par curiosité--j'aimerais penser que FP est "l'avenir", mais la programmation GUI semble être un assez grand trou à combler.)

189voto

Don Stewart Points 94361

Le Haskell approche semble être à juste envelopper impératif kits graphiques (tels que GTK+ ou wxWidgets) et d'utiliser "faire" des blocs de simuler un impératif de style

Ce n'est pas vraiment le "Haskell approche" -- c'est juste la façon dont vous lier à l'impératif kits graphiques les plus directement, en passant par un impératif de l'interface. Haskell arrive juste à avoir assez dominante liaisons.

Il y a plusieurs modérément matures, ou plus expérimental purement fonctionnelle/déclarative approches pour les Interfaces graphiques, principalement en Haskell, et principalement à l'aide fonctionnel réactif de programmation.

Un exemple est

Pour ceux d'entre vous qui ne connaissent pas Haskell, Flapjax, http://www.flapjax-lang.org/ la mise en oeuvre de la fonctionnelle de réactif de programmation sur le dessus de JavaScript.

75voto

Edward Kmett Points 18369

Ma question est, est-il possible d'avoir une approche fonctionnelle de la programmation GUI?

Les mots clés sont "fonctionnel réactif de programmation" (FRP).

Conal Elliott et quelques autres l'ont fait un peu une industrie artisanale de essayer de trouver la bonne abstraction de PRF. Il existe plusieurs implémentations de PRF concepts en Haskell.

Vous pourriez envisager de commencer avec Conal les plus récents de "Push-Pull Fonctionnel Réactif de Programmation" de papier, mais il ya plusieurs autres (les plus âgés) des implémentations, dont certains sont liés à partir de la haskell.org site. Conal a un talent pour couvrir l'ensemble du domaine, et son livre peut être lu sans référence à ce qui est venu avant.

Pour avoir une idée de la façon dont cette approche peut être utilisée pour le développement du GUI, vous voudrez peut-être regarder à Fudgets, qui, même s'il est un peu long dans la dent ces jours-ci, en cours de conception dans le milieu des années 90, constitue un solide PRF approche de l'interface graphique de conception.

63voto

Tomas Petricek Points 118959

Windows Presentation Foundation est une preuve que l'approche fonctionnelle fonctionne très bien pour l'interface de programmation. Il a de nombreux aspects fonctionnels et le "bon" code WPF (recherche de pattern MVVM) met l'accent sur l'approche fonctionnelle plus impératif. Je pourrais courageusement prétendre que WPF est la plus réussie dans le monde réel fonctionnelle GUI toolkit :-)

WPF décrit l'interface Utilisateur dans le code XAML (bien que vous pouvez réécrire à fonctionnellement à la recherche de C# et F# trop), afin de créer de l'interface utilisateur, on peut écrire:

<!-- Declarative user interface in WPF and XAML --> 
<Canvas Background="Black">
   <Ellipse x:Name="greenEllipse" Width="75" Height="75" 
      Canvas.Left="0" Canvas.Top="0" Fill="LightGreen" />
</Canvas>

En outre, WPF permet également de décrire de manière déclarative des animations et des réactions à des événements à l'aide d'un autre ensemble de déclaratif des balises (encore une fois, la même chose peut être écrite comme C#/F# code):

<DoubleAnimation
   Storyboard.TargetName="greenEllipse" 
   Storyboard.TargetProperty="(Canvas.Left)"
   From="0.0" To="100.0" Duration="0:0:5" />

En fait, je pense que WPF a beaucoup de choses en commun avec Haskell PRF (même si je crois que WPF concepteurs ne savais pas à propos de PRF et c'est un peu malheureux, WPF se sent parfois un peu bizarre et difficile de savoir si vous êtes en utilisant le point de vue fonctionnel).

29voto

Tomas Petricek Points 118959

En fait, je peux dire que la programmation fonctionnelle (F#) est bien meilleur outil pour l'utilisateur de l'interface de programmation que par exemple C#. Vous avez juste besoin de réfléchir sur le problème un peu différemment.

Je discuter de ce sujet dans ma programmation fonctionnelle livre dans le Chapitre 16, mais il y a un extrait gratuit disponible, ce qui montre (à mon humble avis) la plus intéressante des modèles que vous pouvez utiliser en F#. Dites que vous voulez mettre en œuvre le dessin des rectangles (de l'utilisateur appuie sur le bouton, déplace la souris et relâche le bouton). En F#, vous pouvez écrire quelque chose comme ceci:

let rec drawingLoop(clr, from) = async { 
   // Wait for the first MouseMove occurrence 
   let! move = Async.AwaitObservable(form.MouseMove) 
   if (move.Button &&& MouseButtons.Left) = MouseButtons.Left then 
      // Refresh the window & continue looping 
      drawRectangle(clr, from, (move.X, move.Y)) 
      return! drawingLoop(clr, from) 
   else
      // Return the end position of rectangle 
      return (move.X, move.Y) } 

let waitingLoop() = async { 
   while true do
      // Wait until the user starts drawing next rectangle
      let! down = Async.AwaitObservable(form.MouseDown) 
      let downPos = (down.X, down.Y) 
      if (down.Button &&& MouseButtons.Left) = MouseButtons.Left then 
         // Wait for the end point of the rectangle
         let! upPos = drawingLoop(Color.IndianRed, downPos) 
         do printfn "Drawn rectangle (%A, %A)" downPos upPos }

C'est un très impératif approche (dans l'habitude pragmatique F# style), mais il évite d'utiliser des mutable état pour le stockage de l'état actuel de dessin et de stocker un premier emplacement. Il peut être encore, plus fonctionnel, si, j'ai écrit une bibliothèque qui n'est que dans le cadre de mon mémoire de Maîtrise, qui devrait être disponible sur mon blog dans les prochains jours.

Fonctionnel Réactif de Programmation est une approche plus fonctionnelle, mais je trouve cela un peu plus difficile à utiliser car elle repose sur très avancée, Haskell fonctionnalités (telles que des flèches). Cependant, il est très élégant dans un grand nombre de cas. C'est la limitation est que vous ne pouvez pas encoder facilement une machine d'état (qui est une utile modèle mental réactif programmes). C'est très facile en utilisant le F# technique ci-dessus.

17voto

sblom Points 15074

Si vous êtes un hybride fonctionnelle/OO de la langue comme F# ou OCaml, ou dans un but purement fonctionnel de la langue comme Haskell où les effets secondaires sont relégués à l'IO monade, c'est surtout le cas qu'une tonne de travail nécessaires pour gérer une interface graphique beaucoup plus comme un "effet secondaire" que comme un point de vue purement fonctionnel de l'algorithme.

Cela dit, il y a eu quelques vraiment solide de recherche mis en fonctionnelle des Interfaces graphiques. Il y a même certains (la plupart) fonctionnelles, boîtes à outils tels que Fudgets ou FranTk.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X