personale December 31, 2006 4:55 pm (Save post)
Signori, per me è una notte problematica, speriamo che poi l’anno vada migliorando.
Nel frattempo auguro al mio sparuto gruppo di lettori buona fine e buon principio, ci si sente nel 2007!
personale December 31, 2006 4:55 pm (Save post)
Signori, per me è una notte problematica, speriamo che poi l’anno vada migliorando.
Nel frattempo auguro al mio sparuto gruppo di lettori buona fine e buon principio, ci si sente nel 2007!
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.
software December 28, 2006 11:34 am (Save post)
Ok, lo so che ormai è notizia vecchia ma stando lontano da casa avevo abbandonato del tutto windows e quindi non avevo ancora provato internet explorer 7.
Tornato a casa, e ritrovando il buon vecchio XP in ottimo stato (leggasi: mio fratello non è ancora riuscito a renderlo del tutto inutilizzabile) ho colto l’occasione per sperimentare.
Anzitutto, cosa che non avevo mai letto: IE7 ha l’antialiasing ottimizzato per monitor LCD, stile ClearType, io non lo sopporto sul mio vecchio CRT, e quindi il browser non verrò più usato.
Seconda cosa: l’autodiscovery dei feed funziona con i tag come
< link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\" href=\"http://feeds.feedburner.com/Pdi2\" />
ma, afaik, solo con quel mime type, se provate text/xml, text/rss, application/atom+xml o altro non li vede, a differenza del 99% degli aggregatori.
In compenso la visualizzazione dei feed è molto molto carina.
Per il resto devo dire che il browser non è male, è veloce, leggero, i tab sono funzionali e l’interfaccia è pulita.
Certo, non esiste nessun motivo per cui io debba abbandonare firefox in favore di IE7, ma fa piacere vedere che mamma microsoft ha tirato fuori un software discreto.
web December 27, 2006 8:16 pm (Save post)
Lo so che a forza di scrivere micro post mi gioco la mia credibilità.. emh.. vabè, dicevo, lo so che vi stufate di leggere micropost invece dei miei soliti mattoni intimisti piuttosto che banalmente hi-tech, ma questi giorni va così, prometto di migliorare per l’anno nuovo.
Non è vero, il progetto per l’anno nuovo è di mettere online il mio tumblelog, di modo che tutto il testo sotto le venti righe lo sbatto di là e lo legge solo chi davvero vuole.
La cosa affascinante è che ho già scritto l’applicazione 3 volte con piattaforme differenti, ma ancora non sono in grado di trovare un design accattivante per una lista sterminata di
<div class="Quote">
<blockquote>
corpobla bla bla blaaaaaaaaaaaaaaaaaaaaaaaaa
</blockquote>
<h4>autore</h4>
</div>
<div class="Image">
<img src="url"/>
<h4>titolo</h4>
</div>
<div class="Link">
<a href="miao">titolo</a>
<h4>commento</h4>
</div>
Ad ogni modo, il tema di questo post era che ho appena scoperto il progetto OpmlIcons, che vuole proporre un’icona standard per i file opml come è stato fatto per l’icona dei feed.
AFAIK non è ancora diffusissima, ma è carina e la usano già tagjag & grazr & feedburner, che è più di quanto si possa dire di tutte le altre. Mi piace, magari la metto pure io, prima o poi.
ruby, fastidio 2:42 am (Save post)
Capisci che in quello che usi c’è troppa fantasia, e che il lato oscuro della forza è più semplice ma non più potente, quando quel delirio pazzesco che è Camping se ne viene fuori con
Camping Problem!
Tum::Controllers::Atom.GET
TypeError can't dup NilClass:
* (eval):3:in `dup'
* (eval):3:in `R'
* (eval):5:in `URL'
* /Users/rff/work/tum/tum.rb:113:in `_atom'
* /Users/rff/work/tum/tum.rb:131:in `_atom'
* /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/builder-2.0.0/lib/builder/xmlbase.rb:139:in `_nested_structures'
* /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/builder-2.0.0/lib/builder/xmlbase.rb:59:in `method_missing'
* /Users/rff/work/tum/tum.rb:128:in `_atom'
* /Users/rff/work/tum/tum.rb:127:in `_atom'
* /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/builder-2.0.0/lib/builder/xmlbase.rb:139:in `_nested_structures'
* /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/builder-2.0.0/lib/builder/xmlbase.rb:59:in `method_missing'
* /Users/rff/work/tum/tum.rb:117:in `_atom'
* (eval):10:in `method_missing'
* /Applications/Locomotive2/Bundles/standardRailsSept2006.locobundle/i386/lib/ruby/gems/1.8/gems/markaby-0.5/lib/markaby/builder.rb:123:in `capture'
* (eval):10:in `method_missing'
* /Users/rff/work/tum/tum.rb:106:in `get'
* (eval):25:in `service'
* (eval):44:in `run'
* i386/lib/ruby/gems/1.8/gems/camping-1.5.177/lib/camping/reloader.rb:117:in `run'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel/camping.rb:41:in `process'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel.rb:580:in `process_client'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel.rb:579:in `process_client'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel.rb:686:in `run'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel.rb:686:in `run'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel.rb:673:in `run'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel/configurator.rb:267:in `run'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel/configurator.rb:266:in `run'
* i386/lib/ruby/gems/1.8/gems/camping-1.5.177/bin/camping:203:in `cloaker_'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel/configurator.rb:134:in `listener'
* i386/lib/ruby/gems/1.8/gems/camping-1.5.177/bin/camping:191:in `cloaker_'
* i386/lib/ruby/gems/1.8/gems/mongrel-0.3.13.4/lib/mongrel/configurator.rb:51:in `initialize'
* ...
Notate il modo in cui si finisca in un eval() per tre volte ed allo stesso tempo come ci siano 4 riferimenti a method_missing. Ed alla fine viene fuori che il significato di questa eccezione era “l’azione ‘atom’ ha due argomenti e ne hai passato uno solo”. Ma d’altronde se non fosse così, a chi piacerebbe Camping, il microframework?
web, fun December 26, 2006 12:19 pm (Save post)
su reddit c’è un flame del genere “che linguaggio preferisci”. Citazone necessaria:
Not Java. I don’t want to touch a language so fearsome that it has spawned its own industry of code-mucking tools.
Dehe.
personale December 24, 2006 11:59 am (Save post)
Buona festa del sole, natale, chanuka o semplicemente buona serata e buon 25 dicembre.
E se ancora vi manca un regalo consiglio Hogfather, è in tema e Morte che fa “HO HO HO” è geniale. Da dove sia uscito il film non lo so.
UPDATE:
so da dove è uscito il film di hogfather, che AFAIK è il primo film su discworld di terry pratchett. Da Sky, attendo fiducioso, perché non sembra malaccio. Ridcully e Morte sono abbastanza azzeccati, Nobby purtroppo no, ma era impossibile :/
personale, erasmus December 22, 2006 12:58 pm (Save post)
Caro Lettore, avrai notato che non ho scritto per un po’, e poi ho fatto una sfilza di minipost non personali. Siccome ho stima di te, so che potresti immaginare il perché, ma penso valga la pena spiegarlo lo stesso.
Fondamentalmente, sono triste, perché tu non lo sai, ma tanta gente se ne va per il mondo per natale per non tornare più (bonus per 3, ops 4), e a me è presa brutta. Poi un giorno sono andato da Eszter, la nostra responsabile su in magiarolandia e lei mi ha chiesto se gli italiani stavano sentendo freddo. Certo, ma non nelle mani, è che ti intorpidisce il cuore sapere che c’è gente che non vedrai mai più, e lei mi ha detto che lo sa, sono anni che fa questo mestiere e si intristisce, e che alla fine uno deve ricordarsi delle cose belle e bla bla. Sono frasi fatte, ma che ci devi fare, sono anche vere.
Però mi ha dato un biscotto, e ricorda questo, Caro Lettore, puoi maturare quanto ti pare ma non puoi smettere di essere un ragazzino, quindi le strategie classiche biscotto/abbraccio/fai le tò-tò/carezze funzionano sempre come antidepressivo.
Sicché alla fine mi trovo a tornare nel bel paese, e ricomincio alla grande col traffico sul Grande Raccordo Anulare, fila al casello, mio padre che si lamenta di mia madre che lavora troppo, mia madre che si lamenta dei miei capelli e di mio fratello che è un cretino e tra l’altro ha messo Snoopy nel posto sbagliato sull’albero di natale quindi devo spostarlo, e posso mangiare gli avanzi del pranzo, e gli spaghetti con le vongole e il pane del forno a legna e posso grattarmi i paesi bassi sul divano, che finalmente sono solo. Casa.
Il mio fido mecbuc (ma quale fido, lo odio) mi ha seguito nel mio rientro, e finalmente ho tempo di farvi un filo d’ordine, sapete com’è al giorno d’oggi tutti hanno una macchina digitale, per cui ho 9 gigabyte di foto. E diciamocela tutta, non è che siano tutte bellissime, ma vale la pena ordinarle, perché ogni tanto si trovano delle chicche (guarda sullo sfondo, ci sono due donne che palpano XYZ! Chi cavolo è questo tipo che mi sta abbracciando? Scusa, quand’è che siamo stati ad un concerto dei pearl jam? Perché in questa foto a budapest c’è un mio amico di roma?). Tra l’altro devo ancora caricare tutte le foto dei finlandesi, etnia meravigliosa che però ha speso una parte notevole della sua vita girando per fiere erotiche, il che causa dei problemucci nel gestire le fotografie.
In compenso ho anche 18 gigabyte di musica, io che ero partito senza niente, e adesso mi trovo con folk italiano, heavy metal catalano, reggae/ska/raggamuffin ungherese, punk brasiliano, e musica demenziale portoghese. Vorrei poter dire che ho voluto io che accadesse tutto questo, ma non è vero, la gente ha semplicemente abusato del mio laptop.
Su altri fronti ci sono impicci quindi meglio non parlarne, scusa ma sono riservato alle volte.
programmazione, personale, fun 2:13 am (Save post)
Riportiamo questo cavolo di blog all’origine: programmazione!
Questo è un giochino visto di recente da qualche parte, ma niente link perché non mi ricordo dove.
Viene data una funzione step() che fa salire un robottino di un gradino verso l’alto, se funziona, e lo fa scendere di un gradino, se fallisce. Implementare una funzione step-up() che faccia sicuramente salire il robottino di un gradino. Senza usare contatori.
Molto carino, imo, e (mostly) language agnostic. Se invece di step() si usa una funzione (step-raise) che lanci eccezioni in caso di fallimento viene fuori un problema alternativo, ma equivalente (step-raise e step sono implementabili l’una con l’altra). In realtà non servono neanche strutture di controllo, ma questo dovreste già averlo immaginato. Buon lavoro!
web December 21, 2006 1:36 pm (Save post)
e questo è dovuto al fatto che
SiteExplorer è veramente bello. E kudos a Yahoo! (e MS) per aver adottato il meccanismo delle Sitemap di google. A mettere un formato come standard son capaci tutti, adottare le proposte dei concorrenti richiede molto più sforzo.
Ora tutti a votare la mia proposta, sebbene sia stata già verificata dal team, sembrerebbe. Se non la implementano entro un paio di mesi o non mi danno una risposta valida vi passo il mio script di screenscraping
Get free blog up and running in minutes with Blogsome
Theme designed by Janis Joseph