URL: https://linuxfr.org/news/crystal-un-langage-proche-de-ruby-en-version-0-16 Title: Crystal, un langage proche de Ruby, en version 0.16 Authors: Bruno Michel Benoît Sibaud Date: 2016年05月06日T11:54:17+02:00 License: CC By-SA Tags: crystal, ruby et sortie_version Score: 40 Crystal est un langage de programmation, encore jeune. Il s'inspire de Ruby pour la syntaxe mais vise des performances proches du C. La version 0.16 vient de sortir, avec un nouvel algorithme pour l'inférence de types. À noter, le compilateur de Crystal est écrit en Crystal. Voici à quoi ressemble un serveur HTTP basique écrit en Crystal : ```ruby # A very basic HTTP server require "http/server" server = HTTP::Server.new(8080) do |context| context.response.content_type = "text/plain" context.response.print "Hello world, got #{context.request.path}!" end puts "Listening on http://0.0.0.0:8080" server.listen ``` ---- [Le site officiel de Crystal](http://crystal-lang.org/) [L'annonce de la sortie de la version 0.16](http://crystal-lang.org/2016/05/05/crystal-0.16.0-released.html) [Le code de Crystal sur github](https://github.com/crystal-lang/crystal) [Essayer Crystal en ligne](https://play.crystal-lang.org/) ---- ## Une syntaxe proche de Ruby Comme on peut le voir dans l'exemple ci-dessus, la syntaxe est très proche de celle de Ruby. C'est un des objectifs du langage. Ceci dit, la compatibilité avec Ruby n'en fait pas partie. On retrouve ainsi des classes similaires à celles de Ruby : ```ruby class Person def initialize(name : String) @name = name @age = 0 end def name @name end def age @age end end ``` Ou la notion de _blocks_ : ```ruby def twice yield yield end twice do puts "Hello!" end ``` ## Typage statique Mais il existe également des différences avec Ruby. Par exemple, Crystal a un typage statique et des génériques : ```ruby class MyBox(T) def initialize(@value : T) end def value @value end end int_box = MyBox(Int32).new(1) int_box.value # => 1 (Int32) string_box = MyBox(String).new("hello") string_box.value # => "hello" (String) ``` En général, l'inférence de types permet de ne pas spécifier les types des variables et méthodes, mais vous pouvez de manière optionnelle le faire : ```ruby def add(x : Number, y : Number) x + y end ``` ## Bindings avec le langage C Crystal permet de déclarer des bindings avec le langage C. Et, fait notable, ces bindings peuvent être déclarés en Crystal. Voici [un exemple pris de la bibliothèque standard](https://github.com/crystal-lang/crystal/blob/master/src/yaml/lib_yaml.cr) pour s'interfacer avec la libyaml : ```ruby @[Link("yaml")] lib LibYAML alias Int = LibC::Int PARSER_SIZE = 480 type Parser = Void* struct VersionDirective major : Int minor : Int end # ... fun yaml_parser_initialize(parser : Parser*) : Int end ``` ## Génération et évaluation de code au moment de la compilation Le meta-programming de Ruby est très puissant mais aussi très coûteux en performances. Crystal a donc choisi une autre voie : les macros. Celles-ci permettent d'éviter d'avoir à écrire beaucoup de code répétitif sans impacter de manière notables les performances. Une macro reçoit un noeud [AST](https://fr.wikipedia.org/wiki/Arbre_syntaxique_abstrait) et va générer du code lors de la compilation. ```ruby macro define_method(name, content) def {{name}} {{content}} end end # Va générer: # # def foo # 1 # end define_method foo, 1 foo #=> 1 ``` ## Concurrence et parallélisme Crystal permet actuellement de construire des programmes concurrents avec des primitives comme les _fibers_ et _channels_, mais la jeunesse du langage se fait sentir sur ces aspects. On peut séparer des tâches à effectuer dans des _fibers_. Chaque _fiber_ a un contexte propre et est comparable à une goroutine en Go par exemple. Les _fibers_ sont coopératives et ne vont passer la main à une autre _fiber_ que de manière explicite (par opposition aux threads, qui sont pré-emptifs). Il existe également une _fiber_ un peu particulière, l'_Event Loop_, qui gère tous les I/O. Enfin, les _fibers_ communiquent entre elles via des _channels_. ```ruby require "socket" channel = Channel(String).new spawn do server = TCPServer.new("0.0.0.0", 8080) socket = server.accept while line = socket.gets channel.send(line) end end spawn do while line = gets channel.send(line) end end 3.times do puts channel.receive end ``` Ainsi, Crystal permet déjà de structurer son code pour gérer la concurrence, mais est limité de la même façon que le JavaScript pour le parallélisme : une seule fibre peut s'exécuter à un moment donné. ## Compilation vers du code natif efficace Crystal profite de LLVM pour compiler vers du code natif. Les performances sont au rendez-vous. Par exemple, [dans ce benchmark](https://github.com/kostya/benchmarks), Crystal se retrouve entre C/C++ et Go/Node (et donc loin devant Ruby).

AltStyle によって変換されたページ (->オリジナル) /