IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> Elixir - Phoenix Live view & Hooks, Retour vers le futur
Options
Jaypee
posté 27 May 2020, 09:53
Message #1


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Bonjour,

J'ai été amené à m'intéresser à cette technologie, pour pouvoir participer à un projet dont des amis développent les aspects applicatifs, j'interviens en support technique. C'est autour du robot fermier de FarmBot, composé d'un Arduino pour la partie CNC ET d'un Raspberry pour les applications, et il se trouve que le portail d'administration et d'application intégré, Open Source, est écrit en Elixir et Phoenix.

Petit retour en arrière, vers 2004, la technologie Ruby on Rails révolutionnait le développement Web rapide, et avait permis entre autre de déployer la première version de Twitter. Son héritage est toujours présent avec l'architecture de l'application et des fichiers que beaucoup de "frameworks" de dev pour le web utilisent aujourd'hui encore. Son problème, les perfs. Un des développeurs de ce projet RoR décide de repartir sur des bases plus solides, sans renier le style de Ruby, et crée Elixir, avec comme fondation rien moins que Erlang, le langage d'Ericsson, spécialisé dans le temps réel, un vrai socle ancré dans la culture industrielle. Le langage ressemble beaucoup à Ruby, avec un parti pris de "programmation fonctionnelle", et de "pattern matching". Parmi les constructions du langage, inhabituelle mais très expressive et concise, se trouve par exemple le "cond", qui est comme un switch/case mais avec des booléens et des cas multiples, pas seulement une seule expression et les deux cas vrai ou faux. Les cas ont chacun une expression booléenne, et la première qui est évaluée à vrai, déclenche une action et la sortie de ce branchement, une manière expressive et concise de remplacer des if..then..else imbriqués. Pour les traitements l'opérateur pipe: "|>" initialement introduit par Microsoft dans F# est présent. Pour les bibliothèques, ce sont celles de Erlang qui sont interopérables, donc inutile de réinventer la roue, en plus des bibliothèques Elixir.
Et de la même manière que Rails apporte la dimension développement web à Ruby, Phoenix est la plateforme web associée à Elixir. L'idée est de laisser le serveur générer l'HTML grâce à des templates, et d'utiliser une communication rapide par websockets avec le navigateur. Récemment (< 18 mois), le Phoenix de base s'est enrichi de deux nouveaux aspects Live View (générateur d'HTML du serveur) et Hooks (pour interopérer avec JS). Et bien sûr, il existe aussi plusieurs intégrations de la techno Web Assembly de Mozilla.

Cela ressemble à un parfait premier de la classe qui coche toute les cases, avec déjà une certaine maturité, mais qui reste dans une niche. Pour les curieux quelques videos YT, pas trop longues :
- Pour ceux qui veulent rester à un haut niveau sans trop de détails, https://www.youtube.com/watch?v=yo8Y1SUGW1w
- Plus de code, mais pas trop d'explications, construction d'un "chat" persistant les messages dans Postgres : https://www.youtube.com/watch?v=ZUNzXbIP_FQ
- Gratuit avec inscription, cours d'intro à Elixir sur Udemy: https://www.udemy.com/course/elixir-program...-for-beginners/

Notez que les tutos ou formations Phoenix doivent s'aligner sur ces technos (LiveView et Hooks) récentes et tous/toutes ne le font pas.
J-P

Ce message a été modifié par Jaypee - 27 May 2020, 10:05.
Go to the top of the page
 
+Quote Post
Jaypee
posté 15 Jun 2020, 07:39
Message #2


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Un dernier élément dans ce fil, un peu à part, c'est juste pour attirer l'attention bidouilleuse qui sommeille en chacun de nous.

Il existe un environnement de dev basé sur Elixir (donc Erlang) et Phoenix, qui sert à transformer un Raspberry Pi en objet connecté, fermé, sécurisé : un système audio, une station météo etc... sans aucun outil restant au niveau de l'OS (pas de shell), qui en faciliterait l'attaque.

https://elixirschool.com/en/lessons/advanced/nerves/ (Tiens ! pas de traduction française !)

https://hexdocs.pm/nerves/getting-started.html

JP
Go to the top of the page
 
+Quote Post
Jaypee
posté 7 Aug 2020, 23:07
Message #3


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Pour compléter les infos sur ce topic:

- Il faut une connaissance pas trop approfondie de Ruby-On-Rails pour pouvoir suivre ensuite son évolution : Une formation gratuite très complète, mais avec un bémol : comme elle date de 5 ans, la mise à niveau de la plateforme pour pouvoir suivre le cours est un exercice difficile, plus difficile que le cours lui-même. Mais faisable. Avantage de ce cours, il ne demande aucune connaissance préalable. C'est en Français sur OpenClassrooms : https://openclassrooms.com/fr/courses/31491...a-ruby-on-rails
- J'ai déjà cité le cours gratuit d'Elixir sur Udemy
- Formation gratuite sur Phoenix/LiveView (le RoR d'Elixir) : Je n'ai pas fini encore, mais c'est très intéressant. Le style de programmation est moderne. Sans renoncer aux jolis effets, on reste dans un framework de haut niveau qui va s'interfacer en sous-marin avec Node, puisque qu'à aucun moment on ne code de JavaScript. L'asynchronisme est utilisé sans effort, jamais on ne parle de thread ou de futur ou de promesse, et malgré tout on va pouvoir faire apparaître des animations d'attente, pendant que les tâches s'exécutent en arrière-plan. Pour éviter la trop grande attention portée à la base de données, on travaille avec des résultats en dur dans le code. Le pattern matching est très souvent utilisé et simplifie la programmation de la logique. Au lieu d'utiliser la technique Javascript d'ajax, deux websockets sont utilisés pour synchroniser le client et le serveur avec l'échange de juste les changements. Tout ce qui n'a pas changé vient du cache.
Ça se passe sur un site privé de formation en anglais, mais c'est gratuit: https://online.pragmaticstudio.com/courses/

Voilà, pour les curieux qui voudraient varier un peu les plaisirs pour s'intéresser à Ruby/Erlang/Elixir plutôt que les sempiternels Python ou JavaScript et PHP. Que ce soit OpenClassRooms ou Pragmatic Studio, dans les deux cas, la formation est bien construite
: on suit un chemin bien balisé qui mène à une bonne compréhension, après visionnage de présentations en video et TP, mains sur le clavier, des sujets abordés.

Si ça peut aider ou inspirer...
J-P

Ce message a été modifié par Jaypee - 7 Aug 2020, 23:18.
Go to the top of the page
 
+Quote Post
Jaypee
posté 8 Aug 2020, 09:06
Message #4


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Un petit exemple simple de code Elixir pour avoir une idée du style général. Ce n'est pas le parfum vanille le plus simple, c'est un peu avec supplément Chantilly et noisettes smile.gif
Code
# fichier factorielle.exs
defmodule Factorielle do
  def de(n) when n > 0 do
    fact0(n, 1)
  end    
  defp fact0(1, accumulateur) do
    accumulateur
  end
  defp fact0(n, accumulateur) do
    fact0(n - 1, n * accumulateur)
  end
end
{nombre, _} = IO.gets("Saisir un nombre entier positif : ") |> Integer.parse
IO.puts("#{nombre}! vaut #{Factorielle.de nombre}")

Exemple d'exécution :
Code
jaypee@MacMini2018JP Elixir % elixir factorielle.exs
Saisir un nombre entier positif : 100
100! vaut 93326215443944152681699238856266700490715968264381621468592963895217599993229915
608941463976156518286253697920827223758251185210916864000000000000000000000000

On voit que les fonctions qui s'appuient sur la bibliothèque standard Erlang/OTP ont une signature du type : {résultat, status} = fonction(x, y, z), si on veut ignorer le status on utilise le souligné. Cela correspond aux types Option<type> qu'on trouve souvent dans d'autres langages fonctionnels.
Le module permet d'encapsuler une famille de définitions, publiques (def) ou privées (defp)
Les fonctions sont dites multi-clauses, avec exactement la même signature (mêmes arguments du même type), mais on peut séparer les cas, et la correspondance se fait automatiquement, ce qui réduit le nombre de if..then..else qui encombrent la logique.
On peut cascader les appels de fonction avec l'opérateur "pipe" |> bien connu des Fsharpistes et autres OCaMListas. L'indentation c'est pour faire joli, pas comme en Python.

Le seul inconvenient du module est l'ajout du nom lors de l'appel Factorielle.de(n) au lieu de factorielle(n)
Ici, la Chantilly et les noisettes, c'est la fonction privée fact0 qui passe le résultat partiel du tour précédent en 2nd argument, cela évite d'exploser la pile si n est grand. Par exemple Factorielle.de(100000) met plusieurs secondes mais finit par s'afficher.

Code
jaypee@MacMini2018JP Elixir % time elixir factorielle.exs
Saisir un nombre entier positif : 100000
100000! vaut 28242294079603478742934215780245355184774949260912248505789180865429779509010630
.... plusieurs pages de chiffres supprimées
000000000000000000000000000000000000
elixir factorielle.exs  15,57s user 0,99s system 76% cpu 21,616 total

Note : Il y a aussi des fonctions du type map-reduce qui permettraient de réduire tout le code à une seule ligne, mais c'est moins parlant smile.gif
Voila pour les curieux smile.gif
JP
PS: Timing des autres méthodes
Code
def avec_reduce(n) when n > 0 do
  Enum.reduce(1..n, &(&1 * &2))
end

def recursive(n) when n > 0 do
  case n do
    1 -> 1
    n -> n * recursive(n - 1)
  end
end

Si on exploite la possibilité des fonctions multiclauses, on peut supprimer ce "case"
Code
def recursive(1)
  1
end

def recursive(n) when n > 0 do
  n -> n * recursive(n - 1)
end


Bilan : La méthode avec reduce est un poil plus performante, même pour n = 100000, avec un temps légèrement au dessus de 15s.
la méthode récursive classique est un gros cheveu plus performante que la méthode avec accumulateur, avec un temps en dessous des 15s et la pile n'explose pas !
Comme quoi, faut pas toujours se bercer de principes, faut juste vérifier la réalité des faits...
PPS: Python et Ruby ont aussi une bibliothèque de programmation fonctionnelle avec une fonction reduce en python et inject en Ruby. 100000! se calcule en 4,5s en Python et 2,7s en Ruby.
PPPS: Elixir n'est pas le meilleur choix pour la performance, mais le meilleur choix pour la robustesse, le multi-tâche. L'inconvénient est qu'il demande des programmeurs pointus, c'est souvent le cas dans le style fonctionnel. Le cours dont il me reste encore la moitié à suivre, fournit une bon niveau de productivité avec un effort raisonnable. Comme Elixir/Phoenix permettent un développement "full-stack", tout comme ECMAScript/JavaScript, on peut se concentrer sur un seul type de langage, qui est très expressif et facilite le codage sans trop de complexité incidente : Exemple de complexité incidente en Python: les tabulations et le rajout de self comme argument invisible des méthodes d'un objet, migration 2.x - 3.x pas fluide. Exemple en JavaScript, il existe plusieurs styles, et les bibliothèques ont toutes un style différent, gestion des dépendances.

Ce message a été modifié par Jaypee - 13 Aug 2020, 10:35.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 15th November 2024 - 15:07