Ancora su j – Autojump e source

Il post su Autojump  è piaciuto. E pensare che l’idea ce l’avevo da parecchio tempo, non so quante volte ho cominciato a scriverci e poi lo abbandonavo perché non mi piaceva :-)


OK, postandolo ci sono stati i commenti con suggerimenti e precisazioni. E adesso è tutto molto più chiaro. Vorrei allora chiudere l’argomento con questa breve nota, approfittando della vostra pazienza ;-)

Il suggerimento di Marco Delmastro (il suo blog, Borborigmi  è über-yotta-mitico) di usare source funziona, da approfondire.

Il prof Lipari, glipari ha indicato il metodo usato da Autojump, un post di StackOverflow. Era stato glipari che mi aveva fatto conoscere Autojump e sospendere i miei tentativi di ricreare j con Linux.

Il commento di bit3lux / Luigi dà una soluzione che funziona ma “non è elegante“, come illustrato nel commento di glipari. Si vede che Luigi è troppo giovane: quando non c’era l’ambiente grafico ormai pervasivo il terminale era tutto per la shell. E potevi (OK, anche adesso) avviare una sub-shell digitando sh (non bash o csh, non usare mai quei nomi). Non so se il termine è corretto ma da noi si diceva che attivavi una sessione ospite. Con ctrl-D o exit uscivi da questa sub-shell e tornavi a quella precedente. Nulla vietava di annidare sub-shell per più livelli anche se 1) non so bene a cosa potesse servire; e 2) consumava memoria. Con tanti ctrl-D quanti erano i processi attivati tornavi alla shell originale; se ne battevi uno in più ti slogavi (c’era una variabile da settare per evitare che ciò avvenisse, la usavano solo i niubbi che allora si chiamavano pivelli).

Autojump di Joël Schaerer è perfetto, auto impara quali sono le directory che vengono usate e dimentica quelle vecchie; usa un algoritmo per indovinare quello che vuoi impiegando una regular expression (RegEx, RE) da paura. E poi Python è un linguaggio di script trendy e simpa (i francesi come Joël dicono così). Certo, seguendo l’indicazione di Marco si potrebbe fare a meno di Python, magari coinvolgendo Perl per la RE ;-)

Non credo che mi avventurerò per questa strada ma per source ho provato a googlare un pochino. Ecco cosa ho scovato.

source
Avendo a disposizione il SysV Command Reference di Apollo, novembre 1989 ho voluto indagare se source c’era già in Unix-SysV. Pare di no. Il manuale ha la Section 1 –quella che m’interessa– e la Section 6 –games. I comandi sono in ordine alfabetico. A p.1-511 (si apre automaticamente lì) inizia SH(1), la Bourne shell, occupa le pagine fino a 1-523 compresa. Rimanda a pagine di SysV Programmer’s Reference che non ho. Non cita source.

CSH(1), la c-shell inizia a p. 1-91 e arriva fino a p. 1-115 compresa.
E c’è source, a p. 1-108, copio:

source name
Read commands from name. You may nest source commands, but if you nest too many deeply, the shell may run out of file descriptors. An error in a source at any level terminates all nested source commands.

source -h name
Place commands in the history list without executing them. Normally, input during source commands is not placed on the history list.

KSH(1), la Korn shell è descritta nelle pagine da 1-295 a 1-323. Ebbene sì Apollo permetteva di usare la shell che volevi, bash non c’era ancora. Nessun riferimento a source.

Idea per il futuro: se a qualcuno interessa potrei mettere le scansioni di queste pagine e magari incorrere nelle ire di HP.

A p. 1-528 c’è SORT(1) e a p. 1-529 SPELL(1) che continua anche sulla successiva, niente source quindi.

OK! source è nato in BSD e SysV non ce l’aveva. Mistero il motivo per cui tutti (a quanto pare) usassero la Bourne shell quando c’era la Korn, più nuova, almeno a giudicare da com’è ridotto il manuale.

E per Linux? Tanti, credo, sanno che si può usare source quando si modifica ~/.bashrc ma solo quello. Tranne Marco :-D e pochi altri.
La googlata per source è stata fruttuosa, ecco

http://www.cyberciti.biz/faq/linux-bsd-unix-source-command/
nixCraft è un sito da bookmarkare, imho. Toh! lo dice anche qui che è BSD.

http://bash.cyberciti.biz/guide/Source_command
stesso sito, altra pagina, Linux (credo).

http://webtools.live2support.com/linux/period.php
Web Tools, lo sapete che source può essere scritta come . (punto, dot)? Da bookmarkare anche questo, sempre imho.

http://ss64.com/bash/
An A-Z Index of the Bash command line for Linux. Già che ci siete  bookmarkate anche questo.

Ah questa non la sapevo:


Visto: source – Esegue comandi da un file nella shell corrente.
Nella shell corrente.

Quante cose ci sono da imparare! E quante cose so di non sapere (cit.).
Riuscirò mai a diventare quasi-geek o rimarrò per sempre un aspirante-geek? ;-)

Visto nel Web – 14

Presto che è tardi e ho un sacco di cose da fare, il post precedente ha generato tante cose, poi mi ci metto a esaminarle ma per intanto ecco cosa ho visto nel Web

Giulio Cavalli, click

In BASH, when to alias, when to script, and when to write a function?
discorso lungo e complesso; prima o poi vorrei farci un post tutto mio, immaginando fin d’ora il casino putiferio che scatenerei ;-)
::: StackExchange

Back on Linux
Mac o Linux? un confronto
::: dywypi

Europe’s ‘Right To Be Forgotten’ Threatens Online Free Speech
::: Slashdot

Code in next Debian release valued at $A17 billion
::: ITWire

Ubuntu 11.10 Review: Benchmarked Against Windows 7
Three months have passed since the latest version of Ubuntu launched. With its classic desktop gone, Oneiric Ocelot is all Unity. The training wheels are off; no turning back now. Is Ubuntu ready for touchscreens? And how does it compare to Windows 7?
::: tom’s

L’erba del vicino: la neutralità violata in Korea.
Stefano, in italiano si dice Corea, poi, certo è preoccupante
::: Quinta’s

Move to mobile will bring big changes for Linux
::: ITworld

L’ACTA è carta straccia:neanche la Germania sottoscrive
::: MacLinuxLovers

Best E-book Readers For Android
::: TechSource

Ubuntu 12.04: primi benchmark stupefacenti
forse non lo abbandono neanche questa volta
::: oneOpenSource

G’MIC : utilisez de nombreux filtres prédéfinis sous The Gimp
::: Tux-planet

wxPython: All about Menus
bello, semplice, completo. Bravo Mike!
::: Mouse vs Python

Biculturalism
Unix vs Windows: fondamentale! dovrebbe essere una recensione di The Art of UNIX Programming di Eric S. Raymond ma è ottimo anche come post. Per dire io ho capito perché non mi piace Windoze e detesto i ‘puter con la iMela Morsicata.
::: Joel on Software

Zuck hai vinto: Facebook sarà il mio profilo pubblico
Se lo dice Silvio, non quello, il Gulizia. Io comunque resisto, FB lo uso pochissimo
::: Comunità Digitali

Thoughts on the new Windows logo
lo dice John D. nèh ;-)
e tanti altri :-D
::: The Endeavour

Da zero a Pinterest in dieci mosse
Pinterest è un social network ispirazionale, che ti consente di archiviare e catalogare tutti i tuoi interessi. Scopri come usarlo (e come avere un invito).
::: Comunità Digitali

Avoiding Red Lights By Booking Ahead
chissà se funzionerebbe con i nostri numerosi (troppi) furbetti?
::: Slashdot

Julia, a language for technical computing
un altro? sì, something that is dirt simple to learn, yet keeps the most serious hackers happy, we want it interactive and we want it compiled
::: Lambda the Ultimate

aracarota

Open source, università italiane, e PMI
::: Tech Economy

Tetris In 140 Bytes
::: Slashdot

Google Chrome: the New Web Platform?
::: Slashdot

Linux si, Linux no.
si può riprodurre per il PC quanto è avvenuto per Android?
::: vencizOn

Transistor con un solo atomo, nuova frontiera dei computer
::: tom’s

What does Ubuntu want to be when it grows up?
You can use Ubuntu in the cloud, on servers, on the desktop, on tablets and smartphones, but can the popular Linux distribution play in all these spaces?
::: ZDNet

click per ingrandire

OK, andata, per adesso. Prossimamente ancora su j (Autocomp e dintorni) e source e altro, forse ;-)

Autojump


Posso raccontarvi un po’ di storia personale? Sì?
OK, allora quando ho iniziato a lavorare mi sono trovato un minicopmuter (mini è fuorviante, pensate a un armadio grosso) tutto mio. Cioè no ma da gestire.
Era, l’ho già detto altre volte, un Prime, anzi PR1ME.
E era arrivato un Prime perché degli amici e colleghi avevano il Prime (il loro capo era appena tornato da MIT, vicino a Natick, dove c’era la fabbrica dei Prime –bei tempi, sigh!
Uno dei miei amici (anche se non ricordo chi) aveva deciso di semplificare il comando cd (sì, sul Prime non si chiamava cd ma attach, abbrevviabile in a; come per il VMS del Vax i comandi potevano essere abbreviati, basta che non ci fossero conflitti, ancora meglio del tab di Unix/Linux).
Per cui A LAVORI 1 2 poteva essere scritto J L. Bella comodità, l’avevo adottata al volo. E poi questo comando l’ho rifatto per MS-DOS, prima come batch command e poi con Turbo Pascal, antenato di Delphi.

Poi ho provato a farlo anche su Linux, e non ci sono riuscito. Adesso vi faccio vedere il perché.

Con Windows si può creare questo semplice script (loro non li chiamano script ma è uno script), j-t-w.bat

@echo off
c:
cd C:\DOCUME~1\Alice\IMPOST~1\Temp
echo sei in
cd
echo fatto.

eseguendolo nel Prompt dei comandi otteniamo

Come si vede al termine dello script la directory corrente è diventata Temp sul disco C:.
Proviamo a fare la stessa cosa con Linux, ecco lo script t.sh

#!/bin/sh
cd /tmp
echo sei in $(pwd)
echo fatto.

provo a eseguirlo

OPS! non funziona. Durante l’esecuzione dello script è effettivamente in /tmp ma quando lo script termina mi ritrovo nella directory di partenza. OK, la cosa è logica e naturale, Linux (e Unix prima) sono fatti meglio ma non fa quello che volevo. E non è facile farglielo fare.

La cosa all’inizio mi dava parecchio fastidio e ogni tanto riesumavo il progetto, senza concludere nulla. Cioè c’ero riuscito in un paio di modi ma non eleganti. Poi qualcuno (credo sia stato il prof Lipari ma non riesco a rintracciare il link) mi ha segnalato Autojump di joelthelionJoël Schaerer.

Dai, non era facile: bravo Noël, le lion! C’è riuscito con due script, uno tranquillo in Python e uno terribile in bash (e zsh, per chi usa questa shell). Noël è davvero un leone.

Autojump –in realtà si usa il comando j, proprio come facevamo su Prime, anche se allora j derivava da join– lo trovate nel Software Center di Ubuntu ma conviene installare l’ultima versione da github.

Per chi usa spesso il terminale è comodo, anche se ogni tanto mi fa ricadere nella tentazione di capire come funziona.

Era da un po’ che non mi capitava poi qualcuno ne ha parlato recentemente e mi sono deciso a prendere il toro per le corna: vediamo se questo post mi libera da questa ossessione.

Ah! visto che i miei amici Bit3Lux e Lightuono stanno portando avanti un corso di bash, questo post è dedicato a loro ;-)

Numeri primi in Haskell

Rieccoci con la serie di post sulla programmazione funzionale, finalmente (o purtroppo, dipende dal vostro gradimento). Oggi cercheremo di realizzare un semplice test per i numeri primi in Haskell. Lo scopo è di essere didattici, non di essere efficienti, quindi i matematici e i super esperti portino pazienza, per favore!

Vediamo prima di fare un po di sommario.

Puntate precedenti:

Ripasso di Haskell

Sì, perché l’ultima volta è stata un sacco di tempo fa, e allora facciamo un po’ di ripassino.

I linguaggi funzionali prediligono le funzioni. Tutto è funzione, l’utente definisce funzioni, che possono prendere in ingresso altre funzioni, e ne può fare delle applicazioni parziali per ottenere delle funzioni più semplici. In particolare in Haskell per definire una funzione basta scrivere un’equazione. Ad esempio, ecco la funzione che data una lista ci restituisce un’altra lista contenente solo i numeri pari:

pari :: [Integer] -> [Integer]
pari l = [ x | x <- l, even x ]

Vi ricordo che la prima linea è la type signature, cioè la dichiarazione del tipo di dato che passiamo come argomento in input e del tipo di dato che diamo come output; la seconda linea è invece la definizione vera e propria della funzione. In questo caso abbiamo usato la list comprehension, ricordate? Leggiamolo come se fosse notazione matematica: “tutti gli x tali che x appartiene a l, e x è pari”.

Numeri primi

Per continuare il ripasso, proviamo timidamente a scrivere una funzione che ci dica se un dato intero è primo o no. Per cominciare, ci serve sapere se un numero divide un altro. Si dice che un numero divide esattamente un altro, se il resto della divisione è zero. Quindi, dato n il numero da dividere e x il divisore, deve essere vero che:

n `mod` x == 0

Dove mod è la funzione che calcola il resto. A onor del vero bisognerebbe scrivere

(mod n x) == 0

perché Haskell usa la notazione prefissa. Però chi ha inventato Haskell sa bene che a volte la notazione infissa (quella degli operatori) è più comoda. Per cui ha dato la possibilità di usare entrambe. Se avete una funzione di due argomenti, potete usare la notazione infissa se mettete la funzione tra “backtick”. Quindi, scrivere mod n x è equivalente a scrivere n `mod` x. Chiaro? (se la risposta è no, non vi preoccupate, ci saranno altri esempi nel seguito).

Per fare le cose un po’ più leggibili, definiamoci una funzione chiamata divides:

divides :: Integer -> Integer -> Bool
x `divides` n = n `mod` x == 0

Ok, adesso vogliamo sapere se un numero è primo. La definizione dice che un numero n è primo se è divisibile solo per se stesso e per l’unità. Quindi, dobbiamo provare a dividere n per tutti i numeri da 2 a n-1, e vedere se viene fuori che qualcuno è divisibile.

La lista di numeri da 2 a n-1 si scrive semplicemente [2..n-1]. La funzione divides ci restituisce dei valori booleani, ovvero True oppure False. Se io applico la funzione divides a tutti i membri della lista [2..n-1] ottengo una lista di True e False. Se tutti i valori della lista risultante sono False, allora il numero è primo, mentre se almeno uno è True, allora il numero è composto. Ci siamo fino a qui? Bene, guardiamo il codice che esprime questo mio ragionamento:

isprime :: Integer -> Bool
isprime n = not $ or [ x `divides` n | x <- [2..n-1] ] 

Spiegazione, cominciando dal fondo: qui vedete una bella list comprehension per costruire la lista di booleani (tutti i risultati della funzione x `divides` n tali che x appartiene alla lista [2..n-1]). La funzione or, come ci si aspetterebbe, prende una lista di booleani e ne fa l’or logico. La funzione not restituisce la negazione logica del suo input e ci da il risultato. Direi che ci siamo… no aspetta, e quel dollaro? Il dollaro serve per evitare di mettere troppe parentesi. Infatti, Haskell legge da sinistra verso destra, e se non mettete le parentesi potrebbe incasinarsi: il dollaro serve a dirgli “aspetta che arrivi il risultato di quello che sta a destra del dollaro prima di valutare la funzione che sta a sinistra del dollaro”. Tecnicamente: cambia l’ordine di precedenza delle funzioni, o meglio associa a destra invece che a sinistra.

Ed ecco il programmino risultante:

module Main where
import System.Environment

main :: IO()
main = do args <- getArgs
          putStrLn ( show $ isprime (read $ args!!0) )

divides :: Integer -> Integer -> Bool
x `divides` n = n `mod` x == 0

isprime :: Integer -> Bool
isprime n = not $ or [ x `divides` n | x <- [2..n-1] ] 

Per provare il codice: salvate il testo qui sopra in un file chiamato ‘primo.hs’ (oppure come meglio credete). Quindi, compilate il file da linea di comando con :

ghc primo.hs

e otterrete il file eseguibile primo, che potete eseguire così:

./primo 1237

e dovrebbe restituirvi True.

(Esercizio: che cosa succede se togliete il dollaro senza mettere alcuna parentesi? provare per capire…)

Let e where

Un matematico storcerà il naso a vedere il mio algoritmo. Inefficiente! Infatti, per provare che un numero è primo, è sufficiente testare i numeri da 2 fino alla radice quadrata di n. E allora facciamolo, che aspettiamo?

Per fare la radice quadrata di n si usa la funzione sqtr che però prende un double e restituisce un double (insomma, quasi). Mentre il nostro n è intero: e quindi se scrivo sqrt n il compilatore protesta: come vi ho già detto, Haskell è fortemente, maledettamente tipato, e se non gli dai i tipi giusti non ti compila. E quindi, bisogna trasformare n in un double, e poi il risultato di sqrt di nuovo in intero. Ecco come si fa:

floor $sqrt $fromIntegral n

Al solito, i dollari evitano le parentesi.

Potremmo mettere l’espressione con la radice quadrata direttamente in linea al posto di n-1, ma sarebbe orribile a leggersi. Potremmo definire una nuova funzione:

sqn n = floor $sqrt $fromIntegral n
isprime n = not $ or [ x `divides` n | x <- [2..sqn n] ] 

ma definire una nuova funzione sembra eccessivo, specialmente se questa funzione viene usata solo dalla funzione isprime. E allora usiamo il let:

isprime :: Integer -> Bool
isprime n = let sqn = floor $sqrt $fromIntegral n  
            in not $ or [ x `divides` n | x <- [2..sqn] ] 

Let serve a definire delle funzioni “locali” alla funzione isprime. Si usa come nella notazione matematica, e quindi si legge così: “sia (let) sqn la radice quadrata di n, nell’espressione not …”. Quindi, dopo il let si mettono le definizioni locali (anche più di una, su righe diverse), quindi la parola chiave in, e infine si mette l’espressione che usa le definizioni precedenti. Altro esempio:
mytan x = let s = sin x
              c = cos x
          in s / c

definisce la tangente di un angolo. Invece di let si può usare un costrutto alternativo che si chiama where:
mytan x = s / c
          where s = sin x
                c = cos x

che si legge: “la funzione mytan x è definita come s / c, dove (where) s è definito come il seno di x, e c è definito come il coseno di x”. Si legge bene, vero?

C’è una differenza importante fra usare let e where. Let può essere messo dovunque ci sia un’espressione, e quindi anche dentro un’espressione più grande. Per esempio, riscriviamo la nostra sqn

sqn n = floor (let i = fromIntegral n in sqrt i)

Come potete vedere, abbiamo inserito una let/in in un’espressione più grande. La where invece può solo essere legata a una funzione, e quindi la seguente cosa dà un errore di sintassi:
sqn n = floor (sqrt i where i = fromIntegral n)

Se proprio volete usare il where, dovete scrivere:
sqn n = floor s 
        where s = sqrt (fromIntegral n)

Lo so, non è chiarissimo, ma nel seguito spero di inserire qualche altro esempio.

Il secondo programmino:

module Main where
import System.Environment

main :: IO()
main = do args <- getArgs
          putStrLn ( show $ isprime (read $ args!!0) )

x `divides` n = n `mod` x == 0

isprime :: Integer -> Bool
isprime n = let sqn = floor $sqrt $fromIntegral n
            in not $ or [ x `divides` n | x <- [2..sqn] ] 

Al solito, fermatevi e prendetevi 30 secondi di tempo per compilare, eseguire, etc. E magari, provate a usare il where invece del let.

Ricorsione!

Adesso siamo un po’ più efficienti, ma ancora lontani da una buona soluzione. Per esempio, possiamo controllare la divisibilità solo per i primi contenuti tra 2 e la radice quadrata di n. Infatti, non ha senso controllare la divibilità per 4 una volta che il numero non è più divisibile per 2. Ed è inutile controllare la divisibilità per 9 se il numero non è divisibile per 3, ecc.

Ma la lista di primi fino alla radice quadrata di n non ce l’abbiamo! Idea: non potremmo utilizzare la stessa definizione di isprime per calcolarci questa lista?

Allora, adesso proviamo a ragionare top/down. Abbiamo già una funzione isprime decente (anche se non ottimizzata), proviamo ad utilizzarla per calcolare la lista (infinita) di tutti i primi. Come vi ho spiegato qualche tempo fa Haskell permette di definire liste infinite, ovvero liste che potenzialmente contengono un numero infinito di elementi. Haskell è lazy, e quindi non è che effettua un calcolo infinito: semplicemente, calcola gli elementi man mano che servono. Ecco la lista infinita di primi a partire dal 2:

primes :: [Integer]
primes = (filter isprime [2..])

Abbiamo usato la funzione filter che prende come argomenti una funzione (in questo caso isprime), e una lista (in questo caso la lista infinita degli interi maggiori o uguali a 2), e applica la funzione a tutti gli elementi della lista. Il risultato è una lista che contiene tutti e solo gli elementi per i quali isprime ha restituito True, ovvero la lista dei primi.

Ci siamo quasi. Adesso, per testare la primalità, ci basta controllare tutti la divisibilità per tutti i numeri primi fino alla readice quadrata di n. Ecco il codice:

isprime n = let sqn = floor $sqrt $fromIntegral n
            in not $ or [ x `divides` n | x <- takeWhile (<=sqn) primes ]

Spiegazione: la funzione takeWhile prende due paramteri, una funzione e una lista. La prima funzione è una sezione dell’operatore <= e ci restituisce True quando un numero è minore o uguale di sqn. Il secondo argomento è una lista, nel nostro caso la lista infinita primes. La funzione takeWhile applica la funzione a tutti gli elementi della lista finché la funzione restituisce True, poi si ferma. Il risultato è quindi tutta la prima parte della lista fino a che troviamo un numero pari a sqn.

Vi si sta attorcigliando il cervello? No problem, accade sempre con casi di ricorsione doppia incrociata con scappellamento a destra! Qui abbiamo che la funzione isprime ha bisogno della lista primes per essere calcolata, e quest’ultima si calcola a partire dalla funzione isprime. Proviamo a vedere se funziona:

module Main where
import System.Environment

main :: IO()
main = do args <- getArgs
          putStrLn ( show $ isprime (read $ args!!0) )

x `divides` n = n `mod` x == 0

isprime :: Integer -> Bool
isprime n = let sqn = floor $sqrt $fromIntegral n
            in not $ or [ x `divides` n | x <- takeWhile (<sqn) primes ] 

primes :: [Integer]
primes = (filter isprime [2..])

Salvate in un file chiamiato primi2.hs, compilate e eseguite. Ed ecco quello salta fuori:

lipari@lipari$ ./primi 11
primi: <<Loop>>

Ahi ahi. Che è successo? E’ successo che Haskell si è incasinato e non riesce a venire fuori da questa ricorsione doppia con lista infinita. In particolare, quando ha cercato di calcolare il primo elemento della lista primes, è andato in loop. Non avremmo esagerato? Beh, sì un po. Vediamo perché e magari salterà fuori che abbiamo capito qualcosa in più di come funziona il tutto.

  1. Per prima cosa, Haskell cerca di calcolare la fuzione isprime sul numero che gli abbiamo passato sulla linea di comando, che è 11. Per fare questo cerca di risolvere la list comprehension, e in particolare cerca di estrarre il primo elemento della lista primes per darlo in pasto alla takeWhile.
  2. Bisogna quindi calcolare il primo elemento (solo il primo!) della lista primes, che corrisponde al primo elemento della lista risultante dalla funzione filter
  3. Per fare questo, deve prima calcolare isprime 2.
  4. Torniamo su: per calcolare isprime 2 ha bisogno del primo elemento della primes…
  5. Haskell a questo punto si accorge di essere finito in un ciclo infinito, e alza le braccia, stampando l’errore sul terminale e uscendo dal programma.

L’errore qui è che lui non riesce a partire, non ha un punto di inizio. In matematica, si direbbe che abbiamo un’induzione senza una base; in informatica, abbiamo una ricorsione senza una condizione di terminazione. Notate che Haskell non vi pianta il calcolatore fino al fatidico out of memory. Si accorge del loop infinito, e esce subito.

La soluzione è più semplice di quanto possiate immaginare. Se Haskell non riesce a calcolarsi il primo elemento della lista primes, possiamo suggerirlo noi! La definizione di primes diventa:

primes = 2:(filter isprime [3..])

Il primo della lista lo mettiamo noi, gli altri glieli lasciamo calcolare. Adesso abbiamo la base induttiva.

Proviamo a rifare il ragionamento di prima. Dopo il punto 2, il punto 3 ci dice che il primo elemento di primes è 2, che è minore di sqn. Quindi, x prende il valore 2. 11 non è divisibile per 2, quindi il primo elemento della lista da dare in pasto alla funzione or è un bel False. A questo punto dobbiamo calcolare il secondo elemento di primes. Per far questo dobbiamo calcolare isprime 3. La radice di 3 è sqn=1.73…, quindi l’espressione takeWhile (<sqn) primes è una lista vuota. L’or di una lista vuota da come risultato False, e quindi isprime 3 è True. Quindi il secondo elemento di primes è 3, e possiamo tornare a calcolare isprimes di 11. 3 non divide 11, quindi adesso la lista di booleani contiene due False, e ci tocca andare a calcolare il terzo elemento di primes… che penso ci possiamo fermare qui.

A questo punto, dopo tutto questo sforzo mentale, provate a compilare e lanciare il programma!

Ultima piccola modifica. Nel calcolare la lista dei primi, noi sappiamo già che i pari non sono primi, e quindi potremmo applicare una piccola ottimizzazione:

primes = 2:(filter isprime [3,5..])

La lista [3,5,..] è un modo elegante e molto haskelliano di rappresentare i numeri dispari da 3 in su.

Conclusioni

Naturalmente, se proprio vogliamo calcolare la lista dei numeri primi, ci sono metodi parecchio più efficienti, come il crivello di Eratostene, ma questo magari lo vediamo la prossima volta che oggi penso di avervi incriccato la cervice abbastanza. E chissà, magari, forse, prima o poi diamo uno sguardo anche al crivello di Atkin (ah, gli studenti di oggi!)

Note

L’immagine è presa da questo blog.

Vicissitudini con newLISP 10.4

Tutto è bene quel che finisce bene anche se ci sono stati momenti di panico! O almeno di scazzsconforto e perplimosità.
Ma forse è meglio se vi racconto tutto dall’inizio, vero?


Tutto è cominciato ieri sera, con un tweet, questo


che, come si vede, ho anche ritwittato –non avrei mai pensato che si scrivesse così :-)

Poi avevo altro da finire, la stanchezza, la procastinazione e altro, insomma a farla breve ho rimandato tutto a oggi pomeriggio.

Dovrebbe essere una cosa banale, scarichi il file .deb, lo doppioclicki e fatto. Ehm no!
Il Software Center comincia a frullare, continua a frullare, mi faccio un caffè intanto che frulla, continua ancora a frullare e frullare.
Poi smette ma niente.

Panico? No dai niente panico, com’è scritto sulla copertina della Guida Galattica. Sono o non sono un aspirante geek in attesa di essere autopromosso a apprendista geek-quasigeek?


Si può fare a mano! Sì dai ci provo, questa è la situazione attuale


Dopo un back-up e alcune contrattazioni con la shell (per via dei permessi, sono tutto sudato) ecco


Da un paio di verifiche volanti sembra tutto OK :-D
E la nuova versione sembra alquanto uguale alla precedente.
Ma sono salito di un gradino nella scala della geekosità, e questo è bene (cit.) :-D

Visto nel Web – 13

Neve & freddo in abbondanza; niente di meglio per riscaldarsi che una rassegna di cose interessanti viste nel web, ecco…

Google In Battle With Its Own Lawyers
questa sarebbe comica se il prezzo non lo pagassimo tutti noi; come Totò e Peppino
::: Slashdot

Hail the penguin
::: stuff.co

Filenames.WTF
file extensions are ridiculous
::: Dan’s Data ::: Chris Siebenmann

Four Levels of Idea Theft
::: Programming in the 21st Century

What is RTOS? – Real Time Operating Systems Basics
quasi; OK, non è facile riassumere in un post tutto quanto, diciamo che è un’intro introduttiva ;-)
::: The Geek Stuff

Five Reasons why Windows 8 will be dead on arrival
Some of my die-hard Windows friends are very excited by Windows 8 arrival later this year. Others fear that Windows 8 will be a repeat of Microsoft’s Vista disaster. Me? I know Windows 8 will be a Vista-sized fiasco.
::: ZDNet

Is Linux Spark Tablet An iPad Killer?
::: Datamation

Canonical Pulls Kubuntu Personnel Funding
::: Slashdot ::: Muktware ::: oneOpenSource ::: MacLinuxLovers

Le difficoltà di Compiz e il futuro di Unity
::: oneOpenSource

The Designer’s Guide to Avoiding Terminal
questo blog dovete proprio RSSarlo; io non lo citerò più, avvisati, nèh
::: Brad Colbow

Apple’s great GPL purge
::: mathew

LibreOffice Math/Formula Editor Examples
::: Thoughts on Technology

Category:Programming languages
da un cinguettio di [perso il nome], da perdersi :-D
::: LiteratePrograms

Former Google Exec: Traditional Search Market Shrinking
ah! Volunia, forse
::: Slashdot

The Zuckerberg Tax
Robin Hood dove sei?
::: Slashdot

The RedMonk Programming Language Rankings: February 2012
::: RedMonk ::: The Endeavour

RIAA contro Google e Wikipedia
::: Quinta’s

GNOME 3, un nuovo approccio nel definire le applicazioni sul desktop
non concordo, e anche il primo commento è con me
::: Ossblog

Pycoder’s Weekly
One e-mail each Friday(starting Feb. 17th), easy to unsubscribe, only god knows why you would want to do that. Segnalato da al3hex
::: Pycoder’s

Status Code
is a language agnostic roundup of the latest ideas, releases, trends, events and must-read articles from the field of software development. Segnalato da al3hex
::: Status Code

Dodici comandamenti per l’accesso aperto
forse un po’ OT, ma è il Web
::: Minima academica

High performance libraries in Java
::: Vanilla #Java

I have a dream!
il compleanno del Picchio diventa l’occasione per un meeting interessantissimissimo
::: il nido del Picchio

Ma i computer li fanno ancora?
xfce, perché i nuovi DE per chi ha un po’ di finestre aperte sono disastrosiscomodi
::: Luca Ferrari

NASA Unplugs Its Last Mainframe
come i dinosauri: a un certo punto si è andati avanti senza di loro
::: Slashdot

OK, a lavorare adesso, anche se con i diti tutti intirizziti ;-)

Il sesso del(la) dock

Perché su OS X si chiama “il dock” e ovunque si chiama “la dock”? Dilemma.
Ma non è l’unico caso, anzi! Il guaio è che l’italiano, come parecchie lingue neolatine (almeno quelle che conosco) ha abbandonato il neutro. Male! Notare che di questo sussistano reliquie, dove meno te lo aspetti: lui, lei, esso. Esso? sì, meno male che non si usa più. In diversi dialetti italiani ne trovi tracce (a parte il fatto che non so citarne neanche un esempio al volo; e non so nemmeno quale sia il plurale giusto di “traccia” e “faccia” e “ciliegia” e “curriculum”).

OK, tornando a noi nelle lingue germaniche (no, solo un pizzico d’inglese) invece abbonda e qui saltano fuori le occasioni di perplimosità. Tante. Su alcune parole si è arrivati a una conclusione più o meno condivisa, altre restano aperte all’inventiva e al sentimento del momento. Una mia amica dice “la web” perche sia “rete” che “ragnatela” sono femminili ma io ho sempre sentito dire l’opposto –non per i francesi.
Anticamente si diceva “il batch” ma un grafico che frequento dice “la batch” forse perché si riferisce alla batch list di Photoshop.
E quasar? qualcuno dice “la quasar” per lo stesso motivo di web. OK, chi usa questa parola di solito parla inglese, ma Piero Angela… E Giacobbo e Zichichi? Non sempre ma (soprattutto una volta) la nave –ship– veniva usata al femminile in inglese, come “site” e –orrore– “computer” (come in spagnolo del resto).

OK, tutto ciò premesso, di nascosto dalla Crusca e dal prof di tagliano –sapete com’è– che ne dite di un sondaggio/referendum per attribuire un sesso a queste parole, frequentissime che non hanno ancora acquisito una forma in italiano –e chissà se ce l’avranno mai. Perdere del tempo nel stilare una lista di nomi più o meno neutri è tempo perso, tutti noi, uomini donne e geek (maschile o femminile? Vedi!), ne conosciamo a sufficienza per comprendere in linea generale il senso di questo post.

Ma il dilemma si espande, assume un’altra forma quando andiamo a ricordare il tono in cui gli utenti OS X chiamano il loro aggeggio posto in basso “il mio dock” (con una voce alla Gianni Morandi)  e quelli GNU/Linux chiamano la propria dock “leva quella merda di una dockbar” (quasi sempre riferito a cairo dock). Siamo troppo avanti per utilizzare un neutro, o anche questo viene utilizzato in secondo piano nella guerra di “chi lo ha più lungo”?

OK, potete andare da Gusions (fate click sul banner qui sopra) e votare. Tra tutti i partecipanti verranno estratti a sorte 3 fortunati che riceveranno assolutamente niente.

Ma vorrei allargare la discussione: diamo un genere a tutte queste parole, proponetene altre, le vostre preferite o detestate.

Bonus #1: tempo fa HP Italia usava “direttorio” per “directory”. Ahemm, la Rivoluzione Francese è acqua passata e da noi “directory” si dice “elenco” o “lista” come in Unix/Linux e O.S. seri.

Bonus #2: mi risulta, da informazioni riservate, che se ne occupa dell’argomento anche il Tamburo Riparato, qui

nag – task manager minimale in Python

Jack Mottram‘s nag is probably the simplest command-line task manager out there. But while this tiny Python script won’t replace a full-blown task manager, nag can come in handy for maintaining a short list of tasks with a minimum of fuss.

Si trova tutto sul suo sito GitHub.


Basta scaricare nag.py, rinominarlo nag, metterlo in ~/bin e renderlo eseguibile con chmod +x nag e avrete un todo list manager minimale ma funzionale.

Restano alcuni dubbi:
1) cosa vuol dire nag?
tra le varie possibilità suggerite da Google Traduttore scelgo brontolare;
2) perché nag?
qui risponde direttamente mottram: “I know the world doesn’t need yet another CLI todo list thingy, but I just finished Learning ‘Python the Hard Way’ and wanted to try to make something“.

Ecco, io lo uso, da oggi in poi.
Sono in tutto 90 righe, praticamente perfette, non credo serva commentarle, dai sono chiarissime. Proprio a voler essere pistini a livello cosmico si potrebbe inserire dopo la prima riga questa:
# -*- coding: utf-8 -*-
così accetta anche i caratteri accentati.

Un’ultima osservazione, la dritta me l’ha data Linux Magazine, qui

Tornando a Jack lo sapete che ha un blog dove trovi di tutto, tutto quello che non ti aspetteresti di trovare, per esempio questo bisonte


o il link a un’implementazione di life di Conway in HTML 5, e questo sarebbe un altro blog da surfare ;-)

SmallBASIC

Quelli che hanno avuto la fortuna di trovarsi con l’età giusta al momento dello sboccio dei personal computer hanno un grande rimpianto: non c’è più il BASIC di una volta!
Anche per quelli che non lo dicono, o a domanda negano, in realtà la pensano così.

Io, purtroppo, a quella stagione non ho partecipato: ero troppo vecchio e avevo un ‘puter (allora si chiamava calcolatore, termine che ogni tanto mi scappa ancora) ben più grosso, diciamo che pesava diversi quintali e aveva ben 1/2 MegaByte di RAM. E si usava solo il FORTRAN, anche se c’erano ben due interpreti BASIC (ma se vi racconto storie su di loro rischio di far arrabbiare qualcuno, anzi diversi che sanno dove trovarmi).


Il BASIC allora. Intanto ce n’erano diversi, molto diversi tra di loro, alcuni raffinati altri molto meno. Mi ricordo un giovane che scriveva codice a una velocità incredibile senza lasciare spazi fra le parole e mettendo le istruzioni sulla stessa riga, separate da due-punti, GOTO e GOSUB come se piovesse, poi ha lavorato anche in Microsoft. A proposito, fare un interprete BASIC dev’essere relativamente semplice, ne ha fatto uno anche Bill Gates (si dice).

Quando poi il PC IBM si è imposto il BASIC era doppio: Basica sull’IBM e GW-BASIC (quello di Bill) sui compatibili. Ma forse qualcuno si ricorda anche il Turbo Basic, poi PowerBASIC.

Poi da Microsoft sono usciti QuickBasic (e QBasic) e VisualBasic prima per DOS e poi per Windows, non male quest’ultimo, la sua interfaccia grafica ha fatto scuola.

Poi a Redmond si sono poi convertiti al C/C++ e varianti, anche se gli adepti del Basic hanno resistito a lungo e se ne trovano ancora.

Tutta questa premessa per introdurre un post faticoso: l’ho riscritto più volte e è nato per via di un incontro tra vecchi, di quelli che si fanno attorno tra Natale e Capodanno.


Allora il mio amico, chiamiamolo Alberto, che ormai non scrive più codice ma dirige e raccomanda Java mi ha parlato di SmallBASIC, per lamentarsi che non sia portato avanti come si dovrebbe.

SmallBASIC is a fast and easy to learn BASIC language interpreter ideal for everyday calculations, scripts and prototypes. SmallBASIC includes trigonometric, matrices and algebra functions, a built in IDE, a powerful string library, system, sound, and graphic commands along with structured programming syntax.

Sì ha ragione, SmallBASIC è come il BASIC di una volta, fatto bene, c’è una comunità e un forum attivo, si possono trovare cose sorprendenti, come quest’implementazione di life di JH Conway, scritto con la sintassi antica, probabilmente si tratta di un porting da chissà dove.

SmallBASIC è stato creato da Nicholas Christopoulos di cui si hanno scarse notizie: ha un suo sito, in greco.

Il progetto è adesso gestito da Chris Warren-Smith di Brisbane nel cui profilo Twitter si presenta come “Parent, Programmer, Musician, Cyclist…“.

OK, adesso dovrei fare la conclusione: SmallBASIC è carino, buono ma il mondo è andato avanti. Oggi l’equivalente del BASIC è Python (secondo me) o Java (per Alberto).

Avvertenza: Microsoft ha un basic che si chiama, indovinate come, sì, SmallBasic, non c’entra niente con SmallBASIC — vedete che tra maiuscolo e minuscolo c’è differenza anche al di fuori di Unix/Linux? :-D

Visto nel Web – 12

Dopo abbondanti nevicate –comunque non i #settantacentimetri di Roma– freddo, tanto! Si sono gelati i tubi dell’acqua e sono senza riscaldamento e senz’acqua calda. Mi si stanno congelando anche i diti, chissà se riesco a finire questo post… OK, basta lamentarsi, niente panico, ecco la solita rassegna

un po' in ritardo, i ritardati mentali

Saltare dal top al footer e viceversa in un click
Mattux rockz, lo sapete vero? altrimenti guardate qua
::: Mattux’s

Ubuntu HUD: Solving A Problem That Doesn’t Exist
controcorrente
::: Muktware

Why The Movie Industry Can’t Innovate and the Result is SOPA
::: Steve Blank

I migliori IDE per Python
::: <edit>

Il Mercato colpisce ancora
::: anonimoconiglio

Vuoi farti l’app per Android? Non sai programmare? Ecco come fare
non l’ho provato ma Silvio Gulizia è affidabile; anche se il primo commento…
::: Comunità Digitali

Retail Chains To Strike Back Against Online Vendors
::: Slashdot

Buying a Computer
::: Brad Colbow

Wikipedia Chooses Lua As Its New Template Language
::: Slashdot

Unicode for dummies — Encoding
::: Python Conquers The Universe

Mucche digitali
scampati alla vaccata fava-leghista, pare, per ora
::: manteblog

Google Begins Country-Specific Blog Censorship
sempre meno liberi
::: Slashdot

L’erba del vicino: Andiamo a dissepellire Moana Pozzi
non fate gli spacconi; citate solo Disney e Padre Pio
::: Quinta’s

How to compute jinc(x)
programmare è difficile, quasi impossibile; se mi capitasse una cosa così penserei OK, panico!
::: The Endeavour

Flying Robots Flip, Swarm and Move In Formation At UPenn
vorrei giocarci anch’io
::: Slashdot

Device Production
Manu lavora per la concorrenza ma ha ragione da vendere
::: Bonkers World

Top Educational Android Apps For Kids
spesso capita di vedere ragazzini che mandano messaggi o giocano con il telefonino, allora ecco…
::: TechSource

How can I write to the second line of a file from the command line?
Queste cose qua mi sconvolgono. Funziona ma… Forse meriterebbero un post. O è materia di Bit3lux & Lightuono?
::: StackExchange

What five years of PC technology changed for me
ordinariamente impressionante; però oggi tutti girano con portatili ultra-super-mega o aggeggi che dovrebbero servire a telefonare
::: Chris Siebenmann

OK, non sono ancora completamente congelato, quasi-quasi preparo un altro post; ma prima faccio un salto in cucina dove c’è la stufa, grande invenzione :-D

Follow

Get every new post delivered to your Inbox.