<br><br><div class="gmail_quote">2011/12/8 Manlio Perillo <span dir="ltr"><<a href="mailto:manlio.perillo@gmail.com" target="_blank">manlio.perillo@gmail.com</a>></span></div><div class="gmail_quote"><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


A me proprio non piace.<br>
Mi piace invece il suo modello della concorrenza, e la robustezza del<br>
suo runtime.<br></blockquote><div><br></div><div>Beh, di quello che si parla! La sintassi e' semplicemente funzionale a quello.</div><div>E si, ci sono alcune menate che rompono le palle (sintattiche e semantiche).</div>


<div>Pero' quello che e' globalmente non mi dispiace.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Il problema è che per fare cose pratiche non lo vedo molto bene.<br></blockquote><div><br></div><div>Si e no. La mia opinione globale concorda con la tua. Mi chiedo sempre se il problema fondamentale e' che io non penso in Haskell e di conseguenza debba tradurre, con ovvi problemi. Quello che io penso, ma potrei sbagliare, e' che se avessi in Haskell l'esperienza che ho con la programmazione ad oggetti, sfrutterei al meglio le sue features per girare intorno ai suoi limiti. Esattamente come faccio con Python.</div>


<div><br></div><div>Potrei sbagliare. Effettivamente Darcs mi ha messo i brividi. Comunque Haskell e' in crescita. Vediamo cosa succedera'.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



La lazyness che è non banale da controllare (però le strutture dati lazy<br>
mi piacciono perchè le vedo come una generalizzazione dei generatori), e<br>
il voler tenere a tutti i costi separato l'I/O dal resto porta a<br>
complicazioni che si potevano evitare (credo sia più pratico l'approccio<br>
di SML e/o Ocaml).<br></blockquote><div><br></div><div>Ah... beh, la laziness non ho finito di decidere se mi piace. Le strutture dati lazy credo che siano molto piu' di una generalizzazione dei generatori. Sono la logica conclusione di un modo di programmare dichiarativo.</div>


<div><br></div><div>Se sei veramente dichiarativo, perdi il concetto di "prima e dopo" che hai nella programmazione imperativa. In questo senso semplicemente definisci le cose. Se sei lazy, sei appunto 1-1 con la definizione. Perche' non hai il passaggio intermedio di "costruisco una lista cons-ando questo elemento con la lista costruita...".</div>


<div><br></div><div>Hai semplicemente "la mia lista e' la lista tale che ...".</div><div><br></div><div>E cosi' via con tutte le strutture dati del caso.</div><div><br></div><div>Il problema e' che essenzialmente questo stile funziona molto bene per modellizzare cose che effettivamente non hanno il prima e il dopo. Quando hai il prima e il dopo sono d'accordo con te: hai complicazioni. Perche' devi modellare una cosa che prima era invece implicita nel modello (eseguo questo, poi questo).</div>


<div><br></div><div>In un programma "normale" il prima e il dopo sono gia' parte della semantica del linguaggio. In haskell devi modellarli esplicitamente. Guarda caso la semantica denotazionale e' una palla per i fatti suoi, scriverci programmi puo' essere veramente pesante. ma ancora, forse sono io che non mangio abbastanza haskell.</div>


<div><br></div><div>Riguardo alle "inutili" complicazioni... se sei lazy, non puoi avere IO. Cioe' sarebbe troppo poco intuitivo.</div><div><br></div><div>Ti troveresti subito con troppa roba sorprendente. Per inciso, e' anche un plus su STM.</div>


<div><br></div><div>In Clojure ho STM e infatti dicono chiaro e tondo di non fare IO dentro le transazioni. Se no, ovviamente, stampa apparentemente a caso (ovvero, l'IO non e' trasparente rispetto alle transazioni).</div>

<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

In particolare in Haskell sei costretto a crearti (e definire con<br>
precisione) i tuoi pattern (Monadi) molto più spesso che in altri<br>
linguaggi. Magari è un pregio, ma per programmatori normali è un difetto.<br></blockquote><div><br></div><div>Quoto. Immagino che imparando diventa piu' leggero.</div><div><br></div><div>Guarda, essendo in contatto con un sacco di gente che sta imparando a programmare ad oggetti, vedo una cosa simile. Si devono definire i loro pattern per scrivere codice sensato (per assurdo il procedurale puro e' "piu' semplice" dal punto di vista di non ciccare le astrazioni). </div>


<div><br></div><div>Solo che quello noi tendiamo a non contarlo perche' abbiamo gia' imparato. </div><div><br></div><div>Poi sono d'accordo: non oso pensare cosa capiterebbe ad imparare da 0 con Haskell, magari da parte di uno non eccessivamente brillante.</div>


<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Sto cominciando a studiare altri linguaggi funzionali come SML e OCaml,<br>
ma il mancato supporto alle Type Classes di Haskell non me li fa apprezzare.<br></blockquote><div><br></div><div>Beh, sono piu' vecchiotti sotto tanti punti di vista. SML poi cerca di rimanere molto piccolino.</div><div>


A proposito... F#? Dovrebbe andare benino.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>
>  Clojure.<br>
<br>
</div>Piace anche a me, ma è ancora troppo giovane.<br></blockquote><div><br></div><div>Quoto. Ci sono ancora tante cose che devono finire di aggiustare.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">



E non ha CLOS, mi sembra (però vedo bene le interfacce: in Common Lisp è<br>
abbastanza brutto non averle, e le generic functions non sono usate<br>
molto nello standard - e probabilmente non sono efficienti come una<br>
implementazione semplice come quella in Clojure).</blockquote><div><br></div><div>Non direi che "non ha CLOS"... cioe', si, non ha CLOS (anche se mi sembra ci siano implementazioni). </div><div>Ma non mi sembra che manchi di particolari features di CLOS a parte l'ereditarieta' di implementazione (che se mi manca posso comunque avere passando per il bridge clojure-java).</div>


<div><br></div><div>Probabilmente mi sfugge qualcosa... </div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div>> IMHO i campi dove Python davvero spacca sono:<br>
> 1. calcolo scientifico (c'e' di tutto, altissima qualita', ottime<br>
> performance,<br>
<br>
</div>Non dimentichiamo però che le performance dipendono dai vari "core"<br>
scritti in C.<br></blockquote><div><br></div><div>O addirittura in Fortan. Mi sembra inevitabile! :)</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


Basta che fai qualcosa di non standard (vedi post di qualche tempo fa<br>
riguardo la scarsa efficienza quando il codice scritto in C deve<br>
chiamare codice scritto in Python nel main loop dell'algoritmo),<br>
e cominci ad avere problemi.<br></blockquote><div><br></div><div>Pero' attenzione... chiamare Python da C non e' uno use-case comunissimo. </div><div>Nel caso di Numpy per dire, al limite da C chiamero' le stesse librerie C/Fortran su cui si appoggia numpy.</div>

<div><br></div><div>Poi voglio dire... di fatto Matlab, al di la della sintassi ben piu' merdosa, fa esattamente questo. Scrivere estensioni in C per Matlab pure non e' una passeggiata. E, come dicevo, va bene.</div>

<div><br></div><div>Sono d'accordo che per fare scientifico sarebbe bello avere un linguaggio comodo come Python e veloce come C. Ma apparentemente non esiste. :)</div><div>Con il risultato che il miglior compromesso al momento disponibile sia usare un linguaggio espressivo e chiamare cores molto veloci.</div>

<div><br></div><div>Aggiungo poi... buona parte dei problemi di performance con Python+Numpy o matlab sono dovuti al fatto che non si e' scritto codice con il classico stile matriciale per cui sono pensati. Se cominci a smontare e rimontare le matrici tutte le volte, ovviamente vai piano.</div>

<div><br></div><div>Tornando poi a noi, con pypy che avanza, credo che anche molte di queste cose andranno parzialmente scomparendo.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


In casi come questi magari Ocaml o Common Lisp sono una valida alternativa.<br>
Peccato che Common Lisp che non ha una comunità attivissima (ma in<br>
Maxima, ad esempio, ci sono moltissime cose disponibili) e Ocaml che non<br>
ha un modello di sviluppo "aperto" come quello di Python.</blockquote><div><br></div><div>Questa e' una possibilita'. Pero' attenzione... Ocaml e' molto veloce, niente da dire. Pero' non mi piace quando va "imperativizzato" per guadagnare performance. Riguardo Common Lisp, ovviamente in parte hai ragione. Di per se ce la puo' fare (specie SBCL). Non so pero' come se la cava con lo smazzamento matriciale.</div>

<div><br></div><div>Anche avere le librerie fa molto: tipo un minimizzatore che va di gradiente coniugato scritto da me in 10 minuti e scritto in fortran da persone che ci hanno preso dei mesi e tunato per anni IMHO non e' paragonabile. Alla fine credo che saremmo sempre a "core in C/Fortran" chiamate da common lisp.</div>

<div><br></div><div>E ribadisco, con pypy che spinge, non so quale delle due soluzioni finirebbe per essere piu' veloce: dopotutto delegando i float a numpy e facendo gli interi con numpy (cicli e compagnia) c'e' rischio che si stia prendendo il meglio dei due mondi.</div>

</div><div><br></div>-- <br> .<br>..: -enrico-<br>