Visto nel Web – 180

Ecco, prima di subito che devo fare ‘na roba. Intanto ecco cosa ho visto nel Web.
17624_10205529109818690_2585183910160065757_n
Glorious Cable Management
::: cannabusoc

Calabresi: “Serve collaborare con Google e i social media, non sono nemici”
::: la Stampa

Japan robot receptionist welcomes shoppers
::: FRANCE24

Plus de 100 000 signatures pour la pétition #StopLoiRenseignement
::: mbaudier

Google Is Not What It Seems
::: Wikileaks

tumblr_nlyzurjVIw1t3op9po1_540

Twitter Now Lets You Opt In To Receive Direct Messages From Anyone
::: TechCrunch

#Wikipedia: Congressedits (@congressedits) the bot who wins a @shortyawards #ShortyAwards
::: ulaulaman

Swift Tops List of Most-Loved Languages and Tech
::: Slashdot

Internet.org: delivering poor Internet to poor people
::: Boing Boing

Revolt of the free-riding Netizens
::: The Asian Age

sac150331

An open letter to Mark Zuckerberg on Net neutrality
::: Livemint

Tor Is Building the Next Generation Dark Net With Funding From DARPA
::: Slashdot

Global poll shows millennials have positive opinion of Edward #Snowden
::: ACLU

post-2008 impennata delle proposte di censura web
::: AntonioCasilli

#Mobilegeddon – Ormai il digitale è ufficialmente mobile-first
::: Giuseppe Granieri

11138589_10204170532605246_688387234679363500_n

GCC 5 Release Series – Changes, New Features, and Fixes
::: GCC ::: Meeting C++

Project Fi svelato da Google, che diventa un operatore mobile
::: Downloadblog ::: Luca De Biase

Gianni Morandi e la sua ‘lezione’ sull’Italia e i social network
::: Il Fatto Quotidiano

Quand je dois expliquer les différents métiers IT
::: CommitStrip

We’ll Be the Last PC Company Standing, Acer CEO Says
::: Slashdot

claraoswaldnewyorktimesapplewatch

Median Age At Google Is 29, Says Age Discrimination Lawsuit
::: Slashdot

Ubuntu Desktop To Eventually Switch To Snappy Packages By Default
::: Web Upd8

Diffamazione, stretta anche sui blog
::: la Repubblica ::: Valigia Blu

La Stampa è una fogna?
::: manteblog

Zerocalcare e l’Apple Watch
::: Wired ::: Medium ::: Slashdot

11150445_1573520646250159_4538093039714607471_n

How many of you use Ninja comments for code commenting?
::: HackerEarth

OOVCDE
oovcde project searches subdirectories and parses C++ code to automatically create object oriented static class, zone, component, and sequence diagrams, which allow easy navigation between diagrams and code
::: OOVCDE

Rust Once, Run Everywhere
::: The Rust Programming Language

10 giochi per insegnare a programmare ai ragazzi
::: Wired

40 Key Computer Science Concepts Explained In A Simple Language
::: The Ubuntu Incident

davvero?

What Your Students Really Need to Know About Digital Citizenship
::: Edutopia

Google and Facebook Execs Question Government Desire for Encryption Backdoors
::: Technology Review

This is why I prefer android
::: 9GAGTweets

Report from the Python Language Summit
::: LWN

Comcast. Lobby del potere
::: Luca De Biase

CC_wFKQW8AAC_cW

Tre domande sulla nuova ipotesi di “web tax”
::: Wired

Tutti i segreti del sistema Linux, il preferito di “AstroSamantha”
anche su la Repubblica, bravi :grin:
::: Messaggero Veneto

How I make presentations
::: Ned Batchelder

C++timeline
::: b3h3m0th

Lubit e i pacchetti magici
::: the secrets of ubuntu
linus_torvalds_wallpaper_by_glenn1794-d4xkv55
OK, adesso installo ‘buntu, la nuova versione, chissà… :mrgreen:

Risorse Python

python-logoUn commento dell’amico Flavio, the Man from Mars (da quando se n’è andato Marte è l’unico pianeta conosciuto abitato interamente da robots) mi fa una domanda impegnativa, qui:

volendo imparare il Python 3.x, la risorsa (libro, pdf, web) definitiva ed unica che mi consigli di seguire

Mica facile. Anzi, il contrario. Vi faccio un esempio metaforico di una cosa che avete forse già vissuto tutti quanti, probabilmente più e più volte.
Ma prima un avvertimento, un disclaimer: non sono responsabile in alcun modo di eventuali effetti collaterali (side effects) e/o conseguenze immediate, future e protratte nel tempo. Questo va inteso virtualmente, un Gedankenexperiment, nèh!
OK! allora immaginate di entrare in una pasticceria. Ecco, capito? Mica è facile. Nel senso che come si fa a limitarsi a uno, o due, o –ok, QED.

In ogni caso un PDF disponibile liberamente sul web che mi sembra buono è Think Python – How to Think Like a Computer Scientist di Allen B. Downey.
Giù in fondo c’è l’URL per la versione 3.x (versione adattata da Michael Kart) in PDF.
Mi sembra che si possa partire da lì.

Poi naturalmente –avete presente la metafora della pasticceria?– scoprirete che Ce n’est qu’un début, quindi aggiungo un po’ di roba.
Intanto la documentazione sul sito ufficiale di Python, qui: Python 3.4.3 documentation, trovate l’elenco di altre risorse, tante. E quelle raccomandate da loro.
Ci sono i corsi online, per esempio Codecademy, elementare e versione 2.x (è ancora la prevalente, anche se sono d’accordo per insistere con la 3) oppure qui Centre for Education in Mathematics and Computing at the University of Waterloo, 3.x ma molto basico, un assaggino.
Sempre sui corsi online c’è una discussione su Quora: Which online Python course is the best?
C’è un Wikibook: Python Programming, 2-x con indicazioni variazioni 3.x, sembra bello.
Un altro testo vecchio ma usabile, anche questo con parecchi link è Dive Into Python.
Una comunità pythonista su G+.
Infine una cosa che ho scoperto sono ultimamente: ZEEF – Find information through people, nel nosto caso Python by Alan Richmond.
Trovate tante cose, anzi avrei potuto rispondere a Flavio, the MfM, comunicandogli solo questo link (ma il mio blog ne avrebbe sofferto). Per esempio utilissimo il CheatSheet e le espressioni regolari e millemila cose ancora.

Due cose ancora:

  • ci sarebbe tutto il discorso di NumPy/SciPy –prossimamente forse;
  • sì, ho problemi di peso.

Mission-Accomplished

:mrgreen:

Qualche considerazione su CLOS

oopPractical Common Lisp di Peter Seibel, that book is dead sexy, dice Xach.

Vero. È diventato parte integrante delle mie giornate, poi ci ripenso anche la notte, anche a mia insaputa.
Ma credo ve ne sarete accorti, il blog sta dicendo che sono diventato monomaniaco —kwasy :oops:
Già promesso, anche se non ancora processata la promessa, che avrò il libro su carta (sono conservatore in questo campo) perché –oops! mi sto ripetendo.

Però una critica, forse solo mia e di uno dei miei (rari) contatti: alle volte Peter è troppo prolisso (si usa “pistino”? si capisce o è, al solito, uno dei termini gergali locali di qui?), si dilunga troppo sulle cose, anche quelle che si sanno e si perde il filo del discorso.
Mi riferisco in particolare a come viene affrontato l’argomento degli oggetti nel Lisp, dove si chiama CLOS —Common Lisp Object System— nei capitoli che ho copiato nei post Lisp – oggetti – funzioni generiche – N con N in 1..3 e Lisp – oggetti – classi – N con N in 1..4 (non metto i link, li trovate nell’Indice, qui a sinistra).

L’esempio che viene sviluppato –la gestione di un conto corrente bancario– non è quello che avrei voluto. Ricordo perfettamente (kwasy) il manuale del Turbo Pascal 5.5 con la metafora dei nuovi ragnetti degli entomologisti del Brasile (OK, questa è la mia versione, derivata dal manuale, adesso lo comunico a Giors, forse confermerà).
Oppure le forme geometriche, usuale per introdurre l’argomento, ho messo anche l’immagine. Tornando a Peter l’esempio è troppo generico e astratto, secondo me. Da un certo punto in poi smette di pubblicare il codice relativo, tanto ci saranno gli esempi pratici, prossimamente.

Resta sullo sfondo una cosa meravigliosa, a mio modo di vedere: l’estensione del linguaggio per inserire tutto l’ambaradan della OOP (classi, istanze, metodi &rest) viene quasi automatica grazie al concetto di macro.
Sulle macros ho una bozza che prima o poi pubblicherò ma per intanto anticipo che per me è una delle idee più meravigliose di sempre, al pari della pipe di Doug McIlroy di Unix e l’s-expression di John McCarthy &rest –sì ce ne sono altre; poi queste sono le mie, per voi chissà…

Ecco io avrei –forse, non ci ho provato, non credo sia facile, affrontato in modo un po’ diverso l’argomento. Partendo da qualche schema e dettagliando poi, con esempi esplicativi. È una cosa diversa, ma per rendere l’idea copio da Bert Burgemeister.
Inserisco immagini per via dell’impaginazione. deflcass:

defclass

defmethod:

defmethod

Come si vede sono sempre macros:

typog

Quindi?
Quindi l’OOP entra nel Lisp, nato in ere precedenti, in modo semplice e naturale, senza bisogno di aggiustamenti a martellate. Anche se la definizione del linguaggio alla fine risulta meno semplice e bella di quella originale. Siccome sono niubbo sull’argomento non so se e quanto si usi l’OOP nel Lisp, se entri nella programmazione funzionale che mi sembra diversa, una cosa scorrelata, molto lispica.

OK, fine dello sfogo, anzi mi è già passato tutto, domani riprendo che c’è un esempio pratico che attende.
Anche se EWD (non corretto geograficamente) dice che:

dijkstra

Lisp – oggetti – classi – 4

cbxOggi concludo il capitolo, continuando da qui.

Ereditarietà multipla

Tutte le classi viste finora hanno una sola superclasse diretta. Common Lisp supporta l’ereditarietà multipla, una classe può avere più superclassi dirette, ereditando i metodi applicabili e gli specificatori di slot da ognuna di esse.

L’ereditarietà multipla non è poi tutta quella cosa, abbiamo già visto che ogni classe ne ha già una estendendo standard-object che estende T, e quindi abbiamo due superclassi. L’unica differenza è di avere più superclassi dirette e se queste definiscono sono dei metodi comuni occorre fonderli.

Cioè se le classi hanno una sola superclasse diretta ordinare le classi è banale, ogni classe e tutte le sue superclassi possono essere ordinate direttamente partendo dalla classe stessa, seguita dalla sua diretta superclasse, seguita dalla serie delle superclassi fino ad arrivare a T. Ma quando le superclassi dirette sono multiple queste superclassi non sono, tipicaamente, correlate le une alle altre. In questo caso la regola che le subclassi sono più specifiche delle superclassi non è più vera. C’è allora una seconda regola per ordinare le superclassi non correlate, in funzione dell’ordine con cui sono listate nelle liste delle defclass delle superclassi. Questa regola è in qualche misura arbitraria ma consente di avere una lista di precedenza delle classi lineare che può essere usata per determinare quale superclasse può essere considerata più specifica delle altre. Non c’è però un ordinamento globale delle classi, ognuna a la sua lista di precedenza e le classi possono apparire in ordini differenti per differenti classi.

Per vedere come questo funzioni aggiungiamo una classe all’applicazione bank dei post precedenti, money-market-account. Un money market account combina le caratteristiche di checking account e saving account, un costumer può scrivere checks ma anche ricevere interessi (non traduco i termini perché vengono usati nel codice). Si può definire in questo modo:

(defclass money-market-account (checking-account savings-account) ())

La lista di precedenza per la classe money-market-account sarà:

(money-market-account
 checking-account
 savings-account
 bank-account
 standard-object
 t)

Notare che questa lista rispetta entrambe le regole: ogni classe appare prima delle sue superclassi e checkig-account appare nell’ordine specificato in defclass.

Questa classe non definisce slots suoi proprii ma eredita da entrambe le sue superclassi dirette inclusi gli slots che queste ereditano dalle loro superclassi. Similmente ogni metodo che è applicabile a qualunque classe nella lista di precedenza delle classi sarà applicabile a un oggetto money-market-account. Siccome tutti gli specificatori di slot per lo stesso slot sono fusi non importa che money-market-account erediti lo stesso specificatore di slot due volte (a differenza del C++).

L’eredità multipla è più facile da comprendere per superclassi con comportamenti completamente indipendenti. per esempio money-market-account erediterà slots e comportamenti per gestire con checks da checking-account e slot e comportamenti per calcolare interessi da saving-account. Non ci si deve preoccupare per la lista delle precedenze se gli slots sono ereditati da una superclasse o dall’altra.

Tuttavia è possibile ereditare metodi diversi per qualche funzione generica da diverse superclassi. In questo caso entra in gioco la lista di preferenza delle classi. Per esempio supponiamo che l’applicazione abbia definito una funzione generica print-statement usata per generare un rapporto mensile. Presumibilmente questo metodo ci sarà per entrambe le classi e entrambi questi metodi saranno applicabili ma quello in checking-account sarà considerato più specifico perché checking-account precede saving-account nella lista delle precedenze di money-market-account.

Assumendo che i metodi ereditati siano tutti primari e non si siano definiti altri metodi, il metodo specializzato in checking-account sarà utilizzato per print-account in money-market-account. Tuttavia questo può non essere il comportamento voluto siccome probabilmente si vorrà un comportamento che contenga elementi delle due superclassi.

Si può modificare il comportamento di print-account per money-market-account in un paio di modi. Il modo diretto è di definire un nuovo metodo specializzato per money-market-account; questo da il massimo del controllo per il comportamento ma richiede più codice nuovo. Il problema è che mentre si può usare call-next-method per chiamare il successivo metodo più specifico, in questo caso quello specificato in checking-account, non c’è modo di invocare un metodo particolare meno specifico, come quello specificato in saving-account. Quindi se si vuole poter riusare in codice che stampa la parte di saving-account si deve spezzare il codice in una funzione separata che si possa chiamare direttamente dai metodi sia da money-market-account che di saving-account.

Un’altra possibilità è di scrivere un metodo primario per tutte tre le classi per chiamare call-next-method. Quindi il metodo specializzato in money-market-account userà call-next-method per invocare il metodo specializzato in checking-account. Quando questo metodo chiamerà call-next-method chiamerà il metodo di saving-account perché questo risulterà il successivo più specifico per la lista di precedenza di money-market-account.

Ovviamente se ci si basa su call-next-method per essere sicuri che tutti i metodi applicabili vengano eseguiti verrebbe da pensare di usare invece metodi ausiliari. In questo caso invece di definire un metodo primario in print-statement per checking-account e saving-account si possono definire questi metodi come metodi :after, definendo un solo metodo primario in bank-account. Quindi print-statement chiamato in un money-market-account stamperà un po’ dal metodo specializzato di bank-account seguito dai dettagli dei metodi :after specializzati in saving-account e checking-account. E se si vogliono aggiungere dettagli specifici per money-market-account basterà definire per questo un metodo specializzato :after che sarà eseguito per ultimo.

Il vantaggio di usare metodi ausiliari è che si rende più chiaro quali sono i metodi primari responsabili per l’implementazione della funzione generica e quali sono quelli che contribuiscono alla funzionalità. Lo svantaggio è che non si ha un controllo fine, se si vuole avere lo scambio dell’ordine in money-market-account bisogna cambiare l’ordine con cui questa subclassa le classi. Ma questo cambiamento drammatico può avere effetti sugli altri slots. In generale –vedete un po’ voi :wink:

D’altra parte se non è così importante l’ordine che si vuole per essere consistenti attraverso diverse funzioni generiche usare i metodi ausiliari è il modo corretto. Se per esempio oltre a print-statement si vuole avere la funzione generica print-detailed-statement si può implementare entrambe le funzioni usando metodi :after per le varie subclassi di bank-account, e l’ordine delle parti sia regolare che dettagliato sarà lo stesso.

Corretta progettazione orientata agli oggetti

Questo è quanto per le opzioni principali del sistema a oggetti di Common Lisp. È un campo molto vasto, come si è visto. Come dice il manuale di Perl:

Now you need just to go off and buy a book about object-oriented design methodology and bang your forehead with it for the next six months or so.

Ma, dice il Peter (rockz!) vedremo presto esempi pratici, prossimamente :mrgreen:

Lisp – oggetti – classi – 3

Arun SKEbbene sì: continuo a copiare da qui.

with-slots e with-accessors

le funzioni d’accesso rendono più facile la manutenzione del codice ma tendono a essere prolisse. E ci sono casi in cui si vuole accedere direttamente agli slot, senza scrivere funzioni ausiliarie.

Questo è quello per cui c’è slot-value; tuttavia anche questo è prolisso. A peggiorare le cose una funzione o un metodo che accede troppe volte a diversi slots intasa le chiamate a slot-value (dice Peter, nèh!). Per esempio anche questo esempio semplice non piace:

(defmethod assess-low-balance-penalty ((account bank-account))
  (when (< (balance account) *minimum-balance*)
    (decf (slot-value account 'balance) (* (balance account) .01))))

E se si decide di volere un accesso diretto al valore dello slot per evitare metodi ausiliari diventa ancora peggio:

(defmethod assess-low-balance-penalty ((account bank-account))
  (when (< (slot-value account 'balance) *minimum-balance*)
    (decf (slot-value account 'balance) (* (slot-value account 'balance) .01))))

Per fortuna ci sono due macros standard: with-slots e with-accessors. Entrambe creano un blocco di codice in cui semplici nomi di variabili possono essere usate per riferirsi a slots di un particolare oggetto. with-slots permette l’accesso diretto a slots, come fa slot-value mentre with-accessors fornisce una scorciatoia per accedere ai metodi.

la forma base di with-slots è la seguente:

(with-slots (slot*) instance-form
  body-form*)

Ogni elemento di slots può essere sia il nome di uno slot, che è anche usato come nome di variabile, o una lista di due elementi dove il primo è il nome da usare come variabile e il secondo il nome dello slot. L’instance-form è valutata una sola volta per produrre l’oggetto i cui slots saranno acceduti. Dentro il corpo ogni occorrenza di uno dei nomi di variabile è tradotto in una chiamata a slot-value con l’oggetto e il nome dello slot appropriati come argomenti. A essere rigorosi e pistini le variabili non sono vere variabili ma symbol macro, vedremo in futuro …
Quindi si può scrivere per accedere a access-low-balance-penalty così:

(defmethod assess-low-balance-penalty ((account bank-account))
  (with-slots (balance) account
    (when (< balance *minimum-balance*)
      (decf balance (* balance .01)))))

o, usando le liste di due elementi:

(defmethod assess-low-balance-penalty ((account bank-account))
  (with-slots ((bal balance)) account
    (when (< bal *minimum-balance*)
      (decf bal (* bal .01)))))

Se si è definito un :accessor invece di un solo :reader si può usare with-accessors la cui forma è come with-slots solo che ogni elemento dello slot è una lista di due elementi contenente un nome di variabile e il nome di una funzione d’accesso. Dentro il corpo di with-accessors un riferimento a una delle variabili è equivalente a una chiamata alla funzione d’accesso.Se questa è setf-abile così sarà la variabile:

(defmethod assess-low-balance-penalty ((account bank-account))
  (with-accessors ((balance balance)) account
    (when (< balance *minimum-balance*)
      (decf balance (* balance .01)))))

La prima balance è il nome della variabile, la seconda quello della funzione d’accesso; non è necessario che siano identiche. Per esempio si può scrivere un metodo per fondere due accounts usando due chiamate a with-accessors, una per ciascun account:

(defmethod merge-accounts ((account1 bank-account) (account2 bank-account))
  (with-accessors ((balance1 balance)) account1
    (with-accessors ((balance2 balance)) account2
      (incf balance1 balance2)
      (setf balance2 0))))

la scelta se usare with-slots o with-accessors è la stessa come tra slot-value e la funzione d’accesso. In genere conviene with-accessors tranne particolari ragioni per non farlo.

Slots allocati alla classe

L’ultima opzione per lo slot è :allocation. Il valore di :allocation può essere :instance (valore di default) o :class. Quando uno slot ha l’allocazione :class lo slot ha un solo valore che è memorizzato nella classe per tutte le istanze.

Tuttavia gli slots :class sono accessibili proprio come gli slots :instance, con slot-value o una funzione d’accesso, che vuol dire che si può accedere al valore dello slot solo un istanza alla classe anche se non è memorizzato nell’istanza. le opzioni :initform e :initarg hanno lo stesso comportamento eccetto che vengono valutate una sola volta quando la classe è creata. D’altra parte passando un initarg a make-instance setterà il valore per tutte le istanze della classe.

Siccome non si può ottenere uno slot class-allocated senza un’istanza a una classe questi non sono equivalenti a static del C++ o class field di Python. Sono invece usati per salvare spazio, vedi te.

Slots e ereditarietà

Come visto in precedenza le classi ereditano i comportamenti delle loro superclassi grazie al meccanismo delle funzioni generiche, un metodo specializzato alla classe A è applicabile non solo alle istanze dirette di A ma altresì alle istanze delle subclassi di A. Le classi ereditano anche slots dalle loro superclassi ma il meccanismo è leggermente diverso.

Un dato oggetto può avere un solo slot con un particolare nome. Tuttavia è possibile che più di una classe nella gerarchia ereditata da una data classe specifichino uno slot con quel particolare nome. Può capitare sia perché una subclasse include uno specificatore di slot con lo stesso nome di uno slot specificato in una superclasse oppure perché più superclassi specificano slots con lo stesso nome.

Il Common Lisp risolve queste situazioni fondendo tutti gli specificatori con lo stesso nome dalla nuova classe e tutte le sue superclassi creando un singolo specificatore per ogni singolo slot. Quando fonde specificatori slots di opzioni sono trattati diversamente. Per esempio se più classi specificano un :initform la nuova classe usa quello della classe più specifica. Questo consente a una subclasse di specificare un diverso valore di default in sostituzione di uno che altrimenti erediterebbe.

D’altra parte :initargs non è necessario sia esclusivo, ogni opzione :initarg crea un parametro keyword che può essere usato per inizializzare lo slot; più parametri non creano un conflitto cosicché tutti i nuovi specificatori di slot contengono tutti gli :initargs. Le chiamate a make-instance possono usare qualunque degli :initargs per inizializzare lo slot. Se una chiamata passa più argomenti keyword che inizializzano lo stesso slot allora viene usato quello più a sinistra in make-instance.

Le opzioni per :reader, :writer e :accessor ereditate non sono incluse nello specificatore dello slot fuso essendo che i metodi creati dalla defclass della superclasse saranno applicati alla nuova classe. La nuova classe può tuttavia creare le proprie funzioni accessorie fornendo le proprie opzioni :reader, :writer e :accessor.

L’opzione :allocation è affine a :initform, determinata dalla classe più specifica che specifica lo slot. È quindi possibile per tutte le istanze di una classe di condividere uno slot :class mentre istanze di una subclasse possono avere i loro slot :instance con lo stesso nome. E una sub-subclasse può ridefinirlo allo slot :class. In quest’ultimo caso lo slot condiviso dalle istanze a sub-subclasse è diverso da quello della superclasse originale.

Per esempio, supponiamo di avere queste classi:

(defclass foo ()
  ((a :initarg :a :initform "A" :accessor a)
   (b :initarg :b :initform "B" :accessor b)))

(defclass bar (foo)
  ((a :initform (error "Must supply a value for a"))
   (b :initarg :the-b :accessor the-b :allocation :class)))

Istanziando la classe bar si può usare l’initarg ereditato, :a, per specificare il valore dello slot a e in effetti occorre farlo per evitare un errore siccome :initform fornito per bar sostituisce quello ereditato da foo. Per inizializzare lo slot b si può usare sia l’initarg ereditato :b o il nuovo :the-b. Tuttavia, siccome l’opzione :allocation sullo slot b è bar il valore specificato verrà memorizzato nello slot condiviso da tutte le istanze di bar. Lo stesso slot può essere acceduto sia con il metodo della funzione b che specializza in foo o con un nuovo metodo per la funzione generica the-b che specializza direttamente in bar. Per accedere lo slot a sia in foo che in bar si continuerà a usare la funzione generica a.

Normalmente fondendo definizioni di slot funziona tranquillamente. Tuttavia è importante sapere che usando eredità multiple che slots non correlati con lo stesso nome saranno fusi in uno solo nella nuova classe. Questo è un problema , vedremo in futuro, che si supera con i packages.

Pausa (panicosa) qui :evil:
Ma poi continuerò ancora, forse :mrgreen:

Linguaggi vecchi e nuovi

plOggi un post su Slashdot — quanti suggerimenti da /. :grin — mi costringe a finire una cosa in sospeso da ormai troppi giorni.

Top39-700
Ecco, credo si possa partire da questo diagramma per iniziare. Potrei farla lunga ma passo a chi ne sa più di me. E poi ognuno ha le sue idee.
Il diagramma viene da qui: Python is Now the Most Popular Introductory Teaching Language at Top U.S. Universities. Da leggere.
Alcuni di questi linguaggi sono solo accademici, altri invece tutto il contrario.

Il sondaggio di Stack Overflow fa vedere cose interessanti. Rompo la mia neutralità solo per esternare la mia perplessità su Swift, che peraltro non conosco, fa parte del mondo Apple. Non so bene come interpretare quei terrori, costringono a usare quei linguaggi o cosa? Anch’io avrei i miei.

Poi sono finito qui: I Missed Nim.
Interessante, il post e il blog –RSSato subito. Di Nim, quando ancora si chiamava Nimrod, ho letto qualcosa sul defunto Dr.Dobb’s. Interessante; chissà se in futuro…
Un mio ex-capo, uno che rockz, adesso usa Go, ha quasi promesso che mi faceva un post o due, tempo fa ma è impegnatissimo, chissà…
Rust è un altro da tener d’occhio, se ricordo bene Robitex sa tutto in proposito.

Ah! quasi dimenticavo: l’altro giorno ho trovato questo su uno dei miei linguaggi preferiti: Python by Alan Richmond.

OOPS! mi sono dimenticato che avevo detto che non volevo influenzare nessuno. Ci sono quasi riuscito: non ho detto niente contro Matlab :wink:

Lisp – oggetti – classi – 2

peano-gosperProcedo, continuando da qui a copiare qui.

Funzioni d’accesso

Credo si debba tradurre così “Accessor Functions”, se no cambierò.
Con make-instance e slot-value abbiamo tutti i tools necessari per creare e manipolare le istanze a una classe. Tutto quello che può servire d’altro si può implementare in termini di queste funzioni. Tuttavia si sa che nella programmazione orientata agli oggetti accedere direttamente agli slots (o field o variabili membro) di un oggetto genera codice fragile. Per esempio supponiamo di voler cambiare la definizione di bank-account in modo che invece di memorizzare balance come numero come una lista temporale di prelievi e depositi. Il codice che accede direttamente allo slot balance va in errore se si tenta di cambiare la definizione della classe per rimuovere lo slot o per per aggiungere la nuova lista nel vecchio slot. D’altra parte se si definisce una funzione, balance, che accede allo slot si può ridefinirlo dopo per preservarne il comportamento anche se la sua rappresentazione interna cambia e tutto il codice che usa questa funzione continua a funzionare senza bisogno di modifiche.

Un altro vantaggio di usare funzioni d’accesso invece dell’accesso diretto a slot-value è che queste permettono di limitare i modi con cui il codice può modificare lo slot. Può essere bello per gli utenti della classe bank-account di ottenere balance ma si può volere che tutte le sue modifiche passino attraverso depositi e prelievi. Se i clienti sanno che possono manipolare questi oggetti solo attraverso le API funzionali pubblicate si può fornire una funzione balance ma non renderla setf-abile se si vuole tenere read-only.

Infine usando funzioni d’accesso si rende il codice più chiaro perché questo evita usi di funzioni di slot-value verbose.

È immediato definire una funzione che legge il valore dello slot balance:

c17-12

Tuttavia se si vuole definire una subclasse di bank-account può essere un’idea di definire balance come funzione generica. In questo modo i possono fornire i diversi metodi in balance per quelle subclassi o estenderne le loro definizioni con metodi ausiliari. Quindi si può riscrivere così:

c17-13

Come detto non si vuole che l’utente possa accedere direttamente a cambiare balance ma per altri slot, come customer-name si può prevedere una unzione per settarlo. In questo caso il modo più chiaro è definire una funzione come una funzione setf.

Una funzione setf è un modo di estendere setf, definendo un nuovo tipo di posto settabile. Il nome di una funzione setf è una lista di due elementi in cui il primo è setf e il secondo è un simbolo, tipicamente il nome di una funzione usata per accedere al posto che la funzione setf setterà. Una funzione setf può prendere qualunque numero di argomenti ma il primo è sempre il valore da assegnare al posto. Si può per esempio definire una funzione setf per settare lo slot customer-name in bank-account così:

c17-14

Dopo la valutazione della definizione un’espressione come:

(setf (customer-name *account*) "Sally Sue") ==> "Sally Sue"

Nota: qui mi becco un errore; vedo di ricaricare tutto quello di ieri. OK.

c17-15

Niente di difficile per scrivere queste funzioni d’accesso ma non è The Lisp Way scriverle a mano. Pertanto defclass supporta tre opzioni di slot che permettono di crearle automaticamente le funzioni di reader e writer per uno specifico slot.

L’opzione :reader specifica il nome da usarsi per la funzione generica che accetta un oggetto come suo singolo argomento. Quando la defclass è valutata la funzione generica è creata se già non esiste. Viene poi aggiunto un metodo specializzante il suo argomento della nuova classe e restituito il valore dello slot alla funzione generica. Il nome può essere qualunque ma è di solito il nome dello slot stesso. Quindi invece di scrivere la funzione generica balance e i metodi visualizzati sopra si può cambiare lo specificatore slot nella definizione di bank-account così:

(balance
 :initarg :balance
 :initform 0
 :reader balance)

L’opzione :writer è usata per creare una funzione generica e un metodo per settare il valore di uno slot. Funzione e metodo seguono le specifiche di una funzione setf, prendendo il nuovo valore come primo argomento e ritornandolo come risultato cosicché si può definire una funzione come (setf customer-name). Per esempio si possono provvedere i metodi reader e writer simili a quelli appena scritti cambiando solo lo specificatore dello slot così:

(customer-name
 :initarg :customer-name
 :initform (error "Must supply a customer name.")
 :reader customer-name
 :writer (setf customer-name))

Siccome è comunissimo voler sia le funzioni reader e writer defclass fornisce l’opzione :accessor che crea le funzioni dette e la corrispondente setf. Quindi riscriviamo così:

(customer-name
 :initarg :customer-name
 :initform (error "Must supply a customer name.")
 :accessor customer-name)

Infine un’ultima opzione per lo slot è :documentation –devo dire a cosa serve?
Mettendo tutto assieme e aggiungendo un metodo reader per gli slots account-number e account-type la form defclass per la classe bank-account diventa:

c17-16

Pausaaaa :evil:
Ma poi si continua :mrgreen:

Lisp – oggetti – classi – 1

l19Finito il racconto sui metodi si parte con le classi.

Se le funzioni generiche sono i verbi del sistema degli oggetti le classi sono i nomi.
Ogni valore in Common Lisp è un’istanza a qualche classe e tutte le classi sono organizzate in una singola gerarchia la cui radice è la classe T.

La gerarchia delle classi consiste di due famiglie maggiori, built-in e deinite dall’utente. Le classi che rappresentano tipi di dati come quelli visti finora come integer, string e list sono tutte built-in. Vivono nella loro sezione della gerarchia, organizzate nelle loro sub- e superclassi appropriate e sono manipolate con le funzioni viste finora. Non è possibile subclassare queste classi ma, come visto nei post precedenti, si possono definire metodi per specializzarle, estendendone il comportamento.

Ma –riprendendo l’esercizio iniziale– quando si vogliono definire nuovi nomi, come le classi per l’esempio di bank-account dei post precedenti, si devono definire le proprie classi. Ecco oggi questo.

defclass

Si creano classi con la macro defclass. Siccome i comportamenti associati alla classe sono definiti con funzioni generiche e metodi specializzatori per la classe defclass deve solo definire la classe come tipo di dati.

I tre aspetti della classe come tipo di dati sono il nome, le sue relazioni con altre classi e i nomi degli slots che creano le istanze della classe. Gli slots sono quelli che altri chiamano fields, variabili membro o attributi.
la forma base è semplicemente:

(defclass name (direct-superclass-name*)
  (slot-specifier*))

Cosa sono le “Classi definite dall’utente”
Il termine user-defined class non è un termine tecnico, sono quelle classi che subclassano standard-object e la cui superclasse non è standard-class. Ma non ce ne dobbiamo preoccupare, dice Peter. Poi la cosa sarebbe ancora più incasinata, per esempio c’è defstruct, terribile, nato prima di CLOS e inserito dentro a martellate. Dai, questo paragrafo si può ignorare :wink:

Come per funzioni e variabili si può usare qualunque simbolo per il nome di una nuova classe. I nomi delle classi sono un namespace separato sia dalle funzioni che dalle variabili così si può avere classe, funzione e variabile tutte con lo stesso nome. Si usa il nome della classe come argomento di make-instance, la funzione che crea nuove istanze per classi definite dall’utente.

Le direct-superclass-names specificano le classi che la nuova classe subclassa. Se nessuna superclasse è elencarla la nuova classe sarà una subclasse diretta di standard-object che a sua volta è una subclasse di T. Quindi tutte le colassi user-defined sono parti di una singola gerarchia di classi che contiene anche tutte le classi built-in.

Trascurando per un momento gli slots specificatori le forms defclass di qualcuna delle classi usate nell’esempio dei post passati sono simili a questo:

(defclass bank-account () ...)

(defclass checking-account (bank-account) ...)

(defclass savings-account (bank-account) ...)

Peter ci dirà in “Ereditarietà multipla” cosa vuol dire una lista di più di una diretta superclasse in direct-superclass-names.

Specificatori di slot

La maggior parte di defclass consiste della lista di specificatori di slot. Ogni specificatore di slot definisce uno slot che sarà parte di ogni istanza della classe. Ogni slot in un’istanza è il posto che può contenere un valore, che sarà accessibile usando la funzione slot-value. slot-value prende un oggetto e il nome di uno slot come argomenti e ritorna il valore dello slot nominato nell’oggetto dato. Si può usare setf per definire il valore di uno slot in un oggetto.

Una classe eredita anche gli specificatori di slot dalle sue superclassi, cosicché il set di slot realmente presenti in qualunque oggetto è l’unione di tutti gli slot specificati in una form defclass della classe e quelli specificati in tutte le sue superclassi.

Come minimo uno specificatore di slot nomina lo slot, nel qual caso lo specificatore può essere solo un nome. Per esempio si può definire la classe bank-account con due slots, customer-name e balance, così:

c17-0

Ogni istanza a questa classe conterrà due slots, con questa definizione i può creare un nuovo oggetto bank-account usando make-instance:

c17-1

La rappresentazione dell’oggetto ritornato è determinata dalla funzione generica print-object. In questo caso il metodo applicabile può essere uno di quelli previsti dall’implementazione, specializzato in nel metodo print di standard-object. Usa la sintassi #<> che induce il reader a segnalare un errore se deve leggerlo. In futuro vedremo come definire un metodo di print-object che rende le cose più umane.

Usando la definizione di bank-account data sopra nuovi oggetti possono essere creati con i loro slots scollegati (unbound). Ogni tentativo di accedere al valore di un unbound slot segnala un errore per cui occorre settare uno slot prima di poterlo leggere:

c17-2

Adesso è possibile leggere i valori degli slots:

c17-3

Inizializzazione degli oggetti

Siccome con gli slots unbound non si può fare molto sarebbe bello poter creare oggetti con gli slots già inizializzati. Ci sono tre modi per controllare i valori iniziali degli slots. I primi due implicano di aggiungere allo specificatore dello slot nella form defclass l’opzione :initarg specificando un nome che potrà essere usato come parametro keyword per make-instance e i cui argomenti saranno memorizzati nello slot. Una seconda opzione, :initform, permette di specificare un’espressione Lisp che sarà usata per calcolare il valore per lo slot se non si passa un argomento :initarg a make-instance. Infine, per un completo controllo dell’inizializzazione, si può definire un metodo nella funzione generica initialize-instance che è chiamato da make-instance. Trascuriamo per adesso un’altra cosa ancora: :default-initarg.

Uno specificatore di slot che include le opzioni :initarg o :initform è scritto come una lista iniziante con il nome dello slot e seguito dalle opzioni. Per esempio se si vuol modificare la definizione di bank-account per permettere alle chiamate a make-instance di passare il nome dell’utente e il saldo iniziale e provvederne uno iniziale di zero si può scrivere:

c17-4

Adesso è possibile creare un account e specificarne i valori degli slots allo stesso tempo:

c17-5

Se non si fornisce un argomento :balance a make-instance lo slot-value di balance verrà calcolato nella valutazione della form tramite l’opzione :initform. Ma se non si fornisce un argomento per :customer-name lo slot customer-name sarà unbound e un tentativo di leggerlo prima di assegnarlo segnalerà un errore:

c17-6

Se ci si vuole assicurare che il nome dell’utente sia fornito quando l’account è creato si può segnalare un errore nella initform visto che verrà valutata solo se un initarg non è fornito. Si possono anche usare initforms che generano un differente valore ogni volta che sono valutate –l’initform viene valutata per ogni nuovo oggetto. Per provare queste tecniche si può modificare lo specificatore dello slot customer-name e aggiungere un nuovo slot, account-number, che sarà inizializzato con un contatore con valore sempre crescente.

c17-7

Nella maggior parte dei casi  la combinazione delle opzioni :initarg e :initform risulterà sufficiente per inizializzare propriamente un oggetto. tuttavia, mentre un initform può essere qualsiasi espressione Lisp, essa non ha accesso all’oggetto che si sta inizializzando cosicché non si può inizializzare uno slot basato sul valore di un altro. Per far questo occorre definire un metodo nella funzione generica initialize-instance.

Il metodo primario di initialize-istance specializzato in standard-object si cura di inizializzare gli slots basati dalle opzioni :initarg e :initform. Siccome non si vuole disturbare questo il modo più comune di aggiungere codice di inizializzazioni personalizzate è di definire nella classe un metodo :after specializzato. Per esempio se si vuole aggiungere lo slot account-type che dev’essere settato a uno dei valori :gold, :silver o :bronze basato sulla balance iniziale si può cambiare la definizione della classe, aggiungendo lo slot account-type senza un opzione:

c17-8

Quindi si può definire un metodo :after per initialize-instance che setta lo slot account-type basato sul valore che è stato inserito nello slot balance.

Nota: Uno degli errori tipici è di definire un metodo initialize-instance senza qualificatore :after. In questo modo si crea un nuovo metodo primario che maschera quello di default. Si può rimuovere il metodo non voluto con remove-method e find-method:

(remove-method #'initialize-instance
  (find-method #'initialize-instance () 
    (list (find-class 'bank-account))))

Tornando al dunque:

c17-9

L’&key nella lista dei parametri è richiesta per premettere alla lista dei parametri del metodo di essere congruente con la funzione generica –la lista dei parametri specificata nella funzione generica initialize-instance contiene un &key per permettere ai metodi individuali di  fornire i loro parametri keyword ma non sono obbligatori. Quindi ogni metodo deve specificare un &key anche se non ha parametri di quel tipo.

D’altra parte se un metodo specializzato di initialize-instance in una particolare classe specifica un parametro &key questo parametro diventa un parametro legale per make-instance quando viene creata un’istanza a una classe. Per esempio se la banca paga a volte una percentuale della balance iniziale come bonus quando un account viene aperto si può implementare usando un metodo di initialize-instance che prende un argomento keyword che specifica la percentuale del bonus, così:

c17-10

Definendo questo metodo si crea :opening-bonus-percentage un argomento legale di make-instance quando si crea un oggetto bank-account:

c17-11

Pausa :mrgreen:

Il blog, i post e me

Pare che i blogs stiano morendo. È una di quelle notizie ricorrenti, un meme oserei dire se sapessi cosa significa quella parola.
Forse è vero, questa volta, parecchi di quelli che conosco si lamentano; qualche blogger latita da tempo. Sull’altro blog le visite si sono dimezzate, i miei collaboratori non collaborano –OK, sono entrato anch’io a far parte del coro :cry:

Ma qui le cose sono per certi aspetti differenti, provo a spiegarne qualcuno.

Rosie_The_BloggerIntanto una cosa che mi sto chiedendo da tempo e non riesco a venirne a capo: io faccio parte di una minoranza decisamente trascurabile, lo so, non faccio niente per uscirne, anzi…
Sono vecchio, pensionato ormai e fuori dal mondo della produzione, bloggo per avere qualche interesse e i miei interessi sono sempre più cose interessanti solo per me –di questo dopo.

Parecchi di quelli che frequento (e qualche blogger via mail) non dicono mai quello che fanno, a volte ti raccontano cose se e solo se poi non dici niente a nessuno. E non sono cose brutte o estremamente innovative; anzi googlando (o meglio stakoverflowando, githubando e simili) trovi di meglio –quando riesci a capire. Sono quelli che commentano con mail, resta una cosa sussurrata, almeno fino a quando mi scappa.
C’è un blogger con il quale sono in contatto via mail che finita la scuola si è messo a scrivere furiosamente cose meravigliose (per me) e poi ha smesso improvvisamente. Siccome avevo commentato qualche suo post l’ho contattato e mi ha detto che i contenuti erano cose che gli erano servite per la tesi (o la scuola) e adesso che aveva trovato lavoro (completamente diverso da quel che cercava) non aveva più tempo e voglia (non era più motivato).
Altro motivo qui: oggi si fanno cose che non sono mie, come il mobile o il web. Io sono vecchio, forse l’ho già detto.

xkcdAnche i linguaggi di programmazione non sono più loro. Racconto una storia personale: un po’ di tempo fa sono stato contattato da un vecchio conoscente per aggiornare programmi ormai maggiorenni ma tuttora validi. Scritti come Randall racconta qui. In Fortran, difficili da tradurre, senza grafica. Io ci ho pensato su un po’ e ho scoperto Gnuplot. Funziona benissimo. Solo che… non è quello che i giovani gli utenti di oggi vogliono. Ah! quelli che conosco sono tutti con Windows (Xp e Sette ma ormai anche 8.x) , oltre che smartphones sempre più fantabulosi.

python310714Non è che sono rimasto fermo al Fortran, anzi tutt’altro: io sono un pythonista, generalmente ma flessibile, poliglotta.
Ho le mie antipatie (Basic, Java, C++ quando non serve (poi quando serve sono cose troppo difficili per me), altri ancora).
Quando ho proposto Python mi sono scontrato con Visual Basic, poi Java e poi è arrivato Matlab. Adesso è tutto un proliferare di Matlab, che è proprietario e oneroso, assay. Il clone freeware Octave non fa le stesse cose, non è esattamente compatibile, non interessa.

Come risultato –l’ho detto che devo fare qualcosa per non sentirmi troppo vecchio?– ho riscoperto una cosa rimasta da approfondire da sempre: il Lisp.

250px-GEBcoverDopo averlo scoperto per via di Douglas Hofstadter e averci giocato un po’ con una versione davvero antica l’ho usato su PC, forse XLISP ma non ho più nessuna documentazione e non ne sono sicuro. Poi AutoLISP per AutoCAD (anche se i disegnatori preferivano farne a meno, anzi lo detestavano con tutte le loro forze). Bello newLISP che ho scoperto quando era nuovissimo e ne ho seguito l’evoluzione. D’accordo non è un Lisp vero ma per gli script veloci è eccezionale (questo lo dice anche una mia amica (di quelle che lavorano dove non si può bloggare ma la trovate su Facebook), siamo in due (almeno) a pensarla così).

pclPerò il Lisp vero, il Common Lisp da cui sono poi derivati linguaggi funzionali (servono fuori dal web? ne dubito) non l’avevo mai affrontato come si deve. Fino a pochi mesi fa. Dopo una falsa partenza (l’indice era molto promettente ma il testo ancora quasi completamente da scrivere) ho scoperto Peter Seibel e il suo fantastico Practical Common Lisp.

È impegnativo, ci dedico qualche ora al giorno, esaurisce le mie capacità intellettive, anzi va oltre. Ma è un modello; se si deve imparare qualcosa di nuovo è l’unico modo. Almeno per me: mi sembra di essere tornato a scuola.

Per contro, tornando al blog, i post sul Lisp hanno pochissime visite. Quasi nessuna. E se mi preoccupassi della cosa dovrei rimediare cambiando tutto, postare foto di gattini, p.es. :wink:
Ma ho anche materiale per altri post, per esempio su aspetti storici (chi ha inventato il concetto di macro nel Lisp? p.es.) o su altri linguaggi (quando finisco questo).

E poi … chissà :mrgreen:

Visto nel Web – 179

Una domanda prima di iniziare la solita rassegna: funziona il Blogroll? Cioè posso non citare qui tutti i post dei blog che sono là? Ovvio che se vedo qualcosa di clamoroso lo metto anche qui.
E adesso ecco cosa ho visto nel Web.

1viJiI9KzaEN24IPJiMeiIg
Siamo tutti televisioni (ovvero: perché tanta gente è attenta a Periscope)
::: Giuseppe Granieri

We now come to the decisive step of mathematical abstraction
::: SICPQuotes

L’esercito degli utenti falsi del web
::: Linkiesta

@PietroGrasso deve spiegare perché il problema è “cyber” a fronte di questi dati
::: fabiochiusi

La pétition contre le #PJLRenseignement a recueilli ce matin 55.000 signatures
::: btabaka ::: nitot ::: jerezim

sac150210

Do EU petitions work? | euronews, Europe
::: fabiochiusi

L’éternelle insatisfaction du codeur
::: CommitStrip

Bitcoin is Not a Good Consumer Product
già sentita ma OK
::: Armin Ronacher

Republicans Introduce a Bill To Overturn Net Neutrality
internet è in pericolo, sempre
::: Slashdot

Linux Getting Extensive x86 Assembly Code Refresh
::: Slashdot

0ff2dadc-633f-4d7f-9320-bf45ede07f47

Kaspersky releases decryption tool that unlocks ransomware
per in windoziani
::: Engadget

Ubuntu: tracciare un grafico del traffico di rete
::: TUXJournal

Parigi brucia?
E se le rivelazioni fatte da Edward Snowden avessero avuto un effetto deleterio?
::: Signor D

Digital music sales have exceeded those from CDs for the first time
::: WSJ

Glad Commission continues to take #Google case by the horns
::: MartinSchulz

liberta e sicurezza

Chess Grandmaster Used iPhone To Cheat During Tournament
Moggi?
::: Slashdot

MIT’s Picture Language Lets Computers Recognize Faces Through Inference
::: Slashdot

Introduction to Graph Tool
::: Connor Johnson

The New Inquisition
::: Town hall

Nokia agrees to buy Alcatel-Lucent for $16.6 billion
::: The Verge

how

EU Has ‘Effective’ Powers to Take on Google: Oettinger
::: Bloomberg ::: il Sole 24 Ore ::: Luca De Biase ::: Slashdot ::: la Repubblica ::: la Stampa ::: Slashdot

Reda report: the 10 worst and the 5 best amendments
::: Communia

Libertà digitale? Cominciamo dalla #scuola
::: MarcoAlici

The Crazy-Tiny Next Generation of Computers
::: Slashdot

SHA1
::: SIAMO GEEK

funny-ducks-taking-pictures-duckface

Moore’s Law@50: “The most important graph in human history”
::: Computer History Museum

Le declinazioni nazionali della sorveglianza
::: Signor D

How Many Hoaxes Are On Wikipedia? No One Knows
::: Slashdot

Python 2, Python 3, Stretch & Buster
Booo, Python 2!
::: debian

DARPA Memex, motore di ricerca per il dark web
::: tyllasistemi

eb680198-40c3-4ccd-975f-bf165091b480

Se vuoi ottenere una risposta da qualcuno mandagli un messaggio su FB
::: emmecola

Dr. Alan Kay on the Meaning of “Object-Oriented Programming”
storia :grin:
::: PURL

GNU Hurd 0.6 Released
::: Slashdot

Code Quality
::: xkcd

Global right to information rating map
::: rosybattaglia

myprint_gothamcity

Microsoft Open Technologies Is Closing: Good Or Bad News For Open Source?
::: Slashdot

Snowden a #ijf15: “Contro la sorveglianza serve la resistenza civile”
::: Wired

How The Facebook Bubble Is Driving Online Startups Into The Arms Of Offline Advertising
::: TechCrunch

Snowden and the debate on surveillance versus privacy
::: Doc Madhattan

Twitter Moves Non-US Accounts To Ireland, and Away From the NSA
::: Slashdot

PicsArt_1425311641410-1-1

Iscriviti

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

Unisciti agli altri 85 follower