IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Roc se présente comme un langage de programmation rapide, fonctionnel et convivial
. Roc est un descendant direct d'Elm, les deux langages sont similaires, mais pas identiques

Le , par Anthony

21PARTAGES

14  0 
Roc est un langage de programmation rapide, convivial et fonctionnel. Il est optimisé pour la vitesse et se compile directement en code machine ou en WebAssembly. Le langage Roc se veut accessible et intuitif, avec une syntaxe, une sémantique et des outils conçus pour être centrés sur l'utilisateur. Roc s'appuie par ailleurs sur un petit ensemble d'éléments de langage simples et adhère à une approche multifonctionnelle à paradigme unique.

Le langage de programmation Roc tire son nom d'un oiseau mythique, ce qui se reflète dans son logo - un oiseau en origami rendant hommage au symbole du tangram d'Elm. Roc est, par essence, un successeur direct d'Elm, présentant des similitudes avec ce dernier tout en conservant des caractéristiques distinctes. À l'instar des ressemblances entre l'origami et le tangram, les deux langages impliquent la création de diverses structures à partir de primitives simples, la programmation fonctionnelle soulignant le caractère commun des plis.


Roc est un langage rapide

Le code Roc est conçu pour être construit et exécuté rapidement... mais qu'entend-on par "rapide" ? Et dans quelle mesure l'implémentation actuelle de Roc est-elle proche de cet objectif ?


Roc est un langage convivial

En plus d'avoir une communauté amicale, Roc se veut aussi un langage convivial. Cela a un impact sur la syntaxe, la sémantique et les outils livrés avec Roc.


Roc est un langage fonctionnel

Roc est conçu pour avoir un petit nombre de primitives de langage simples. Cet objectif fait de Roc un langage fonctionnel à paradigme unique, tandis que ses objectifs de performance conduisent à des choix de conception peu courants dans les langages fonctionnels.


Essayer Roc

Vous pouvez essayer Roc en utilisant cette boucle lecture-évaluation-impression (REPL), qui s'exécute dans votre navigateur en WebAssembly.

Exemples

Roc est un jeune langage. Il n'a même pas encore de version numérotée, juste des nightly builds ! Cependant, il peut déjà être utilisé pour plusieurs choses si vous êtes prêt à être un early adopter - avec tous les bugs et les fonctionnalités manquantes qui viennent avec ce territoire.

Voici quelques exemples d'utilisations possibles aujourd'hui.

Interfaces de ligne de commande

Code : Sélectionner tout
1
2
main =
    Stdout.line "Hello!"

Vous pouvez utiliser Roc pour créer des scripts et des interfaces de ligne de commande (CLI). Le compilateur produit des exécutables binaires, de sorte que les programmes Roc peuvent être exécutés sur des appareils qui n'ont pas Roc lui-même installé.

À titre d'exemple, le code HTML du site web du langage Roc est généré à l'aide d'un simple script Roc. Vous pouvez voir le code de ce script dans le dépôt principal du code Roc.

Si vous cherchez un point de départ pour construire un programme en ligne de commande dans Roc, basic-cli est une plateforme populaire à consulter.

Serveurs web

Code : Sélectionner tout
1
2
handleReq = \request ->
    Task.ok { body: … }

Vous pouvez également construire des serveurs web en Roc. basic-webserver est une plateforme avec une interface simple : vous écrivez une fonction qui prend une requête, faites quelques E/S, et renvoie une réponse.

En coulisse, il utilise les bibliothèques hyper et tokio de Rust pour exécuter votre fonction Roc sur les requêtes entrantes.

Pour l'accès à la base de données, roc-pg vous permet d'accéder à une base de données PostgreSQL - avec vos types Roc vérifiés par rapport aux types du schéma de votre base de données.

Intégration

Code : Sélectionner tout
1
2
fn = require("foo.roc");
log(`Roc says ${fn()}`);

Vous pouvez appeler des fonctions Roc à partir d'autres langages. Il existe plusieurs exemples de base sur la façon d'appeler des fonctions Roc depuis Python, Node.js, Swift, WebAssembly et les langages JVM.

Tout langage qui supporte l'interopérabilité avec le C peut appeler des fonctions Roc, en utilisant des techniques similaires à celles trouvées dans ces exemples.

La plupart de ces exemples sont des preuves de concept minimales, mais roc-esbuild est un travail en cours qui est utilisé chez Vendr pour appeler des fonctions Roc depuis Node.js.

Exemple de code avec explications

Voici un exemple de code qui montre quelques aspects différents de Roc :

  • E/S de fichiers et requêtes HTTP
  • Correspondance de motifs pour la gestion des erreurs
  • Désérialisation JSON par inférence de type
  • Sucre syntaxique commun : interpolation de chaînes, pipelines, et backpassing

Le tutoriel introduit ces éléments progressivement et plus en profondeur, mais ceci donne un bref aperçu.

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Click anything here to see an explanation.
Comments in Roc begin with a # and go to the end of the line.


main =
    Path.fromStr "url.txt"
    |> storeEmail
    |> Task.onErr handleErr

storeEmail = \path ->
    url <- File.readUtf8 path |> Task.await
    user <- Http.get url Json.codec |> Task.await
    dest = Path.fromStr "\(user.name).txt"
    _ <- File.writeUtf8 dest user.email |> Task.await
    Stdout.line "Wrote email to \(Path.display dest)"

handleErr = \err ->
    when err is
        HttpErr url _ -> Stderr.line "Error fetching URL \(url)"
        FileReadErr path _ -> Stderr.line "Error reading from \(Path.display path)"
        FileWriteErr path _ -> Stderr.line "Error writing to \(Path.display path)"

Pour débuter avec le langage, essayez le tutoriel.

Source : Roc : A fast, friendly, functional language

Et vous ?

Que pensez-vous du langage de programmation Roc ?

Trouvez-vous qu'il s'agit d'un langage fiable et utile ?

Voir aussi

Pourquoi la programmation fonctionnelle n'est-elle pas la norme de l'industrie du code ? L'auteur de « Elm in action » s'exprime, « c'est une question de temps avant que la POO soit détrônée »

Faut-il éviter d'utiliser des classes et s'appuyer autant que possible sur une approche fonctionnelle ? Un point de vue d'Andy Peterson basé sur son expérience en entreprise avec Typescript

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Pyramidev
Expert éminent https://www.developpez.com
Le 25/11/2023 à 15:47
Cette semaine, petit à petit, j'ai parcouru le site du langage Roc.

Il s'inscrit effectivement dans le paradigme fonctionnel. Les fonctions sont pures et les variables sont immuables. Les habitués du paradigme fontionnel seront donc familiers avec les patterns suivants :

  • Il n'y a pas de boucle while ou for. À la place, il faut passer soit par des fonctions récursives soit, ce qui est plus fréquent, par des fonctions d'ordre supérieur comme List.map.
  • Le développeur n'appelle pas des opérations qui modifient des collections. En Roc, Set.insert prend un ensemble en entrée et retourne un ensemble avec un élément de plus en sortie. Mais le compilateur peut optimiser en modifiant sur place le même ensemble s'il sait que c'est possible.
  • Les fonctions les plus natuelles à écrire sont celles qui n'ont aucun effet de bord. Si on veut interagir avec l'extérieur du programme, il faut utiliser un type spécial, Task (l'équivalent de IO en Haskell). Si on veut séquencer plusieurs interactions avec l'extérieur du programme, il faut passer par de la composition de fonctions, typiquement avec Task.await. Pour que ces compositions de fonctions soient lisibles, on a alors besoin de sucre syntaxique. @unanonyme, pour répondre à ta question, les détails sont dans le tutoriel : https://www.roc-lang.org/tutorial#tasks

Mais il y a une très grande différence avec Haskell : le langage cherche à être plus accessible, à être moins élitiste. Il y a plein de détails intéressants à ce sujet dans la FAQ. J'en copie-colle un extrait :

Higher-kinded polymorphism

The explicit plan is that Roc will never support higher-kinded polymorphism.

[…]

It's also important to consider the cultural implications of deciding whether or not to support HKP. To illustrate these implications, imagine this conversation:

Programmer 1: "How do you feel about higher-kinded polymorphism?"

Programmer 2: "I have no idea what that is."

Programmer 1: "Okay, how do you feel about monads?"

Programmer 2: "OH NO."

For some, this conversation does not require imagining, because it's so familiar: higher-kinded types come up in conversation, another programmer asks what that means, monads are given as an example, and their reaction is strongly negative. On the flip side, plenty of programmers love HKP and vigorously advocate for its addition to languages they use which don't have it. Feelings about HKP seem strongly divided, maybe more so than any other type system feature besides static and dynamic types.

It's impossible for a programming language to be neutral on this. If the language doesn't support HKP, nobody can implement a Monad typeclass (or equivalent) in any way that can be expected to catch on. Advocacy to add HKP to the language will inevitably follow. If the language does support HKP, one or more alternate standard libraries built around monads will inevitably follow, along with corresponding cultural changes. (See Scala for example.) Culturally, to support HKP is to take a side, and to decline to support it is also to take a side.

Given this, languages have three options:

  • Have HKP and have Monad in the standard library. Embrace them and build a culture and ecosystem around them.
  • Have HKP and don't have Monad in the standard library. An alternate standard library built around monads will inevitably emerge, and both the community and ecosystem will divide themselves along pro-monad and anti-monad lines.
  • Don't have HKP; build a culture and ecosystem around other things.

Considering that these are the only three options, an early decision in Roc's design—not only on a technical level, but on a cultural level as well—was to make it clear that the plan is for Roc never to support HKP. The hope is that this clarity can save a lot of community members' time that would otherwise be spent on advocacy or arguing between the two sides of the divide. Again, it's completely reasonable for anyone to have a different preference, but given that languages can only choose one of these options, it seems clear that the right choice for Roc is for it to never have higher-kinded polymorphism.
On verra si l'avenir me donne raison, mais je pense que cette voie va déboucher sur une impasse. De mon point de vue, quand un langage met beaucoup l'accent à la fois sur l'immuabilité et les fonctions pures, on a vite besoin des monades ou d'autres abstractions du même genre.

Prenons l'exemple des nombres aléatoires. Le site fournit un exemple : https://www.roc-lang.org/examples/Ra...rs/README.html
Dans le paradigme fonctionnel, pour gérer l'aléatoire, les fonctions prennent en entrée une graine aléatoire et retournent en sortie une nouvelle graine aléatoire.
À présent, parlons des abstractions. Comment modéliser une callback qui modifie potentiellement un état aléatoire ? Par exemple, quand on veut filter les éléments d'une collection selon un prédicat (une fonction qui retourne vrai ou faux), comment dit-on que ce prédicat peut au passage modifier une graine aléatoire, mais pas forcément (ça dépend du prédicat) ?
Dans un langage qui ne suit pas à la lettre le paradigme fonctionnel, ce n'est pas un problème : une callback peut modifier un état sans que cela n'affecte son type. Dans mon exemple, le prédicat sera de type a -> Bool avec a le type d'un élement de la collection. Si au passage le prédicat édite une graine aléatoire, ce n'est même pas visible dans son type.
Dans un langage comme Haskell, comment on modélise un tel prédicat ? Le prédicat sera de type Monad m => (a -> m Bool) ou bien passera par un autre type plus général qu'une monade. Dans le cas particulier où l'utilisateur veut que le prédicat puisse modifier une graine aléatoire, il passera par la monade State.

Ce que je viens d'écrire ne sera compréhensible que pour ceux qui sont déjà familiers avec ces concepts. Mais, dans les grandes lignes, en Roc, pour écrire du code réutilisable, il y aura pas mal de limites, car les contraintes typiques du paradigme fonctionnel ne seront pas assez compensées par les abstractions.

À côté de ça, il y a plein de choses bien pensées dans le langage Roc. Son concepteur, Richard Feldman, est visiblement intelligent.

Mais, fondamentalement, je pense que ce langage débouchera sur une impasse. On verra si le temps me donne raison.

  • Ceux qui ont déjà un peu étudié un langage comme Haskell seront frustrés par le manque de puissance d'abstraction.
  • Ceux qui sont hostiles par défaut au paradigme fonctionnel ne seront pas intéressés non plus.
  • Ceux qui sont hostiles aux langages fonctionnels élitistes mais quand même ouverts au paradigme fonctionnel, après avoir testé ce langage, risqueront de se dire : "Le paradigme fonctionnel apporte des garanties intéressantes, ce qui est très bien pour quelques programmes bien précis, mais il est trop rigide dans la plupart des cas. Use the right tool for the job." En vrai, le paradigme fonctionnel sera pertinent pour un nombre de cas plus élevé, mais à condition d'avoir sous la main les bonnes abstractions.
2  0 
Avatar de unanonyme
Membre éclairé https://www.developpez.com
Le 22/11/2023 à 16:02
Bonjour,

Quelle est l'utilité des Task.await dans storeEmail ?

Bonne journée.
0  0 
Avatar de unanonyme
Membre éclairé https://www.developpez.com
Le 25/11/2023 à 18:48
Bonjour,

Non je ne vois toujours pas pourquoi ces appels sont déportés
vers des stack async alors que très visiblement,
tout cela est séquentiel et ne saurait en être autrement.

Enfin si, j'ai bien une petite idée,
mais ce serait trop décevant.

Bonne journée.
0  0