PDI^2

Uno spell Corrector in perl6, parte 2

perl6 May 15, 2007 9:08 am (Save post)

Abbiamo già visto come scrivere delle funzioni per creare le mutazioni di una stringa usando ler regex di perl6, ma abbiamo anche detto che questo non funzionerà nel pugs attuale.

Quindi vediamo un’implementazione alternativa degli stessi metodi, basata su Str.substr. L’unica cosa da tenere a mente è che questo metodo fa side effect modificando la stringa corrente, e restituendo la sottostringa eliminata.

IMO sarebbe stato meglio se il metodo restituisse una coppia di valori ($modificata,$eliminata) ma non si è voluta rompere la compatibilità con perl5.

Ad ogni modo, l’assegnazione tra stringhe effettua una copia, quindi per evitare di fare side effect useremo semplicemente una copia della stringa. Il codice dovrebbe essere autoesplicativo:

# 'abc' -> 'ac'
sub deletion($word) {
  (^$word.chars).map: {substr(my $tmp = $word,$_,1)=''; $tmp};
}
	
# 'abc' -> 'adc'
sub substitution($word) {
  gather {
    for (0..$word.chars-1) X @ALPHA {
      substr(my $tmp = $word,$_[0],1)=$_[1];
      take $tmp;
    }
  }
}
	
# 'abc' -> 'abbc'
sub insertion($word) {
  gather {
    for (0..$word.chars) X @ALPHA {
      substr(my $tmp = $word,$_[0],0)=$_[1];
      take $tmp;
     }
  }
}
	
# 'abc' -> 'acb'
sub transposition($w) {
  gather for ^$w.chars {
    my $tmp=$w;
    my $removed =(substr($tmp,$_,1)='');
    substr($tmp,$_+1,0)=$removed;
    take $tmp;
  }
}

Ricordate che il valore restituito da una funzione è l’ultimo calcolato, come in ruby e lisp vari, quindi implicitamente noi restituiamo il valore di gather

È ora possibile definire una funzione edits1 che restituisca tutte le possibili variazioni di una singola lettera per una parola, in questo modo::

sub edits1($w) {
  transposition($w),insertion($w),substitution($w),deletion($w)
}

il comma operator cioè la virgola, concatenate gli array e quindi la funzione restituisce semplicemente un grosso array con tutte le variazioni.

Paragonando questo codice a quello di norvig noterete che lui usa i Set in edits1 mentre noi usiamo semplici liste, ma va bene perché non ci sono duplicati tra le variazioni. Federico credo faccia la stessa cosa in erlang :)

Ora serve una funzione known(@array) che selezioni gli elementi della lista che sono parole valide. Ricordate che abbiamo una variabile %WORDS{word}=>number che abbiamo inizializzato con le parole del vocabolario e la loro frequenza.

La funzione known usando questo dizionario diviene molto semplice:


sub known(@words) {
@words.grep: { %NWORDS{$_}
}

E correct($word) diventa:

sub correct($word) {
  my @values =  known([$word]) or             # the word is known
                              known(edits1($word)) or # a single letter variation is known
                              [$word];                                # we don't have suggestions
	
  # single argument max() doesn't work yet
  @values.max: {%NWORDS{$^a} < => %NWORDS{$^b}}
}

L’ultima linea potrebbe essere più carina ma il codice è comunque abbastanza semplice e pulito.

Per gli ultimi pezzetti aspettate un po’ o implementateli da soli :)

spell corrector in perl6, parte 1

perl6 May 12, 2007 2:45 pm (Save post)

(english version here)

Se leggete GoTo 10 (o reddit o mezza blogosfera) avrete visto lo spell corrector in 20 righe di python di peter norvig.
Siccome sembra che il mio LoTY, almeno per ora, sia perl6, ho provato a riscriverlo.

L’idea è semplice: sio costruisce un database di parole esistenti e della loro frequenza, poi correct(”word”) verifica se “word” è nel database, o se c’è una variazione della parola, o una variazione della variazione.

Se c’è più di una variazione si restituisce quella più comune (”cinera” -> “cinema” piuttosto che “cinerea”).

Se non si trova niente, viene restituita la parola (volevi veramente dire “1337″).

La variazioni possibili sono 4,

  • inserimento: ‘cio’ -> ‘ciao’
  • sostituzione: ‘fipo’ -> ‘filo’
  • eliminazione: ’sessso’ -> ’sesso’
  • scambio: ‘maer’ -> ‘mare’

Il codice python usa list comprehension per iterare e manipola le stringhe come array per creare le variazioni. Ogni variazione viene immagazzinata all’interno di un oggetto Set, che è un oggetto iterabile che non ammette duplicati.

In perl6 non c’è una classe Set builtin (ma c’e n’è una come estensione in pugs), quindi invece di usare gli insiemi ho usato le Junction.
Una Junction è una superposizione di vari oggetti: any(1,2,3) crea un oggetto che multiplexa le operazioni su tutti gli oggetti contenuti, e che quindi ad esempio in un’operazione di confronto “if any(1,2,3) >2” farebbe eseguire il blocco if, perché uno degli elementi rispetta la condizione (alternativamente potremmo usare junction all, none o one).

Invece di trafficare con le stringhe come fa norvig in perl6 possiamo implementare le operazioni più facilmente con Str.subst(regexp,replacement), ed usare la forma gather/for per l’iterazione e l’estrazione dei risultati.

L’implementazione delle 4 operazioni sarà dunque:

# 'abc' -> 'ac'
sub deletion($w) {
    gather take $w.subst(/./,'’) for ^$w.chars
}

gather crea uno scope dove agirà take. Una chiamata a quet’ultima inserità l’argomento in un array implicito che verrà poi restituito da
gather.
il for statement modifer itera su di un oggetto iterabile, in questo caso si tratta di un range 0..numero_caratteri che viene creato tramite l’operatore ^ detto upto operator.

L’espressione regolare è semplice: at(N) è una zero-width assertion che ha successo all’ N-esimo elemento, che poi catturiamo con “.” e rimpiazziamo con una stringa vuota, cancellandolo.

Le sostituzioni sono altrettanto semplici:

# 'abc' -> 'adc'
sub substitution($w) {
    gather take $w.subst(/./,$_[1]) for ^$w.chars X @ALPHA
}

l’unica differenza rilveante è che usiamo il cross operatorX“. Il cross operator genera un prodotto cartesiano di due oggetti iterabili, quindi ‘a’..b’ X 1..2 genera ((’a',1),(’a',2),(’b',1),(’b',2)).
Il codice all’interno del for è: rimpiazza il carattere N-esimo con tutti quelli nell’alfabeto (@ALPHA=’a’..’z’).

L’inserimento fa la stessa cosa senza eliminare un carattere, ed effettua un’iterazione in più per aggiungere un carattere anche a fine stringa:

# ‘abc’ -> ‘abbc’
sub insertion($w) {
gather take $w.subst(//,$_[1]) for ^($w.chars+1) X @ALPHA
}

Infine, lo scambio usa una subst leggermente differente, dove il rimpiazzo è un blocco, che accederà agli elementi catturati:

# 'abc' -> 'acb'
sub transposition($w) {
    gather take $w.subst(/(.)(.)/,{”$1$0″})  for ^$w.chars
}

Semplicemente prende i caratteri N e N+1, e li scambia.

Un’implementazione semplice e pulita, imo. Peccato che in realtà non funzioni, perché pugs non permette l’interpolazione di variabili in una regexp, per ora.

Per l’implementazione funzionante aspettate la seconda parte o pensateci da voi :)

motivi per cui pugs è -Ofun

perl6, pugs May 4, 2007 10:14 am (Save post)

Perché tu vai su #perl6 e dici “ma subst non è implementata? Va bene se ne metto una versione scema in Prelude.pm?” e larry wall ti risponde “si va bene” (log).

Dopo di che passi ad implementarla, usando una quantità di tempo incredibilmente superiore alle aspettative, navigando in haskell, pseudo haskell, meta haskell, perl5 e perl6, sotto la guida di gaal, moritz & fglock. Ed avendo cura di infilarci una discussione su italiano, ebraico e ungherese, tanto per soddisfare il linguista che è in te.

E finisci per definire un pezzettino delle specifiche di perl6, in modo che assomigli di più a ruby (log) ;)

UPDATE:

ripensandoci, forse è simpatico se vi faccio vedere il codice di subst :)

 1     method subst($rule, $replacement) is primitive is safe {
	
 2         my ($rgx,$adv,$dup = self);
 3 
 4         if $rule.isa(Str) {
	
 5           $rgx =  "<’$rule‘>";
 6         }
 7         else {
	
 8           $rgx = Pugs::Internals::rule_pattern($rule);
 9           $adv = Pugs::Internals::rule_adverbs($rule);
10         }
	
11 
12         my $advstr = $adv.map: { ":$_[0]"~"($_[1])"}.join if $adv;
	
13         my $apply = () if $replacement ~~ Code;
14         my $op="s$advstr/$rgx/\$replacement$apply/";
	
15 
16         eval($dup ~~ ~$op);
17         $dup
18     }
	

le dichiarazioni “is primitive is safe” sono per pugs, e sono una delle cose che mi poiace in perl6. Concettualmente si possono attaccare un sacco di metadati a una funzione, in questo caso ci limitiamo a dire che è una funzione di basso livello e che può essere usata all’interno di eval(), quindi ad esempio attraverso run.pugscode.org o lambdabot.

I puristi della OO e dei linguaggi dinamici dovrebbero arrabbiarsi per quei blocchi condizionali che fanno un check sul tipo, ma purtroppo è l’unica soluzione a cui sono arrivato.

Ora: in perl6 è possibile usare una espressione regolare all’interno di un’altra in questo modo: /< $regex>/ ma questo non è implementato in pugs, motivo per cui devo ricostruire la cosa a colpi di string interpolation & eval.

Altra cosa curiosa è che in pugs non si può risalire facilmente ad una rappresentazione di una regex per cui valga eval($regex.qualcosa())==$regex. In ruby ad esempio, Regexp#to_s restituisce una rappresentazione eval’abile, perché le Regexp sono essenzialmente solo delle stringhe.

In Perl6 invece una Rule (non le chiamiamo più regex perché sono molto di più) è più simile ad un programma che a una stringa, con tanto di regole di scope, argomenti, ereditarietà etc.

IMHO questo non significa che non si possa avere una rappresentazione in forma di stringa, ma per ora dalla regia dicono di no.

Questo per quanto riguarda il secondo ramo dell’if.

Il primo ramo sfrutta invece un’altra nuova caratteristica di Perl6, ovvero una sintassi speciale per effettuare il match di una stringa letterale, per cui
“hello” matcha /he..o/, matcha /< 'hello'>/ ma non matcha /< 'he..o'>/.

Ovviamente anche questo lo impacchettiamo nell’eval.

Infine facciamo la porcata di aggiungere un “()” per forzare l’applicazione di $replacement in caso questo sia un blocco di codice invece che una string.

Confusionario, lo so, ma pensate che quando l’interpolazione di una rule in un’altra sarà possibile tutto si ridurrà a una riga :)

Per concludere, il testcase

Perle Perl6 n° 2

perl6, pugs, lettura March 19, 2007 12:17 pm (Save post)

Forse cose come questa sono un errore di percorso:

# warning: codice inutile e volutamente oscurato, benché valido
=<>!====<>====<>

ciò perché in perl6 si può usare =<> per leggere una riga, in modo analogo a <> in perl5, credo.

Ed esiste un simpatico operatore === che rappresenta l’uguaglianza con semantica eterna, che è un modo perverso per dire che confronta l’identità degli oggetti invece che la loro rappresentazione (i.e. “ciao” e “ciao” possono essere oggetti diversi ma $s e $s sono lo stesso).

Infine, è possibile concatenare gli operatori di comparazione, in modo da avere, come in python: a < b > c.

Nell’angolo di pugs culture voglio invece perlarvi del file READTHEM che si trova nel trunk svn, in pratica un file di consigli per la lettura, sia informatici, come Advanced Topics in Types and Programming Languages che non.

Esempio: Il Silmarillion, che ha delle strane connessioni con pugs, come dimostrano header in giro per i sorgenti, o strane parafrasi di Eärendil il marinaio

Perle Perl6 n° 1

perl6 March 13, 2007 9:51 am (Save post)

Tanto per dire, quando nei messaggi di commit trovi cose come questa capisci che perl6/pugs sono decisamente aldilà della tua comprensione. Notare l’uso sbarazzino della punteggiatura:

* SigMonoid: audreyt++ points out that
:($x) :+: :($x, $y?) = :($x, $y?), and not :($x)

Groovy 1.0, D 1.0, Perl 6, Java 7 e Ruby 1.8

java, perl6, pugs January 4, 2007 8:56 am (Save post)

Pare che questa sia stata una settimana intensa sul fronte dei linguaggi di programmazione, ed è una cosa buona.

In particolare è una cosa buona per me, visto che oggi ho tempo di scrivere questo post mentre domani me ne torno nella terra degli unni, il che significherà un probabile /away di un mese dal mondo tecnologico. Siccome voglio chiudere in bellezza vi lascio qualcosa di corposo da leggere.

Pugs & teoria dei numeri
Ma dicevo, settimana intensa sul fronte programmatorio. Anzitutto l’Autore è diventato committer di pugs, dimostrando che effettivamente il commit bit viene dato via con estrema facilità.
In particolare il suo ultimo contributo è stato il problema numero 32, implementare l’algoritmo di euclide per il minimo comune multiplo:

# Perl6 impone l'ottimizzazione delle tail call, per cui
# non abbiamo bisogno di scrivere la routine in forma iterativa.
# Ale' !
	
multi sub gcd(Int $a, Int $b){
    return $a if $b == 0;
    return gcd($b,$a % $b);
}
	
is gcd(36,63), 9, \"We should be able to find the gcd of 36 and 63\";
is gcd(63,36), 9, \".. and viceversa\";
is gcd(0,5)  , 5, '.. and that gcd(0,$x) is $x';
is gcd(0,0)  , 0, '.. even when $x is 0';


Notate la finezza per cui gcd è definito come un multimetodo, perché in teoria è possibile definire la funzione in qualsiasi anello commutativo, non solo per gli interi.

Ovviamente io so che esiste una cosa chiamata anello commutativo, ma non mi ricordo cosa sia veramente e questa nota è un semplice plagio da wikipedia.

Il che tra l’altro mi da l’occasione di far notare che la definizione di numero primo su en.wikipedia è sbagliata.
Uno (1) non è un numero primo, per definizione un numero primo è un numero positivo divisibile solo per se stesso e per 1 ma diverso da uno (o -1).
Questo perché, se usiamo questa definizione poi ci viene fuori il fantastico teorema fondamentale dell’aritmetica che è:

Ogni numero naturale diverso da 1 o è un numero primo o si può esprimere come prodotto di numeri primi. Tale rappresentazione è unica a meno dell’ordine in cui compaiono i fattori.

Il motivo di questo delirio era ovviamente la soluzione del problema 31.

Tornando a Perl6, forse l’Autore potrà raccontare ai suoi nipotini che se una subroutine dichiarata come Bool converte automaticamente un valore di ritorno undef in False è merito suo. Larry sembrava ponderoso sull’argomento, ma ci sono speranze.

Groovy 1.0
E a proposito di linguaggi con dichiarazioni di tipo opzionali, Groovy ha finalmente raggiunto la versione 1.0.
Per parte mia, ritengo che Groovy sia un linguaggino carino, mi piace un sacco che abbiano la variabile implicita “it” nei blocchi, ad esempio, che permette di scrivere

[1,2,3].each { print it}

Ma in fondo è solo un poco interessante dialetto di ruby per la JVM.
Il Lettore arguto potrebbe obiettare che ruby è solo un poco interessante dialetto del lisp o di smalltalk per unix, ma ho fiducia che i Lettori arguti non siano dei rompipalle.

D 1.0
Più interessante è invece il linguaggio D, che raggiunge la 1.0 , e mi han fatto notare che adesso c’è anche un pacchetto debian di gdc.

L’Autore invita a notare che gdc è un anagramma di gcd, e questo ovviamente non è un caso.

IMHO D è un’ottimo esempio di linguaggio di sistema moderno. Design By Contract, libreria ricca (regexp, socket, thread), strutture dati come array dinamici ed hash integrate, OOP fatta in modo sensato, supporto unicode etc..

Ma perché D prenda piede ha bisogno di un progettone open source che lo traini (server ftp/http/whatever, nuova implementazione di X11, linguaggio usato per nuke’em forever…) , e questo non verrà fuori a brevissimo tempo, temo.
Python e Ruby ci hanno messo una decina d’anni a sfondare.
E nel frattempo la concorrenza non se ne sta ferma, con il nuovo C++ in arrivo, il nuovo C# e i futuri Java, quindi imo il futuro di D non è particolarmente brillante.
Ma speriamo che mi sbagli.

Java 7
Guardiamoci in faccia, la comunità Java si è data una svegliata, hanno corretto, o provato a correggere, il linguaggio dove aveva delle falle troppo grosse (generic, autoboxing etc), hanno esteso la libreria dove ce n’era bisogno (java.util.concurrent etc), hanno cercato di abbracciare le richieste della comunità (JVM open source, invokedynamic).
E in java 7 ci saranno anche le closure, cosa che già sapeva , ma quello che non sapevo è il modo con cui esse si integreranno con le api precedenti.

In pratica, la closure viene utilizzata per costruire un’oggetto anonimo che viene poi infilato dentro l’interfaccia che già esisteva per i metodi. Ok, non si è capito, intendo dire che ad esempio una funzione startComputation(Runnable r) può essere richiamata con una closure come argomento, che verrà poi convertita automaticamente nel metodo run di un oggetto Runnable creato al volo.
Ovviamente, affinché il compilatore sia in grado di gestire correttamente la cosa è necessario che riesca a capire in che metodo mettere il blocco, quindi perché la cosa funzioni l’interfaccia deve fornire un solo metodo, come fa Runnable con run.

Per il resto è bello vedere come queste closure siano identiche ai blocchi in ruby, ad esempio non vengono segnalate nell’eccezioni come funzioni aggiuntive, il return da una closure esce dal blocco esterno ad essa invece che dalla closure, se si mettono come argomenti speciali si può usare una sintassi più carina etc..
Vabè, ma è inutile che ve ne parli io, andatevi a leggere l’intervista a neal gafter

Conclusione
Siamo al 4 gennaio, e già c’è un sacco di roba a cui pensare.
In più lawrence ha scelto erlang come LoTY, il che suggerisce che si potrebbe seguirlo.
E poi mi sono impegnato a rendermi utile con sette gruppi di persone differenti.
Ed avrei due o tre progettini da portare avanti.
E devo prendere una cavolo di laurea (”oh no, di nuovo!” [cit]) .

Ma se ne parla da febbraio, da febbraio.

99 problems in perl6: viaggio tra i blocchi

ruby, personale, perl6 December 30, 2006 2:13 pm (Save post)

Nel repository subversion di pugs si è materializzata una lista di 99 problemini di programmazione, list ispirata da una in Common Lisp, a sua volta ispirata da una in prolog.

Sicché ieri notte mi è venuta l’idea di provare a risolverne qualcuno, tra cui il semplice problema 28, che si compone di due parti, la prima delle quali è: ordina una lista di liste in base alla lunghezza degli elementi.
In ruby sarebbe:

>> a=[[1,2,3,4,5],[1,2],[1],[1,2,3],[4,3,2,1]]
=> [[1, 2, 3, 4, 5], [1, 2], [1], [1, 2, 3], [4, 3, 2, 1]]
>> a.sort
=> [[1], [1, 2], [1, 2, 3], [1, 2, 3, 4, 5], [4, 3, 2, 1]]

Ma c’è il problema che l’ultimo elemento non è ben posizionato, perché?
Perché Enumerable#sort si appoggia al metodo <=> degli argomenti, che è definito per gli interi, le stringhe, gli array e così via in modo ragionevole. Si tratta di un classico caso di progettazione OO ben fatta. Solo che per gli Array è definito in un modo simile:

class Array
 def <=>(other)
  each_with_index do |elem,i|
   res= elem <=> other[i]
   return res unless res.zero?
  end
 end
end

In pratica “confronta gli elementi uno a uno finché sono uguali, se sono diversi restituisci il risultato”.

Ciò significa che per ottenere un risultato sensato dobbiamo applicare una funzione di comparazione ad hoc, in questo modo

>> a.sort_by {|e| e.size}
=> [[1], [1, 2], [1, 2, 3], [4, 3, 2, 1], [1, 2, 3, 4, 5]]

In perl6 la cosa dovrebbe essere, altrettanto banalmente

pugs> my @a=[1,2,3,4,5],[1,2],[1],[1,2,3],[4,3,2,1]
(#<Array :0x11face4>,
 #<Array :0x17e53e4>,
 #<Array :0x17e53dc>,
 #<Array :0x11fc644>,
 #<Array :0x11fd1ac>)
pugs> @a.sort
((1,), (1, 2), (1, 2, 3), (1, 2, 3, 4, 5), (4, 3, 2, 1))

Ma otteniamo lo stesso errore che avevamo in ruby, sebbene la logica sottiostante sia differente.
Andiamo per gradi: cosa è sort()?
Si tratta di una multi sub (funzione generica in CLOS, multimetodo nel resto del mondo) cioè di una funzione che è definita un sacco di volte per differenti tipi, e il cui dispatch viene poi fatto a runtime.
sort può ricevere in input una funzione di due parametri (classica sort) di un parametro (shwartzian transform, come sort_by in ruby o sort(key=foo) in python) o nessun input, usando di default l’operatore cmp

cmp è l’equivalente generico di <=> che in perl è limitato ai tipi numerici.
Insomma, di fondo la sort funziona esattamente allo stesso modo.

Possiamo quindi usare lo stesso approccio usato in ruby, ordinare usando un comparatore a argomento singolo.
Sappiate che, per ragioni a me ignote, la lunghezza di una lista in perl6 si ottiene con +$lista. Un blocco in linea ottiene l’argomento attraverso $_ quindi sperimentiamo usando la funzione map:

pugs> map {+$_}, @list
(5, 2, 1, 3, 4)

Perfetto, andiamo al sort:

pugs> sort {+$_}, @list
((4, 3, 2, 1), (1, 2, 3), (1,), (1, 2), (1, 2, 3, 4, 5))

Ma che cavolo di ordinamento è?
E qui viene la parte divertente: parlando con larry wall su #perl6 scopro che la sort di un solo argomento non è che funzioni proprio benissimo in questo momento storico. Ok, non mi do per vinto, proviamo con quella di due argomenti.

Ora, come li prendo due argomenti un una sub in linea?
In Perl6 esistono due modi per definire delle funzioni/closure in linea, la sintassi che abbiamo appena usato, con i blocchi in stile perl5, e quella con la freccetta:

pugs> my $fun= -> @l { +@l }
->{Syn \"block\" {App &prefix:+ (: Var \"@l\")}}
pugs> $fun(@list)
5
pugs> $fun(@list[0])
5
pugs> $fun(@list[1])

Proviamo il sort:

pugs> my $comparator= -> $a,$b { +$a < => +$b }
->{Syn “block” {App &infix:>=> (:
                                App &prefix:+ (: Var “$a”), App &prefix:+ (: Var
 “$b”))}}
pugs> sort $comparator, @list
((1,), (1, 2), (1, 2, 3), (4, 3, 2, 1), (1, 2, 3, 4, 5))

Ops, scusate in linea:

pugs> sort(-> $a,$b { +$a <=> +$b }, @list)
((1,), (1, 2), (1, 2, 3), (4, 3, 2, 1), (1, 2, 3, 4, 5))

Perfetto funziona. Solo che è complicatissimo da scrivere ed illegibile.

E questo ci da l’occasione di introdurre una cosa che a me piace tantissimo in perl6, le variabili segnaposto, che ci permettono di riscrivere il tutto come:

pugs> sort {$^a <=> $^b}, @list
((1,), (1, 2), (1, 2, 3), (4, 3, 2, 1), (1, 2, 3, 4, 5))

Ora, il codice dovrebbe essere ovvio, l’unica cosa strana è la presenza di quelle due variabili con nomi assurdi, $^a e $^b, che sono appunto le variabili segnaposto.
In pratica nei “bare block” ovvero nei blocchi senza lista di argomenti esplicita, viene definita una lista implicita basata sulle variabili segnaposto, quelle con il “^”, ordinate lessicograficamente.

Si tratta a mio giudizio di una soluzione che permette di ottenere codice molto compatto e chiaro, e perfettamente in linea con la politica per cui implicito e meglio che esplicito. Chissà che non venga adottata in altri linguaggi, prima o poi.

Post Archivio n. 7

ruby, personale, blogosfera, pugs March 21, 2006 8:54 am (Save post)

è tardi! è tardi! ripeteva il nabaztag.

  • Salvatore Cariello si accorge che gli internauti stanno virando salla semplice ricerca di keyword (”gnocca”) ad una più articolata (”dove trovo una gran gnocca”). Sono stato un pioniere, già nel 2003 usavo google per dimostrare agli amici che 1 non è un numero primo.
  • blog italirubyci in aumento, volevo fare un link dump ma mi sono perso l’opml.. comincio a pensare che ci voglia un’aggregatore, se qualcuno lo scrive (nah, planet no).
  • in un giorno ho scoperto che due mie idee per diventare ultramiliardario nel tempo libero esistono già, sigh. Consiglio però la lettura di questo ottimo articolo che spiega come per fare soldi con internet oggi ci voglia un’idea da 5 dollari. Di quelle che gli amici ti dicono “ah cazzo, e ci hai pure pensato?”, e che non diresti mai ad un membro del sesso opposto (“sai ho inventato datey.org, un sito che serve a xyz”) perché ti vergogneresti
  • Luca Conti fa notare che fra un po’ forse ci sarà digg in italiano, prima che ci sia un digg italiano.
  • se usate ancora win32 e non vi piace il software di masterizzazione interno, e non avete voglia di stare li a crackare nero (che poi magari avete originale ma datato da qualche parte) consiglio l’uso di CD Burner XP PRO 3 (freeware)
  • C’è ancora che dice che ruby non è enterprise ready. Un disastro ferroviario in attesa di avvenire, secondo questo tizio.
    self.notes < < "verificare se mcgovern è un demente"
  • Audrey Tang e Koichi Sasada a scrivere codice insieme per far si che Pugs possa usare YARV come backend. Sono quasi spaventato.
Perl6? Python 2.5, quantomeno..

python, perl6 January 14, 2006 12:30 am (Save post)

Un nuovo articolo su perl6, per chi non avesse mai voluto indagare sul perché sia necessario un perl nuovo, e volesse saperne di più è un’ottima lettura.
(more…)

Haskell is..

haskell, perl, pugs September 10, 2005 8:11 am (Save post)

“faster than C++, more concise than Perl, more regular than Python, more flexible than Ruby, more typeful than C#, more robust than Java, and has absolutely nothing in common with PHP.”

(secondo Autrijus Tang, letta in questa intervista su perl.com)

Get free blog up and running in minutes with Blogsome
Theme designed by Janis Joseph