tag:linuxfr.org,2005:/tags/fonctionnelle/publicLinuxFr.org : les contenus étiquetés avec « fonctionnelle »2022-02-06T11:06:54+01:00/favicon.pngtag:linuxfr.org,2005:Diary/400772022-01-06T01:29:20+01:002022-01-06T08:42:04+01:00Letlang, encore un nouveau langage de programmationLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-un-peu-de-contexte">Un peu de contexte</a></li>
<li>
<a href="#toc-quelques-amuse-gueules">Quelques amuse-gueules</a><ul>
<li><a href="#toc-syst%C3%A8me-de-type">Système de type</a></li>
<li><a href="#toc-null-et-undefined">Null et undefined</a></li>
<li><a href="#toc-coroutines-et-streams">Coroutines et Streams</a></li>
<li><a href="#toc-effets-de-bord-et-exceptions">Effets de bord et exceptions</a></li>
<li><a href="#toc-ensembles-infinis">Ensembles infinis</a></li>
</ul>
</li>
<li><a href="#toc-bravo">Bravo</a></li>
</ul>
<p>Bonjour Nal,</p>
<p>Cela faisait longtemps que je ne t'avais pas écrit, mais je n'avais pas grand chose de pertinent à dire, tu me pardonneras j'espère.</p>
<p>Aujourd'hui, je vais te parler d'un de mes "side-project", j'ai nommé <strong>Letlang</strong>.</p>
<p>Si tu as la flemme de tout lire, tu peux aller mettre en favoris le site web <a href="https://letlang.dev">https://letlang.dev</a> pour une lecture du soir.</p>
<p><strong>DISCLAIMER:</strong> Très peu de code existe pour l'instant, le projet en est à ses balbutiements. Même le design de la syntaxe et fonctionnalités ne sont pas définitifs.</p>
<h2 id="toc-un-peu-de-contexte">Un peu de contexte</h2>
<p>Au cours de ma carrière, j'ai pu toucher à de nombreux langages de programmation, et je me suis spécialisés dans certains. Je regarde aussi les petits nouveaux qui génèrent de l'engouement, ou les propositions d'améliorations de langage existant (coucou <a href="https://tc39.es/">TC39</a>, un jour je comprendrais ton nom, promis).</p>
<p>Pour chacun de ces langages, j'ai une liste de choses qui me déplaisent et une liste de choses que j'adore. J'en suis venu à me poser la question suivante:</p>
<blockquote>
<p>A quoi ressemblerait mon langage idéal ? Celui dont la liste de choses qui me déplaisent n'existerait pas.</p>
</blockquote>
<p>Un papier, un crayon plus tard, je commençait à décrire <strong>Letlang</strong>.</p>
<h2 id="toc-quelques-amuse-gueules">Quelques amuse-gueules</h2>
<p>Tout d'abord, il s'agit d'un langage de programmation fonctionnelle, paradigme dont je suis tombé éperdument amoureux. Le compilateur est implémenté en Rust.</p>
<p>Il s'inspire de <a href="https://elixir-lang.org">Elixir</a> (mon petit favori), <a href="https://python.org">Python</a>, <a href="https://rust-lang.org">Rust</a>, <a href="https://go.dev">Go</a> (et pourtant je déteste ce langage), <a href="https://typescriptlang.org">TypeScript</a> et des mathématiques.</p>
<h3 id="toc-système-de-type">Système de type</h3>
<p><strong>Letlang</strong> a ce que j'appelle un <strong>typage strict</strong> (j'aime pas la notion de fort/faible) :</p>
<blockquote>
<p>On vérifie la cohérence des types le plus souvent possible, à la compilation comme à l'exécution</p>
</blockquote>
<p>Cependant, à la différence de la plupart des langages de programmation, une valeur n'a pas un unique type. Au contraire, je m'inspire ici des mathématiques :</p>
<ul>
<li>
<code>42</code> est un entier mais aussi un réel</li>
<li>
<code>(1; 2)</code> est un vecteur 2D mais aussi une matrice 2x1</li>
</ul>
<p>De la même manière, en <strong>Letlang</strong>, c'est la définition d'un type qui détermine si une valeur lui appartient. Ainsi, je peux écrire :</p>
<pre><code>class int(n: number) check {
frac(n) = 0
}
</code></pre>
<p>Ici je défini un type <code>int</code> qui est construit à partir d'un <code>number</code> nommé <code>n</code>. Je lui rajoute un prédicat que tout <code>n</code> lui appartenant doit valider, ici: la partie décimale du nombre doit être 0.</p>
<p>Les prédicats sont une logique d'ordre supérieur (<a href="https://en.wikipedia.org/wiki/Higher-order_logic">Higher Order Logic</a>), je peux ainsi définir le type suivant :</p>
<pre><code>class even(n: int) check {
thereis k: int, n = 2 * k
}
</code></pre>
<p>Le prédicat dit qu'il existe un entier tel que <code>n = 2 * k</code>, qui est la définition mathématique d'un nombre pair. Ainsi <code>42</code> appartient aux types <code>number</code>, <code>int</code> et <code>even</code>, alors que <code>43</code> appartient uniquement aux types <code>number</code> et <code>int</code>.</p>
<p>On peut également combiner plusieurs types en un seul avec les opérateurs <code>|</code>, <code>&</code> et <code>!</code> :</p>
<pre><code>class odd(n: int & !even)
</code></pre>
<p>Par définition, un nombre impair est un entier qui n'est pas pair.</p>
<p>Pour terminer sur le système de type, on a les types génériques :</p>
<pre><code>class ok<T>(val: (:ok, T))
class err<E>(val: (:error, E))
class result<T, E>(val: ok<T> | err<E>)
</code></pre>
<p>Les paramètres d'un type générique peuvent être contraint à un autre type :</p>
<pre><code>class vector2<T: int | float>(xy: (T, T))
</code></pre>
<p>Dans l'exemple ci-dessus, <code>vector2<int></code> et <code>vector2<float></code> existent, mais <code>vector2<string></code> génèrera une erreur de compilation.</p>
<h3 id="toc-null-et-undefined">Null et undefined</h3>
<p>En <strong>Letlang</strong>, une variable peut ne pas avoir de valeur définie, mais la valeur <code>null</code> ou <code>undefined</code> n'existe pas.</p>
<p>C'est particulièrement utile pour travailler avec des équations :</p>
<pre><code>let x: int # x n'a pas de valeur, mais cela sera un entier
let x > 0 # toujours pas de valeur, mais elle est positive
x - 3 = 0 # cette équation possède une solution, donc l'expression retournera true
1 / x = 0 # aucune solution n'existe pour cette équation, donc l'expression retournera false
</code></pre>
<blockquote>
<p><strong>NB:</strong> <code>=</code> est un opérateur de comparaison, <code>==</code> dans la plupart des langages. L'opérateur d'assignation est <code>:=</code>.</p>
</blockquote>
<p>De la même manière, on pourra définir la valeur de <code>x</code> grâce au mot clé <code>let</code> :</p>
<pre><code>let x: int # x n'a pas de valeur
let x - 3 = 0 # une seule solution existe, x = 3
</code></pre>
<p>Attention avec cette notation cependant:</p>
<pre><code>let x: number
let 1 / x = 0 # produira une erreur, car aucune solution n'existe.
</code></pre>
<p>Pour résumer :</p>
<ul>
<li>le mot clé <code>let</code> est une assertion de la part du développeur au compilateur/runtime</li>
<li>les variables sans valeur définie peuvent être utilisées dans des comparaisons</li>
<li>une variable est définie si on lui assigne une valeur avec <code>:=</code> ou si l'ensemble des définitions <code>let</code> produit une unique solution</li>
</ul>
<h3 id="toc-coroutines-et-streams">Coroutines et Streams</h3>
<p>En <strong>Letlang</strong>, comme en Go, les fonctions n'ont pas de <a href="https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/">couleur</a>.</p>
<p>N'importe quelle fonction peut être exécuté en parallèle :</p>
<ul>
<li>le mot clé <code>coro</code> transforme un appel de fonction en coroutine</li>
<li>le mot clé <code>join</code> permet d'attendre la fin d'une coroutine et d'en récupérer le résultat</li>
</ul>
<p>Un exemple vaut 1000 mots :</p>
<pre><code>import stdlib as std
func main(args: list<string>) -> :ok {
c := coro std.strlen("foo")
# do other stuff
let 3 = join c
:ok
}
</code></pre>
<p>Les streams sont des objets qui permettent de communiquer avec des coroutines :</p>
<ul>
<li>envoyer une valeur dans un stream est instantané</li>
<li>lire une valeur depuis un stream est bloquant tant que le stream est vide</li>
</ul>
<pre><code>let s: stream<int>
let v: int
# écrit dans le stream
s << 42
# lit depuis le stream et place le résultat dans la variable v
s >> v
</code></pre>
<p>Ce qui peut donner par exemple :</p>
<pre><code>func double(s: stream<int>) -> :ok {
let x: int
s >> x
match x {
-1 => :ok,
_ => {
s << (x * 2)
double(s)
}
}
}
func main(args: list<string>) -> :ok {
let s: stream<int>
c := coro double(s)
s << 1 << 2 << 3 << 4 << -1
let :ok = join c
let (a, b, c, d): (int, int, int, int)
s >> a >> b >> c >> d
let a = 2
let b = 4
let c = 6
let d = 8
:ok
}
</code></pre>
<h3 id="toc-effets-de-bord-et-exceptions">Effets de bord et exceptions</h3>
<p>Faire un langage fonctionnel pur c'est bien, mais les effets de bords c'est quand même bien pratique parfois.</p>
<p>Une fonction pure c'est une fonction qui, comme en math, retourne toujours le même résultat étant donné les mêmes paramètres. Si <code>f(x) = x + 1</code>, alors <code>f(1)</code> donnera toujours <code>2</code>.</p>
<p>Les fonctions du style <code>readline()</code> ou <code>get_time()</code> retourneront des résultats différents, ce sont donc des fonctions impures.</p>
<p>En <strong>Letlang</strong>, ce n'est pas possible de créer de telles fonctions. A la place, on va utiliser les <strong>effets</strong>. Un effet se déclare comme une signature de fonction :</p>
<pre><code>effect log(level: "debug" | "info", message: string) -> :ok
</code></pre>
<p>On peut ensuite appeler cet effet grâce au mot clé <code>perform</code> :</p>
<pre><code>let :ok = perform log("info", "hello world")
</code></pre>
<p>Cela permet de déléguer la gestion de l'effet à celui qui appelle le code l'utilisant, cela avec la structure de contrôle <code>do {}</code> :</p>
<pre><code>let :ok = do {
perform log("info", "hello world")
}
effect log("debug", _message) {
:ok
}
effect log("info", message) {
std.print(message)
:ok
}
</code></pre>
<p>Si un effet n'est pas géré par une clause <code>effect</code>, alors il sera propagé jusqu'au runtime de <strong>Letlang</strong>. Si le runtime ne connait pas l'effet en question, le programme plantera.</p>
<p>Ainsi, le runtime <strong>Letlang</strong> fournit un ensemble d'effets "builtin" sur lesquels le développeur pourra se reposer pour interagir avec le monde extérieur.</p>
<p>Ensuite, les exceptions sont un cas particulier d'effet : <strong>elles ne rendent pas le contrôle au code qui les appelle</strong>.</p>
<p>C'est un mécanisme de retour prématuré :</p>
<pre><code>let :oops = do {
throw :error
:never_reached
}
catch :error {
:oops
}
</code></pre>
<h3 id="toc-ensembles-infinis">Ensembles infinis</h3>
<p>Allez, un dernier pour la route. <strong>Letlang</strong> peut travailler avec des ensembles infinis, ils sont construit à l'aide d'une variable et d'un prédicat :</p>
<pre><code>s := { x: int | x > 0 }
42 in s # true
-1 in s # false
</code></pre>
<p>Ici, le type de <code>s</code> est donc <code>set<int></code>. C'est important à cause du paradoxe de Russel.</p>
<p>Imaginons 2 secondes que le type <code>set<any></code> existe (ce qui n'est pas le cas car <code>any</code> n'existe pas).</p>
<p>On pourrait écrire :</p>
<pre><code>s := { x: set<set<any>> | x not in x }
</code></pre>
<p>Soit : L'ensemble de tout les ensembles qui ne se contiennent pas eux même.</p>
<p>Posons nous la question suivante : <em>est-ce que <code>s</code> appartient à <code>s</code> ?</em></p>
<ul>
<li>si oui, alors le prédicat <code>x not in x</code> est faux, donc non en fait</li>
<li>si non, alors le prédicat <code>x not in x</code> est vrai, donc oui en fait</li>
</ul>
<p>Le simple fait que <code>any</code> n'existe pas nous empêche de créer de tels ensembles. Ouf.</p>
<h2 id="toc-bravo">Bravo</h2>
<p>Pour ceux qui ont tout lu jusqu'ici, voici une petite récompense :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f7777772e6d616665726d65656e76696c6c652e66722f77702d636f6e74656e742f75706c6f6164732f323031372f31312f6b69742d7261636c657474652d6d612d6665726d652d656e2d76696c6c652e6a7067/kit-raclette-ma-ferme-en-ville.jpg" alt="raclette" title="Source : https://www.mafermeenville.fr/wp-content/uploads/2017/11/kit-raclette-ma-ferme-en-ville.jpg"></p>
<div><a href="https://linuxfr.org/users/linkdd/journaux/letlang-encore-un-nouveau-langage-de-programmation.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/126476/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/linkdd/journaux/letlang-encore-un-nouveau-langage-de-programmation#comments">ouvrir dans le navigateur</a>
</p>
David Delassushttps://linuxfr.org/nodes/126476/comments.atomtag:linuxfr.org,2005:Diary/333682012-11-14T13:24:19+01:002012-11-14T14:21:20+01:00Adopter un style de programmation fonctionnelLicence CC By‑SA http://creativecommons.org/licenses/by-sa/3.0/deed.fr<p><a href="http://fr.wikipedia.org/wiki/John Carmack" title="Définition Wikipédia">John Carmack</a>, c'est ce développeur de renom chez IdSoftware, qui a participé à la création de titres phares du jeu vidéo PC avec la série des Doom, des Wolfenstein et des Quake. Bien que n'étant pas des logiciels libres, leurs moteurs sont régulièrement libérés et LinuxFR se fait l'écho de ces libérations depuis sa création (<a href="http://linuxfr.org/news/doom-en-gpl">ici</a>, <a href="http://linuxfr.org/news/le-moteur-de-doom3-plac%C3%A9-sous-gplv3">là</a> et <a href="http://linuxfr.org/news/quake-2-en-gpl">là</a> par exemple). Bref tout ça pour dire que je sais bien qu'il ne fait pas du logiciel libre, mais d'une certaine manière, il a contribué pour beaucoup à des jeux libres.</p>
<p>John Carmack (contrairement à d'autres) n'est pas connu pour ses trolls, mais au contraire, il a (ou du moins tente d'avoir) toujours une position mesurée et réfléchie. Il tient un blog dans lequel il parle de ses expériences dans le développement et de différentes techniques qui y sont liées. Son dernier billet de blog « <a href="http://www.altdevblogaday.com/2012/04/26/functional-programming-in-c/">Functional Programming in C++</a> » (dont je souhaite me faire l'écho) est une tentative d'expliquer comment adopter un style de programmation fonctionnelle, malgré l'utilisation d'un langage qui ne l'est pas.</p>
<p>C'est vraiment un article très intéressant (<a href="http://cpp.developpez.com/redaction/data/pages/rubrique/cpp/carmack/fonctionnel/">qui, de plus, a été traduit en français sur developpez.com</a>) et agréable à lire.</p>
<p>Ce que je trouve particulièrement intéressant, c'est de prendre réellement les avantages de la programmation fonctionnelle (les fonctions pures, c'est-à-dire sans effets de bord) dans les langages que l'on trouve un peu de partout (rien dans ce qu'il décrit n'est spécifique au C++, on peut appliquer les mêmes méthodes à du C, du Java, du perl ou du python). Il ne s'arrête donc pas aux lambdas fonctions qui, bien que très agréables à utiliser, sont plus proches du sucre syntaxique que d'un véritable style de programmation.</p>
<p>En outre, il explique comment faire évoluer une base de code en prenant en compte ces principes. Chez IdSoftware, ils possèdent une grande base de code en C++ qui continue d'être utilisée, ils ne peuvent pas se permettre de la jeter pour la réécrire. Bref, c'est vraiment agréable à lire, pas moralisateur, juste quelques conseils à garder en tête.</p>
<p>Si vous regardez son blog, son précédent billet parle d'analyse de code statique. C'est encore une fois intéressant, mais plus proche d'un retour d’expérience sur les différents outils qu'il a eu à disposition et la manière de s'en servir.</p>
<p>Bonne lecture à tous.</p>
<p>PS : si vous avez dans vos flux d'autres perles de ce type, je serais très intéressé d'y jeter un œil. </p><div><a href="https://linuxfr.org/users/barmic/journaux/adopter-un-style-de-programmation-fonctionnel.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/96412/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/barmic/journaux/adopter-un-style-de-programmation-fonctionnel#comments">ouvrir dans le navigateur</a>
</p>
barmichttps://linuxfr.org/nodes/96412/comments.atomtag:linuxfr.org,2005:News/283222011-06-22T20:09:53+02:002021-07-11T19:11:18+02:00Opa, un nouveau langage pour le développement d’applications WebLicence CC By‑SA http://creativecommons.org/licenses/by-sa/3.0/deed.fr<div><p>Après des années d’efforts, nous sommes heureux d’avoir libéré le code d’une nouvelle technologie Web nommée Opa. La licence choisie est la <a href="http://fr.wikipedia.org/wiki/GNU_Affero_General_Public_License"><em>GNU Affero General Public License</em></a> version 3 (AGPLv3).</p>
<p>Cette dépêche a pour but de vous expliquer ce qu’est, et n’est pas, Opa.</p>
</div><ul><li>lien nᵒ 1 : <a title="http://opalang.org" hreflang="en" href="https://linuxfr.org/redirect/72450">Site Opalang</a></li><li>lien nᵒ 2 : <a title="http://opalang.org/resources/book/index.html" hreflang="en" href="https://linuxfr.org/redirect/72451">Manuel Opa avec des exemples de code</a></li><li>lien nᵒ 3 : <a title="http://opalang.org/see.xmlt" hreflang="en" href="https://linuxfr.org/redirect/72452">Liste d’applications en Opa</a></li><li>lien nᵒ 4 : <a title="https://github.com/mlstate/opalang" hreflang="en" href="https://linuxfr.org/redirect/72453">Dépôt sur GitHub</a></li><li>lien nᵒ 5 : <a title="http://opalang.org/download/faq_opa" hreflang="en" href="https://linuxfr.org/redirect/72454">La FAQ du projet</a></li></ul><div><h2 id="toc-opa-cest-quoi">Opa, c’est quoi ?</h2>
<p>Opa est une technologie de développement d’applications Web distribuées. C’est un nouveau langage de programmation fortement couplé à une bibliothèque Web standard qui remplit toutes les fonctions : de serveur d’applications Web, à serveur de base de données.</p>
<p>En un mot, Opa ne dépend pas des piles serveurs actuelles (à la Apache / PHP / MySQL / Symfony). Un code source Opa est compilé en un binaire autonome du service, qui se contente d’une distribution GNU/Linux nue (même micro) pour l’exécution.</p>
<p>Opa est spécialement conçu pour le Web et spécifie l’ensemble des aspects de l’application :</p>
<ul>
<li>le code client comme le code serveur sont écrits en Opa : le compilateur détermine automatiquement les parties client et serveur (des annotations existent pour lui forcer la main), traduit le code client en JavaScript et automatise les échanges entre client et serveur ;</li>
<li>la structure de la base de données et les requêtes sont également écrites en Opa : là aussi, le compilateur analyse les requêtes pendant la compilation et génère le code d’accès aux données.</li>
</ul>
<h2 id="toc-pourquoi-un-nouveau-langage">Pourquoi un nouveau langage ?</h2>
<p>En développant Opa, nous avions deux objectifs :</p>
<ol>
<li>rendre le Web sûr (et en conséquence sécurisé) : pour cela, il fallait idéalement réécrire proprement l’ensemble des technologies serveur en une, pour minimiser la quantité de code nécessaire (et faire une implémentation propre) ;</li>
<li>rendre le Web simple à programmer : nous voulions notamment distribuer automatiquement code et données… et cela imposait de fait un nouveau langage.</li>
</ol>
<p>Mais le résultat est là : un <a href="http://opalang.org">Webchat distribué</a> s’écrit (sans bibliothèque <em>chat</em> existante…) en 20 lignes de code en Opa, un Wiki guère plus… et déjà de nombreuses petites (et plus grandes) applications Web ont été très rapidement <a href="http://opalang.org/see.xmlt">écrites en Opa</a>.</p>
<h2 id="toc-opa-faitil-le-café">Opa fait‐il le café ?</h2>
<p>Désolé, mais non. Opa n’est pas fait pour écrire autre chose qu’une application Web ou un service Web. En effet, l’adhérence entre le compilateur et la bibliothèque standard est forte, et cette dernière est entièrement dédiée au Web. De même, le modèle applicatif est celui de serveurs distribués et de multiples clients qui discutent via les protocoles Web.</p>
<p>Opa n’est aujourd’hui pas non plus fait pour s’intégrer directement avec des langages ou des bases de données existants. Pas de liaison <a href="https://fr.wikipedia.org/wiki/ODBC" title="Définition Wikipédia">ODBC</a> ou de sérialisation de valeurs PHP pour l’instant. La façon d’interagir avec l’existant est au niveau service Web, via <a href="https://fr.wikipedia.org/wiki/SOAP" title="Définition Wikipédia">SOAP</a>, <a href="https://fr.wikipedia.org/wiki/REST" title="Définition Wikipédia">REST</a> et / ou <a href="https://fr.wikipedia.org/wiki/WSDL" title="Définition Wikipédia">WSDL</a>.</p>
<h2 id="toc-le-code-les-binaires-la-doc">Le code, les binaires, la doc</h2>
<p>Le code source d’Opa est maintenant disponible sur <a href="https://github.com/mlstate/opalang">GitHub</a>. Les premiers paquets (Debian / Ubuntu, <em>tarball</em>, Mac OS X) et la documentation sont disponibles sur le <a href="http://opalang.org">site <em>opalang.org</em></a>.</p>
<p>Nous espérons que vous allez rejoindre la communauté des développeurs Opa : nous serions ravis que vous développiez des applications en Opa, nous aidiez à créer des paquets pour votre distribution favorite, contribuiez à la documentation, et en parliez sur votre <em>blog</em>, si vous trouvez, comme nous, qu’Opa est la manière la plus plaisante d’écrire et d’exécuter des applications Web à l’heure du <em>cloud</em> ;).</p>
</div><div><a href="https://linuxfr.org/news/opa-un-nouveau-langage-pour-le-developpement-d-applications-web.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/86566/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/opa-un-nouveau-langage-pour-le-developpement-d-applications-web#comments">ouvrir dans le navigateur</a>
</p>
https://linuxfr.org/nodes/86566/comments.atomtag:linuxfr.org,2005:Diary/307792011-02-17T01:20:28+01:002011-02-17T01:20:28+01:00Guile 2.0 est là
Le 16 février, Guile 2.0 pointait le bout de son nez avec :<br />
<br />
- Un nouveau compilateur et une machine virtuelle. Le compilateur est livré avec des fronts-ends pour Emacs LISP et ECMAScript.<br />
<br />
- Un nouveau REPL et un nouveau debugger.<br />
<br />
- Support des macros hygiéniques (ils sentent moins mauvais).<br />
<br />
- Support d'unicode.<br />
<br />
- Support quasiment complet de R6RS la dernière norme Scheme.<br />
<br />
- Nouveau module FFI permettant la liaison avec des bibliothèques C sans la moindre utilisation d'une ligne de code en C.<br />
<br />
- Utilisation du ramasse-miette Boehm-Demers-Weiser afin d'améliorer les performances, par rapport à l'ancien ramasse-miette, et faciliter l'intégration avec C.<br />
<br />
Et pleins de nouveaux modules, dont, par exemple :<br />
<br />
(sxml ...) : outils pour traiter xml<br />
(texinfo ...) : analyse et production de texinfo<br />
(web ...) : module pour tripatouiller HTTP etc.<br />
(system base lalr) : parseur LALR<br />
<br />
etc.<br />
<br />
News réduite d'où est tiré ce journal : [<a href="http://www.gnu.org/software/guile/news.html">http://www.gnu.org/software/guile/news.html</a>]<br />
News complète : [<a href="http://git.savannah.gnu.org/gitweb/?p=guile.git;a=blob;f=NEWS;h=b53386a0bcfa3e67acf5f63e501ccf84c8242557;hb=958a28e9fec33ebb4673294308a82ccd18cc6071">http://git.savannah.gnu.org/gitweb/?p=guile.git;a=blob;f=NEW(...)</a>]<div><a href="https://linuxfr.org/users/jbbourgoin/journaux/guile-20-est-l%C3%A0.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/57034/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/jbbourgoin/journaux/guile-20-est-l%C3%A0#comments">ouvrir dans le navigateur</a>
</p>
jbbourgoinhttps://linuxfr.org/nodes/57034/comments.atom