user-interface - gui - scilab uicontrol




La programmation GUI fonctionnelle est-elle possible? (10)

J'ai récemment attrapé le virus FP (en essayant d'apprendre Haskell), et j'ai été vraiment impressionné par ce que j'ai vu jusqu'ici (fonctions de première classe, évaluation paresseuse, et tous les autres goodies). Je ne suis pas encore un expert, mais j'ai déjà commencé à trouver qu'il est plus facile de raisonner "fonctionnellement" qu'imparfaitement pour les algorithmes de base (et j'ai du mal à revenir là où je dois).

Cependant, le seul domaine dans lequel le FP actuel semble se stabiliser est la programmation GUI. L'approche de Haskell semble consister simplement à emballer les boîtes à outils à interface graphique impérative (telles que GTK + ou wxWidgets) et à utiliser des blocs «à faire» pour simuler un style impératif. Je n'ai pas utilisé F #, mais je crois comprendre qu'il fait quelque chose de similaire en utilisant la POO avec les classes .NET. Évidemment, il y a une bonne raison à cela - la programmation actuelle de l'interface graphique concerne les E / S et les effets secondaires, donc la programmation purement fonctionnelle n'est pas possible avec la plupart des frameworks actuels.

Ma question est, est-il possible d'avoir une approche fonctionnelle de la programmation GUI? J'ai du mal à imaginer à quoi cela ressemblerait en pratique. Est-ce que quelqu'un connaît des frameworks, expérimentaux ou non, qui essayent ce genre de chose (ou même des frameworks conçus à partir de zéro pour un langage fonctionnel)? Ou est la solution d'utiliser simplement une approche hybride, avec OOP pour les parties GUI et FP pour la logique? (Je demande juste par curiosité - j'aimerais penser que FP est «l'avenir», mais la programmation de GUI semble être un trou assez grand à remplir.)


L'approche de Haskell semble être de simplement encapsuler les toolkits obligatoires de l'interface graphique (tels que GTK + ou wxWidgets) et d'utiliser des blocs "do" pour simuler un style impératif.

Ce n'est pas vraiment "l'approche Haskell" - c'est exactement la manière dont vous liez directement les toolkits graphiques impératifs - via une interface impérative. Haskell a justement des reliures assez proéminentes.

Il existe plusieurs approches purement fonctionnelles / déclaratives, modérément matures ou plus expérimentales, pour les interfaces graphiques, principalement dans Haskell, et utilisant principalement la programmation réactive fonctionnelle.

Un exemple est

Pour ceux d'entre vous qui ne connaissent pas Haskell, Flapjax, http://www.flapjax-lang.org/ est une implémentation de la programmation réactive fonctionnelle sur JavaScript.


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

Les mots clés que vous recherchez sont «programmation réactive fonctionnelle» (PRF).

Conal Elliott et quelques autres ont fait un peu d'industrie artisanale pour essayer de trouver la bonne abstraction pour FRP. Il existe plusieurs implémentations de concepts FRP dans Haskell.

Vous pourriez envisager de commencer avec le plus récent document «Concevoir-Reactive Functional Reactive Programming» de Conal, mais il existe plusieurs autres implémentations (plus anciennes), dont certaines sont liées au site haskell.org . Conal a un talent pour couvrir l'ensemble du domaine, et son document peut être lu sans référence à ce qui précède.

Pour avoir une idée de la façon dont cette approche peut être utilisée pour le développement de l'interface graphique, vous pouvez regarder Fudgets , qui, même s'il est un peu long dans la dent ces jours-ci, étant conçu au milieu des années 90, présente une approche FRP solide à la conception de GUI.


En 2016, il existe plusieurs autres frameworks FRP relativement matures pour Haskell tels que Sodium et Reflex (mais aussi Netwire).

Le livre de Manning sur la programmation réactive fonctionnelle présente la version Java de Sodium, pour des exemples de travail, et illustre comment une base de code d'interface graphique FRP se comporte et évolue par rapport aux approches impératives et basées sur les acteurs.

Il y a aussi un article récent sur le FRP Arrowized et la perspective d'incorporer les effets secondaires, les IO et la mutation dans un contexte de FRP pur et respectueux de la loi: haskell.cs.yale.edu/wp-content/uploads/2015/10/… .

Il convient également de noter que les frameworks JavaScript tels que ReactJS et Angular et bien d'autres sont déjà en train d'utiliser une approche FRP ou fonctionnelle pour obtenir des composants GUI évolutifs et composables.


Je dirais en fait que la programmation fonctionnelle (F #) est un outil bien meilleur pour la programmation de l'interface utilisateur que par exemple C #. Vous avez juste besoin de penser au problème un peu différemment.

Je discute de ce sujet dans mon livre de programmation fonctionnelle au chapitre 16, mais il y a un extrait gratuit disponible , qui montre (IMHO) le motif le plus intéressant que vous pouvez utiliser dans F #. Supposons que vous souhaitiez implémenter le dessin de rectangles (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 une approche très impérative (dans le style F # pragmatique habituel), mais elle évite d'utiliser l'état mutable pour stocker l'état actuel du dessin et pour mémoriser l'emplacement initial. Cela peut être rendu encore plus fonctionnel, j'ai écrit une bibliothèque qui fait cela dans le cadre de ma thèse de maîtrise, qui devrait être disponible sur mon blog dans les prochains jours.

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


La programmation fonctionnelle a peut-être évolué depuis que j'étais à l'université, mais si je me souviens bien le point principal d'un système de programmation fonctionnel était d'empêcher le programmeur de créer un "effet secondaire". Cependant, les utilisateurs achètent un logiciel en raison des effets secondaires qui sont créés, par exemple la mise à jour d'une interface utilisateur.


Le discours d'Elliot sur le PRF peut être trouvé here .

En outre, pas vraiment une réponse mais une remarque et quelques réflexions : en quelque sorte le terme «interface graphique fonctionnelle» semble un peu comme un oxymore (pureté et IO dans le même terme).

Mais ma compréhension approximative est que la programmation GUI fonctionnelle consiste à définir de manière déclarative une fonction dépendante du temps qui prend l'entrée utilisateur (réelle) dépendant du temps et produit une sortie GUI dépendant du temps.

En d'autres termes, cette fonction est définie comme une équation différentielle déclarative, au lieu de par un algorithme utilisant impérativement un état mutable.

Ainsi, dans le FP conventionnel, on utilise des fonctions indépendantes du temps, alors que dans le PRF, on utilise des fonctions dépendant du temps comme des blocs de construction pour décrire un programme.

Pensons à simuler une balle sur un ressort avec lequel l'utilisateur peut interagir. La position de la balle est la sortie graphique (sur l'écran), l'utilisateur poussant la balle est une pression de touche (entrée).

La description de ce programme de simulation en PRF (selon ma compréhension) se fait par une seule équation différentielle (déclarative): accélération * masse = - étirement du ressort * constante du ressort + Force exercée par l'utilisateur.

Voici une vidéo sur ELM qui illustre ce point de vue.


Pour résoudre ce problème, j'ai posté quelques réflexions sur l'utilisation de F #,

http://fadsworld.wordpress.com/2011/04/13/f-in-the-enterprise-i/ http://fadsworld.wordpress.com/2011/04/17/fin-the-enterprise-ii- 2 /

Je prévois également de faire un didacticiel vidéo pour terminer la série et montrer comment F # peut contribuer à la programmation UX.

Je parle seulement dans le contexte de F # ici.

-Fahad


Que vous soyez dans un langage hybride fonctionnel / OO comme F # ou OCaml, ou dans un langage purement fonctionnel comme Haskell où les effets secondaires sont relégués à la monade IO, c'est surtout le cas d'une tonne de travail nécessaire pour gérer une interface graphique est beaucoup plus comme un "effet secondaire" que comme un algorithme purement fonctionnel.

Cela dit, il y a eu des recherches vraiment solides dans les interfaces graphiques fonctionnelles . Il existe même des kits d'outils (principalement) fonctionnels tels que Fudgets ou FranTk .


Une des idées d'ouverture d'esprit derrière Functional Reactive Programming est d'avoir une fonction de gestion d'événement produisant à la fois la réaction aux événements ET la fonction de gestion des événements suivante. Ainsi, un système en évolution est représenté sous la forme d'une séquence de fonctions de gestion d'événements.

Pour moi, l'apprentissage de Yampa est devenu un poing crucial pour obtenir correctement cette fonction fonctions-production-fonctions. Il y a de beaux articles sur Yampa. Je recommande The Yampa Arcade:

http://www.cs.nott.ac.uk/~nhn/Talks/HW2003-YampaArcade.pdf (diapositives, PDF) http://www.cs.nott.ac.uk/~nhn/Publications/hw2003.pdf (article complet, PDF)

Il y a une page wiki sur Yampa sur Haskell.org

http://www.haskell.org/haskellwiki/Yampa

Page d'accueil originale de Yampa:

http://www.haskell.org/yampa (malheureusement est cassé en ce moment)






functional-programming