Racket – Concorrenza e sincronizzazione – 1

l11Continuo lo studio del favoloso Racket, oggi capitolo nuovo, copio da qui: [doc]/guide/concurrency.html.

Racket provides concurrency in the form of threads, and it provides a general sync function that can be used to synchronize both threads and other implicit forms of concurrency, such as ports.

Threads run concurrently in the sense that one thread can preempt another without its cooperation, but threads do not run in parallel in the sense of using multiple hardware processors. See Parallelism [prossimamente] for information on parallelism in Racket.


To execute a procedure concurrently, use thread. The following example creates two new threads from the main thread:

nel terminale:


lanciato da racket:


in DrRacket:


mi sa che conviene usare DrRacket.

The next example creates a new thread that would otherwise loop forever, but the main thread uses sleep to pause itself for 2.5 seconds, then uses kill-thread to terminate the worker thread:


Note: In DrRacket, the main thread keeps going until the Stop button is clicked, so in DrRacket the thread-wait is not necessary.

If the main thread finishes or is killed, the application exits, even if other threads are still running. A thread can use thread-wait to wait for another thread to finish. Here, the main thread uses thread-wait to make sure the worker thread finishes before the main thread exits:


Thread mailboxes

Each thread has a mailbox for receiving messages. The thread-send function asynchronously sends a message to another thread’s mailbox, while thread-receive returns the oldest message from the current thread’s mailbox, blocking to wait for a message if necessary. In the following example, the main thread sends data to the worker thread to be processed, then sends a 'done message when there is no more data and waits for the worker thread to finish.


lo stesso file eseguito nel terminale:


In the next example, the main thread delegates work to multiple arithmetic threads, then waits to receive the results. The arithmetic threads process work items then send the results to the main thread.


naturalmente meglio nel terminale



Racket – creare linguaggi – 6


Continuando finisco  il capitolo copiando da qui [doc]/guide/languages.html, anzi [doc]/guide/module-languages.html.

Configurare la gestione dei moduli

Suppose that the file “death-list-5.rkt” contains


If you require “death-list-5.rkt” directly, then it prints the list in the usual Racket result format:


However, if “death-list-5.rkt” is required by a “kiddo.rkt” that is implemented with scheme instead of racket:

#lang scheme
(require "death-list-5.rkt")

then, if you run “kiddo.rkt” file in DrRacket or if you run it directly with racket, “kiddo.rkt” causes “death-list-5.rkt” to print its list in traditional Scheme format, without the leading quote:


The “kiddo.rkt” example illustrates how the format for printing a result value can depend on the main module of a program instead of the language that is used to implement it.

Unlike the syntax-coloring property of a language (as described in Source-Handling Configuration [Configurare la gestione dei sorgenti]), the result-value format is a property of a module (via its language) as opposed to a property of the module’s source text. That is, the run-time configuration for a module should be available even if the module is compiled to bytecode form and the source is unavailable. Due to this difference, language properties such as run-time configuration are not reported via a get-info function that exported from the language’s parser module, but instead through a separate module whose name is attached to the syntax object for a parsed module form.

Going back to the literal language [], we can adjust the language so that directly running a literal module causes it to print out its string, while using a literal module in a larger program simply provides data without printing. To make this work, we will need three extra module files:

.... (the main installation or the user’s space)
 |- "collects"
      |- "literal"
           |- "lang"
           |    |- "reader.rkt"
           |- "language-info.rkt"   (new)
           |- "runtime-config.rkt"  (new)
           |- "show.rkt"            (new)
  • The “literal/language-info.rkt” module provides reflective information about the language of modules written in the literal language. The name of this module is not special; it will be connected to the literal language through a change to “literal/lang/reader.rkt“.
  • The “literal/runtime-config.rkt” module will be identified by “literal/language-info.rkt” as the run-time configuration code for a main module that uses the literal language.
  • The “literal/show.rkt” module will provide a show function to be applied to the string content of a literal module. The run-time configuration action in “literal/runtime-config.rkt” will instruct show to print the strings that it is given, but only when a module using the literal language is run directly.

Multiple modules are needed to implement the printing change, because the different modules must run at different times. For example, the code needed to parse a literal module is not needed after the module has been compiled, while the run-time configuration code is needed only when the module is run as the main module of a program. Similarly, when creating a stand-alone executable with raco exe, the main module (in compiled form) must be queried for its run-time configuration, but the module and its configuration action should not run until the executable is started. By using different modules for these different tasks, we avoid loading code at times when it is not needed.

The three new files are connected to the literal language by changes to “literal/lang/reader.rkt“:

  • The module form generated by the read-syntax function must import the literal/show module and call its show function.
  • The module form must be annotated with a 'language-info syntax property, whose value points to a get-language-info function exported by a literal/language-info module. The get-language-info function will be responsible for reporting the literal/runtime-config as the run-time configuration action of the language.
  • The 'language-info syntax property value is a vector that contains a module (in this case literal/language-info), a symbol for one of the module’s exports (get-language-info in this case), and an data value (which is not needed in this case). The data component allows information to be propagated from the source to the module’s language information.

These changes are implemented in the following revised “literal/lang/reader.rkt“:

Nota perso: salvo il file reader.rkt precedente come reader-5.rkt, non si sa mai che … :wink:

#lang racket                    ;; literal/lang/reader.rkt
(require syntax/strip-context)
(provide (rename-out [literal-read read]
                     [literal-read-syntax read-syntax])
(define (literal-read in)
   (literal-read-syntax #f in)))
(define (literal-read-syntax src in)
  (with-syntax ([str (port->string in)])
      #'(module anything racket
          (require literal/show)
          (provide data)
          (define data 'str)
          (show data)))
     '#(literal/language-info get-language-info #f))))
(define (get-info in mod line col pos)
  (lambda (key default)
    (case key
       (dynamic-require 'syntax-color/default-lexer
      [else default])))

When a module form with a 'module-language property is compiled, the property value is preserved with the compiled module, and it is accessible via reflective functions like module->language-info. When racket or DrRacket runs a module, it uses module->language-info to obtain a vector that contains a module name, export name, and data value. The result of the function applied to the data should be another function that answers queries, much like the get-info function in a language reader.

For literal, “literal/language-info.rkt” is implemented as:

#lang racket            ;; literal/language-info.rkt
(provide get-language-info)
(define (get-language-info data)
  (lambda (key default)
    (case key
       '(#(literal/runtime-config configure #f))]
      [else default])))

The function returned by get-language-info answers a 'configure-runtime query with a list of yet more vectors, where each vector contains a module name, an exported name, and a data value. For the literal language, the run-time configuration action implemented in “literal/runtime-config.rkt” is to enable printing of strings that are sent to show:

#lang racket            ;; literal/runtime-config.rkt
(require "show.rkt")
(provide configure)
(define (configure data)
  (show-enabled #t))



With all of the pieces for literal in place, try running the following variant of “tuvalu.rkt” directly and through a require from another module:


When using syntax/module-reader to implement a language, specify a module’s language information through the #:language-info optional specification. The value provided through #:language-info is attached to a module form directly as a syntax property.

Nota aggiuntiva (da una pensata notturna): naturalmente funziona tutto anche nel terminale; DrRacket è OK ma non necessario. Tutto questo in attesa di vedere raco :grin:


Quindi, considerazioni personali

Racket è un linguaggio di programmazione programmabile (cit.) :grin: che rende (relativamente facile, seguendo scrupolosamente la procedura) definire il proprio linguaggio personale. Da pensarci su, chissà se serve e quanto serve. Il futuro si sa è imboscato tra le Pastose Appendici del Prodigioso (SSCR) :mrgreen:

Programmazione (pro)logica


Tra i commenti al post Liste infinite1 leggo un commento di zar che chiede:

E di prolog non ne parla più nessuno? Esiste ancora qualcuno che lo usa?

Segue la risposta di glipari.

Di sicuro il Prolog non è uno di quei linguaggi popolari di cui c’è grande richiesta e che fanno trovare lavoro appena usciti dall’università. Non è il Java, con tutto il suo fantastico ecosistema di framework, application server, rule engine

A proposito di rule engine: il Prolog integrato con il C sarebbe perfetto… ma non è roba trendy, non piace, è troppo esotica (ieri si faceva così, continuiamo a fare così), non è roba che dà sicurezza e certezze ai project manager (o chi deve scegliere di adottare una soluzione tecnologica al posto di un’altra), non ci sono colossi che spingono soluzioni del genere, non c’è un know-how diffuso, capillare o centralizzato, non c’è forza lavoro (mentale) a buon mercato…

Una scelta fuori dal coro potrebbe essere la marcia in più per una start-up, ma potrebbe anche segnarne il fallimento… se ciò è ancora accettabile per una start-up, non lo è per chi ha un business in qualche modo già consolidato: questi non vogliono sorprese, ma hanno solo bisogno di “tranquillità”.

Il discorso non vale sempre e ovunque: ogni realtà ha le sue peculiarità. Se il core business di un’azienda non dipende criticamente (almeno secondo quelli che stanno in alto…) dalla tecnologia scelta, stare sullo “spigolo” tecnologico per fare il salto più lungo delle concorrenti non ha senso, perché il terreno di gioco è affatto diverso. Perciò vai di Java e tutto il mondo che ci ruota intorno, così si trovano facilmente competenze per tutte le tasche (e livelli) e supporto eccellente dei prodotti che contano e servono.

Un po’ di tempo fa (tre anni fa) mi ero divertito ad usare il (GNU) Prolog per modellare delle relazioni sociali. Da qui nacque l’idea di un progetto più ampio, un servizio di partner matching (sì, partner matching e non pattern matching) che naturalmente è rimasto su carta, abbozzato in una scarna paginetta A4 (che nemmeno più so che fine abbia fatto). L’engine (brr) che avrebbe eseguito gli algoritmi di ricerca delle corrispondenze ottimali sarebbe stato scritto proprio in un misto di C e Prolog.

Il Prolog è anche ottimo per risolvere alcuni tipi di problemi, perché permette di impostarli con facilità e al resto pensa lui. Per esempio l’ho usato per risolvere un Quesito con la Susi — perdonate l’ennesimo link ad uno dei miei blog…

% gprolog: nth
% swi prolog: nth0
vicino(List, A, B) :-
    nth(IndexA, List, A),
    nth(IndexB, List, B),
    abs(IndexA - IndexB) =:= 1.
chi(Luca, Aldo, Berto) :-
    vicino([4, 0, 2, 1, 3], Luca, Aldo),
    vicino([1, 2, 3, 0, 4], Berto, Aldo),
    \+ vicino([4, 0, 2, 1, 3], Luca, Berto), 
    Luca =\= 0,
    Aldo =\= 0,
    Berto =\= 0,
    Luca =\= Aldo,
    Luca =\= Berto,
    Aldo =\= Berto.

Come vedete si legge con facilità (credo): la procedura vicino/3 ci dice se A e B della lista List sono vicini: lo sono se la differenza tra gli indici della loro posizione nella lista è pari ad 1. nth/3 assegna a IndexA (IndexB) la posizione di A (B) nella lista List. Viene calcolata la differenza (assoluta) tra i due indici e si “dichiara” che debba essere pari a 1. La vicino/3 è vera se sono soddisfatte le tre “dichiarazioni” (la virgola è un and logico). Poiché IndexA in nth(IndexA, List, A) è “libera”, il Prolog le assegna il valore necessario per soddisfare la dichiarazione. Quindi le prime due righe di vicino sono vere, posto che gli elementi si trovino nella lista.

La procedura chi/3 “modella” il problema. Diverse “dichiarazioni” vengono messe in “and”. Il Prolog cerca di assegnare i valori in modo che siano tutte soddisfatte. Quindi, per dire, assegnerà a Luca e Aldo i numeri tali che

vicino([4, 0, 2, 1, 3], Luca, Aldo),

sia vero. Se considerate solo questa riga da sola, i possibili valori di Luca e Aldo che la soddisfano sono svariati: 4 e 0, 0 e 2, 2 e 1, 1 e 3 (e le stesse coppie con valori scambiati); però ci sono tre righe che dicono che Luca, Aldo e Berto non possono avere valore 0; quindi ci restano solo 2 e 1, 1 e 3 (1 e 2, 3 e 1). E così via. Attraverso algoritmi come il backtracking, è possibile trovare la soluzione che soddisfa tutti i diversi vincoli (le “dichiarazioni”): questi vincoli restringono lo spazio dei valori delle “variabili libere” che li soddisfano… Se i vincoli non sono sufficienti a determinare una soluzione unica (cioè ogni “variabile” può avere un solo valore possibile per soddisfare i vincoli), il Prolog non si scompone e ci propone le varie soluzioni.


Una volta “consultato” il file (che ho chiamato susi0.prolog), possiamo “interrogarlo”. In un certo senso quel file rappresenta la conoscenza che ha il sistema. Un file di conoscenza Prolog è una collezione di fatti e regole. Nel nostro caso abbiamo due regole, una che stabilisce il criterio secondo il quale diciamo che due “cosi” sono vicini, e l’altra che risolve il problema (la lettura del quesito può aiutare la comprensione generale).

In questo esempio abbiamo solo delle regole che stabiliscono delle “relazioni”.

Tanto per mostrare che non c’è legame tra i nomi usati nelle regole e quelli passati quando “chiamiamo” la regola, ho rieseguito il goal usando Mario, Unno e Alice. Notare che il goal è un fatto: sto dicendo che tra Mario, Unno e Alice (o Luca, Aldo e Berto) deve valere la relazione chi/3. Questo è l’obiettivo e il Prolog lavora per trovare i valori che rendono vero il “fatto”.

Vediamo qualche altra cosa che possiamo scrivere:

| ?- chi(1, 0, 3).


Qui facciamo una precisa affermazione, con numeri che assegniamo noi. In realtà va letta più come un’ipotesi. E il Prolog ci dice no: quei numeri non soddisfano la regola né corrisponde a un fatto noto (stiamo asserendo qualcosa di falso, cioè la nostra ipotesi, stando ai fatti e alle regole note, non può essere vera).

| ?- chi(3, 1, 2).

true ? 


Qui ho messo i valori giusti e il Prolog dice “vero”. Quando scrive ? il Prolog è fermo in attesa di input, utile nel caso ci fossero soluzioni multiple (non è questo il caso). Digitando ? ottengo un aiuto:

true ? ?
Action (; for next solution, a for all solutions, RET to stop) ? 

Quindi se voglio vedere la soluzione successiva devo premere ;, se voglio che me le scodelli tutte devo premere a; se voglio che si fermi, premo return. In questo caso è un po’ come se dicessi che la soluzione data mi sta bene. Visto che la soluzione è una, se premo qualcosa di diverso da return in questo caso non mi viene presentata nessun’altra soluzione (ovviamente) e scrive no, e con ciò intende semplicemente che non ci sono altre soluzioni.

| ?- chi(p, a, s).


In quest’ultimo esempio ho usato gli atomi p, a, s (cfr. Prolog syntax and semantics). Di questi atomi il sistema non sa nulla: nel knowledge (data) base non c’è nessun fatto che li riguardi. Perciò non potrà mai dirci che quel goal è compatibile con i fatti noti.

Per ora è tutto.

  1. Post del 2011… dovreste aver capito che sto scavando un po’ in questo blog agganciandomi a discorsi fatti o accennati e che per un motivo o per l’altro stimolano i miei interessi.

Linux non sarà mai largamente adottato

SaurabhNon so da dove mi sia arrivato il link al blog di Saurabh Tripathi, studente PhD a Gwalior, 480 km a sud di New Delhi. Devo ancora esaminarlo a fondo ma ci sono parecchie cose, per esempio questo post: Linux Will Never be Adopted Widely, Here is why. Dice cose vere, condivido quasi completamente.

Fine del post. No, aspetta, sarebbe davvero troppo corto. E poi –a dirla tutta-tutta fino in fondo– non è nemmeno tanto originale. Io, per esempio, la storia di AutoCAD l’ho accennata (o raccontata, non ricordo, sapete la mia RAM…) più volte e la do per scontata. E non parlo neanche di GnuPlot, dev’essere il vostro giorno fortunato :wink:

Ma capitano cose anche divertenti, una recentissima che Gwalior mi ha fatto tornare in mente. Adesso vi conto.

Ricevo una mail preoccupata di un mio vecchio amico che non riesce a far funzionare un programmino Python su Windows. Il programma in questione estrae dati da un documento troppo grosso per processarlo a mano. E per di più viene generato periodicamente in automatico, insomma a richiesta avevo scritto qualcosa che automatizza il tutto. Fatto per un PC vecchio con Ubuntu. Ora per standardizzare (e poi quella macchina sta morendo) si è deciso di trasferirlo su Windows. Ma, stranamente, Python per Windows dice che non va.

Sì. Python ha ragione a rifiutarsi di trattare quella roba. Fin dalla prima riga che fa riferimento a /bin/bash (ma è un commento, no?).
E poi in sostanza c’è solo poco più di una chiamata a grep!
Se fossi stato perverso avrei usato awk ma ero giovane e ingenuo allora (qualche anno fa).
Insomma, si potrebbe ma bisogna installare roba e non si vuole.
Sembra incredibile ma con un linguaggio di programmazione normale diventa subito più impegnativo e lungo. Per fortuna c’è Perl –anch’io come Shintakezou :grin:
Perl me l’hanno lasciato installare (forse non se ne sono accorti).


E tutto perché Linux no, mai!
Anzi, da altre parti, c’è chi continua a usare XP: “mi trovo bene con quello” (cit.).

Racket – creare linguaggi – 5


Continuo, oggi qui [doc]/guide/languages.html, cioè qui [doc]/guide/module-languages.html.

Configurare la gestione dei sorgenti

The Racket distribution includes a Scribble language for writing prose documents, where Scribble extends the normal Racket to better support text. Here is an example Scribble document:

#lang scribble/base

@(define (get-name) "Self-Describing Document")


The title of this document is ``@(get-name).''

If you put that program in DrRacket’s definitions area and click Run, then nothing much appears to happen. The scribble/base language just binds and exports doc as a description of a document, similar to the way that “literal.rkt” exports a string as data.


Simply opening a module with the language scribble/base in DrRacket, however, causes a Scribble HTML button to appear. Furthermore, DrRacket knows how to colorize Scribble syntax by coloring green those parts of the document that correspond to literal text. The language name scribble/base is not hard-wired into DrRacket. Instead, the implementation of the scribble/base language provides button and syntax-coloring information in response to a query from DrRacket.


Nota: il messaggio di errore è –al solito– di Firefox.

For security reasons, only languages that have been specifically installed by a user can respond to language-information queries. If you have installed the literal language as described in Installing a Language, then you can adjust “literal/lang/reader.rkt” so that DrRacket treats the content of a module in the literal language as plain text instead of (erroneously) as Racket syntax:

#lang racket                         ;; literal/lang/reader.rkt
(require syntax/strip-context)
(provide (rename-out [literal-read read]
                     [literal-read-syntax read-syntax])
(define (literal-read in)
   (literal-read-syntax #f in)))
(define (literal-read-syntax src in)
  (with-syntax ([str (port->string in)])
     #'(module anything racket
         (provide data)
         (define data 'str)))))
(define (get-info in mod line col pos)
  (lambda (key default)
    (case key
       (dynamic-require 'syntax-color/default-lexer
      [else default])))

This revised literal implementation provides a get-info function. The get-info function is called by read-language (which DrRacket calls) with the source input stream and location information, in case query results should depend on the content of the module after the language name (which is not the case for literal). The result of get-info is a function of two arguments. The first argument is always a symbol, indicating the kind of information that a tool requests from the language; the second argument is the default result to be returned if the language does not recognize the query or has no information for it.

After DrRacket obtains the result of get-info for a language, it calls the function with a 'color-lexer query; the result should be a function that implements syntax-coloring parsing on an input stream. For literal, the syntax-color/default-lexer module provides a default-lexer syntax-coloring parser that is suitable for plain text, so literal loads and returns that parser in response to a 'color-lexer query.

The set of symbols that a programming tool uses for queries is entirely between the tool and the languages that choose to cooperate with it. For example, in addition to 'color-lexer, DrRacket uses a 'drracket:toolbar-buttons query to determine which buttons should be available in the toolbar to operate on modules using the language.

The syntax/module-reader language lets you specify get-info handling through a #:info optional specification. The protocol for an #:info function is slightly different from the raw get-info protocol; the revised protocol allows syntax/module-reader the possibility of handling future language-information queries automatically.

Pausa che devo assimilare :mrgreen:

Sulla steganografia

Immagino che siate in trepidante attesa del seguito di Macchine a stati finiti e pattern matching, o dovete ancora digerire quel malloppo… tranquilli, perché devo trovare il tempo di impegnarmi a scriverlo (suspense…) e su due piedi non mi viene.

Quindi, nel frattempo…


Scavo un po’ questo blog e trovo Due immagini identiche non proprio uguali…. A me la steganografia è sempre piaciuta un sacco; purtroppo quando se ne parla popolarmente spesso e volentieri si fa confusione e si dicono sciocchezze. E poi si fa sempre e solo il classico esempio di “qualcosa” nascosto dentro un’immagine.

Ma perché un’immagine? Forse perché è qualcosa di più “spendibile” in un film o in un racconto? Fa più scena, insomma. Come Nella morsa del ragno.

In quel mio articolo racconto la storiella del «greco [che] scrisse un messaggio sulla testa rasata di un suo schiavo, aspettò che gli crescessero i capelli e gli ordino di recarsi nella città del suo amico destinatario», solo che la ricordavo diversa. Ma il succo è lo stesso ed è ciò che conta.

Qualche giochetto steganografico e molte altre cose si possono apprendere anche da qui. È un gioco e se vi va di giocare non ve ne pentirete. Tanto per capirci (forse), dietro c’è Davide Eynard; parliamo di pezzettini di certa storia. E a proposito, Lore updated 6 years, 5 months and 6 days ago, dice… questo mi mette un po’ di nostalgia (perché 8 anni fa ero più giovane e pensavo che quel sito mi avrebbe fornito materiale nuovo fino all’eternità).

Torniamo in tema: sempre se la memoria non mi tradisce, è lì (giocando su 3564020356) che appresi e la storiella e del libro di Trithemius sulla steganografia… È anche su archive.org. Dovete ripassare un po’ di latino (ma non è il latino di Cicerone, si legge un po’ più facilmente… ehm). Trovate anche cose come Solved: The Ciphers in Book iii of Trithemius’s Steganographia. Sempre per capirci, Trithemius è l’autore di Polygraphia, «the first printed book on cryptography» (lo trovate scansionato su Books Google, se vi interessa).


Naturalmente non poteva non parlarne pure l’NSA, che ci dà anche altri titoli che val la pena leggere nelle fredde serate infernali.


Dicevamo appunto che la steganografia non deve per forza nascondere “qualcosa” in un’immagine, come dimostra la storia del greco.

Oh,     tremenda    tormenta     /
che  mi   bloccò sul     monte!    /
Così  forte    il  vento che    pure /
Harry   Potter, con      gli incantesimi     /
e   le     pozioni  e    /
i   suoi amici   e   la   sua     fortuna,   /
poteva rimanerci secco!    /
Ancora  non capisco    come   riuscii    a   resistere, /
né      donde  venissero  /
i soccorsi     tanto   sperati,      /
che   mi   presero per     i    capelli!  /
Ora    posso      dire d'esser     vivo!   /

Banale ma rende l’idea (o no?). Il seguente programmino può codificare un testo in un testo usando gli spazi. Scusate se ho usato il Perl ma, nonostante sia arrugginito, lo trovo sempre più pratico per fare al volo certe cose!

use strict;
my @frags = ();
my @msg = grep /[A-Z]/, split('',$ARGV[0]);
foreach my $c (@msg) {
    my $a = ord($c) - ord("A");
    push @frags, ($a & 0x1C) >> 2;
    push @frags, ($a & 0x03);
my @lines = ();
while (<STDIN>) {
    my @w = split /\s+/;
    my $s = "";
    foreach my $l (@w) {
        my $n;
        if (@frags > 0) {
            $n = shift @frags;
        } else {
            $n = 0;
        $s .= $l . (" "x($n+1));
    print $s . "/\n";
print STDERR "left: ".@frags."\n" if @frags>0;

Ora a voi sta scrivere il programma di decodifica (poi lo farò pure io per verificare di aver scritto bene quello di codifica:-D…) Dunque c’è la poesia, che non è il messaggio, ma il messaggio non è nemmeno «occheipanico»… c’è ancora un altro livello. E se ce ne fosse un altro ancora (a parte quello allegorico, che avrete notato…)? …

A proposito… il programmino lo potete usare così:

perl encospace.pl "TESTO" <contenitore.txt

(potete usare solo le lettere maiuscole).


Racket – creare linguaggi – 4

kk2Oggi qui: [doc]/guide/languages.html, in particolare qui: [doc[/guide/module-languages.html dove continuo a copiare.

Installare un linguaggio

Sono qui: [doc]/guide/language-collection.html.
So far, we have used the reader meta-language to access languages like “literal.rkt” and “dollar-racket.rkt“. If you want to use something like #lang literal directly, then you must move “literal.rkt” into a Racket collection named “literal” (see also Adding Collections [qui: [doc]/guide/module-basics.html]). Specifically, move “literal.rkt” to “literal/lang/reader.rkt” for any directory name “literal“. Then, install the “literal” directory as a package.

OOPS! ecco:




OK, procedo, ecco:


e, magia!


Note: raco: Racket Command-Line Tools [[doc]/raco/index.html] for more information on using raco.
Lo farò prossimamente, è previsto nell’indice della guida (cap. 21, sono al 17).

You can also make your language available for others to install by using the Racket package manager (see Package Management in Racket [[doc]/pkg/index.html]). After you create a “literal” package and register it with the Racket package catalog (see Package Catalogs [[doc]/pkg/Package_Concepts.html#(part._concept~3acatalog)]), others can install it using raco pkg:

raco pkg install literal

Once installed, others can invoke the language the same way: by using #lang literal at the top of a source file.

If you use a public source repository (e.g., GitHub), you can link your package to the source. As you improve the package, others can update their version using raco pkg:

raco pkg update literal

Note: See Package Management in Racket [[doc]/pkg/index.html] for more information about the Racket package manager.

After moving the file and installing the package, you can use literal directly after #lang:

Mmmm, pausa :grin: devo vedere un po’ di cose :mrgreen:

Racket – creare linguaggi – 3

bb4Continuo, oggi qui [doc]/guide/languages.html, anzi qui [doc]/guide/module-languages.html.

Definire nuovi linguaggi #lang

When loading a module as a source program that starts

#lang language

the language determines the way that the rest of the module is parsed at the reader level. The reader-level parse must produce a module form as a syntax object. As always, the second sub-form after module specifies the module language that controls the meaning of the module’s body forms. Thus, a language specified after #lang controls both the reader-level and expander-level parsing of a module.

Pronto a passare qui: [doc]/guide/hash-lang_syntax.html.

Definire un nuovo linguaggio #lang

The syntax of a language intentionally overlaps with the syntax of a module path as used in require or as a module language, so that names like racket, racket/base, slideshow, or scribble/manual can be used both as #lang languages and as module paths.

At the same time, the syntax of language is far more restricted than a module path, because only a-z, A-Z, 0-9, / (not at the start or end), _, -, and + are allowed in a language name. These restrictions keep the syntax of #lang as simple as possible. Keeping the syntax of #lang simple, in turn, is important because the syntax is inherently inflexible and non-extensible; the #lang protocol allows a language to refine and define syntax in a practically unconstrained way, but the #lang protocol itself must remain fixed so that various different tools can “boot” into the extended world.

Fortunately, the #lang protocol provides a natural way to refer to languages in ways other than the rigid language syntax: by defining a language that implements its own nested protocol. We have already seen one example (in Using [Uso di] #lang s-exp): the s-exp language allows a programmer to specify a module language using the general module path syntax. Meanwhile, s-exp takes care of the reader-level responsibilities of a #lang language.

Unlike racket, s-exp cannot be used as a module path with require. Although the syntax of language for #lang overlaps with the syntax of module paths, a language is not used directly as a module path. Instead, a language is suffixed with /lang/reader to obtain a module path, and the resulting module supplies read and read-syntax functions using a protocol that is similar to the one for #reader.

Note: Reader Extensions [qui] introduces #reader.

A consequence of the way that a #lang language is turned into a module path is that the language must be installed in a collection, similar to the way that “racket” or “slideshow” are collections that are distributed with Racket. Again, however, there’s an escape from this restriction: the reader language lets you specify a reader-level implementation of a language using a general module path.

OK, passo a [doc]/guide/hash-lang_reader.html.

Uso di #lang reader

The reader language for #lang is similar to s-exp, in that it acts as a kind of meta-language. Whereas s-exp lets a programmer specify a module language at the expander layer of parsing, reader lets a programmer specify a language at the reader level.

A #lang reader must be followed by a module path, and the specified module must provide two functions: read and read-syntax. The protocol is the same as for a #reader implementation, but for #lang, the read and read-syntax functions must produce a module form that is based on the rest of the input file for the module.

The following “literal.rkt” module implements a language that treats its entire body as literal text and exports the text as a data string:


The “literal.rkt” language uses strip-context on the generated module expression, because a read-syntax function should return a syntax object with no lexical context. Also, the “literal.rkt” language creates a module named anything, which is an arbitrary choice; the language is intended to be used in a file, and the longhand module name is ignored when it appears in a required file.

The “literal.rkt” language can be used in a module “tuvalu.rkt“:


Importing tuvalu.rkt binds data to a string version of the module content:


OK, passo a [doc]/guide/syntax_module-reader.html.

Uso di #lang s-exp syntax/module-reader

Parsing a module body is usually not as trivial as in “literal.rkt“. A more typical module parser must iterate to parse multiple forms for a module body. A language is also more likely to extend Racket syntax—perhaps through a readtable—instead of replacing Racket syntax completely.

The syntax/module-reader module language abstracts over common parts of a language implementation to simplify the creation of new languages. In its most basic form, a language implemented with syntax/module-reader simply specifies the module language to be used for the language, in which case the reader layer of the language is the same as Racket. For example, with






implements and exports the identity function, since “raquet-mlang.rkt” exports lambda as function.

The syntax/module-reader language accepts many optional specifications to adjust other features of the language. For example, an alternate read and read-syntax for parsing the language can be specified with #:read and #:read-syntax, respectively. The following “dollar-racket.rkt” language uses “dollar.rkt” (see Readtables) to build a language that is like racket but with a $ escape to simple infix arithmetic:


The require form appears at the end of the module, because all of the keyword-tagged optional specifications for syntax/module-reader must appear before any helper imports or definitions.

The following module uses “dollar-racket.rkt” to implement a cost function using a $ escape:



Macchine a stati finiti e pattern matching (parte 2)


Nell’articolo precedente vi ho fatto ricordare dell’Amiga, vi ho rivelato che aveva le sue espressioni regolari per fare pattern matching, vi ho indotto a (ri)leggere tre articoli di questo blog, e… (questo non lo sapete, ma) prima di pubblicarlo ho tagliato un paio di lunghi paragrafi che discettavano un po’ di linguaggi, metalinguaggi e divagazioni annesse e (s)connesse. Ora forse si capiscono meglio certe affermazioni che ho lasciato e che non si adattano benissimo al testo pubblicato; però vanno sempre bene come “scuse” anticipate per il futuro.

Dimenticavo: avevo anche detto che avremmo affrontato la prima fase: “fare” una macchina a stati finiti (FSM). Mi sono seduto e ho buttato giù un po’ di codice che ora rivediamo assieme. Lo trovate nel mio “parco giochi” su github, precisamente qui.

Le classi necessarie al gioco vivono nel namespace mFSM: visto che ho usato nomi molto poco particolari come State, Connection, Rule… non è una brutta idea metterli in un namespace ad hoc.


L’idea guida alla base è come viene di solito rappresentata una FSM; qualcosa come


Ogni stato è un cerchio con un “nome” (un’etichetta) e poi degli archi in uscita e in entrata. La freccia che non ha un’origine indica lo stato iniziale della macchina. Su ogni arco è indicato l’“evento” (nel nostro caso, la ricezione di un carattere) che fa passare la macchina dallo stato da cui esce l’arco allo stato in cui tale arco è entrante (insomma, nella direzione della freccia). Lo stato “a doppio cerchio” è uno stato “finale”: se la macchina, terminato il suo lavoro, si trova in uno di questi stati finali (accepting states, «stati che accettano [l’input e lo riconoscono come facente parte del linguaggio]»), significa che la stringa processata è una stringa corretta del linguaggio.

La macchina dirà allora: io, Macchina, accetto te come legittima stringa

Vi siete già imbattuti in questa roba:


Sarebbe bello poter dire: lo stato S1 è uno stato finale, la macchina passa dallo stato S1 a S2 quando riceve uno 0, ma resta sullo stato S1 quando riceve 1, ecc.

In effetti basterebbe poter descrivere il graf(ic)o così: lo stato S1 va a S2 tramite l’arco 0, va a sé stesso tramite l’arco 1; lo stato S2 va a S1 tramite l’arco 0, va a sé stesso tramite l’arco 1; infine, lo stato S1 è uno stato finale accettabile.


Quindi per noi lo stato è un cerchio singolo o doppio con un’etichetta inscritta. Questi elementi fanno parte della sua identità e sono “passivi” e “statici”. Farne una classe è semplice

class State
    State(const std::string& name, bool final=false);
    bool accept() const;
    const std::string& name() const;
    void setFinal(bool final=true);
    std::string name_;
    bool final_;

La maggior parte degli stati non sono final, da cui il default sul costruttore; ci sono due getter (per il nome e final) e un setter, nel caso volessimo cambiare final dopo aver creato l’istanza. (Se creiamo noi gli stati, serve a poco; ma vedrete dopo che la creazione degli stati può essere fatta implicitamente da un’altra classe).

Uno stato ha anche degli archi uscenti; potremmo farne uno stato consapevole del fatto che, quando riceve un certo messaggio, può dover passare il cerino ad un altro stato. Dal punto di vista della macchina nel suo insieme, lo stato con il cerino è quello in cui si trova la macchina (lo stato corrente). Con questa metafora posso dire che gli archi descrivono la “dinamica”, e ogni stato conosce la parte che gli compete, cioè i suoi archi che vanno (se valgono certe condizioni) verso un altro stato.

La classe AwareState, derivata da State1, aggiunge due cose: un metodo per stabilire un arco (onRule) e uno per iterare sugli archi. Quest’ultimo metodo è usato dal “supervisore”, cioè dal codice che fa girare la macchina: lo stato è sì “consapevole” delle sue relazioni regolate, ma non è lui a tenere traccia di chi ha il cerino e a decidere cosa farne se la regola si rivela valida o no.

Però lo stato deve fornire gli elementi affinché il “supervisore” possa decidere, e lo fa senza esporre i dettagli sul come mantiene le connessioni2: il chiamante invoca il metodo overConnectionsDo fornendo come argomento una funzione che riceve una regola (Rule) e lo stato di destinazione. Il “supervisore” applica la regola sull’input (di cui lo stato non è aware) che sta elaborando e decide se mantenere lo stato corrente o passare a quello di destinazione.

Non è un design entusiasmante… però ci permette di buttare in pentola una cosa del C++11: l’header functional ci dà std::function<...> tramite il quale è facile specificare il “prototipo” della funzione che ci aspettiamo come argomento… e che potrà essere — e sarà — una closure

bool AwareState::overConnectionsDo(
        std::function<bool(const Rule*,
                       const std::string& stateName)> action) const
    for (auto& c : connections_) {
        if (action(c.rule, c.destState)) {
            return true;
    return false;

Usando altre due comodità del C++11 (ovvero auto e il for each che ci permette di iterare sugli elementi di una classe itarabile) passiamo in rassegna le “connessioni”; se l’action ritorna vero, usciamo a nostra volta con vero; altrimenti proseguiamo con la “connessione” successiva. Se per nessuna delle connessioni l’action ha restituito true, allora ritorniamo al chiamante con false. (Nel codice ho messo una versione alternativa di cui parlo alla fine.)

Praticamente ci aspettiamo che il chiamante usi action per segnalarci quando ha trovato una regola soddisfacente (solo il chiamante sa qual è l’input!) Se abbiamo più regole che danno true, la nostra FSM è malfatta. Non c’è nessun controllo nel codice per impedire ciò: sta a chi la costruisce non creare situazioni strane.

L’ordine delle regole va considerato arbitrario, cioè non dobbiamo far affidamento su un ordine preciso di controllo per fare magari qualche trucchetto strano. Nella specifica implementazione le regole ordinate in base alla dimensione dell’insieme di caratteri che possono soddisfarla. Quindi any, che è l’unica regola che acchiappa tutto (dunque 256 codici…), starà sempre in fondo.

AwareState& AwareState::onRule(const Rule* rule, const AwareState* dest)
    Connection con{rule, dest->name()};
    connections_.sort([](const Connection& a, const Connection& b)->bool {
            return a.rule->size() < b.rule->size();
    return *this;

L’ordinamento è fatto passando una funzione anonima (di fatto una lambda function) al metodo sort gentilmente offerto da list, che è la classe di connections_.

Per capire qual è il problema che l’ordinamento risolve, consideriamo le regole a, any, ~b controllate in quest’ordine. Non hanno molto senso: se l’input è a (1) prendiamo la prima; in tutti gli altri casi si applica any (256) e mai ~b (255). Se l’ordine fosse a, ~b, any, l’input a verrebbe catturato dalla prima, c dalla seconda e b, infine, dalla terza. I numeri tra parentesi contano i caratteri per i quali la regola è valida (un ottetto ha 256 possibili valori).


AwareState mantiene le connessioni tramite una lista (list) in cui mettiamo le coppie 〈regola, nome dello stato di destinazione〉 (struttura Connection). Ho usato il nome invece del puntatore (passato in onRule) perché c’era un meccanismo che distruggeva e ricreava gli stati e in questo modo si evitavano puntatori ballerini (dangling pointer). Naturalmente i nomi vanno risolti, e questo è a carico della classe FSM che mantiene un’anagrafe di stati e regole.

Le regole (Rule)

Un arco parte da uno stato (che è quello che lo mantiene, nella lista connections_ di AwareState) e finisce in un altro (Connection.destState) “tramite” una regola, modellata dalla classe Rule. Con “tramite” intendo dire che c’è (o ci dovrebbe essere…) una relazione tra l’avvenuta o mancata transizione e la validità dell’input rispetto alla regola in questione (e dirò anche, in alternativa, che la regola è valida per quell’input).

La regola è espressa tramite una stringa e si applica a un singolo carattere in input (passato come int). Quando dico carattere intendo in realtà byte: il codice non gestisce stringhe in codifiche multibyte. Il metodo satisfiedBy ritorna vero se il carattere soddisfa la regola, falso altrimenti.

Dal codice per satisfiedBy si capisce che le regole sono pochine: match esatto, qualunque carattere e infine match con tutto tranne un carattere specifico. Possiamo espanderle a piacere anche con l’intento di semplificare la macchina3.

Cosa accade se la regola è soddisfatta dipende dalla funzione action passata a overConnectionsDo. Il metodo viene invocato da FSM::feed.

Le regole possono venir usate più volte da diversi stati: la regola che accetta la a è sempre la stessa, sia che la usi lo stato X sia che la usi lo stato Y. Questo fatto viene sfruttato dalla classe FSM, che ha un magazzino di regole.


La classe FSM mette insieme un po’ tutte le altre classi, usandole in modo opportuno. È la classe che “rappresenta” la macchina a stati finiti ed è contemporaneamente la classe che la fa “girare”.

Per costruire la nostra macchina usiamo principalmente connect, che crea implicitamente gli stati di cui non conosce il nome; tuttavia crea stati non-final di default, per cui gli stati final vanno creati esplicitamente a parte.

m.state("S1", true);
m.connect("S1", "S2", "0");
m.connect("S1", "S1", "1");
m.connect("S2", "S1", "0");
m.connect("S2", "S2", "1");

L’ultima riga definisce lo stato di partenza; in questo caso non serviva perché il primo stato creato è anche quello di partenza.

La macchina m così creata è quella dell’esempio di wikipedia e serve per vedere se un numero ha un numero pari di 0.

Come usiamo questa macchina? Abbiamo due modalità principali.

Una è quella passo-passo: le diamo in pasto dei caratteri (tramite il metodo feed) e lei si comporta di conseguenza, cambiando il suo stato (oppure no…). Quando abbiamo finito possiamo sapere se la macchina è in uno stato final usando il metodo accepted(). Se vogliamo riusare la macchina per un’altra sequenza, dobbiamo riportarla allo stato iniziale (metodo rewind).

L’altra modalità prevede di far girare la macchina su una stringa (run). Questo metodo parte sempre dallo stato iniziale, ma al termine lascia la macchina nello stato dove l’input l’ha condotta; perciò dovete chiamare rewind se dopo un run volete usare feed con la macchina nello stato iniziale.

Il metodo run ha due modi diversi di funzionamento: uno strict, in cui l’assenza di una regola che gestisca l’input interrompe il processamento e restituisce false (però la macchina potrebbe essere ferma su uno stato final… sta al chiamante decidere che fare…); un altro in cui ogni carattere per il quale non c’è una regola lascia la macchina indifferente (si passa al carattere successivo rimanendo nello stesso stato). Il default è la versione “rilassata”; si può cambiare chiamando il metodo strict(true).

Il metodo feed è un po’ il cuore dell’esecuzione. Dopo un breve preambolo per assicurarsi che ci sia uno stato iniziale e quello corrente, abbiamo una bella closure passata al metodo overConnectionsDo dello stato corrente.

    const AwareState* next_current = current_;
    bool matched = current_->overConnectionsDo(
        [c,&next_current,this](const Rule* r, const std::string& s)->bool {
            if (r->satisfiedBy(c)) {
                if (this->states_.count(s) > 0) {
                    next_current = states_[s];
                return true;
            return false;
    current_ = next_current;    

Se andate a vedere il codice di overConnectionsDo, vedete che è un ciclo sulle “connessioni”, cioè sulle coppie 〈regola, stato destinazione〉. È quello che la funzione riceve in ingresso (r e s). Oltre agli argomenti, la funzione “cattura” c, next_current e this. Poiché abbiamo bisogno di cambiare next_current, lo catturiamo per riferimento (this è un puntatore e quindi automaticamente con this->states_ facciamo riferimento all’istanza e non ad una sua copia).

Se il carattere c soddisfa la regola che lo stato ci ha passato, allora il prossimo stato sarà quello specificato da s, posto che esista. Alla fine della giostra matched sarà vero se c soddisfa almeno una delle regole r, e sarà falso altrimenti (se nessuna regola è stata soddisfatta).


Il codice testFSM.cpp crea alcune FSM e le mette alla prova. In particolare ho creato la FSM corrispondente al pattern #?.info… Il pattern non richiede che dopo .info non ci sia altra roba. Sapete modificare la FSM in modo che la stringa da verificare debba finire esattamente con .info? (Con le RE ciò equivale a .*\.info$4).

Trovate anche la macchina per la grammatica a(ab)n e quella per riconoscere i codici 12A45 o 22B48 (cfr. Macchine a stati 2). Potete aggiungere tutti i test che volete per verificare che si comporti come vi aspettate… Se trovate un bug, sono qui per schiacciarlo… sempre tempo permettendo!

Sul codice

Non ci dovrebbero essere cose particolarmente difficili.

Ho cercato di mettere un minimo di enfasi su ciò che personalmente trovo più interessante nel C++11, ovvero le funzioni che stanno guadagnando il posto di cittadini di prima classe e ci permettono di adottare un po’ del paradigma funzionale. A tal scopo, oltre a functional, ho incluso algorithm per riscrivere il codice di overConnectionsDo usando std::any_of, che restituisce vero se per uno qualunque degli elementi il predicato ritorna vero (qui il predicato è data dalla nostra action, che dobbiamo però wrappare in un’altra closure per “adattare” gli argomenti5).

bool AwareState::overConnectionsDo(
    std::function<bool(const Rule*,
                       const std::string& stateName)> action) const
    return std::any_of(connections_.begin(),
                       [&](decltype(connections_.front()) c) {
                           return action(c.rule, c.destState);

Un’altra cosa che torna comoda è poter demandare al compilatore l’ingrato compito di “capire” il tipo giusto di un dato, visto che lui può dedurlo; alle volte non è solo ingrato, ma anche piuttosto complicato (non è il caso del codice della FSM, ma il discorso è generale). Su questo versante ho usato due novità: auto e decltype, che vedete nel frammento sopra. Sconsiglio l’uso di decltype come l’ho usato io: l’ho fatto solo per farvi vedere che, volendo, si può fare… (a mano avremmo scritto const Connection&).

Infine, tutto vive in due file soltanto, FSM.cpp e FSM.hpp. In teoria sarebbe più carino se avessimo State.cpp, AwareState.cpp, Connection.cpp, Rule.cpp, FSM.cpp e relativi .hpp. Ma viste le dimensioni del tutto, non credo che sia un peccato troppo grande aver fatto un nunico malloppo.


Per divertirvi con i test, la compilazione è

g++ -I src/ -std=c++11 src/FSM.cpp src/testFSM.cpp -o testFSM.cpp

Questo se state nella root del progettino (un livello sopra src). Forse ci aggiungerò un Makefile in futuro.

  1. Poteva esserci anche una sola classe State, che fosse già anche consapevole, visto che State normale non è usata… Potete provare come esercizio ad eliminare State incorporandola direttamente in AwareState (poi potete rinominarla in State). È andata così perché prima è uscita la classe, piuttosto ovvia, State e solo dopo mi sono trovato a dover scegliere come rappresentare le “connessioni” tra i diversi stati. Dalla scelta fatta è nato l’AwareState

  2. Questo perché per progetto le “connessioni” sono informazioni che lo stato tiene con sé, diventando “stato consapevole”, AwareState. Si poteva fare diversamente, forse meglio: una classe che descriveva tutta la FSM: dallo stato Si si va allo stato Sj quando la regola Rn è valida… ecc. Il “supervisore” non avrebbe fatto altro che leggere questa descrizione e agire basandosi su di essa e sull’input. Invece per ciascuno stato l’informazione che serve al “supervisore” è nello stato stesso, per cui c’erano almeno due opzioni: un getter per ottenere la lista degli archi uscenti (connections_), o un metodo che invoca una funzione su ciascuna connessione trovata — ogni “connessione” è una “regola” e uno stato destinazione.

  3. Per esempio: se il carattere è in un elenco (immaginate [0-9]), salta allo stato Sn. Dobbiamo fare un arco per ciascun carattere; se la Rule consentisse il match con un elenco, ci risparmieremmo un po’ di archi.

  4. Invece nel caso dei pattern Amiga è implicito, nel senso che il match è sempre esatto; con le RE è come se scrivessimo sempre ^...$ (dove ... rappresenta il resto della RE); quindi in realtà il pattern che la FSM implementa è #?.info#? e non #?.info.

  5. Si potrebbe usare std::function<bool(const Connection&)> e risparmiarci un livello: il predicato sarebbe direttamente action.

Visto nel Web – 203

Questa settimana –beh, ve ne sarete accorti tutti: Shintakezou rockz!
E le visite al blog sono almeno raddoppiate, i brockers consignano “buy”. A me resterebbe da capire cosa vogliono dire sia “shintake” che “buy” ma so bene che “l’erba voglio non c’è…”. Per intanto ecco cosa ho visto nel Web.
Edward SnowdenTalks Alien Communications With Neil deGrasse Tyson
::: Slashdot

Umberto e il cerchio delle bufale
a una certa età si rischia di diventare –come dire. Avete presente Salamanca? Ecco (due C nèh!) :wink:
::: manteblog

E-commerce libero o proprietario? Il caso Magento
::: Tech Economy

Oltre al compleanno di google, oggi è il giorno in cui Richard Stallman decise di creare un “free unix”
OK, era domenica scorsa ma voglio ricordarlo
::: gigitux

A macro is just a function that showed up too early
::: krisajenkins


Cosa dice l’accordo Usa-Cina sulla cybersicurezza (e perché dubitare serva a qualcosa)
::: Chiusi nella rete

Genuinely stunned France has adopted the word “wifi”
::: webofevil

The No.1 APP for idea creation and productivity
::: JamesBlute

Mark Zuckerberg isn’t trying to provide Internet access everywhere
::: dangillmor

50 Shades of Go: Traps, Gotchas, and Common Mistakes for New Golang Devs
::: Devs Security


The JavaScript Ecosystem Demystified
::: Differential’s

Rilasciato Lubit 6 nome in codice AKI
::: Marco’s Box

Five years of LibreOffice
::: The Document Foundation

Spawned Shelter!
::: Spawned Shelter

quick network tip/test, add this to your shell config
::: ghantoos


PC Lenovo venduti ancora con applicazioni potenzialmente pericolose pre-installate
::: Tech Economy

Could big data and wearables help the fight against diseases?
::: Daniel Lemire

Python for Bash scripters: A well-kept secret
::: Red Hat Magazine

The Future of the News Business: A Monumental Twitter Stream All in One Place
::: a16z

Meanwhile, a thousand people at Fort Meade just opened Twitter
::: Snowden ::: Popular Science


When praising Apple for its commitment to privacy
::: garybernhardt

Huge if confirmed > Twitter Plans to Go Beyond Its 140-Character Limit
::: fabiochiusi

Why IPython is the best thing since sliced bread
::: Python For Engineers

Un Hackathon Scratch per valorizzare la creatività dei ragazzi
::: CoderDojo Voghera

terminalCV: the resume for hackers and sysadmins
::: opsfile


Interim OS is a radical new operating system with a focus on minimalism. It steals conceptually from Lisp machines (language-based kernel) and Plan 9 (everything is a file system). It boots to a JITting Lisp-like REPL and offers the programmer/user the system’s resources as filesystems.
::: mntmn

Il Sistema Operativo Universale
::: Dario Cavedon (iced)

The Global Struggle To Prevent Cyberwar
::: Slashdot

Cosa cambia per la libertà di tutti noi ora che anche Snowden è su Twitter
::: CheFuturo

#agendadigitaleER i cittadini emiliano romagnoli e il web…
sarebbe bello saperne di più
::: masomasetti


If you have a problem, and you think the solution is using regular expressions
non sempre, anzi proprio adesso… -1 :grin:
::: abt_programming

Functions without ”function”
::: Medium

#OpenLibri: Codice Libero – Free as in Freedom
::: Tech Economy

Open source, alleato dell’insegnamento
::: Oggi Scienza

Google and Microsoft Agree To Stand Down In Patent Wars
::: Slashdot


Functional-navigational programming in Clojure(Script) with Specter
::: thoughts from the red planet

Sempre più in basso
un ‘puter vero a $9
::: Apogeonline

Yay! new ‘Jessie’ Raspbian on @Raspberry_Pi
::: zosho

Python SuperSmoother
::: jakevdp

gatspy: General tools for Astronomical Time Series in Python
::: astroML

New York 1940

New York 1940

IBM Scientists Find New Way To Shrink Transistors
::: Slashdot

Read our story of the Ubuntu Edge campaign that broke crowdfunding records
::: ubuntu

Community Ubuntu: istruzioni per l’uso
::: Tech Economy

Zuckerberg, buon pastore. Internet.org si aggiusta in Free Basics by Facebook
::: Luca De Biase

Siete stressati? Vi dovete sfogare ma non vi va di distruggere il servizio buono?
::: CodePen


A vim Tutorial and Primer
::: Daniel Miessler

The ‘Microsoft Loves Linux’ Baloney is Still Being Floated in the Media While Microsoft Attacks Linux With Patents, New Lawsuits Reported
::: Techrights

Adblock è stato venduto: ora mostrerà le pubblicità ritenute accettabili
::: Downloadblog

SBTB 2015: Li Haoyi, A Better Scala REPL?
::: YouTube

Hack the derivative
::: Code Words

In esclusiva, solo per (milioni come) te, perché Linux non sarà mai Apple
vecchio di 3 anni ma concordo con Dario, è importante e attuale :grin:
::: Dario Cavedon (iced)


Twitter noob Snowden gets hammered with 47GB of notification emails
::: Engadget

FLIF: The Newest Free Software Image Format For Smaller Web Images
::: [Phoronix]

Sei miti da sfatare a proposito di Open Access

Got a new URL for #awesomewm
conosco chi ne parla mooolto bene
::: juldanjou

In case of fire
::: hmemcpy


Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 89 follower