Lisp – cl-launch – 1

1200x400Continuo da (indovina?) qui: Lisp – cl-launch – 0.
Sì ho problemi di titolazione, ma ci sto lavorando, prossimamente… forse… :wink:

Sono sempre alle prese con cl-launch, voglio provare con un esempio pratico. Pensa che ti ripensa mi è venuto di pensare che potrebbe essere una bella pensata la sequenza di Leonardo Pisano, Fibonacci per gli amici.

Adesso se uno volesse fare le cose per bene seguirebbe François-René, Faré. Questo è come la racconta lui.
Panico :evil:

OK, a frequentare i nerd non ti capita mai e poi mai (assolutamente mai) di trovarti nella stanza sbagliata (che sarebbe poi quella dove il più nerd sei tu). Vista così va meglio e mi da la forza di continuare.

La mia versione è decisamente più realistica:

(defvar n)
(defun fib (x &optional (y 0) (z 1))
   (if (< x z)
     nil
     (append (list z) (fib x z (+ y z)))))

(defun start (n)
   (format t "~a~%" (fib n)))

che gira così:

cl9

Con qualche piccola aggiunta diventa la versione per cl-launch:

#!/usr/bin/cl --entry start
(defvar n)
(defun fib (x &optional (y 0) (z 1))
   (if (< x z)
     nil
     (append (list z) (fib x z (+ y z)))))

(defun start (argv)
   (setf n (parse-integer (car argv)))
   (format t "~a~%" (fib n)))

Notare la shebang con l’opzione --entry e la variabile speciale argv. argv è una lista di stringhe (si vede nel post precedente) per cui devo fare un cast e –pensa te!– mi è venuto car invece di first (chi va con lo zoppo il nerd…).

cl10

Ahemmm… no :evil:
Si deve abilitare (stavo per scrivere chmodare ma poi Sergio…):

cl11

OK :grin:

Ho provato anche a creare l’immagine ma ottengo un errore, eventualmente una cosa per il futuro. Ho anche installato Quicklisp, dal suo sito.

Da parecchio tempo ormai sono conosciuto come pythonista. Anzi agli albori del blog gli amici blogger (quasi tutti passati a cose diverse, più serie, remunerative) mi avevano anche affibbiato un cognome subclassando dal Guido, m’è rimasto (con problemi di pronuncia: van si dice fan e Juhan Giu-an, nèh). Allora da pythonista mi viene da scrivere:

#!/usr/bin/python3
import sys

lim = int(sys.argv[1])
a, b = 1, 1
fib = [a, b]
while b < lim:
	a, b = b, a + b
	fib.append(b)
fib.pop(-1)
print(fib)

cl12

Ecco, non so se sono solo io ma mi viene da ragionare in modo differente. E se per il Lisp posso essere ripreso per aver usato una variabile globale –sarebbe bastato un let— qui la lista viene troppo lunga e devo rimuovere l’ultimo elemento :oops: Sì, si può fare di meglio in entrambi i casi ma ho messo quello che mi è venuto in mente al volo.

cl13

Un confronto impietoso. Facendo la media tra 7 run, eliminando i casi migliore e peggiore, è risultato che il tempo richiesto da cl-launch è 14 volte quello richiesto da Python 3.
E, a rincarare le cose anche la RAM, guarda qua (tre lanci in rapida sequenza):

cpu

Faré ne parla, purtroppo la documentazione è dispersa e non sempre lineare, vedi il link sopra.

Continua, forse… anche perché OOPS! :oops: non posso ancora dirlo :mrgreen:

Lisp – cl-launch – 0

lisp__400x400Con l’installazione di ASDF arriva anche cl-launch:

a0

Uhmmm… non viene nominato ma c’è:

cl0

OK, vediamo, passo passo che sono niubbo.
Invece dell’opzione -h conviene forse -H, prima però ancora una cosa che faccio sempre:

cl1
OK, bene & …

cl2

cioè cl è un link simbolico di cl-launch, risparmio i tasti, i diti, faccio prima, … :wink:

E cl-launch (e cl) è uno shell-script:

cl3

Non resta che provarlo, seguendo la tradizione di K&R:

(defun hello-lisp () 
  (format T "Hello Lisp!~%"))

Nella REPL ho:

cl4

invece con cl-launch:

cl5

Fine (da leggere come “fain“, non ho finito). Soddisfatta la tradizione è ora di affrontare l’help, quello more, quello -H.

Interessante, ottimo punto di partenza, François-René Rideau, aka Faré rockz-assay :grin:

Ci sono parecchie cose da vedere; comincio a prendere appunti: -E, -o, -d, …

Al capitolo Simple cl-launch scripts trovo un primo script da verificare:

#!/usr/bin/cl --entry main
(defun main (argv)
  (format t "Hello, World!~%~S~%" argv))

L’opzione --entry è la forma lunga di -E. Verifico:

cl6

OK :grin:

Ecco il capitolo Dumping images che:

You can dump an image (for static compilation and fast startup) with option `--dump IMAGE` where `IMAGE` specifies the path where the image will be dumped.

Al solito --dump equivale a -d:

cl7

No, problemi; crea l’immagine ma non fa quello che mi aspettavo. Con il codice hello.lisp invece è quasi OK:

cl8

Devo approfondire, se del caso, per adesso lo metto tra i sospesi.

Anche perché subito dopo c’è Standalone executables :razz:

You can create standalone executables with the option `--dump '!'` (or by giving a `--dump` argument identical to the `--output` argument).

Non sono riuscito a fare niente di diverso dall’opzione precedente. Da indagare.

OK, adesso seguo i suggerimenti di Faré, c’è il link: See our web page.

Uhmmm… la home riporta quanto visto finora ma c’è parecchio altro.
A studiare :mrgreen:

Lisp – alla scoperta di ASDF – 1

lisplogoIl Lisp procede –lentamente– anche se non ne scrivo. Ma tanto sono i post meno visti quindi non dovrebbe essere così grave. Sto studiando, purtroppo solo nei ritagli di tempo. Anche perché ci sono altre cose –forse, prossimamente, chissà :roll:

Allora ASDF, ne ho parlato qui: Lisp – ASDF cos’è?
Prima impressione: è diverso da come pensavo. Intanto c’è da documentarsi e finora ho fatto poco. Anzi pochissimo da far vedere, seguendo il manuale online: ASDF: Another System Definition Facility.
Intanto c’è, risponde:

a0

sì, due versioni della stessa richiesta :wink:

L’installazione da Software Center di Ubuntu l’ha posto /usr/share/common-lisp/

dove

Il manuale è piuttosto tecnico, devo cercare qualcosa più facile, da niubbo, un tutorial. Voglio gli esempi semplici e spiegati. E mi sa che devo vedere su cl-launch. So che ci sono adesso mi metto a cercare, purtroppo il tempo è scarso e dopo un po’ non capisco più quello che faccio. Per niente, nada, zilch :mrgreen:

Ma non desisto, anche se ci sono altre cose urgenti (al solito), ma prossimamente… forse… :mrgreen:

Quine dice Yusuke Endoh

Oggi avevo in programma di postare sul Lisp e ASDF e roba simile e già che c’ero lamentarmi un po’ (in fondo è lunedì) ma invece no.
Capita un tweet di quelli che ti attivano immediatamente la modalità ferma le macchine!
mame2-twitter_400x400Adesso vi racconto tutto per filo e per segno, è importante.
Versione breve: Yusuke Endoh (non so se il nome è scritto come usano i giapponesi, gli ungheresi, i carabinieri, i padagni e al Poli o come usa il resto del mondo e nel dubbio lo scrivo tutto intero) è bravissimo, mooolto di più di tanto. Per dire se il rapporto tra quanto è seguito e quanto segue su Twitter è 4.46 (following 276 – followers 1231): è popolare. Peccato che scriva in giapponese.

Tutto è partito da un retweet, questo: This kind of genius need to be celebrated more.
Si tratta di questo: quine-relay – An uroboros program with 100 programming languages.
Che sarebbe come dire: This is a Ruby program that generates Scala program that generates Scheme program that generates …(through 100 languages in total)… REXX program that generates the original Ruby code again.

OK, confesso che non l’ho provato. Anche perché ci sono linguaggi che per me sono come il giapponese. E altri che c’erano una volta ma adesso molto meno. Non solo il Fortran ma –pensa te– ratfor!

Yusuke Endoh è un genio, info qui.

Notare che il mio tweep Luis Souto Graña è spagnolo (España – Galicia – Cangas, dice lui), Martin Trojer è svedese e vive a Londra, Yusuke Endoh in Giappone: con il Web la tua casa è il mondo intero, peccato non conoscere il giapponese, almeno un po’.

Visto nel Web – 184

Sto studiando e ripensando… prossimamente vi racconto :wink:
Per intanto ecco cosa ho visto nel Web.
CFnrQ7zVAAEpUn1
Arduino Announces New Brand, Genuino, Manufacturing Partnership with Adafruit
::: Make:

Freestyle pc for Kids. Sistema operativo per bambini. Chi lo ha provato?
::: Luca De Biase

Nim binary size from 160 KB to 150 Bytes
::: HookRace

How Windows 10 Performs On a 12-inch MacBook
sarà vero? M$ è come $ilvio, imho
::: Slashdot

Solving the Data Extraction Problem in 10 lines
non so se riuscirò a vederlo ma sembra molto interessante
::: rodri.cios

I-Dont-Think-Id-Even-Attempt-It

I won’t post more code in my blog
atz! appena RSSato, lo gistso invece; ma ha appena postato un post! indagare!!!
::: svpino

Kore
is an easy to use web application framework for writing scalable web APIs in C
::: Kore

creating a Python 3 virt. env. on Ubuntu
::: Python Adventures

Turning an Arduino Project Into a Prototype
::: Slashdot

PyToolz
Toolz provides a set of utility functions for iterators, functions, and dictionaries
::: Toolz

6fb5bc40a2a00132cb29005056a9545d

The director of our company decided we’re all moving to Windows
::: codestandards

Da Arduino a Genuino: intervista a Massimo Banzi
::: YouTube

Learning bash scripting for beginners
::: NixCraft

Kim Dotcom Calls Hillary Clinton an “Adversary” of Internet Freedom
::: Slashdot

Why Today’s Automobile Industry Looks A Lot Like IBM in 1985
::: TechCrunch

Programmers will know.

The internet risks hitting peak capacity soon, but it can be saved
::: Engadget

Can C++ become your new scripting language?
::: ν42

La carica dei mostri…
io sono lontano fisicamente da questi posti ma vicinissimo dentro :grin:
::: CoderDojo Voghera

Draining the Swamp: Micro Virtual Machines as Solid Foundation for Language Development
Our goal is to remove an important barrier to performant and semantically sound managed language design and implementation
::: Lambda the Ultimate

Simulatore di circuiti analogici
::: SIAMO GEEK

punto-virgola

Welcome to the Museum of Pocket Calculating Devices, Solingen, Germany
::: Museum of Pocket Calculating Devices

Un’università spagnola abbandona Windows e passa a Linux
::: TUXJournal

how to sort 3 values
non so voi ma io trovo queste cose intriganti; da solo non mi verrebbero mai in mente; idea per test? :wink:
::: The Ubuntu Incident

In case you are looking to learn about Git and GitHub
::: svpino

Russia is making its own smartphone platform, sort of
::: Engadget

2015 - 1

Paleoelettronica
::: ElectroYou

Backlash Against Facebook’s Free Internet Service Grows
::: Wired ::: Chiusi nella rete

Microduino mCookie: The smallest electronic modules on LEGO®
::: Kickstarter

Tech Giants Tell Obama To Resist Calls For Backdoor Access To Encrypted Data
::: TechCrunch

How to implement WhatsApp messaging into your business
::: The Next Web

Phobos and Deimos

Code is the best documentation of how a system is implemented
::: afuerstenau

Isaac Asimov warns the kids…
::: PulpLibrarian

Alan Turing’s “The Applications of Probability to Cryptography” notes have entered the public domain & now on Arxiv
::: FredericJacobs

list your Firefox add-ons
::: The Ubuntu Incident

Comprehensive learning path – Data Science in Python
::: Analytics Vidhya ::: Analytics Vidhya

81f4e9e9-a079-43e5-8dbb-5eee98c1d71a

Putting the evil academic publishers in perspective
grossi guai per FOSS: l’immagine
::: Daniel Lemire

Choosing the Right IDE
è sempre una delle prime tre domande che mi fanno
::: Slashdot

Russia plans Linux-based mobile operating system to rival Android and iOS
::: Ars Technica

La Russie menace de couper Facebook, Google et Twitter
::: Numerama

Meet PyCharm 4.5: All Python tools in one place
::: JetBrains

11265184_1039846246045135_8448956196772554302_n

Keep it simple
::: fabiochiusi

La mia protezione 50 di questa estate?
::: Marghe_Mariotti

Bravi i colleghi di @libreveneto
::: suxsonica

Functional Programming in Haskell by Examples
::: caiorss

Go Is Unapologetically Flawed, Here’s Why We Use It
::: Brave New Geek

10982195_906847702686890_2990561880313378582_n

Becoming Productive in Haskell
::: Mechanical Elephant

Thinking Functionally with Haskell
::: The Pragmatic Programmers

Online Photo Editor | Pixlr Editor
::: Pixlr

informatici ed emigranti
::: Quinta’s

thank you

Once you go functional, you can never go back
::: ZX coder

“La privacy non interessa più a nessuno”
::: fabiochiusi

The Traveling Salesperson Problem
::: nbviewer

Google developing “Brillo” Internet of Things OS based on Android
::: Ars Technica

winzoz

How Java Changed Programming Forever
::: Slashdot

25 Years Today – Windows 3.0
ecco perché a volte i giovani mi guardano perplessi (sono vecchio)
::: Slashdot

#golang: The Next Great Teaching Language
::: roseland

Java’s 20 Years Of Innovation
::: Forbes
irlanda

Comandi composti

dennis-ritche-unix-quote

Una delle cose più meravigliose di Linux (in realtà Unix) è che i comandi (una volta tutto avveniva via terminale e comandi, niente WIMP) è che possono –anzi spesso devono– essere composti tra di loro. Come i mattoncini del Lego direbbe Marco. Ma siccome la metafora è sua non la uso; non parliamone più. Ma è così.

Come mi hanno chiesto due baldi giovani (ehi! il figlio di P. che lavorava con me quando è nato :grin: come passa il tempo!) riguardo al caso dell’altro giorno, questo.

Si vorrebbe modificare questo output:
c0

trasformandolo così:

c1

Si può fare vero? Certo :grin:
Ci sono due comandi che sembrano fatti proprio per quello, sed e AWK.
Adesso un vecchio come me (o sono solo io) farebbe in un altro modo, come ha sempre fatto ma sì, l’idea sembra OK. Proviamo…
Salta fuori che non è immediato, non come sembrava. Per fortuna c’è il Web; e StackOverflow (al solito), qui.

Vediamo prima sed:

c2

Uh! panico! no, dai, vediamo…
Non devo spiegare la pipe | vero? già fatto tante volte, quindi resta la parte di sed.
Cominciando dalla fine s/\n/ /g è semplicissimo sostituire ogni (g) carattere a-capo (\n) con uno spazio.
La prima parte è più interessante. Intanto sono 3 comandi separati da  punto-virgola.
:a è una label, un etichetta ci serve per ritornare lì con b (branch).
N appende la riga che legge al testo precedente.
$ è l’ultima riga dell’input e quindi salto a a solo se non ci sono arrivato (! al solito vale not).
Facile vero? O non tanto?

L’alternativa è AWK:

c3

Intanto lo lanciamo sostituendo il valore di RS (record separator) con l’opzione -v e con l’opzione -F risettiamo il field separator.
A questo punto basta dire di scrivere il valore del primo field con 1. Ma dobbiamo ricordargli che è cambiato per cui $1=$1.
Facile vero? O non tanto?

joke-unix-friendly

Yep! non tanto facile; anzi piuttosto macchinoso e siamo stati fortunati a trovarlo fatto nel Web (anche se il titolo era sbagliato) :grin.

Ma però, io che sono vecchio la soluzione ce l’avevo fin da subito (anche questa peraltro si trova facilmente nello stesso sito):

c4

echo fa l’eco di quello che gli viene passato; nel nostro caso però il testo non ce l’abbiamo ancora. Niente panico con $() eseguo il comando tra le parentesi con priorità maggiore, pronto per echo.

Facile vero?
Fare la stessa cosa con un linguaggio di programmazione (quello che volete) sarebbe decisamente più lungo. Magari più facile ma meno elegante.
Lasciato come esercizio :mrgreen:

Lisp – ASDF cos’è?

small-cover

Finito l’ottimo Practical Common Lisp continuo –forse, anzi molto probabilmente– con il Lisp. C’è ancora molto da fare—- imparare, sono niubbo, assay :roll:

Intanto una cosa, serve anche da ringraziamento a Peter Seibel, il suo libro, anzi due, è altamente raccomandabile (“that book is dead sexy” dice Xach). Vero che non ho fatto gli esercizi pratici che propone nei capitoli dal 23 al 31 ma non è detto che prima o poi, quando sarò vecchio…

Ieri mi sono letto l’ultimo capitolo, Conclusion: What’s Next? che non riassumo ma metto in pratica. Fin da subito –o quasi :wink:

Devo vedere una montagna di cose, partendo dai link forniti da Peter (anche se il libro non è recentissimo sono ancora tutti validi) e poi –il bello del Web, siano rese grazie a san sir TBL) da link nasce link (OK, lo so che si dovrebbe dire URI, ma quelli dai!).

asdf

Magari un punto di partenza potrebbe essere ASDF. Anzi vado con una pre-intro esplorativa. Senza pretese nèh! :roll:

Allora, prima di subito, ecco qui: ASDF Another System Definition Facility.

Usando Ubuntu sarà il caso di verificare se per caso non è che lo trovo nel Software Center? Uh! ebbene sì:

sc0

Aspetta, mi dice che c’è anche questo:

sc1
Fatto. Adesso viene il bello; torno alla pagina web che stavo vedendo.

Cos’è? quello che dice il suo nome, nella continuità di DEFSYSTEM di un tempo (che in inglese suona meglio:  in the continuity of the Lisp DEFSYSTEM of yore).

Consiste di due parti asdf/defsystem e uiop (Utilities for Implementation- and OS- Portability una libreria per la portabilità e il supporto del sistema a runtime). uiop fin da subito si dice che non è semplice come potete supporre, avvisati nèh! :roll:
Notare l’HEΛP –sono geeks! E se continuo poi magari anch’io arrivo a somigliarci, con il tempo, mica subito, avrei davvero dovuto iniziare a vedere queste cosse da yore :wink:

Nota: non che sia importante ma visto dove si trova heλp? Si Milano, roba di Marco Antoniotti, marcoxa, prof alla Bicocca. Mika ke c’è solo EXPO2015 a Milan :grin:
E DISCo sta per Dipartimento Informatica Sistemistica e Comunicazione, che volete sono geeks.

Cosa non è. ASDF non scarica i componenti mancanti per te, per questo c’è QuickLisp (prossimamente). ASDF non è per costruire o lanciare software dalla command-line; per questo c’è cl-launch (ce l’ho!) o buildapp.

Tra le implementazioni supportate c’è SBCL :grin: ci sono tutte.
Esempi: sono disponibili attraverso QuickLisp.
Documentazione: disponibile in diversi formati; adesso mi segno quello in HTML che mi sa che diventerà importante e scarico il PDF che stampo e mi metto a leggere (pochi minuti e non ci sono più per nessuno, per tutto il tempo che ci vuole, nèh!).

Altre cose, per esempio ritrovo qui il  ASDF 3, or Why Lisp is Now an Acceptable Scripting Language di François-René Rideau, letto ieri sera, fare è un geek, io se continuo forse …

OK, ci sarebbe altro ancora ma basta posto e non ci sono più, sto studiando (forse) :grin:

Ah! ‘na roba: di solito si dice nerd ma io preferisco geek, provate a dire le due parole a alta voce, vero che suona meglio quella?

:mrgreen:

Molto più bravi di me con il foglio di calcolo

programmer_joke12Io su Facebook sono alquanto atipico. Lo uso solo per spammare, nel senso che segnalo quando faccio un post sui blog. E poco più. Rispondo a chi mi tagga (si dice così, vero?) e ogni tanto ci do una scorsa ma senza né impegno né metodo. Ho anche smesso di fare gli auguri di compleanno, mi sembra una cosa non da orso quale vorrei essere, o almeno sembrare.
Poi capitano cose che mi fanno dire “Ohhh!” proprio come quel testa-di-povia di Povia.

Sto parlando di questo post trovato sul gruppo Figli di Archimede, legittimi e…in adozione che non so bene se si riesca a vedere da chi non ne fa parte.

In particolare mi riferisco al post del 19 maggio 2015 di Cristiano Armellini che riproduco (se del caso cancello quanto mi verrà chiesto):

questo file Excel non l’ho fatto io ma lo propongo perché ha una formula molto interessante per ottenere i numeri primi (nulla di particolare ma minimizza lo spazio di memoria).

Problema adesso: non so se posso mettere il link al foglio di calcolo, cioè l’ho messo ma non so se funziona e allora metto un paio di immagini per ricostruirlo (tipo Ikea, anzi ricetta per libro di cucina (tipo ricettario)).

x1

Come si vede nella colonna B si trovano i numeri naturali (per qualche motivo la serie parte dalla riga 2, forse per poter mettere un titolo alle colonne). La colonna C invece ha una formula, a partire dalla riga 3; quella che in B3 ha il testo 2.

Le formule con questo tipo di strumento sono un po’ –come dire– facciamo che metto quella per la cella C6, quella in cui mi trovo nell’immagine precedente:

x2

Chiaro no? L’unica cosa particolare è RESTO che è quello che di solito si chiama modulo e viene scritto % o mod(), questo dice l’help:

resto

Quindi tornando alla formula io la trovo che mi meraviglia, assay.

Per scriverla basta posizionarsi in C3 e scrivere:

=SE(SOMMA(SE(RESTO(B3;B$2:B2)=0; 1; 0))=1; 1; "")

Poi copiarla e incollarla su tutte le celle sottostanti e gli indici vengono aggiornati automaticamente (tranne quelli bloccati con il $); per esempio in C6 abbiamo quella della figura là sopra, questa:

=SE(SOMMA(SE(RESTO(B6;B$2:B5)=0; 1; 0))=1; 1; "")

Per capire cosa fa, proprio come nel Lisp (anche qui le parentesi abbondano) si riduce partendo dalla coppia di parentesi più interne e si procede verso l’esterno e il tutto diventa chiaro. Se la somma del valore della lambda per il calcolo del modulo per il numero nella colonna a sinistra rispetto a tutti i numeri precedenti (partendo dal 2) è zero il numero è primo e viene scritto 1 nella cella.

OK? :grin:

Ecco io ho usato lambda, parola che non credo si trovi nei manuali di queste cose ma è quella. Anche perché RESTO da solo farebbe un’altra cosa.
Quello che mi fa poviare è com’è scritta la formula, la sua sinteticità; con i linguaggi normali (tranne APL e successori) sarebbe parecchio più lunga. Ma resta comprensibile, l’ho capita anch’io.

Poi che io ci riesca a scriverla è un altro discorso, completamente differente. Anche perché, se del caso, ho altre possibilità. Esempio:

factor

Oppure, installando bsdgames:

primes

Ma se fossi invidioso l’invidia per gli excelsers rimarrebbe tutta :mrgreen:

Lisp – sugli ‘esempi pratici’ di PCL – 1

beatlesIeri mattina all’alba (delle otto e mezza, non è mai buona cosa esagerare) affronto, come di solito ultimamente il Practical Common Lisp di Peter Seibel (rockz!). Il programma era di iniziare il capitolo 23: Lisp – esercizio: un filtro per lo spam.

Mi ci sono impegnato per un bel po’ di tempo, via-via più insofferente per quel che stavo facendo. Come al solito ho preparato un post (che non pubblicherò) in cui mettevo giù gli appunti (come facevo a scuola, roba dello scorso millennio, anzi prima) e pasticciavo con la REPL per eseguire il codice di Peter. Con grossi problemi.
Peter ha messo online il suo codice, qui, compresso sia come tar he zip.
Ma poi usa anche packages esterni, cita dove sono ma bisogna assemblare il tutto (e io lo faccio a martellate). Capita poi che di qualcuno non ha detto quasi niente, come ASDF, già trovato via googlata ma non ancora visto. Insomma mi sono trovato a scrivere (vale auto-citarsi, tipo “comunicazione personale“?): “Sono di nuovo capitato in un esercitazione che non è agevole verificare per davvero. Già successo e allora mi ero arrabbiato. Non oggi, non voglio iniziare male la settimana”.
In ogni caso mi ho macinato una prima parte del capitolo (anche se non è il mio caso amo il saggio che dice “quando il gioco si fa duro…” (inizio-di-cit.)) anche se l’esercizio non m’interessa. Ma poi, finita la fase di studio e passato a quella di impacchettamento, adattamento delle immagini e correzione degli errori di scrittura e frasi incomprensibili ho visto che c’era qualcosa che proprio non andava. Non era quello che volevo. E ho fatto altro (indovina? sì: sono in ritardo). E alla fine ho realizzato (ahemmm…) che per il resto del libro (pregevole, lo consiglio) lo devo affrontare in modo diverso. Intanto non “copiarlo” sul blog ma dire quello che trovo di nuovo che non sia un esercitazione come quella di ieri.
Lì di cose nuove non ne ho viste (OK, esagero); è lo sviluppo di un progetto (astratto, almeno per me) dove c’è il 90% è costituito dall’imballaggio e il prodotto vero è nascosto dentro. Forse mi sbaglio, controllerò e se trovo qualcosa vi farò sapere.

billQuello che ho in mente io come esercizi è qualcosa di diverso. Devono essere piccoli e focalizzati. Mi è tornato in mente Bill the Lizard, un tipo tosto attivo su Stack Overflow (e in altri social-cosi). Un po’ di tempo fa macinava il SICP in modo molto intrigante, p.es. qui, qui e qui (sì, presi a caso, ma sono rappresentativi).
pavelIntanto pausa di riflessione :mrgreen:

Lisp – loop per cinture nere – 4

cetOggi, proseguendo da qui finisco il capitolo.

Predisporre e concludere

Al solito non so tradurre i modi di dire di Peter; Peter smettila :wink:

Una delle caratteristiche di loop è la possibilità di far precedere il ciclo da codice per settare coe e farlo seguire da altre alla fine.

Per esempio consideriamo questo esempio in Perl:

l18

Adesso modifico l’array ed ecco:

l19

OOPS! In nota dice che andava bene qualunque linguaggio tipo C; ma ormai è fatto :wink:
Il ciclo propriamente detto è l’istruzione foreach; ma questa da sola non basta, il codice del ciclo si riferisce a variabili dichiarate precedentemente e il lavoro che il ciclo compie non si vede senza l’if finale che riporta il risultato. In Common Lisp il costrutto loop è un’espressione che ritorna un valore ma di solito serve qualcosa di più.

I progettisti di loop ci hanno pensato e per questo ci sono due keyword, initially e finally.

Dopo initially o finally si possono essere clausole consistenti di  forms Lisp che saranno eseguite una sola volta come prologo e epilogo. Entrambe possono riferirsi a variabili locali del loop.

Il prologo viene sempre eseguito anche se il ciclo itera zero volte. Il loop può ritornare se capita una di queste condizioni:

  • viene eseguita una clausola return;
  • return, return-from o un altro costrutto di controllo viene chiamato dentro una form del corpo (ma puoi terminarlo eseguendo l’epilogo con la macro loop-finish);
  • il loop termina immediatamente per una clausola always, never o thereis (ve vedremo subito).

Dentro l’epilogo return o return-from possono essere usate esplicitamente per ritornare un valore del loop. Questo valore ha la precedenza su ogni valore che può altrimenti essere fornito da una clausola di accumulazione o test di terminazione.

Per consentire l’uso di return-from a ritornare da un loop specifico (utile per quelli annidati) si può nominare il loop con la keyword named, che se appare dev’essere la prima clausola. Per un esempio semplice assumiamo che lists è una lista di liste e vogliamo trovare un elemento che soddisfa qualche criterio in una di queste liste annidate. Si può fare con una coppia di cicli annidati:

(loop named outer for list in lists do
     (loop for item in list do
          (if (what-i-am-looking-for-p item)
            (return-from outer item))))

Uhmmm… quasi-quasi…

l20

Test di terminazione

Mentre le clausole for e repeat forniscono la base per le iterazioni a volte c’è bisogno di interrompere prima. Abbiamo già visto return e return-from ma ci sono altri modelli per decidere quando uscire dal ciclo. Questi modelli sono supportati dalla clausole while, until, never e thereis, che hanno la seguente forma:

loop-keyword test-form

test-form viene valutata a ogni iterazione e in base al valore il ciclo può terminare. Differiscono per quel che succede dopo che il ciclo termina (se lo fanno terminare) e come decidono.

while e until sono le più miti; quando fanno terminare il loop il controllo passa all’epilogo che può ritornare un valore o fare quel che vuole per uscire dal loop. while termina appena trova un falso, until al primo vero.

Un’altra forma di terminazione tranquilla è la macro loop-finish, una Lisp form regolare –non una clausola di loop– così che può essere usata ovunque dentro le forms di una clausola do. Causa anche un immediato salto all’epilogo. Risulta utile quando un’istruzione dei cicli non può essere condensata in una form singola che si possa usare con while o until.

Le altre tre clausole —always, never e thereis— terminano il loop con estremo pregiudizio (cit.). Escono immediatamente dal loop, senza eseguire l’epilogo. Forniscono anche un valore di default, anche per quando non fanno terminare loro il loop. Tuttavia se il ciclo non è terminato da una di queste l’epilogo viene eseguito e può ritornare un valore diverso dal default.

Siccome forniscono un valore di default non possono essere combinate con clausole di accumulazione a meno che quest’ultima abbia una subclausola into. Il Lisp segnala un errore se lo sono (non ho capito cosa). Le clausole always e never ritornano solo booleani quindi sono usate per i predicati. Con always si può testare che sia sempre vero e con never nil. Se si giunge alla fine il loop ritorna T.

Per esempio se si vuole testare che tutti i numeri in una lista siano pari si può scrivere:

l21

La clausola thereis è usata per testare se il test è vero (problema di traduzione qui). Appena il test ritorna non-nil il loop termina ritornando quel valore. Se il ciclo finisce normalmente ritorna il valore di default, nil.

l22

Assemblare il tutto

OK, abbiamo così visto le caratteristiche principali di loop. Si possono combinare le clausole viste fintanto che si rispettano le seguenti regole:

  • la clausola named, se presente, dev’essere la prima;
  • dopo la clausola named vengono tutte le clausole initially, with, for e repeat;
  • dopo viene le clausole del corpo: di esecuzione condizionale e non condizionale, accumulazione e terminazione;
  • infine si finisce con le clausole finally.

La macro loop sarà espansa in codice che fa le seguenti azioni:

  • inizializza le variabili locali come dichiarate con clausole with o for come pure quelle implicite di accumulazione; le forms sono valutate nell’ordine con cui appaiono;
  • esegue le forms fornite da ogni clausola initially (il prologo) nell’ordine con cui appaiono;
  • itera, eseguendo il corpo come di seguito descritto;
  • esegue le forms fornite con finally (l’epilogo) nell’ordine in cui appaiono.

Mentre il loop itera il corpo è eseguito iniziando dalle variabili di controllo dell’iterazione e poi eseguendo le esecuzioni condizionali e non, quelle di accumulazione e i test di terminazione nell’ordine in cui appaiono. Se una delle clausole nel corpo fa terminare il ciclo il resto del corpo è saltato e il loop ritorna, eseguendo l’epilogo se c’è.

E questo è tutto quello che si può fare (quasi tutto, in realtà). Lo useremo spesso, minaccia Peter, studiatelo! :grin:

:mrgreen:

Iscriviti

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

Unisciti agli altri 85 follower