Category Archives: Storielle

Storie varie sul rutilante mondo dell’informatica

Una definizione meravigliosa

Da piccolo avevo un terminale collegato a un mini (per i giovani: un armadio con qualche terminale dumb collegato via  RS232  seriale, una stampante a catena, un hard disk di ben 80 MB, roba come il mitico PDP 11; in realtà Pr1me 550) con il Fortran. OK, c’era anche qualcos’altro, l’assembler PMA, e il CPL (un linguaggio di scripting interpretato che serviva per via che la shell (che non si chiamava così) non era programmabile). Erano tempi pre-Unix, anzi il PrimOS era un derivato di Multics. Una nota ancora per i giovani: io sto barando, tutte le sigle e i nomi dovrei scriverli tutto maiuscolo.

Poi a un certo punto è arrivato un Basic, atipico, mai usato. Invece leggendo il GEB mi viene la voglia, chiedo al tecnico (allora l’assistenza era indispensabile, costava anche cara) e ottengo un nastro con il Lisp, il Pascal e forse altro ancora che adesso non ricordo. Il Pascal l’ho provato per un po’ la sera con uno studente ma chi m’intrigava era il Lisp. Ci sono dei siti (per esempio qui e qui) con raccolte di documentazione dell’epoca ma del Lisp non ho trovato traccia. Forse era solo una beta o qualcosa di non ufficiale. Chissà.

Ci ho passato un po’ di sere con manuali fotocopiati dopo ricerche varie: “cos’è che hai in mente di fare?”, “perché?”, “ma fare come fanno tutti (cioè in Fortran)…”.

Insomma quella voglia mi è rimasta, tanto che poi ho provato anche con versioni più serie (sì, CL (Common Lisp)) su altre macchine. Ma non ho mai prodotto niente di usabile. Fino a quando uscito dal mondo del lavoro e con Linux ho trovato un’infinità di risorse. Ne ho utilizzato diverse versioni, anche eretiche. Poi sono passato a Scheme, cioè Racket. Una meraviglia. Adesso che sono alle prese con Haskell non devo pensarci troppo altrimenti mi viene il magone.

Non l’ho dimenticato, è sempre nella mente e nel cuore (ahemmm…). E oggi questa definizione, un cinguettio così bello che lo copio e metto nel blog per non dimenticarlo:

Lisp is a recognition that whoever designed the language doesn’t know what problems you’d want to solve with it; so you may want to change the language.

La cit. è di Will Byrd, dovrebbe essere quello di The Reasoned Schemer, c’è anche su Twitter, cercando il tweet ho deciso di followarlo. Non ho trovato invece la fonte iniziale.

Tornando alla cit. bella vero? Tutto anche per via delle macro, mooolto diverse da quelle del C.

Ah! già che si parla del meglio questo potrebbe essere ancora migliore, lollando, così:

L’amico Edo dopo aver letto la bozza mi guarda perpluto. Probabilmente –quasi certamente– ha ragione. Quando io ho cominciato il computer era una cosa non da tutti ma a breve sarebbe sbocciata la rivoluzione dei personal. Oggi poi siamo nella maturità della successiva, quella dei telefoni. Per la programmazione poi l’evoluzione non è stata come pensavo, come i lispers pensavano; anche se non si sono estinti, il tweet viene dalla setta dei clojuristi. E mica finisce qui, Edo e voi giovani ne vedrete delle belle (no, non la robocalypse).

👽

Annunci

Pausa e… –e altro ancora

Sam Altman rockz! 💥 Sarebbe da followare su Twitter ma ne seguo già troppi e si occupa di cose non molto affini ai miei interessi. Cioè sarebbe anche interessante ma troppo difficile stargli dietro senza investire troppo tempo e attenzione. E conosco i miei limiti, per cui per ora un rincrescioso no. Per fortuna c’è chi lo rilancia, oggi mi trovo questo qui.

Quando si dice la serendipitipità! Proprio come dice l’Orietta. Adesso vi conto.
Cioè no, non esattamente, non metto il codice ma rendiconto. Avete presente quando devi scrivere uno script che deve fare qualcosa di relativamente semplice, si può fare a mano ma è lungo e ripetitivo p.es. cercare in elemento in una lista di qualche migliaio senza usare nessun strumento di ricerca, neanche Excel, neanche grep, scorrendo la lista non ordinata. Ecco una cosa così. Inoltre devi usare Python (ci sarebbe il Visual Basic come alternativa ma sono allergico). Vado, c’è Stack Overflow e se non basta Google (ho la pessima abitudine di non considerare DuckDuckGo).

Dopo qualche tentativo ho scoperto che anche con le Batteries Included sto cercando qualcosa che o non c’è o è nascosta in qualche package che non riesco a identificare. Parto con la ricerca e trovo solo una manciata di casi vagamente simili.

A dirla tutta abbandono presto l’idea di cercare solo Python, se trovo la dritta con un altro linguaggio e capisco come si deve fare… Mi perdo sempre di più, nessuno che ha avuto mai il mio problema? In questi casi mi faccio prima un caffè e poi una passeggiata con i miei cani, il bello di essere in campagna, qui in fondo alla West Padagna 😁

È incredibile, mi sorprende ogni volta, come staccare aiuti. Ieri ho deciso, già durante la passeggiata che sbagliavo tutto! cioè, detto in termini meno tragici, dovevo affrontarlo in modo molto diverso. Tra Linux e Windows ci sono differenze profonde, essenzialmente gli utenti. Non so spiegarlo sinteticamente in modo razionale ma do per scontato che non si possa chiedere a loro di usare cose come il terminale, questione di evoluzione culturale. Considerando l’uso di un paio di funzioni JavaScript inserite in una pagina HTML in locale risulta che, anche se meno elegantemente del progetto iniziale, si può fare. Entro sera avevo il prototipo funzionante. Per sicurezza lo zippo e lo mando al destinatario; ho fatto tutto su Linux e non vorrei mai che ci fossero sorprese.

A questo punto devo chiamare Srinivasa Ramanujan come testimone. È noto che la dea Namagiri gli suggeriva cosa e come fare.
Ramanujan dice il vero, anche se Namagiri è da intendersi come una personificazione di Sua Pastosità il Prodigioso Mostro Volante degli Spaghetti, FSM. Che questa notte, appena prima della sveglia mi ha dato la dritta! Ecco perché non trovavo niente ontehtoobz! Era troppo semplice e c’è senz’altro in Excel. Uh! non ce l’ho ma consulto la documentazione online; sì, si può. Trasferimento a casa del cliente (se gli dicevo tutto via mail risultava che gli fornivo solo un link) e fatto! 👽

Al ritorno scopro su Twitter una meravigliosa meraviglia che purtroppo è ormai scaduta, a meno di considerarla decisamente troppo in anticipo. Ma è troppo bella, la metto lo stesso, se mi ricordo saprò dove trovarla l’anno prossimo. Sempre che continui il tormentone –che quelli di Windows non capiscono, non è razzismo ma non è per tutti– questa:

😁

Facciamo che gli faccio un fax

Questa è una storiella che volevo raccontare da un po’, ne avevo parlato con un mio giovane collaboratore che rockz on teh webz (assay) ma per lui era no, non era credibile.

Poi giovedì questo tweet di un torinese tosto che dovreste conoscere. Io l’ho visto al Linux Day, al Centro Nexa, è attivo su Twitter e da altre parti ancora. A proposito di Twitter la sua fotina la odio: quella forse mosca, forse no ma in ogni caso bòja (per i non locali: insetto) che cammina|vola mi da i nervi. Ma si diceva, ecco l’avvocato Carlo Blengino e questo è il tweet.

Visto? Nel 2018 (o, per essere precisi ed evitare possibili contentazioni, fine 2017) si parla del fax, con il suo nome da festa: telefax.

Adesso vengo alla mia storiella. Da noi dal Tabachin si possono comprare le sigarette, i giornali, lotto e lotterie, i biglietti del pullman, ricariche del telefono e servizi informatici, per esempio ti fa la stampa, la fascicola. E ti fa anche il fax. “Ho da fare questo fax”, l’ho sentito io perso. Non ho osato svolgere indagini in situ e –spheega– sono stato servito subito 😡

Poi l’ho raccontato a uno che produce industrialmente roba per il Web –compresi Facebook e Twitter– ma mi ha guardato con un’espressione che non vi dico e telepaticamente ho sentito “questi vecchi… alle volte… bisogna capirli… compatirli…”. Insomma non mi ha creduto. Avrei potuto dirgli che i calendari dei mangimifici (ne ho diversi in casa) hanno i numeri dei cellulari, del telefono fisso RA e del fax. Avrei anche potuto dirgli che a casa ho l’elenco telefonico della provincia di Cuneo (anche se non è la mia) su carta, le Pagine Bianche (da qualche anno sono invece sprovvisto di quelle Gialle). Ma meglio ancora il cinguettio del Blengino. Quello dovrebbe chiudere la questione, ristabilire la mia credibilità.

Ecco, quello che volevo dire l’ho detto. Ma non so se questo è un post da leggere; anzi se non avete motivi particolari non leggetelo. Ma sappiate che il fax…

🤩

Presto! uh! no, ripensandoci…

Non so se capita solo a me che sono lento a capire le cose o è un problema più generale che riguarda l’umanità tutta. Niente di grave ma vorrei condividere cosa mi è capitato ieri pomeriggio. E poi questa mattina, presto, molto presto. E cosa mi perplime 😯

Ieri salta fuori improvvisamente un bug in uno script stagionato ma sempre attivo. Niente di grave ma in un caso –improbabile– viene saltata la fine di un blocco di testo fino all’inizio del paragrafo successivo e la pagina HTML, se uno la leggesse, vedrebbe una frase senza senso. Una cosa simile a quello che ho raccontato qui.

Il caso che sto raccontando però è diverso. Era un bug vero, per una condizione non prevista, forse perché improbabile, è saltato fuori eri e scoperto finalmente.

La correzione dello script ha richiesto pochissimi minuti, un paio di verifiche volanti e via.

Tutto bene quel che finisce bene! Ahemmm, no, non esattamente. Questa mattina dopo il primo caffè ho visto la luce: il codice

if stringa buggosa then
  modifica la stringa buggosa
endif

dev’essere eseguito subito, una volta per tutte, ci sono almeno due punti dove si può fare, non durante la creazione dell’HTML.

Detto così sembra banale, anzi quasi inutile. E la soluzione pensata ieri (cioè non tanto pensata in realtà) era la più immediata: qui c’è il bug, correggo qui. Ma poi, anche l’eleganza, dai 👌

Adesso, corretto il bug e in attesa del prossimo, la domanda finale: capita solo a me di essere troppo precipitoso “ah, ecco!”. O no?

Io poi sono recidivo 😡

🤩

La storiella di un bug annidato

 Alle volte capita  Mi è capitato recentemente che un programma usato più volte al giorno da almeno cinque anni si rifiutasse di funzionare con una serie di dati apparentemente assolutamente normali.

No, niente codice, sarebbe troppo complesso anche a semplificare. Lo accenno discorsivamente, chissà se si capisce.

Il programma recupera –se c’è– il record da un database corrispondente a un dato codice (in gergo, da noi almeno, chiave). Ed è capitato che il database interrogato per una particolare chiave ha restituito un record. Ma quella chiave non esiste, non può esistere. E invece sì, c’è. È nata per un record che poi si è visto, prima di completarlo, che era sbagliato ed è stato abbandonato. Per qualche motivo non è stato cancellato ed è passato indenne anche alla successiva fase di controllo.

Il programma per interrogare il database ha un’interfaccia grafica, si inizia a inserire la chiave e magicamente compare la lista ordinata dei codici compatibili. Nel nostro caso il codice errato e quello vero erano simili ma non uguali e quello con l’errore compariva prima. Ed è stato scelto.
Come detto il record non era completo ma il programma non lo ha verificato. Siccome era una condizione impossibile che il database fosse scorretto (deve aver pensato il programmatore) la verifica sarebbe stata qualcosa di ridondante, inutile.

A questo punto abbiamo già due errori ma poi ci si mette il linguaggio, così:

Qui ho usato JavaScript nel programma il linguaggio era un altro. Ma si è verificata la stessa confusione tra numeri e stringhe, come se fosse tutto regolare. Effettuate le elaborazioni del caso l’output finale è risultato una frase incompleta, cosa che ha fatto rilevare l’errore. Questo perché l’operatore ha effettivamente letto il testo. Forse nel passato… chissà se siamo sempre stati così scrupolosi?

Resta il fatto che un messaggio di warning sarebbe stato opportuno. Meglio ancora interrompere il programma dopo la segnalazione dell’errore –come succede adesso.

Il debug ha richiesto più tempo di quello che si potrebbe pensare perché –si sa– il database è corretto sempre. Quasi, a volte no.

Non so se sono riuscito a rendere chiaro il caso, se traspare il panico da debug. E se può servire per il futuro.

🤩

Pause e riprese

Non so se solo io (me) o è una cosa più generale, se capita anche a voi, quanto spesso, se c’è una cura o cosa. Adesso mi spiego.

Ci sono programmi grossi, che richiedono tempi lunghi per essere scritti, testati, debuggati. Il tutto più volte. Altri invece sono molto meno impegnativi come risorse e tempi di scrittura, test e debug. Da tempo non ho a che fare con la prima categoria –sono vecchio– ma esclusivamente con la seconda, gli script.

Non so nemmeno se si continui per quelli grossi a usare linguaggi “seri”, compilati, per dire C (si usa ancora o è come il greco di Omero? (ma senza aoristo)), C++, Fortran (l’ho detto, l’ho detto!). Non so bene se anche Java rientri in questa categoria. Poi ci sono gli altri: Python, Octave (pron. MatLab), JavaScript (sì, raramente anche fuori dal browser). Ci sarebbe un’ulteriore categoria che comprende Delphi, Visual Basic, C#, AWK, sed, bash e altri ancora. Siccome io sono solo Linux e tutti gli altri (che frequento) no questa categoria è vietata. Anche se per uso personale –confesso– sono addict, assay.

Un grosso vantaggio dei linguaggi interpretati è che puoi “correggere” lo script al volo ed è subito pronto (OK, in teoria, se uno è bravo e fortunato) senza bisogno di compilare e creare l’eseguibile. È anche un loro limite: se non sei scrupoloso rischi di perdere la versione che funziona; ma non voglio stressare nessuno con pratiche esoteriche (back-up).

Siccome –già detto ma mi viene bene ripetermi– sono facili da modificare la modifica viene richiesta un nientesimo di secondo prima di usarla. E tutti (anche il programmatore) credono che si possa fare. A volte lo faccio anch’io; ne ho modificato uno all’inizio di questa settimana. Tutto OK 😍

Poi mi è venuto da pensarci, la sera, prima di prendere sonno. E di nuovo il mattino dopo, appena sveglio. Mi sono fatto mandare lo script e sì, avevo visto giusto: una condizione (vecchia) non veniva mai eseguita e chissà come mai non avevo pensato a un modo molto più elegante (quasi ugualmente semplice) per parte del nuovo. Ho modificato da me, testato e rispedito; dimenticando di togliere le istruzioni di scrittura di variabili su un file di debug. Non è che fosse grave ma sai com’è. E se poi lo scopre qualcun altro? Insomma una nuova mail con allegata la nuova versione. Secondo me questo sistema di pause per ripensare con calma a quello che si è scritto dovrebbe essere la norma. A me è successo più volte. Ma forse solo a me.

Il divertente della cosa è che lo script aveva ormai esaurito il suo compito e chissà quando ritornerà d’attualità (e magari non nell’ultima versione).

OK, solo uno sfogo. Anzi non è nemmeno veramente vero. E non so nemmeno se vale un post senza codice 😯

Ancora una cosa: c’è un’altra categoria di linguaggi ma se ne nomino qualcuno di quelli rischio.

Ah! forse devo occuparmi di un altro ancora, nuovo (per me) ma vecchio (quello vecchio l’ho già usato). Prossimamente… forse… Ma roba dell’anno prossimo.

🤩

TIL anche questo

If you are the smartest person in the room, then you are in the wrong room.
Confucius

E sì! 🐳 Certo. E quelli di reddit, dove la cit. ha un’altra attribuzione, al solito la sanno lunga e disquisiscono, qui.

Se con una piccola astrazione consideriamo il Web come un ambiente (cioè con case) e un social come una di queste e chi seguo su Twitter come una stanza risulta –per quanto mi riguarda– confermata la saggezza di Confucio e Richard.

Sì perché –oggettivamente– seguo nerds che davvero rockzs! 💥 👽
Anzi se avessi tempo potrei seguirne tanti altri.

Alle volte qualcuno esagera, come oggi. Ho provato a resistere, pensare alle funzioni nella programmazione funzionale, ma niente da fare: devo dirvelo, se del caso non leggete.

Ci sono cose che avrei potuto inventare io se non ci fosse qualcuno che mi ha preceduto, vedi Peano, l’HTML, cioè il Web, per dirne un paio. Altre invece sono meno auto-evidenti, non ci sarei mai arrivato, la Relatività Generale, ma anche quella ristretta, o la saga di Diskworld, per dire.

Ecco un caso di quest’ultima classe, qui.

Partiamo dall’immagine, di autore ignoto anche se meriterebbe fama imperitura. Riesce a visualizzare un concetto che è –come dire…– forse non solo per me. E la sua applicazione! Io che sono vecchio ricordo certe discussioni Google vs. Yahoo dove c’era chi citava [autocensura qui] e –OK, discordi da piola dietro un fiasco di barbera.

Tornando al tweet poi, certo, di lì si parte seguendo il link proposto e si viene condotti alla scoperta di tutto un mondo da nerds mooolto più smart di me.

OK, è tutto quello che volevo dire. E il Web e Twitter come parte dello stesso rockzs! 💥 👽

Forse è solo per me, forse no, chissà. Ah! posso smettere quando voglio, nèh! Forse 😋

🤩

Capita solo a me?

Una storiella di cosa mi è capitato ieri pomeriggio. E poi ho continuato a pensarci; mi tornava in mente a tradimento, anche la notte. Per cui racconto tutto anche se non ci faccio una bella figura 😯 ma chissene 🧙‍

Tutto è partito da questo tweet: Finally someone explained monads in a way that is actually possible to understand.

Seguendo il link si finisce su Quora, qui: How would you explain the purpose and benefit of monads to a non-programmer?

Panicz è un tipo tosto, già visto altre volte, è un little [non tanto little] schemer 😁
Il post è lungo e impegnativo. Parte bene anche se –secondo me– prende la cosa un tantino troppo alla lunga, dai siamo tutti programmatori, magari non consapevoli ma sì, yepp.

Inizia con l’esempio del calcolo del fattoriale in pseudo-assembly. Ehi! quando io ho cominciato, in Fortran, si programmava così 👽
Anche l’evoluzione dell’esempio è quasi-Fortran, mi sa che in futuro ne riparlo.
Panicz poi introduce l’astrazione ed ecco Haskell

factorial 0 = 1
factorial n = n * factorial(n - 1)

che possiamo ridurre a

factorial n = fold (*) [1..n]

Però una cosa: Note that the above formulation is ambiguous, because we don’t know the order in which expressions should be reduced. If we interpret the expression as (((a ▽ b) ▽ c) ▽ d), we get a left fold, and if we interpret it as (a ▽ (b ▽ (c ▽ d))), we get a right fold.

Ecco qui mi sono perso. Cerrrto colpa mia, solo mia ma… adesso vi conto.

Non ho resistito e ho lanciato GHCi

OK, come previsto ma con (-) si ha

Verifico, è semplice e poi c’è la definizione lì sopra delle due funzioni… E qui il dramma: il -7 non mi viene.

In questi casi so benissimo che sono io che sto sbagliando, che basterebbe scrivere su carta (come si faceva una volta, come dovrei fare sempre, mi conosco, so di essere pasticcione…) e tutto diventa chiaro, così:

(2 - (3 - (4 - 10)))

e ovviamente

Ma non sono stato così razionale. Ho risolto mentalmente l’equazione, sbagliando di nuovo 👿

Panico 👿
No, non mi sono ricordato che in questi casi devo smettere, andare a farmi un caffè o due passi, ho ben quattro cani che adorano le passeggiate anche se sono in aperta campagna, volendo possono farsele da soli, anche se non è notte e non si deve necessariamente abbaiare.

Insomma, non me lo so spiegare ma ci ho messo parecchio prima di decidermi a operare passo-passo, così

(2 - (3 - (4 - 10))) =
(2 - (3 - (-6))) =
(2 - (3 + 6)) =
(2 - 9) =
-7

OK! E sì le parentesi più esterne non sono necessarie ma l’abitudine –mia, il Lisp.

C’è un ulteriore motivo (recondito direi, se sapessi cosa vuol dire) che mi ha panicato e continua a panicarmi: il tutorial che sto seguendo alla fine di ogni lezione propne esercizi; di solito semplici ma Haskell non sono ancora riuscito a farlo mio, è diverso dagli altri linguaggi. Gli esercizi sono senza soluzione, e chissà se quello che ho scritto è vero. Poi proseguendo di solito si scopre che la soluzione viene data nelle trattazioni successive. Intanto panico 👿

Ma sono uscito fuori tema. Stavo scrivendo delle monadi come le vede Panicz.

Panicz ci racconta delle notazioni algebriche: it may or may not be useful to know that mathematicians call a set with an associative operation a semigroup. […] Of course, mathematicians also came up with a name for semigroups with identity element: they are called monoids. (Moreover, if the each element has its inverse element, then this structure is called a group, and is the subject of study of a vast branch of algebra called Group theory.)

For example, strings with concatenation operation form a monoid, where the empty string is the neutral element. But perhaps more importantly, functions with the operation of function composition form a monoid, where the neutral element is of course the identity function. Sì ho saltato la parte relativa all’elemento neutro.

Having the notion of identity element solves yet another problem. Recall the formulation of fold that I gave above. It did not specify what should the value of a fold over an empty list be. Intuitively, the sum of all the elements of an empty list should be 0, for example. For the same reason, the product of all elements of an empty list should be 1.

However, the idea of folding is not limited to monoid, or not even to the things of the same kind. The variants of fold that are most commonly used in Haskell take an additional argument, the “initial value” e, so that, for example, you can understand foldl ▽ e [a,b,c,d] as ((((e ▽ a) ▽ b) ▽ c) ▽ d) and foldr ▽ e [a,b,c,d] as (a ▽ (b ▽ (c ▽ (d ▽ e)))).

Altra digressione qui su version control, poi si passa al lambda calculus, salto che c’è spiegato bene di là. Mica finisce qui, ci sono le callbacks e la pyramid of doom.

E poi:

Monads, finally
So far we have seen that we can usually avoid the pyramid of doom rather easily by introducing new syntactic forms to our language. However, for some reason many programmers do not like to use languages whose syntax is based on s-expressions and prefer other syntaxes that correspond better to their whims. Since these syntaxes make the introduction of new syntactic forms to the language really difficult, they come up with other means to avoid the pyramid of doom.

They suggest that it is a good idea to have a single special form that is able to convert nesting into sequencing, that is implicitly parameterized with some sort of composition operator (this special form is called “do-notation” in Haskell and “for-comprehension” in Scala). The implicit parametrization occurs with the help from the type system (for example, in Haskell it makes use of the mechanism called type classes).

Salto i dettagli, e arrivo al dunque. [T]he developers of Haskell decided that its sequencing operator should be parameterized not only with the composition operator (which is written as >>= and pronounced “bind” in Haskell), but there should also be a “unit” operator that does nothing interesting — or to be more precise, it does nothing in some particular sense (it is called return in Haskell, probably to confuse programmers with background in imperative programming).

Arguably, there are some “monadic laws” that ought to be satisfied by these operators. […]

These laws may remind you the definition of monoids. This should explain at least some bit of the popular phrase “monads are just monoids in the category of endofunctors, what’s the problem?”.

The problem is that neither the notion of category, nor the notion of an endofunctor gives any clues whatsoever with regard to sequencing. […] Salto polemica su IO. E:

TL; DR they allow to replace nesting with sequencing in languages that have a poor support for macros but offer sufficiently elaborate type systems. And they probably allow some programmers to look smart. The name “monad” is terrible, because it focuses on some irrelevant (and unnecessary) details, giving no clue of the purpose whatsoever (truly, the name “sequencing” would be way better).

Insomma Panicz è chiaro ma forse troppo polemico. E, per quanto mi riguarda, mi conferma che le mie difficoltà con Haskell non sono solo mie. Ma insisto, quando il gioco si fa duro… (inizio-cit.) 😉

🤩

Pipes, ovvero qual è il titolo di questo post?

Devo una risposta a un giovane nerd davvero über (anche se feroce sostenitore di JavaScript, ma gli passerà (con il tempo) (forse)). In breve la risposta è sì.

Non ricordo da dove siamo partiti (sapete la RAM, la mia) ma siamo finiti che su come si fanno adesso le cose io ormai sono rassegnato, personalmente ci rinuncio e mi occupo solo di programmazione funzionale (Haskell, anche se è tutt’altro che semplice, troppo matematicoso).

In particolare Windows, non ci riesco più. È cambiato da quando lo usavo io –XP– e ha cambiato gli utenti. Per esempio il vantaggio di Octave (per i ricchi MatLab) rispetto a Python è l’ambiente integrato, fai tutto lì dentro, tutto a portata di mouse. Python invece… Uh! ecco, eravamo partiti di lì. E io dicevo che ultimamente con Numpy, Scipy, Matplotlib, Pandas &co. sarà dura per gli altri.

Ma mi hanno detto che sono legato ai tempi della linea di comando 😡
Che è la vera verità. Ovviamente.

Avrei anche potuto raccontare di quando sul TTY avevi un solo processo in foreground, altri potevi lanciarli in background con l’opzione &, i giovani non capirebbero. Mi sono invece lanciato a magnificare la potenza e l’eleganza della shell, per esempio le pipes:

(mica è facile trovare un esempio semplice e significativo nella history 😐)

Visto che ormai ero lanciato ho dichiarato che si potrebbe fare ancora oggi, con gli script autoprodotti, per esempio con questo: Leggere dati in formato CSV con impostazioni locali.

Sul momento non ho fatto una demo volante, ma adesso arriva. Anzi eccola qui:

Visto? e questi sono gli scripts python:

somma.py

import fileinput

somma = 0
for line in fileinput.input():
    somma += int(line)
print(somma)

prodotto.py

import fileinput

prodotto = 1
for line in fileinput.input():
    prodotto *= int(line)
print(prodotto)

E, ovviamente, si può fare di più, per fare la somma dei quadrati dei dati uso

quadrati.py

import fileinput

for line in fileinput.input():
    n = int(line)
    quad = n * n
    print(quad)

ed ecco

Sì, anche con Windows, dove cat si chiama type. Ma questa è solo una demo da completare, un inizio.
A contarla tutta, mentre io parlavo, GG (posso usare ancora una volta il vecchio nick?) ha risposto a tutte le mails sul telefono, bravissimo a scrivere con i soli pollici. Li ho opponibili anch’io ma non ci riuscirei mai. Ecco.

🤩

Funzioni e programmazione funzionale

Prima di iniziare vorrei precisare che non mi sto lamentando, anzi è tutto OK, sto imparando cose nuove (Haskell! 😁). Però –come risulterà tra poco– un po’ di comprensione, una metaforica pacca sulla spalla, un bacio sulla guancia dalla mamma (o da Miss Universo) credo di meritarmela. Tutta.
Adesso vi conto.

Questa mattina stavo seguendo la lezione di Haskell, anzi l’esercitazione con esercizi. Niente di impossibile ho due prof davvero über. Ma sono solo e in certi momenti mi sembra di essere abbandonato anche da Sua Pastosità il Prodigioso FSM, sempre sia condito, RAmen.

L’esercizio in oggetto richiedeva di contare gli elementi dispari di una lista di interi, la funzione della disparità è data, odd, quella standard.

Uh! facile (mi sono detto) e mi sono messo a scrivere. Non ho salvato i tentativi, diversi e tutti disastrosi. Mi capita anche che quando la REPL tenta di aiutarmi con messaggi d’errore lunghi mi butta giù; comincio a leggerli ma poi vedo che sono tanti e sta ancora parlando della terza riga… 😡

E pensare che so come dovrei fare in questi casi. Usare il metodo Ugo™. Non so se anche voi lo chiamate così, probabilmente no, magari non conoscete nemmeno Ugo del metodo Ugo™. Che dice: quando hai troppi puntatori aggrovigliati stacca qualche minuto, fai una pausa, due passi o un caffè.

OK, quando ho ripreso ho scritto:

countOdds :: [Int] -> Int
countOdds [] = 0
countOdds (x:xs) 
  | odd x     = 1 + countOdds xs
  | otherwise = countOdds xs

E mi è subito sembrata bella, chissà… sì! è OK! 💥

Cioè se la lista è vuota ritorna 0 altrimenti controlla il primo termine e se è dispari si setta a 1 e richiama se stessa con il resto della lista incrementandosi per ogni occorrenza vera. Semplice vero. Con Haskell (mi sto accorgendo) questo è un modo abituale, solo che … (tra poco arriva).

L’esercizio precedente era anche più complesso, bisognava definire un accumulatore, ma a lezione c’era stato un esempio simile e io ho usato quello come traccia, modificandolo (male! lo so!).

E molto probabilmente è stato lui a portarmi fuori strada. A non vedere la semplicità, l’immediatezza della soluzione, percorrere la lista –ricorsivamente, ovvio– contando i dispari.

Poi ho continuato a pensarci e sono capitombolato su quella del calcolo del fattoriale di un esercizio precedente. A dire il vero questa l’ho vista tante volte che la scrivo in modo automatico (male! lo so!). E comunque è matematica pura, non codice 😁

fact :: Int -> Int
fact 1 = 1
fact n = n * fact (n-1)

Perché non m’è venuta in mente al momento opportuno? Perché sono molto simili, basta aggiungere una condizione di verifica.

Adesso non per giustificarmi ma vorrei ricordare che io ho una certa età; ho cominciato con il Fortran e poi attraversato una lista di linguaggi lunga così.

Avete presente il Fortran, quello di una volta? C’erano le funzioni ma il programmatore tipo (sì, anch’io) non le usava, preferiva le subroutines (le procedures del Pascal e Delphi, diciamo funzioni che tornano void) tanto gli argomenti erno passati per indirizzo. E c’erano i commons.

Ecco in questi giorni (ne ho raccontato qualcosa nelle ultime due Storielle) sono stato alle prese con codice vecchio. Scritto in modo mooolto diverso da come si usa con la FP. E che non vale la pena di aggiornare; il codice dovrebbe avere una scadenza come gli antibiotici e gli alimentari. E anche il vino, salvo casi particolari. E anche io. Ma ci provo 😋

🤢