PDA

View Full Version : Imparare a programmare, partendo da ZERO!


GaetanoSena
29-11-2013, 10:31
Salve a tutti, vorrei dire innanzitutto che prima di aprire il post ho cercato tutto quello che potevo sul forum, ma non sono rimasto soddisfatto; nel senso che, il materiale c'è ed è anche buono, ma io non so da dove partire. Ho visualizzato queste pagine: prima (http://www.hwupgrade.it/forum/showthread.php?t=529474), seconda (http://www.hwupgrade.it/forum/forumdisplay.php?f=56), ma mi sento "smarrito".
Allora, premetto che ho 21 anni e nel mio corso scolastico, anche se ho frequentato il tecnico, non ho MAI avuto mezza lezione di programmazione (per motivi che non sto qui a spiegare). Sono un appassionato di informatica, pc, software, videogame e sono stanco di NON essere a conoscenza di questo ramo dell'informatica, ramo che vorrei imparare bene, perchè ho intenzione, in futuro (e se ci capirò qualcosa), di lavorarci, o quantomeno provarci. Leggendo in giro ho visto che per iniziare da ZERO è consigliato il Pascal, ma alcuni dicono il C, solo che io voglio iniziare comunque dal Pascal, perchè voglio imparare prima le cose basilari (anche se alcuni ritengono che il Pascal sia stupido, facile etc etc io voglio imparare prima quello). Ho cercato varie guide e sinceramente preferivo trovarne di meno, ce ne sono troppe e non so quale prendere per buona (anche se comunque cercherò di leggerne più di una, ma devono essere "buone"). Cioè quello che voglio fare è imparare tutta la teoria e tutta la pratica, quindi nessuna delle due deve essere trascurata. Consigliatemi, se volete/potete una o più guide di Pascal e sulla programmazione in generale, che secondo voi mi possano aprire gli occhi su questo mondo a me sconosciuto. Ah una cosa, purtroppo non sto lavorando e non posso permettermi l'acquisto di tali guide, quindi...
Insomma mi sono dilungato abbastanza, ma ci tengo veramente a questa cosa. Se avete avuto la bontà e la volontà di leggere fino a qui, vuol dire che di voi mi posso fidare ;) Grazie ancora dell'attenzione, consideratemi una pagina bianca da programmare... quindi PROGRAMMATEMI PER PROGRAMMARE :mbe:

Programmatore level: :mc:

theUser
29-11-2013, 12:28
Io ti consiglierei Python che ti da delle piccole soddisfazioni da subito senza farti perdere in dettagli di livello un po' più basso che all'inizio potrebbero(e sottolineo potrebbero) scoraggiarti. Se non ti fidi aspettiamo qualcuno di più esperto :D
Se cerchi una fonte gratuita puoi usare questo:http://www.python.it/doc/Howtothink/Howtothink-html-it/index.htm
Dovrebbe trovarsi anche la versione PDF.
Poi ti consiglio di leggere qui: http://www.hwupgrade.it/forum/showthread.php?t=1979444

Braccop
29-11-2013, 15:33
probabilmente verro' flammato a morte ma il mio consiglio e' questo:

parti con il visual c#.

motivazioni:

-ide eccezionale + compilatore assolutamente free (versione express)
-tonnellate di materiale disponibile online
-sintassi c-like
-possibilita' di fare da subito applicazioni utili e con GUI
-know-how che ti potra' tornare sicuramente utile in un eventuale ambito lavorativo

in alternativa, ti consiglierei c++ (o c liscio).

lascia stare linguaggini di scripting o roba obsoleta come il pascal, fidati.

demos88
29-11-2013, 19:06
probabilmente verro' flammato a morte ma il mio consiglio e' questo:

parti con il visual c#.

Flammato a morte no... ma...


-ide eccezionale + compilatore assolutamente free (versione express)

Di IDE ce ne sono a valanghe per i linguaggi più comuni, python incluso.

-tonnellate di materiale disponibile online

Si, vero, si trova molto anche su Python, C++, Java, C...

-sintassi c-like

Beh... come la maggioranza dei linguaggi in circolazione eredita il nome dei costrutti iterativi, condizionali, tipi primitivi...

-possibilita' di fare da subito applicazioni utili e con GUI

Vero... la GUI rientra nelle funzioni dell'IDE.

-know-how che ti potra' tornare sicuramente utile in un eventuale ambito lavorativo

Relativamente vero, penso che sia importante programmare bene prima di tutto, il linguaggio specifico può solo renderti il lavoro più semplice, se sai come farlo.

in alternativa, ti consiglierei c++ (o c liscio).

Io consiglierei Java in alternativa a C#, C++ se non lo domi è una brutta bestia.

lascia stare linguaggini di scripting o roba obsoleta come il pascal, fidati.

Mah, non sono un esperto di pascal, ma definirlo obsoleto penso sia esagerato, considerando che negli ultimi anni lo danno quasi in ripresa: http://www.tiobe.com/index.php/paperinfo/tpci/Pascal.html

ps: la mia è solo una opinione, rispetto la tua, ti ho quotato solo per facilitarmi la risposta :D
C# può andar bene per iniziare, ma anche python.

cdimauro
30-11-2013, 15:37
Python senza alcun dubbio, visto che parte completamente da zero. Non c'è niente di meglio... :cool:

VICIUS
30-11-2013, 16:39
-ide eccezionale + compilatore assolutamente free (versione express)
Visual Studio è un programma estremamente complesso. Ci sono milioni di opzioni, finestre, menu. Secondo me partire con un ide è controproducente perché spaventa e costringe a scontrarsi con l'interfaccia del programma quando l'unica cosa a cui si dovrebbe pensare è il linguaggio che si studia.

Con un linguaggio come python può aprire una console, scrivere python e gli compare l'interprete in modalità interattiva. Avere un ambiente in cui sperimentare, dove ad ogni azione si riceve un feedback dal interprete è incredibilmente potente dal punto di vista didattico.

-possibilita' di fare da subito applicazioni utili e con GUI
Tutti i programmi sono utili. Il novanta percento di quello che scrivo non ha un interfaccia e non verrebbe eseguito senza il codice di altre persone. Eppure non mi pare che il mio lavoro sia meno importante. ;)

-know-how che ti potra' tornare sicuramente utile in un eventuale ambito lavorativo
Anche qui come per l'ide penso sia prematuro pensare al futuro e scegliere di partire con linguaggio perché potrebbe servirgli in futuro per lavoro. Quello che deve imparare ora sono le basi. Come ragionare sul problema, trovare una soluzione generale e i concetti di base che gli permettano di dire al computer quello a cui ha pensato.


Nonostante mi faccia un po' schifo anche io consiglio python per cominciare.

GaetanoSena
30-11-2013, 16:58
Proprio come pensavo, ognuno ha un'opinione diversa :( il problema è che io non voglio programmare, ma voglio imparare la programmazione in generale, in tutti i suoi aspetti, non mi importa programmare alla prima "lezione", preferisco imparare tutto. Comunque c'è chi dice Pascal, chi C, chi Python etcetc, questo è quello che mi confonde!! Io voglio un linguaggio che mi apra le porte a tutti gli altri esistenti. So per sentito dire e per lettura che ad esempio Visual Basic ha un'interfaggia grafica che ti facilità tutto etc.. ecco io voglio EVITARE tutto ciò, voglio imparare le cose basi, senza grafiche e cose avanzate, per poi passarci in futuro quando capirò di cosa stiamo parlando. Quindi mi servono le BASI, le Fondamenta! p.s. comunque grazie a tutti per l'interesse

Xfree
30-11-2013, 17:45
Appoggio anche io la scelta del Python come inizio.

cdimauro
30-11-2013, 17:55
Proprio come pensavo, ognuno ha un'opinione diversa :( il problema è che io non voglio programmare, ma voglio imparare la programmazione in generale, in tutti i suoi aspetti, non mi importa programmare alla prima "lezione", preferisco imparare tutto. Comunque c'è chi dice Pascal, chi C, chi Python etcetc, questo è quello che mi confonde!! Io voglio un linguaggio che mi apra le porte a tutti gli altri esistenti. So per sentito dire e per lettura che ad esempio Visual Basic ha un'interfaggia grafica che ti facilità tutto etc.. ecco io voglio EVITARE tutto ciò, voglio imparare le cose basi, senza grafiche e cose avanzate, per poi passarci in futuro quando capirò di cosa stiamo parlando. Quindi mi servono le BASI, le Fondamenta! p.s. comunque grazie a tutti per l'interesse
Quindi ti serve Python, come ti abbiamo già detto in molti. :O

pabloski
30-11-2013, 18:08
ma voglio imparare la programmazione in generale

è un'affermazione che, purtroppo, non ha molto senso

programmare in generale non significa assolutamente nulla

piuttosto è utile avanzare a piccoli passi, restando il più possibile ancorati a problemi reali, altrimenti diventa una minestra di teorie incomprensibili e prive di qualsiasi ancoraggio pratico


preferisco imparare tutto.


posso assicurarti che nemmeno Stroustrup ( inventore del complessissimo linguaggio C++ ), conosce tutto di quella scienza chiamata Informatica


Comunque c'è chi dice Pascal, chi C, chi Python etcetc, questo è quello che mi confonde!!


di sicuro tutti saranno d'accordo sul python, così com'erano d'accordo sul basic negli anni '80


Io voglio un linguaggio che mi apra le porte a tutti gli altri esistenti.


non esiste, in quanto ogni linguaggio rappresenta un mondo astratto, che può avere regole arbitrariamente complesse e devianti


So per sentito dire e per lettura che ad esempio Visual Basic ha un'interfaggia grafica che ti facilità tutto etc..


facilita la produzione di software, ovvero semplifica il lavoro del programmatore professionista, così come fanno gli IDE

ma partire da un qualcosa che necessita di buone conoscenze del modello teorico su cui è basato, è molto pesante per chi inizia


ecco io voglio EVITARE tutto ciò, voglio imparare le cose basi, senza grafiche e cose avanzate, per poi passarci in futuro quando capirò di cosa stiamo parlando. Quindi mi servono le BASI, le Fondamenta! p.s. comunque grazie a tutti per l'interesse

python è la soluzione

GaetanoSena
30-11-2013, 23:27
Innanzitutto mi scuso se ho detto cose profane, ma non so nemmeno cos'è la programmazione, quindi è normale che dico bestialità. Comunque forse ho trovato da dove iniziare, Python :asd: Non che i consigli di coloro che mi hanno consigliato altro non sono stati apprezzati, anzi, ma sto scegliendo per maggioranza. Bene adesso si passa alla fase successiva. Ho scaricato Python da qui (http://www.python.it/download/) (la versione 3.3.2) e l'ho installato. Adesso il passo successivo (quello più importante) è capire cosa ho sottomano e capire le basi principali della programmazione; ho sentito parlare spesso di Sintassi e cose varie, cose che vorrei imparare mentre studio Python, ma ho bisogno di aiuto. Pdf o qualcosa da cui imparare, tipo questo andrebbe bene? http://www.python.it/doc/Howtothink/Howtothink-html-it/index.htm me l'ha linkato theUser. Non so, sono nelle vostre mani.

paolomec
01-12-2013, 06:52
Una domandina per gli esperti, che può servire anche all'autore del topics (si dice cosi?):

Cosa ne pensate di Codeblock utilizzato con le librerie wxwidget, utilizzando anche il suo RAD wxsmith?

A me sembra un buon sistema, molto simile al RAD di Borland c++builder, anche se non troppo facile a configurarlo.

Gradirei una risposta da chi, se c'è, ne fà un uso abbastanza assiduo.
Vorrei sapere se è buono solo per imparare a programmare o se può essere effettivamente usato per scopi professionali.

Grazie.

cdimauro
01-12-2013, 06:55
@GaetanoSena: per iniziare quel libro va benissimo. Ma installa Python 2.7.

cdimauro
01-12-2013, 06:57
Una domandina per gli esperti, che può servire anche all'autore del topics (si dice cosi?):

Cosa ne pensate di Codeblock utilizzato con le librerie wxwidget, utilizzando anche il suo RAD wxsmith?

A me sembra un buon sistema, molto simile al RAD di Borland c++builder, anche se non troppo facile a configurarlo.

Gradirei una risposta da chi, se c'è, ne fà un uso abbastanza assiduo.
Vorrei sapere se è buono solo per imparare a programmare o se può essere effettivamente usato per scopi professionali.

Grazie.
Dopo PyQt, wxwidget è molto usato (e non soltanto per Python), ed è sicuramente utile. Ma non ho esperienza diretta in merito.

Braccop
01-12-2013, 10:19
Una domandina per gli esperti, che può servire anche all'autore del topics (si dice cosi?):

Cosa ne pensate di Codeblock utilizzato con le librerie wxwidget, utilizzando anche il suo RAD wxsmith?

A me sembra un buon sistema, molto simile al RAD di Borland c++builder, anche se non troppo facile a configurarlo.

Gradirei una risposta da chi, se c'è, ne fà un uso abbastanza assiduo.
Vorrei sapere se è buono solo per imparare a programmare o se può essere effettivamente usato per scopi professionali.

Grazie.

lascia perdere... molto meglio wxdev-c++ nonostante sia un po' buggato qua e la

paolomec
01-12-2013, 13:45
Braccop, ma wxdwvc++ non è multipiattaforma come il codeblock, e mi sembra anche deprecato.

Il codeblock l'avevo installato sia su win8 sia su opensuse e ubuntu (ma ora lo devo reinstallare su tutti perché quei sistemi gli hò tutti upgradati.

Ti ringrazio del parere, ma perché dici di lasciar perdere? L'hai usato?
Perché io hò chiesto un parere a chi lo utilizza.

vendettaaaaa
01-12-2013, 15:18
Braccop, ma wxdwvc++ non è multipiattaforma come il codeblock, e mi sembra anche deprecato.

Il codeblock l'avevo installato sia su win8 sia su opensuse e ubuntu (ma ora lo devo reinstallare su tutti perché quei sistemi gli hò tutti upgradati.

Ti ringrazio del parere, ma perché dici di lasciar perdere? L'hai usato?
Perché io hò chiesto un parere a chi lo utilizza.
ho si scrive senza accento e si dice "li ho upgradati" non "gli ho upgradati".

Braccop
01-12-2013, 15:23
Braccop, ma wxdwvc++ non è multipiattaforma come il codeblock, e mi sembra anche deprecato.

Il codeblock l'avevo installato sia su win8 sia su opensuse e ubuntu (ma ora lo devo reinstallare su tutti perché quei sistemi gli hò tutti upgradati.

Ti ringrazio del parere, ma perché dici di lasciar perdere? L'hai usato?
Perché io hò chiesto un parere a chi lo utilizza.

ho provato, ma sono rimasto molto deluso e sono subito tornato a wxdev-c++

mone.java
02-12-2013, 07:29
Secondo ma già che devi iniziare inizia con qualcosa che ti permetta di essere produttivo, anche perché imparare un linguaggio, secondo me, significa anche conoscerne bene le librerie di base e eventualmente quelle esterne, quindi linguaggi come Python, Java e C# sono perfetti allo scopo, migliaia di librerie esempi community e per quanto riguarda Java e C# avendo la sintassi c-like ti permetterebbero di trovarti a tuo agio con la sintassi di tanti altri linguaggi... Detto questo io mi chiedo come si fa nel 2013 a suggerire di iniziare con il Pascal ( a parte il fatto che "IO HO INIZIATO COSI E QUINDI È GIUSTO COSI") siccome è un linguaggio che è MORTO oppure è vivo almeno quanto il Cobol (che si è molto usato in ambiti Main Frame) il che vuol dire che difficilmente troverai librerie già fatte per affrontare i problemi ODIERNI oppure una community in grado di aiutarti... Per quanto riguarda C e C++ invece sono troppo complessi per iniziare e poco descrittivi quando ti ritrovi a dover correggere gli errori... (anche qui non capisco come si faccia a dire che sono d a usare come primo linguaggio)

Xfree
02-12-2013, 08:57
Secondo ma già che devi iniziare inizia con qualcosa che ti permetta di essere produttivo, anche perché imparare un linguaggio, secondo me, significa anche conoscerne bene le librerie di base e eventualmente quelle esterne, quindi linguaggi come Python, Java e C# sono perfetti allo scopo, migliaia di librerie esempi community e per quanto riguarda Java e C# avendo la sintassi c-like ti permetterebbero di trovarti a tuo agio con la sintassi di tanti altri linguaggi... Detto questo io mi chiedo come si fa nel 2013 a suggerire di iniziare con il Pascal ( a parte il fatto che "IO HO INIZIATO COSI E QUINDI È GIUSTO COSI") siccome è un linguaggio che è MORTO oppure è vivo almeno quanto il Cobol (che si è molto usato in ambiti Main Frame) il che vuol dire che difficilmente troverai librerie già fatte per affrontare i problemi ODIERNI oppure una community in grado di aiutarti... Per quanto riguarda C e C++ invece sono troppo complessi per iniziare e poco descrittivi quando ti ritrovi a dover correggere gli errori... (anche qui non capisco come si faccia a dire che sono d a usare come primo linguaggio)

Questa storia l'ho sentita fino a venerdì scorso di persona.
Infatti non capisco con quale criterio sia stato consigliato. :asd:

van9
02-12-2013, 12:18
Proprio come pensavo, ognuno ha un'opinione diversa :(

Se stai cercando un certo rassicurante consenso, puoi anche metterti il cuore in pace. La situazione a livello mondiale è esattamente questa: Scheme, Standard ML, Haskell, Caml Light, OCaml, C, Python, Ruby, C++, Java, Oberon-2 e tanto altro vengono tutti usati per introdurre alla programmazione in università più o meno prestigiose e sono ognuno più o meno raccomandati da vari esperti nell'industria. Mettiti quindi al lavoro armato di tanta voglia di fare e di esplorare, perché una cosa è certa: da qualunque linguaggio partirai, sta sicuro che non sarà quello definitivo.

mone.java
02-12-2013, 12:40
Si ma la situazione descritta da te è quella in ambito universitario... Infatti anche io arrivato all'università ho fatto Scheme, ma essendo un corso universitario avevo un docente che mi seguiva e che quindi mi ha fatto fare un percorso "sensato" anche in vista del fatto che nel triennio di Informatica (a Bologna) si vedono anche C, C++, Java, Python, BASH ecc (dipende dai prof/corsi/gusti)... Ma uno che deve iniziare da 0 e parte DA SOLO con Dr Scheme (quell'obbrobrio di IDE che ci hanno imposto per Scheme) probabilmente abbandonerà la programmazione senza più volerne sentir parlare per almeno 20 anni. Quindi bisogna partire dal presupposto che si sta parlando con una persona che non avrà docenti che lo seguono e che lo obbligano a fare un certo percorso, accompagnato da opportune esercitazioni/progetti, e men che meno decine di compagni con cui confrontarsi/aiutarsi ecc... Quindi se uno deve iniziare tanto vale che lo faccia con qualcosa di stimolante, di nuovo che ti permette di fare cose carine (con scheme e Dr Scheme non puoi fare nulla di utile praticamente) entusiasmanti... Poi una volta che si è fatto un po le ossa che scenda piano piano a basso livello..

PS comunque l'unica scusa che mi davo per studiare Scheme era "Tanto lo usano anche al MIT" salvo poi scoprire poco tempo fa che sono migrati a Python...

van9
02-12-2013, 15:31
Si ma la situazione descritta da te è quella in ambito universitario... Infatti anche io arrivato all'università ho fatto Scheme, ma essendo un corso universitario avevo un docente che mi seguiva e che quindi mi ha fatto fare un percorso "sensato" anche in vista del fatto che nel triennio di Informatica (a Bologna) si vedono anche C, C++, Java, Python, BASH ecc (dipende dai prof/corsi/gusti)... Ma uno che deve iniziare da 0 e parte DA SOLO con Dr Scheme (quell'obbrobrio di IDE che ci hanno imposto per Scheme) probabilmente abbandonerà la programmazione senza più volerne sentir parlare per almeno 20 anni. Quindi bisogna partire dal presupposto che si sta parlando con una persona che non avrà docenti che lo seguono e che lo obbligano a fare un certo percorso, accompagnato da opportune esercitazioni/progetti, e men che meno decine di compagni con cui confrontarsi/aiutarsi ecc... Quindi se uno deve iniziare tanto vale che lo faccia con qualcosa di stimolante, di nuovo che ti permette di fare cose carine (con scheme e Dr Scheme non puoi fare nulla di utile praticamente) entusiasmanti... Poi una volta che si è fatto un po le ossa che scenda piano piano a basso livello..

PS comunque l'unica scusa che mi davo per studiare Scheme era "Tanto lo usano anche al MIT" salvo poi scoprire poco tempo fa che sono migrati a Python...

"nulla di utile praticamente", wow. Qualche esempio di "utile praticamente" e "cose carine ed entusiasmanti" che tu non sei in grado di programmare in un linguaggio come Racket?

Tra http://www.ccs.neu.edu/home/matthias/HtDP2e e HtDP vecchia versione e i vari teachpacks, corsi come https://www.coursera.org/course/programdesign, libri e risorse varie, forums/ml/canali irc attivi, se uno oggi abbandona un linguaggio come Racket è solo una questione individuale e di motivazione. Alla stessa identica maniera della stragrande maggioranza che parte da autodidatta con Python/Java/Ruby/<lang> e abbandona impietosamente dopo poco.
Io ad esempio non mi sono dovuto dare scuse per imparare Scheme (e C, su Unix) quando sono partito da autodidatta, anzi mi ricordo che ero così contento e mi sembrava di star esplorando e scoprendo chissà che di "magico"... Boh.

mone.java
02-12-2013, 15:56
Forse si io con lo scheme ero partito prevenuto perchè venivo da Java (imparato da autodidatta) però mi ricordo che con DrSceme più o meno c'era tutto però al di la della documentazione ufficiale non c'era molto altro... Di un corso di 120 persone infatti lo odiavamo più o meno tutti ma io cmq me lo sono studiato bene e ho preso 30 e lode nel compito... Però a parte farmi passare il compito con 30 e lode e obbligarmi a imparare la ricorsione (che si può imparare anche con gli altri linguaggi) non è che mi abbia dato molto altro, nel senso che nemmeno piangendo mi sa che trovi da lavorare con Scheme in ambiente DrScheme o simili oppure gente disposta ad aiutarti se hai un problema rognoso (con Java Python e C# la probabilità di trovare la soluzione a un problema è enormemente più alta)... Con cose carine parlo di fare interfacce, connettersi a webservice e cose del genere, che sicuramente fai anche con DrScheme ma altrettanto sicuramente trovi meno supporto/librerie/scelta/esempi per farlo.... Perché come già detto imparare un linguaggio significa anche impararne la libreria di base e le cose imparate su Java, Python e C mi servono tutt'oggi, quelle su DrScheme no.. Per quanto riguarda il C non ho mai detto che abbia dovuto trovare delle scuse per studiarlo ANZI ero uno di quelli che voleva ci venisse insegnato al posto di Scheme(programmazione) e Pascal(algoritmi)... Salvo poi capire conoscendolo che non è un linguaggio adatto per chi inizia... Ma comunque un bellissimo linguaggio e infatti me lo sono studiato con molta attenzione andando ben oltre a quello strettamente richiesto dal corso....

WarDuck
03-12-2013, 19:36
Io userei Java, fosse non solo che è un'ottima via di mezzo e espone bene il concetto di tipizzazione forte, che secondo me è un concetto di fondamentale se non di vitale importanza.

Già solo il fatto che con Python ti accorgi di alcuni errori di sintassi a runtime non lo farei usare così a cuor leggero per iniziare.

cdimauro
03-12-2013, 22:12
Più che altro di semantica. E' difficile vedere errori di sintassi a runtime.

Comunque anche Python è un linguaggio con tipizzazione forte. ;)

van9
04-12-2013, 11:31
Forse si io con lo scheme ero partito prevenuto perchè venivo da Java (imparato da autodidatta) però mi ricordo che con DrSceme più o meno c'era tutto però al di la della documentazione ufficiale non c'era molto altro... Di un corso di 120 persone infatti lo odiavamo più o meno tutti ma io cmq me lo sono studiato bene e ho preso 30 e lode nel compito... Però a parte farmi passare il compito con 30 e lode e obbligarmi a imparare la ricorsione (che si può imparare anche con gli altri linguaggi) non è che mi abbia dato molto altro, nel senso che nemmeno piangendo mi sa che trovi da lavorare con Scheme in ambiente DrScheme o simili oppure gente disposta ad aiutarti se hai un problema rognoso (con Java Python e C# la probabilità di trovare la soluzione a un problema è enormemente più alta)... Con cose carine parlo di fare interfacce, connettersi a webservice e cose del genere, che sicuramente fai anche con DrScheme ma altrettanto sicuramente trovi meno supporto/librerie/scelta/esempi per farlo.... Perché come già detto imparare un linguaggio significa anche impararne la libreria di base e le cose imparate su Java, Python e C mi servono tutt'oggi, quelle su DrScheme no.. Per quanto riguarda il C non ho mai detto che abbia dovuto trovare delle scuse per studiarlo ANZI ero uno di quelli che voleva ci venisse insegnato al posto di Scheme(programmazione) e Pascal(algoritmi)... Salvo poi capire conoscendolo che non è un linguaggio adatto per chi inizia... Ma comunque un bellissimo linguaggio e infatti me lo sono studiato con molta attenzione andando ben oltre a quello strettamente richiesto dal corso....

Quindi per te, quando si deve imparare a programmare, è importante che il primo linguaggio scelto sia anche quello "definitivo", visto che deve avere supporto industriale in termini di librerie ed essere oggetto di annunci di lavoro correnti. Ma se così stanno le cose sia l'università che imparare da autodidatta sono una perdita di tempo - meglio frequentare corsi che all'estero chiamano di "vocational training" così t'insegnano quello che presumibilmente serve per rispondere agli annunci e morta lì. Altrimenti non ho capito il tuo punto.
Diciamo pure che io sono di tutt'altra idea al riguardo.

Su Scheme e lavoro sfondi una porta aperta, il linguaggio è tutto fuorché nato per l'industria. Certo da qui a dire che Lisp non dia granché fa pensare: forse il corso non era tenuto granché bene, forse DrScheme all'epoca era troppo immaturo e si è messo tra i piedi quando una semplice REPL sulla command line sarebbe stato meglio. Boh. Anche a parecchi ex-MIT (visto che li citavi prima) il corso 6.001 non è piaciuto. Ad ognuno il suo mi viene da pensare.

Su DrRacket (la versione attuale) oggi non ho dubbi che sia un ambiente portentoso per insegnare - Matthias Felleisen è uno dei pochi che ci abbia mai capito davvero qualcosa dell'intersezione tra linguaggi di programmazione, informatica e didattica per me. Prova a rivederti DrRacket e vedrai che ho ragione.
Ad esempio citi le gui, vedo nella doc che basta un semplice

(define frame (new frame% [label "Example"]))
(send frame show #t)

per partire.

Sul C, forse ho scritto male ma stavo solo raccontando di quello che avevo imparato io all'epoca.


tipo i corsi regionali di un 15 anni fa in Italia, non so se ne esistono ancora.

van9
04-12-2013, 12:12
Io userei Java, fosse non solo che è un'ottima via di mezzo e espone bene il concetto di tipizzazione forte, che secondo me è un concetto di fondamentale se non di vitale importanza.

Già solo il fatto che con Python ti accorgi di alcuni errori di sintassi a runtime non lo farei usare così a cuor leggero per iniziare.

Secondo me i linguaggi component-oriented hanno già fatto abbastanza danni, nella didattica tanto quanto nell'industria. Nella didattica la mia idea è semplice, ci si deve concentrare su algoritmi e astrazioni - class, public static void, metodi static come finte funzioni, getters & setters e quant'altro sono solo d'intralcio per chi inizia. Non è un segreto che "object-first" ha fallito nella didattica già anni fa. Il primo approccio è meglio che sia a scelta procedurale o funzionale, e che sembri il più possibile "naturale" nel linguaggio scelto.
Certo in Java se uno usa il sistema Kenya o DrJava o mini-interpreti ad hoc qualcosa si può fare di buono nella primissima introduzione, ma a quel punto perché forzare la mano quando ci sono scelte migliori.

Errori di sintassi a runtime che potrebbe commettere un neofita in Python non me ne vengono al momento però.

Su strong typing sono daccordo soprattutto se associata a static typing come in SML o OCaml o Haskell, che sono linguaggi ideali per imparare di questi tempi dove il vecchio orientamento al "processing" lascia sempre più spazio a quello di tipo data-oriented. <rant> Ma vallo a spiegare a chi s'accontenta del solito copy&paste enterprise oriented - poi i pupi escono sconvolti</rant>. Pardon, dicevamo.


che poi ci si dovrebbe prima mettere daccordo su cosa si intenda per "object-oriented programming" nei linguaggi mainstream moderni, visto che ognuno ne ha una sua personalissima definizione e che di object-oriented nel senso classico/simulativo del termine c'è spesso ben poco, tanto nei meccanismi del linguaggio stesso quanto nel modo in cui viene insegnato il design del software.

mone.java
04-12-2013, 12:41
Forse sono stato un po drastico io sullo Scheme e chiedo scusa per la mia esuberanza... Io non ho detto che deve essere quello definitivo.. Io ho fatto scheme all'università e non me ne pento siccome ci hanno poi insegnato tante altre cose (e altrettante me le sono insegnate da solo). Dico solo che, secondo me, uno partendo con un linguaggio come scheme se non seguito da qualcuno capace (un docente in genere) potrebbe essere più facile demotivarsi... A noi a lezione con scheme ci hanno anche fatto disegnare i frattali nonché le GUI, cammini su grafi, alberi liste ecc alla fine mi ero anche appassionato e ora posso dire che si sia stato un bene farlo ma perchè avevo un docente... altrimenti penso che se fossi partito da solo non mi avrebbe appassionato particolarmente... Ripeto che io magari parto prevenuto siccome ho iniziato con Java e con un IDE come eclipse ... Quindi il punto è ora che uno deve imparare da autodidatta tanto vale che si diriga verso una certa direzione.. Ma magari sbaglio..

Ifatti dopo ho letto questa tua risposta..

Secondo me i linguaggi component-oriented hanno già fatto abbastanza danni, nella didattica tanto quanto nell'industria. Nella didattica la mia idea è semplice, ci si deve concentrare su algoritmi e astrazioni e class, public static void, metodi static come finte funzioni, getters & setters e quant'altro sono solo d'intralcio per chi inizia. Non è un segreto che "object-first" ha fallito nella didattica già anni fa - il primo approccio è meglio che sia a scelta procedurale o funzionale, e che sembri il più possibile "naturale" nel linguaggio scelto.
Certo in Java se uno usa il sistema Kenya o DrJava o mini-interpreti ad hoc qualcosa si può fare di buono nella primissima introduzione, ma a quel punto perché forzare la mano quando ci sono scelte migliori.


Pensandoci in effetti mi ricordo che con Java agli inizi ero parecchio perso/perplesso dietro le mille keyword/classi/costrutti che nei milioni di esempi che si trovano ti fanno fare la stessa cosa in mille modi diversi...

Rivedrò la mia posizione... Anche se per ora continuerei a consigliare python a un novizio autodidatta :D

Secondo me i linguaggi component-oriented hanno già fatto abbastanza danni, nella didattica tanto quanto nell'industria

Però perchè dici che hanno fatto danni nell'industria?

van9
04-12-2013, 15:48
Forse sono stato un po drastico io sullo Scheme e chiedo scusa per la mia esuberanza...

Ma figurati quali scuse, è solo che su Lisp troppo spesso si sono sentiti i più fantasiosi "non si può fare" e a me non è mai andato giù (sia per principio, sia perché un po' di esperienza commerciale in Common Lisp l'ho fatta e posso dimostrare coi fatti di cosa parlo).

Io non ho detto che deve essere quello definitivo.. Io ho fatto scheme all'università e non me ne pento siccome ci hanno poi insegnato tante altre cose (e altrettante me le sono insegnate da solo). Dico solo che, secondo me, uno partendo con un linguaggio come scheme se non seguito da qualcuno capace (un docente in genere) potrebbe essere più facile demotivarsi... A noi a lezione con scheme ci hanno anche fatto disegnare i frattali nonché le GUI, cammini su grafi, alberi liste ecc alla fine mi ero anche appassionato e ora posso dire che si sia stato un bene farlo ma perchè avevo un docente... altrimenti penso che se fossi partito da solo non mi avrebbe appassionato particolarmente... Ripeto che io magari parto prevenuto siccome ho iniziato con Java e con un IDE come eclipse ...

Ok sembrava altro dalla prima descrizione. Però resta la perplessità sul perché pensi che frattali/GUI/grafi/alberi e liste siano per l'autodidatta più a portata di mano in Java rispetto a Scheme - a me pare esattamente l'opposto. Il core di Scheme s'impara davvero in un'ora, dopo è tutta Informatica (cit. B. Harvey). Non è un caso se bei libri come https://gustavus.edu/+max/concrete-abstractions-pdfs/index.html ti presentano patterns di figure e frattali in modo completamente naturale e indolore al quarto capitolo. In un tipico libro di Java all'ottavo stai ancora aspettando di completare l'iterazione e manco hai visto la ricorsione (che verrà sistematicamente presentata in modo sbagliato, ovvero per come funziona meccanicamente nel linguaggio piuttosto che come strumento per risolvere problemi). Davvero la media del materiale su Scheme (e Lisp, perché quando ci prendi mano poi farti aiutare a tradurre dall'uno all'altro non è poi impossibile) è eccelsa, forse pure troppo impegnativa alle volte. A confronto la media delle pubblicazioni e materiale su Java mi è sempre sembrata di un grigiore quello si davvero molto poco appassionante. Prova a citarmi ad esempio un libro del mondo Java a cui un neofita potrebbe appassionarsi e che sia all'altezza di Simply Scheme, The Little Schemer, SICP, Concrete Abstractions, HtDP 2a ed.

Liste e alberi figuriamoci, Scheme non chiede di mostrarti efficacemente altro. Sulle GUI, punto forte per un linguaggio che supporta gli oggetti, ti dicevo ho guardato al volo cosa offre oggi Racket in DrRacket. Trovi tutto su http://docs.racket-lang.org/gui/windowing-overview.html#%28part._.Creating_.Windows%29 valuta tu.

Il punto sull'appassionarsi è interessante, ed è altamente soggettivo ovviamente. Come prima per C, che ho imparato anzitutto perché m'incuriosiva la possibilità di capire come funzionassero echo(1), grep(1), tail -f e via così. Allo stesso modo Scheme mi piacque perché usavo Emacs e vedevo girare software di cui volevo capirci qualcosa. Per dirne una, conoscendo Scheme ho poi imparato facilmente Common Lisp e ricordo che ho passato un numero interminabile di ore sul codice di Peter Norvig in Paradigms of Artificial Intelligence Programming, che ancora oggi resta una delle cose più fighe che abbia mai letto/studiato (e diverse idee le ho anche usate al lavoro dopo anni!).
Se penso a quello che avrei letto, studiato e scritto per Java e con Java nel caso avessi iniziato da lì, onestamente non saprei manco come sarebbe andata. Java per me resta più interessante come secondo linguaggio almeno.

Quindi il punto è ora che uno deve imparare da autodidatta tanto vale che si diriga verso una certa direzione.. Ma magari sbaglio..

Ifatti dopo ho letto questa tua risposta..

Pensandoci in effetti mi ricordo che con Java agli inizi ero parecchio perso/perplesso dietro le mille keyword/classi/costrutti che nei milioni di esempi che si trovano ti fanno fare la stessa cosa in mille modi diversi...

Eh, spesso ci si dimentica della fatica fatta inizialmente e di come sono andate le cose. Troppo facilmente oggi ci lasciamo andare a frasi del tipo "impara Java o Python che sono semplici", quando in effetti non sono "semplici" per nulla. Sono linguaggi ricchi, complessi, dove anche un assegnamento nasconde un mondo di semantica. I linguaggi veramente semplici sono altri, Scheme e Standard ML, C (che però è troppo insidioso per iniziare - vedi l'interessante linguaggio Cyclone al proposito) ma anche un Oberon-2 (di cui non sono fissato ma ho ottime ragioni per ritenerlo adatto ad imparare la programmazione dal lato imperativo).

Rivedrò la mia posizione... Anche se per ora continuerei a consigliare python a un novizio autodidatta :D

Anche a me piace Python, anche se però non mi piace il punto di vista da cui spesso viene insegnato. Un collega m'ha fatto una lista di tutte le risorse più interessanti che prendono i dati come punto di partenza piuttosto che il processing/l'aspetto procedurale ma ancora non l'ho guardata.


Però perchè dici che hanno fatto danni nell'industria?

Discorso troppo lungo che non saprei riassumere per un post davvero. Diciamo che si concentrano troppo su promesse che non possono mantenere (il riuso del software) a discapito del resto e dicono di fare quello che in realtà non fanno ("object-oriented programming", quando piuttosto è solo class-based programming). Su quora pochi giorni fa ho letto http://www.quora.com/Object-Oriented-Programming/Was-object-oriented-programming-a-failure dove ci sono passaggi più che eloquenti di cui sono più checovinto da un decennio buono - in breve capisco l'OO nelle GUI, sono daccordo con Jim Coplien sul DCI, ho usato l'oop (nel senso classico) per le simulazioni, ma per gran parte del resto "everything is an object" è più una truffa e una non soluzione che ci trasciniamo appresso dal passato che altro.
Certo non ho una soluzione alternativa pronta per il "mondo Enterprise" ma penso anche che quel mondo, a differenza di quelli in cui ho preferito lavorare io, sia più chiacchiere che sostanza comunque e quindi non me ne preoccupo più di tanto. Quello che mi interessa di più è che si guardi avanti con coerenza e meno alle StupideFactory SolutionFactory FactoryFactory tanto care a troppi.

mone.java
04-12-2013, 16:14
Ok sembrava altro dalla prima descrizione. Però resta la perplessità sul perché pensi che frattali/GUI/grafi/alberi e liste siano per l'autodidatta più a portata di mano in Java rispetto a Scheme - a me pare esattamente l'opposto. Il core di Scheme s'impara davvero in un'ora, dopo è tutta Informatica (cit. B. Harvey). Non è un caso se bei libri come https://gustavus.edu/+max/concrete-a...dfs/index.html ti presentano patterns di figure e frattali in modo completamente naturale e indolore al quarto capitolo. In un tipico libro di Java all'ottavo stai ancora aspettando di completare l'iterazione e manco hai visto la ricorsione (che verrà sistematicamente presentata in modo sbagliato, ovvero per come funziona meccanicamente nel linguaggio piuttosto che come strumento per risolvere problemi). Davvero la media del materiale su Scheme (e Lisp, perché quando ci prendi mano poi farti aiutare a tradurre dall'uno all'altro non è poi impossibile) è eccelsa, forse pure troppo impegnativa alle volte. A confronto la media delle pubblicazioni e materiale su Java mi è sempre sembrata di un grigiore quello si davvero molto poco appassionante. Prova a citarmi ad esempio un libro del mondo Java a cui un neofita potrebbe appassionarsi e che sia all'altezza di Simply Scheme, The Little Schemer, SICP, Concrete Abstractions, HtDP 2a ed.


Ok mi hai convinto la prossima volta che devo suggerire un linguaggio per iniziare ci penserò bene, e magari perchè no dirò scheme! Anche perché effettivamente della IMMENSA-VASTISSIMA-INENARRABILE quantità di materiale per java (dico java perché ho iniziato cosi e quindi ne ho letto davvero tanto) solo poco è davvero ben fatto e solo con l'esperienza si riesce a capire a colpo d'occhio se l'articolo/guida che stai leggendo vale qualcosa o meno, ma il principiante non può capirlo.

Per quanto riguarda l'industria anche qui forse hai ragione, nel senso che anche io troppo spesso mi trovo a perdere tempo per implementare un bel design a oggetti quando non è realmente necessario e anzi il codice finale viene molto incasinato... Quando viene fatto con cognizione di causa può essere molto potente, vedi ad esempio Spring, ma cmq ti ritrovi con il codice prolisso e ripetitivo... Ultimamente ho lavorato con un Architettura a 5 strati per un grosso progetto, e per quanto fosse bella e ben ingegnerizzata (da dai super analisti e non da me :D ) comuqnue dti ritrovi a dover scrivere un sacco di codice ripetitivo tra interfacce, implementazioni, passaggi di oggetti tra gli strati, model to model, ecc...

Stasera con un pò più di tempo mi leggerò l'articolo.. Io avevo molta fiducia nella programmazione a oggetti.. forse stasera mi crollerà il mondo addosso :D :D :D RITIENITI RESPONSABILE!

cdimauro
04-12-2013, 19:33
Eh, spesso ci si dimentica della fatica fatta inizialmente e di come sono andate le cose. Troppo facilmente oggi ci lasciamo andare a frasi del tipo "impara Java o Python che sono semplici", quando in effetti non sono "semplici" per nulla. Sono linguaggi ricchi, complessi, dove anche un assegnamento nasconde un mondo di semantica.
Mah, non mi pare che sia proprio così. Sicuramente ti riferisci all'overloading degli operatori e in generale ai "magic method", che in Python ti consentono di ridefinire il comportamento di un oggetto relativamente a un preciso aspetto.

Ma per ottenere questo devi, appunto, ridefinire quel particolare aspetto che t'interessa. Il che vuol dire che ti sei spinto decisamente avanti nella programmazione con questo linguaggio. Molto avanti.

Python per imparare è semplice proprio perché all'inizio parti necessariamente da concetti semplici, e questo linguaggio ti consente di esprimerli / modellarli / implementarli con poco sforzo, e una sintassi che agevola molto tanto la scrittura quanto la comprensione di quello che si sta facendo.

Io non ho mai visto nessuno partire da zero e cominciare col ridefinire __setattr__...

Come pure non penso nemmeno che sostituire Scheme con Python al MIT sia stato soltanto una questione di moda...

van9
04-12-2013, 23:38
Mah, non mi pare che sia proprio così. Sicuramente ti riferisci all'overloading degli operatori e in generale ai "magic method", che in Python ti consentono di ridefinire il comportamento di un oggetto relativamente a un preciso aspetto.

Ma per ottenere questo devi, appunto, ridefinire quel particolare aspetto che t'interessa. Il che vuol dire che ti sei spinto decisamente avanti nella programmazione con questo linguaggio. Molto avanti.

Python per imparare è semplice proprio perché all'inizio parti necessariamente da concetti semplici, e questo linguaggio ti consente di esprimerli / modellarli / implementarli con poco sforzo, e una sintassi che agevola molto tanto la scrittura quanto la comprensione di quello che si sta facendo.

Io non ho mai visto nessuno partire da zero e cominciare col ridefinire __setattr__...


No per la verità mi riferivo al fatto che il modello a sostituzioni per frames e environments di Scheme resta il più semplice da capire, più o meno finchè non s'arriva per l'appunto a set!, eventualmente a spiegare la beta-reduction e via dicendo. E' (anche) così che i libri su Scheme viaggiano ad un'alta quantità d'informatica per pagina rispetto ad altri (anche se mi rendo conto però che questa non è la priorità di tutti). Python e Java necessitano di spiegazioni certo più operazionali - mutabile, non-mutabile, copie. Ti trovi subito a parlare di aliasing e identità, mentre all'inizio quello che conta davvero sono i valori (e dopo ancora di più, ma questo lo lasciamo per un eventuale rant futuro lol). In Scheme hai solo le parentesi fuori posto - per il resto è matematica, algebra elementare che già conosci e non hai bisogno di un modello radicalmente diverso per iniziare a capire come per Python e Java. In questo senso sono un mondo di ricca e nuova semantica - Scheme un bel pò meno all'inizio.

Poi certo a voler essere sinceri Python vince su alcune cose, l'I/O più diretto e semplificato (almeno parlando di usi comuni come ad esempio nel web programming, altrimenti il reader vince) e soprattutto l'indentazione significativa alla ISWIM di Landin che è perfetta per metter ordine in chi comincia. E no, le parentesi del Lisp non le metto tra i cons di Scheme perché è tutta paura iniziale infondata.

edit: "i cons di Scheme", non me n'ero nemmeno accorto... duh

Come pure non penso nemmeno che sostituire Scheme con Python al MIT sia stato soltanto una questione di moda...

Dall'interno mi dicevano che erano più di 10 anni che pensavano di sostituire 6.001, ma considerando che l'MIT è d'impostazione piuttosto pragmatica mi suona strano. No non è moda perché Python è sostanza, ma popolarità in un certa misura sicuramente. Il primo corso di programmazione (tanto all'MIT quanto in giro per il mondo) ormai accoglie per la maggior parte persone che non diventeranno informatici a tempo pieno e Python va forte proprio in scienze sociali e statistiche, in biologia in particolare, oltre ad essere buono per introdurre a programmare e infine largamente usato. Da questo punto di vista in effetti mi chiedo perché c'abbiano messo tanto. La questione del nuovo curriculum è un giallo ancora da risolvere, il corso dove usano Python con i robot e i sistemi LTI non ho idea se sia stato modificato o che fine abbia fatto. I posti come l'MIT usano senza troppo nascondersi gli studenti come cavie per sperimentare nuove soluzioni nel corso di certe annate, se non segui l'evoluzione delle cose o non ti fai raccontare da qualcuno com'è andata poi non se ne cava molto in conoscenza.
MIT a parte (e se raccolgo notizie su Python le posto) il pezzo più bello l'hanno fatto a Berkeley, dove anche lì hanno sostituito SICP e Scheme che pure erano insegnati da quasi 30 anni con Python. Ma sono stati come dire un filo più "trasparenti", traducendo quasi letterlamente SICP in Python (vedi http://www-inst.eecs.berkeley.edu/~cs61a/sp12/book/functions.html
e http://composingprograms.com/). Quando me lo postarono non ci credevo quasi. Se conosci l'Abelson e Sussman prova a dare un'occhiata al risultato - per certi versi è interessante, per altri ovviamente risulta un pò forzato. Ovviamente per la famosa parte di "Metalinguistic Abstraction" si implementa un piccolo sottoinsieme di Scheme.
Non sembra forse una di quelle scene dove lo zombie proprio non si decide a morire?!

p.s. mi dicono che in entrambe c'è l'alternativa self-paced che segue SICP disponibile, ma quella MIT non l'ho trovata per la verità.

cdimauro
07-12-2013, 10:23
No per la verità mi riferivo al fatto che il modello a sostituzioni per frames e environments di Scheme resta il più semplice da capire, più o meno finchè non s'arriva per l'appunto a set!, eventualmente a spiegare la beta-reduction e via dicendo. E' (anche) così che i libri su Scheme viaggiano ad un'alta quantità d'informatica per pagina rispetto ad altri (anche se mi rendo conto però che questa non è la priorità di tutti).
Francamente Scheme l'ho studiato all'università quasi una ventina d'anni fa, per cui ricordo poco i concetti di frame, environment, e beta-reduction. Magari vedendo qualche pezzo di codice mi tornano alla mente.
Python e Java necessitano di spiegazioni certo più operazionali - mutabile, non-mutabile, copie. Ti trovi subito a parlare di aliasing e identità, mentre all'inizio quello che conta davvero sono i valori (e dopo ancora di più, ma questo lo lasciamo per un eventuale rant futuro lol).
Possiamo parlarne certamente, perché per me sono argomenti interessanti.

Comunque quando inizi con Python non hai bisogno di focalizzare l'attenzione su mutabilità, immutabilità, identità, ecc. Parti col concetto di valore, di variabile, di accettazione, di condizione, di cicli, ecc.

Java, invece, ha bisogno di un'infrastruttura più complessa anche per un banale Hello, world.
In Scheme hai solo le parentesi fuori posto - per il resto è matematica, algebra elementare che già conosci e non hai bisogno di un modello radicalmente diverso per iniziare a capire come per Python e Java.
Non sono d'accordo, perché l'algebra elementare la usi in Python esattamente come hai imparato a scuola: con la notazione infissa. Invece con Scheme devi utilizzare la non comune e più scomoda notazione prefissa (o polacca).

Altra cosa, in Python le funzioni le richiami esattamente come hai imparato a scuola, col nome della funzione, e gli eventuali parametri racchiusi dalle parentesi tonde, separati dalla virgola nel caso ce ne siano più d'uno, mentre in Scheme le parentesi le usi per racchiudere sia la funzione che i suoi parametri, e questi ultimi sono separati dallo spazio anziché dalla virgola.
Ovviamente mi riferisco alla definizione di funzioni generiche, come ad esempio f(x, y) che richiami come f(3, 5). Mentre per le funzioni "tradizionali" con un solo argomento a scuola abbiamo usato la notazione presente in Scheme, come ad esempio sen 3,14.

L'unico vantaggio di Scheme è che le funzioni restituiscono automaticamente il risultato delle operazioni che svolgono, mentre in Python devi utilizzare la keyword return per fare la stessa cosa.
Comunque anche in Python si può fare all'incirca la stessa cosa in alcuni ambiti utilizzando le lambda, ma da pythonista lo trovo una forzatura.
In questo senso sono un mondo di ricca e nuova semantica - Scheme un bel pò meno all'inizio.

Poi certo a voler essere sinceri Python vince su alcune cose, l'I/O più diretto e semplificato (almeno parlando di usi comuni come ad esempio nel web programming, altrimenti il reader vince) e soprattutto l'indentazione significativa alla ISWIM di Landin che è perfetta per metter ordine in chi comincia. E no, le parentesi del Lisp non le metto tra i cons di Scheme perché è tutta paura iniziale infondata.
Non è paura: il codice lo trovo difficile da leggere con tutte quelle parentesi. Preferisco di gran lunga l'indentazione.
edit: "i cons di Scheme", non me n'ero nemmeno accorto... duh

Dall'interno mi dicevano che erano più di 10 anni che pensavano di sostituire 6.001, ma considerando che l'MIT è d'impostazione piuttosto pragmatica mi suona strano. No non è moda perché Python è sostanza, ma popolarità in un certa misura sicuramente. Il primo corso di programmazione (tanto all'MIT quanto in giro per il mondo) ormai accoglie per la maggior parte persone che non diventeranno informatici a tempo pieno e Python va forte proprio in scienze sociali e statistiche, in biologia in particolare, oltre ad essere buono per introdurre a programmare e infine largamente usato. Da questo punto di vista in effetti mi chiedo perché c'abbiano messo tanto.
Esattamente. Basta scambiare qualche parola con un amico o conoscente che non è un informatico, ma si occupa di altro, e affiora immediatamente l'esigenza di voler scrivere programmi per risolvere i loro problemi, senza essere costretti a imparare linguaggi complessi.

E' per questo che Python ha preso tanto piede e continua a conquistare tanta gente: consente di avvicinarsi in maniera semplice alla programmazione. D'altra parte quella gente nella vita ha deciso di fare altro, e non i programmatori. Scrivere codice è il prezzo da pagare per il loro particolare lavoro, e non vogliono pagare caro...
La questione del nuovo curriculum è un giallo ancora da risolvere, il corso dove usano Python con i robot e i sistemi LTI non ho idea se sia stato modificato o che fine abbia fatto. I posti come l'MIT usano senza troppo nascondersi gli studenti come cavie per sperimentare nuove soluzioni nel corso di certe annate, se non segui l'evoluzione delle cose o non ti fai raccontare da qualcuno com'è andata poi non se ne cava molto in conoscenza.
MIT a parte (e se raccolgo notizie su Python le posto) il pezzo più bello l'hanno fatto a Berkeley, dove anche lì hanno sostituito SICP e Scheme che pure erano insegnati da quasi 30 anni con Python. Ma sono stati come dire un filo più "trasparenti", traducendo quasi letterlamente SICP in Python (vedi http://www-inst.eecs.berkeley.edu/~cs61a/sp12/book/functions.html
e http://composingprograms.com/). Quando me lo postarono non ci credevo quasi. Se conosci l'Abelson e Sussman prova a dare un'occhiata al risultato - per certi versi è interessante, per altri ovviamente risulta un pò forzato. Ovviamente per la famosa parte di "Metalinguistic Abstraction" si implementa un piccolo sottoinsieme di Scheme.
Non sembra forse una di quelle scene dove lo zombie proprio non si decide a morire?!
Non ho avuto tempo per leggere tutto, ma ho dato una rapida occhiata, e mi sembra un lavoro ben fatto. Certamente ha un approccio un po' più funzionale, perché da pythonista noto parecchie mancanze riguardo a costrutti e funzionalità tipici di questo linguaggio.

Comunque lo trovo in ogni caso un buon lavoro, perché il tutto è spiegato in maniera semplice, e specialmente il secondo link, facendo uso di tanti grafici, aiuta ancora ancora di più.

L'Abelson e Sussman non lo conosco, per cui non posso valutare... :stordita:
p.s. mi dicono che in entrambe c'è l'alternativa self-paced che segue SICP disponibile, ma quella MIT non l'ho trovata per la verità.
Posta pure, eventualmente. :)

WarDuck
07-12-2013, 10:47
Più che altro di semantica. E' difficile vedere errori di sintassi a runtime.

Comunque anche Python è un linguaggio con tipizzazione forte. ;)

Un code-path in cui vai raramente a finire e che per puro caso contiene un errore sul nome di una variabile.

Il giorno che ci vai a finire, il tuo programma termina, perché hai messo una "a" invece che un "o".

Esempio banale, è vero anche che esistono i static checker, tuttavia per iniziare preferirei che uno studente usasse un linguaggio che gli dia una certa disciplina sui tipi e sul controllo di tipo.

Sono sostenitore convinto della tipizzazione statica e forte.

Trovo in parte assurdo che si siano fatti progressi verso la gestione della memoria automatica, rinunciando in alcuni casi alla tipizzazione statica.

Dopodiché per rispondere a van9 non condivido affatto l'idea che l'object oriented sia stato un fallimento, anzi.

Che cosa dovevamo fare? Continuare con il solito paradigma procedurale in cui i dati sono una cosa e le operazioni sui dati un'altra cosa? In cui tutti potevano vedere tutto e fare tutto? Incapsulamento, ereditarietà e polimorfismo sono concetti che se ben applicati possono portare ad una gestione del codice di gran lunga migliore.

Ciò che è stato un fallimento secondo me è più che altro come questi concetti vengono insegnati e fatti applicare.

La verità è che per quanto possono sembrare semplici, non lo sono per niente (basta vedere la complessità di alcuni design pattern).

Dopodiché è vero che non tutto è object oriented.

vendettaaaaa
07-12-2013, 10:53
Un code-path in cui vai raramente a finire e che per puro caso contiene un errore sul nome di una variabile.

Il giorno che ci vai a finire, il tuo programma termina, perché hai messo una "a" invece che un "o".

Esempio banale, è vero anche che esistono i static checker, tuttavia per iniziare preferirei che uno studente usasse un linguaggio che gli dia una certa disciplina sui tipi e sul controllo di tipo.

Sono sostenitore convinto della tipizzazione statica e forte.

Trovo in parte assurdo che si siano fatti progressi verso la gestione della memoria automatica, rinunciando in alcuni casi alla tipizzazione statica.

Dopodiché per rispondere a van9 non condivido affatto l'idea che l'object oriented sia stato un fallimento, anzi.

Che cosa dovevamo fare? Continuare con il solito paradigma procedurale in cui i dati sono una cosa e le operazioni sui dati un'altra cosa? In cui tutti potevano vedere tutto e fare tutto? Incapsulamento, ereditarietà e polimorfismo sono concetti che se ben applicati possono portare ad una gestione del codice di gran lunga migliore.

Ciò che è stato un fallimento secondo me è più che altro come questi concetti vengono insegnati e fatti applicare.

La verità è che per quanto possono sembrare semplici, non lo sono per niente (basta vedere la complessità di alcuni design pattern).

Dopodiché è vero che non tutto è object oriented, hello world non lo è, ma hello world è banale e le cose banali non hanno bisogno dell'object oriented.
Per quel poco che ho visto finora, concordo.

cdimauro
07-12-2013, 12:58
Un code-path in cui vai raramente a finire e che per puro caso contiene un errore sul nome di una variabile.

Il giorno che ci vai a finire, il tuo programma termina, perché hai messo una "a" invece che un "o".

Esempio banale,
OK, capito, e concordo. Per quest'ultimo problema c'è da dire che Guido (il creatore di Python) non vuole che certi errori siano sollevati a compile time. Ho già affrontato la questione in passato con lui, in particolare per robe come:
a = 1 / 0
giusto per fare un esempio (ma il concetto si può estendere anche alle variabili "inesistenti ma ugualmente referenziate"), ma è stato inamovibile su questo punto, e in parte ha ragione.

Consideriamo, ad esempio, il caso di un ramo che contenga uno di questi errori, e che fa parte di un'applicazione molto complessa. Supponiamo che sia un server espone dei servizi. Il codice del server viene aggiornato e messo in produzione.
Se l'errore fosse segnalato a compile time, quando il server parte prova a compilare il sorgente, ma rileva l'errore di sintassi, per cui tutto si ferma. Il server rimane giù e non può soddisfare NESSUNA richiesta.

Se invece l'errore è segnalato a runtime, quando quel ramo di codice viene effettivamente eseguito, quando il server parte compilare il sorgente, non rileva alcun errore di sintassi, e parte. Serve le richieste che gli arrivano, ma s'inchioda soltanto quando ne arriva una che va ad eseguire proprio la parte di codice incriminata. Però almeno TUTTE LE ALTRE è in grado di soddisfarle.

Questo per dire che entrambi gli approcci hanno pro e contro. Ovviamente per un linguaggio come Python.
è vero anche che esistono i static checker, tuttavia per iniziare preferirei che uno studente usasse un linguaggio che gli dia una certa disciplina sui tipi e sul controllo di tipo.

Sono sostenitore convinto della tipizzazione statica e forte.
Quindi non era sufficiente la sola tipizzazione forte.

Comunque anche lo pseudocodice, i diagrammi di flusso, e quelli di Nassi-Shneiderman, che per anni sono stati proficuamente usati allo scopo di introdurre alla programmazione, condividono le stesse problematiche di Python.

Fissare il tipo di una variabile è senz'altro utile per scoprire prima, a compile time, alcuni errori, ma per contro richiede una sintassi più verbosa, e maggior impegno per chi sta iniziando a programmare.

E quando hai imparato a programmare, imparerai a testare il tuo codice, magari con strumenti come unit-testing, per evitare tutti questi tipi di errori.

Un passo alla volta... ;)
Trovo in parte assurdo che si siano fatti progressi verso la gestione della memoria automatica, rinunciando in alcuni casi alla tipizzazione statica.
Beh, ci sono linguaggi che sono compilati e hanno una tipizzazione statica, ma debole.

Per risolvere tutti i problemi che hai sollevato serve sia la tipizzazione statica che quella forte. Ma tutto ciò ha un costo nella curva d'apprendimento di uno che si avvicina alla programmazione.
Dopodiché per rispondere a van9 non condivido affatto l'idea che l'object oriented sia stato un fallimento, anzi.

Che cosa dovevamo fare? Continuare con il solito paradigma procedurale in cui i dati sono una cosa e le operazioni sui dati un'altra cosa? In cui tutti potevano vedere tutto e fare tutto? Incapsulamento, ereditarietà e polimorfismo sono concetti che se ben applicati possono portare ad una gestione del codice di gran lunga migliore.

Ciò che è stato un fallimento secondo me è più che altro come questi concetti vengono insegnati e fatti applicare.

La verità è che per quanto possono sembrare semplici, non lo sono per niente (basta vedere la complessità di alcuni design pattern).

Dopodiché è vero che non tutto è object oriented.
E per fortuna! Se ci limitassimo esclusivamente a UN paradigma di programmazione, sai che "spasso" programmare? Se un linguaggio fosse PURAMENTE funzionale, o a oggetti, o strutturato... poveri programmatori, che dovrebbero scrivere codice lungo, più complesso, e di più difficile manutenzione.

E' questo il motivo per cui molti linguaggi funzionali consentono di modificare il valore degli identificatori (il famigerato set di Scheme), come pure i linguaggi a oggetti non richiedono l'invocazione di metodi per costruire una stringa elementare (partendo dai SINGOLI caratteri) oppure un array, ma offrono delle scorciatoie a base di zucchero sintattico.

D'altra parte il paradigma funzionale e quello a oggetti si pongono in posizioni praticamente opposte: i primi che si fondano sull'immutabilità e i secondi su quello di oggetto che incapsula uno stato che viene modificato anche frequentemente.

Anche se è un approccio "sporco" e poco accademico, preferisco utilizzare più paradigmi che mi consentono di arrivare nella maniera più semplice, veloce, e facilmente manutenibile, alla soluzione dei miei problemi. ;)

van9
07-12-2013, 15:19
Francamente Scheme l'ho studiato all'università quasi una ventina d'anni fa, per cui ricordo poco i concetti di frame, environment, e beta-reduction. Magari vedendo qualche pezzo di codice mi tornano alla mente.

Dovresti trovare tutto il modello didattico/introduttivo spiegato in/per python proprio su composingprograms.com , visto che è per lunghi tratti la copia speculare di SICP :-)

Possiamo parlarne certamente, perché per me sono argomenti interessanti.

Comunque quando inizi con Python non hai bisogno di focalizzare l'attenzione su mutabilità, immutabilità, identità, ecc. Parti col concetto di valore, di variabile, di accettazione, di condizione, di cicli, ecc.

Java, invece, ha bisogno di un'infrastruttura più complessa anche per un banale Hello, world.

Non sono d'accordo, perché l'algebra elementare la usi in Python esattamente come hai imparato a scuola: con la notazione infissa. Invece con Scheme devi utilizzare la non comune e più scomoda notazione prefissa (o polacca).

Altra cosa, in Python le funzioni le richiami esattamente come hai imparato a scuola, col nome della funzione, e gli eventuali parametri racchiusi dalle parentesi tonde, separati dalla virgola nel caso ce ne siano più d'uno, mentre in Scheme le parentesi le usi per racchiudere sia la funzione che i suoi parametri, e questi ultimi sono separati dallo spazio anziché dalla virgola.
Ovviamente mi riferisco alla definizione di funzioni generiche, come ad esempio f(x, y) che richiami come f(3, 5). Mentre per le funzioni "tradizionali" con un solo argomento a scuola abbiamo usato la notazione presente in Scheme, come ad esempio sen 3,14.

L'unico vantaggio di Scheme è che le funzioni restituiscono automaticamente il risultato delle operazioni che svolgono, mentre in Python devi utilizzare la keyword return per fare la stessa cosa.
Comunque anche in Python si può fare all'incirca la stessa cosa in alcuni ambiti utilizzando le lambda, ma da pythonista lo trovo una forzatura.

Hai semplificato di molto le cose concentrandoti solo sugli aspetti sintattici "superficiali". "l'algebra elementare la usi in Python esattamente come hai imparato a scuola" è falso, il controesempio banale è "x = x + 1" che è uno statement valido in Python ma è privo di senso nell'algebra elementare. Per incontrare qualcosa di più o meno concettualmente simile di solito si deve arrivare al change of rate nel calcolo differenziale e integrale. In realtà siamo così distanti dal modello matematico astratto (un insieme globale di predicati) che si deve arrivare ad esempio al model checking per avere un modello in cui i predicati variano da stato a stato!
Il rebind (la mutabilità) su cui si fondano Python e gli altri linguaggi (prettamente) imperativi introduce per forza di cose un nuovo modello in aggiunta a quello matematico comunemente noto al neofita da prima (riduzione delle espressioni, astrazione nominale e funzionale e poco altro) su questo non si sfugge. Se uno vuole effettivamente introdurre alla programmazione costruendo *sopra* il modello matematico comunemente noto può usare facilmente e con successo (oltre ad alcuni Scheme come Racket) Standard ML. Esempio banale:

$ rlwrap poly
Poly/ML 5.5.0 Release
> val x = 0 ;
val x = 0: int

> val y = 9 ;
val y = 9: int

> x = x + 1 ;
val it = false: bool

> x = y ;
val it = false: bool

(it è simile al _ in Python ma cattura molte più cose)

Anche le altre questioni che sollevi sono tutte piuttosto di superficie - il punto non dovrebbe essere ricopiare l'uso della notazione matematica ma il modello sottostante. "f(x)" è notazione, "n!" idem, "x^2" pure, simbolo di radice, etc. tutte diverse. Se introduco "f(x)" o "f x", cos'è più importante ai fini della continuità con il modello matematico al quale siamo (eventualmente) interessati: la questione della notazione o il fatto che parliamo di un mapping da un insieme di valori all'altro e senza side-effects? Uno Scheme come Racket me ne da garanzia, Python e gli altri linguaggi imperativi per definizione no.

Questo per precisare cosa s'intende normalmente con "vicino al modello matematico a cui si è abituati". Adesso, io non sono uno di quegli integralisti che vorrebbe un certo modello (didattico e non) iniziale per tutti, anzi penso per esperienza che la cosa migliore sia che ognuno s'informi sulle possibilità ma che poi scelga anche per affinità, seppure qualche volta un po' "alla come viene viene". Quello di cui sono convinto è invece che il modello naturale di linguaggi come Standard ML e quello usato nei libri come "How to Design Programs" di Felleisen e gli altri che citavo abbia dei vantaggi non indifferenti. Se si ha tempo converrebbe legge un paio di quei capitoli perché, come per certi buoni libri che usano Python, sono delle sintesi pesate parola per parola che hanno richiesto anni per essere affinati e nessuno meglio di loro può illustrare il fatto completamente.

Poi sia chiaro, quanto espresso sopra è solo per chiarire la differenza tra due possibili modelli - uno è liberissimo di dire "non m'importa, non sono interessato a introdurre alla programmazione con un linguaggio fondato su principi di sostituzione e rewriting (leggi, ad esempio, lambda calcolo), mi interessa presentare da subito un linguaggio/modello più realistico nei termini della macchina (ad esempio, pointer machine model)". A quel punto la discussione non ha più senso in partenza. Resterebbe da vedere uno che criteri e quali risultati ha preso in considerazione per scartare in partenza certe strade.

Non è paura: il codice lo trovo difficile da leggere con tutte quelle parentesi. Preferisco di gran lunga l'indentazione.

Lo pensavo anche io parecchi anni fa, ma poi come mi dicevano i più esperti mi sono dovuto ricredere. Quando si pratica Lisp per un pò scrivendoci software quotidianamente, le parentesi spariscono: inizi presto a vedere solo op arg1 arg2, define func-name args-name e via dicendo. Per il balancing delle parentesi ci pensa un editor decente qualsiasi.

Esattamente. Basta scambiare qualche parola con un amico o conoscente che non è un informatico, ma si occupa di altro, e affiora immediatamente l'esigenza di voler scrivere programmi per risolvere i loro problemi, senza essere costretti a imparare linguaggi complessi.

E' per questo che Python ha preso tanto piede e continua a conquistare tanta gente: consente di avvicinarsi in maniera semplice alla programmazione. D'altra parte quella gente nella vita ha deciso di fare altro, e non i programmatori. Scrivere codice è il prezzo da pagare per il loro particolare lavoro, e non vogliono pagare caro...

Vero sicuramente è così. L'unica cosa che dispiace è vedere Scheme (e Lisp in generale) scambiati erroneamente per linguaggi complessi anche dai professionisti del settore, quando in realtà è dimostrabile che sono proprio tra i più semplici.

Non ho avuto tempo per leggere tutto, ma ho dato una rapida occhiata, e mi sembra un lavoro ben fatto. Certamente ha un approccio un po' più funzionale, perché da pythonista noto parecchie mancanze riguardo a costrutti e funzionalità tipici di questo linguaggio.

Comunque lo trovo in ogni caso un buon lavoro, perché il tutto è spiegato in maniera semplice, e specialmente il secondo link, facendo uso di tanti grafici, aiuta ancora ancora di più.

Ci hanno speso molte energie si vede e qualcosa è inevitabilmente un filo più offuscata rispetto all'originale, però il vantaggio di non dare da subito la sola visione del "qua ce sta 'a memoria, side-effect! side-effect! fatto!" in Python secondo me vale parecchio. Ad un certo punto tocca rompere l'incantesimo con le classi, ma se è per quello pure in SICP introducendo il necessario modello imperativo. E' tutto un gioco d'equilibri - se riesci a far capire da subito che per risolvere diversi tipi di problemi la cosa migliore è saper passare da un certo modello all'altro e che è utile saper fare avanti e indietro tra questi quando e come si vuole, è fatta. Avrai persone che nella vita potenzialmente potranno applicarsi a lavorare su tutto quanto c'è d'interessante senza soffrire troppo, mentre far tornare indietro sui propri passi, abitudini e modelli è quasi sempre costosissimo (vedi ad esempio t'insegno subito e solo Java -> ogni cosa per te sarà un immenso object-graph mutabile senza se e senza ma -> trasformazioni su grosse quantità di dati? correttezza e validazione? concorrenza? parallelismo? a.i.u.t.o.o.o.o.o.o... anche scrivere software semplice mirato al time-to-market diventa più difficile).

L'Abelson e Sussman non lo conosco, per cui non posso valutare... :stordita:

Posta pure, eventualmente. :)

Prendilo, è forse l'eye-opener per eccellenza, di sicuro per contenuti unito allo stile usato nel presentarli il miglior libro mai scritto nel nostro settore. L'unico che per me si avvicina è Bird & Wadler (più il 1^a ed. che il 2^a), altro capolavoro. Ma lì ho una preferenza personale perché quel libro ha modificato la mia visione dell'informatica tanto da farmi cambiare il cosa e come lo applico quotidianamente, il tipo di software che posso scrivere e con che risultati, i linguaggi, l'approccio al testing, nuovi settori e lavori compresi.

p.s. perdona eventuale poca chiarezza e orrori d'italiano, oggi si lavora e scrivo molto di fretta ma se non lo faccio così finisce che poi non rispondo più ed è peccato.

cdimauro
08-12-2013, 10:22
Dovresti trovare tutto il modello didattico/introduttivo spiegato in/per python proprio su composingprograms.com , visto che è per lunghi tratti la copia speculare di SICP :-)
Non ho notato cose estranee quando ho dato un'occhiata a quei link. Sarà perché Python offre alcuni "strumenti funzionali" oppure per il mio vecchio background di Scheme. :p

In effetti dovrei andare a vedere a cosa corrisponde ogni definizione per fissare nuovamente in mente quei concetti.
Hai semplificato di molto le cose concentrandoti solo sugli aspetti sintattici "superficiali". "l'algebra elementare la usi in Python esattamente come hai imparato a scuola" è falso, il controesempio banale è "x = x + 1" che è uno statement valido in Python ma è privo di senso nell'algebra elementare.
Vero, ma non mi pare che (+ x 1) abbia un senso nell'algebra elementare. E Scheme offre pure il set, che si presta alle stesse critiche di Python, con in più l'uso di una sintassi non naturale per le espressioni.

Purtroppo la scelta del simbolo per l'assegnazione è stata poco felice in Python, e conseguentemente quella dell'uguaglianza. Avrei preferito i classici := e = di pascaliana memoria, anziché ereditare le assurde scelte del C.
Per incontrare qualcosa di più o meno concettualmente simile di solito si deve arrivare al change of rate nel calcolo differenziale e integrale. In realtà siamo così distanti dal modello matematico astratto (un insieme globale di predicati) che si deve arrivare ad esempio al model checking per avere un modello in cui i predicati variano da stato a stato!
Il rebind (la mutabilità) su cui si fondano Python e gli altri linguaggi (prettamente) imperativi introduce per forza di cose un nuovo modello in aggiunta a quello matematico comunemente noto al neofita da prima (riduzione delle espressioni, astrazione nominale e funzionale e poco altro) su questo non si sfugge. Se uno vuole effettivamente introdurre alla programmazione costruendo *sopra* il modello matematico comunemente noto può usare facilmente e con successo (oltre ad alcuni Scheme come Racket) Standard ML. Esempio banale:

$ rlwrap poly
Poly/ML 5.5.0 Release
> val x = 0 ;
val x = 0: int

> val y = 9 ;
val y = 9: int

> x = x + 1 ;
val it = false: bool

> x = y ;
val it = false: bool

(it è simile al _ in Python ma cattura molte più cose)
Hum. No, quello appartiene al Perl. In Python _ è un identificatore come un altro se usato da solo, oppure specifica la visibilità per l'esportazione di identificatori, il mangling per le classi, e i magic method, a seconda di come viene usato.

La shell interattiva usa _ per mantenere il risultato dell'ultima espressione valutata, ma è soltanto in questo caso particolare, per facilitare lo smanettamento dell'utente. Non fa parte del linguaggio di per sé, come in Perl (e forse anche in Ruby? Non ricordo bene).
Anche le altre questioni che sollevi sono tutte piuttosto di superficie - il punto non dovrebbe essere ricopiare l'uso della notazione matematica ma il modello sottostante. "f(x)" è notazione, "n!" idem, "x^2" pure, simbolo di radice, etc. tutte diverse. Se introduco "f(x)" o "f x", cos'è più importante ai fini della continuità con il modello matematico al quale siamo (eventualmente) interessati: la questione della notazione o il fatto che parliamo di un mapping da un insieme di valori all'altro e senza side-effects? Uno Scheme come Racket me ne da garanzia, Python e gli altri linguaggi imperativi per definizione no.
Non mi pare sia così. Per lo meno in Python si può utilizzare un approccio funzionale alla risoluzione dei problemi. E' anche per questo che la conversione del SICP è stata semplice.

A naso la mia impressione è questa. Pensi ci siano casi in cui ciò non sia possibile?
Questo per precisare cosa s'intende normalmente con "vicino al modello matematico a cui si è abituati". Adesso, io non sono uno di quegli integralisti che vorrebbe un certo modello (didattico e non) iniziale per tutti, anzi penso per esperienza che la cosa migliore sia che ognuno s'informi sulle possibilità ma che poi scelga anche per affinità, seppure qualche volta un po' "alla come viene viene". Quello di cui sono convinto è invece che il modello naturale di linguaggi come Standard ML e quello usato nei libri come "How to Design Programs" di Felleisen e gli altri che citavo abbia dei vantaggi non indifferenti. Se si ha tempo converrebbe legge un paio di quei capitoli perché, come per certi buoni libri che usano Python, sono delle sintesi pesate parola per parola che hanno richiesto anni per essere affinati e nessuno meglio di loro può illustrare il fatto completamente.

Poi sia chiaro, quanto espresso sopra è solo per chiarire la differenza tra due possibili modelli - uno è liberissimo di dire "non m'importa, non sono interessato a introdurre alla programmazione con un linguaggio fondato su principi di sostituzione e rewriting (leggi, ad esempio, lambda calcolo), mi interessa presentare da subito un linguaggio/modello più realistico nei termini della macchina (ad esempio, pointer machine model)". A quel punto la discussione non ha più senso in partenza. Resterebbe da vedere uno che criteri e quali risultati ha preso in considerazione per scartare in partenza certe strade.
Credo sia questo il nocciolo della questione. Se vuoi un linguaggio che sposi il modello matematico troverai fra quelli funzionali quello che ti ispira di più, ma non sono convinto che questo possa semplificare la vita a chi inizia.

Ad esempio, quando ho visto mia figlia risolvere i famigerati problemini (o conticini? Boh), seguiva uno schema di individuazione degli elementi "da computare", e i risultati intermedi li andava a scrivere in alcune parti del foglio, fino a ottenere il risultato finale. Da programmatore per me è stato lampante l'associazione "spazio per il risultato" -> "variabile che contiene un valore". Tanti passi eseguiti, con dei calcoli intermedi memorizzati da qualche parte, che portano al risultato finale.

Ma potremmo anche prendere una ricetta della cucina per notare come si faccia uso di contenitori per i composti risultanti, siano essi parziali o totali, e di come tali contenitori vengano sovente "riciclati" (quindi possono contenere sia risultati diversi dello stesso tipo di materiale, sia materiali diversi). Anche qui, tanti passi eseguiti, con composti intermedi conservati in contenitori, che portano al risultato finale.

Penso che il concetto sia chiaro, e non poteva essere altrimenti, visto che siamo di fronte a quello arcinoto (per noi) di algoritmo; che, come sappiamo, non passa necessariamente dal lambda-calcolo...

Personalmente trovo più semplice e naturale il modello imperativo, e non perché questo sia più vicino alla macchina; tutt'altro.
Lo pensavo anche io parecchi anni fa, ma poi come mi dicevano i più esperti mi sono dovuto ricredere. Quando si pratica Lisp per un pò scrivendoci software quotidianamente, le parentesi spariscono: inizi presto a vedere solo op arg1 arg2, define func-name args-name e via dicendo. Per il balancing delle parentesi ci pensa un editor decente qualsiasi.
Ho studiato e lavorato per più di 4 mesi con Scheme all'università (all'epoca il corso di Linguaggi di programmazione era annuale; metà si spendeva per Scheme, e l'altra metà per Prolog), per cui ho avuto abbastanza esperienza. Sarà una questione di gusti, ma non mi sono mai trovato bene.

Ironia della sorte, il mio prof. era un fanatico (nel senso buono! Persona rispettabilissima, molto intelligente, e di gran umanità) di Scheme. Ci siamo rivisti qualche anno fa a un seminario, e ho scoperto che è diventato un pythonista. :D Considerato che era, è, e credo rimarrà sempre un grande matematico, è stata una piacevole sorpresa.

Ma qui, lo ribadisco, penso sia una questione di gusti. :)
Vero sicuramente è così. L'unica cosa che dispiace è vedere Scheme (e Lisp in generale) scambiati erroneamente per linguaggi complessi anche dai professionisti del settore, quando in realtà è dimostrabile che sono proprio tra i più semplici.
Non l'ho mai detto, questo. Rileggendo mi rendo conto che quanto ho scritto è un po' ambiguo e può dare adito a questa interpretazione, per cui preciso.

In quel contesto mi riferivo a C++ e Java principalmente, ma anche C. Sono questi i linguaggi con cui si scontrano ricercatori e scienziati delle altre discipline. I più fortunati posso usare Matlab, per chi ha un background matematico.
Ci hanno speso molte energie si vede e qualcosa è inevitabilmente un filo più offuscata rispetto all'originale, però il vantaggio di non dare da subito la sola visione del "qua ce sta 'a memoria, side-effect! side-effect! fatto!" in Python secondo me vale parecchio. Ad un certo punto tocca rompere l'incantesimo con le classi, ma se è per quello pure in SICP introducendo il necessario modello imperativo.
Sicuro? Io non ho visto classi in quei due link che hai passato. E noto, anzi, un approccio molto funzionale rispetto a quello imperativo.
E' tutto un gioco d'equilibri - se riesci a far capire da subito che per risolvere diversi tipi di problemi la cosa migliore è saper passare da un certo modello all'altro e che è utile saper fare avanti e indietro tra questi quando e come si vuole, è fatta. Avrai persone che nella vita potenzialmente potranno applicarsi a lavorare su tutto quanto c'è d'interessante senza soffrire troppo, mentre far tornare indietro sui propri passi, abitudini e modelli è quasi sempre costosissimo (vedi ad esempio t'insegno subito e solo Java -> ogni cosa per te sarà un immenso object-graph mutabile senza se e senza ma -> trasformazioni su grosse quantità di dati? correttezza e validazione? concorrenza? parallelismo? a.i.u.t.o.o.o.o.o.o... anche scrivere software semplice mirato al time-to-market diventa più difficile).
E' anche per questo che all'università hanno insegnato (almeno a me; non conosco il piano di studi utilizzato adesso) tutti i diversi modelli: imperativo, funzionale, logico, e infine a oggetti. Anche se da giovincello ho storto il naso (fissato com'ero con Pascal e assembly), debbo dire quegli studi che mi sono stati imposti li ho apprezzati molto a posteriori.

Oggi, come ho già detto prima, scelgo l'approccio che più mi piace o mi è comodo rispetto al sotto-problema che devo risolvere. Peccato che non possa usare alcuno strumento di pattern-matching del modello logico, che tanto mi piacque col Prolog.
Prendilo, è forse l'eye-opener per eccellenza, di sicuro per contenuti unito allo stile usato nel presentarli il miglior libro mai scritto nel nostro settore. L'unico che per me si avvicina è Bird & Wadler (più il 1^a ed. che il 2^a), altro capolavoro. Ma lì ho una preferenza personale perché quel libro ha modificato la mia visione dell'informatica tanto da farmi cambiare il cosa e come lo applico quotidianamente, il tipo di software che posso scrivere e con che risultati, i linguaggi, l'approccio al testing, nuovi settori e lavori compresi.
Lo metto nell'elenco di libri di prendere. "Fortunatamente" per andare a lavoro e tornare impiego almeno un paio d'ore in autobus; tempo che sto impiegando per lo più a divorare libri. ;)
p.s. perdona eventuale poca chiarezza e orrori d'italiano, oggi si lavora e scrivo molto di fretta ma se non lo faccio così finisce che poi non rispondo più ed è peccato.
Non ti preoccupare, l'importante è discutere, e visto l'argomento che è interessante anche aspettare giorni non è assolutamente un problema. Il tempo scarseggia per tutti, e ognuno ha diversi impegni (io devo pure imparare il tedesco :stordita: ).
Poi se rileggo i miei messaggi noto una montagna di errori, ma francamente sono troppo pigro per editare e correggerli; tanto il senso si capisce lo stesso. ;)

van9
10-12-2013, 17:26
Non ho notato cose estranee quando ho dato un'occhiata a quei link. Sarà perché Python offre alcuni "strumenti funzionali" oppure per il mio vecchio background di Scheme. :p

Ti dice bene, considerando che è un testo di CS1 sarebbe stato preoccupante il contrario :-) Sorvolando invece sul fatto che ad un mucchio di programmatori con 10+ anni d'esperienza certe cose suonano aliene... Cosa te ne sembra dell'approccio usato? Se conosci anche un solo altro testo che usa Python/Java/altro d'estrazione procedurale simile sarei curioso di darci un'occhiata.

Vero, ma non mi pare che (+ x 1) abbia un senso nell'algebra elementare. E Scheme offre pure il set, che si presta alle stesse critiche di Python, con in più l'uso di una sintassi non naturale per le espressioni.

Purtroppo la scelta del simbolo per l'assegnazione è stata poco felice in Python, e conseguentemente quella dell'uguaglianza. Avrei preferito i classici := e = di pascaliana memoria, anziché ereditare le assurde scelte del C.

Infatti in Scheme è set! con il bang("!") apposta, perché ti vuole ricordare che stai (quasi) sempre per combinare un guaio quando decidi di mutare ;-) set mi pare sia addirittura LISP - mi ricordo bene solo di setq ("quote") in Common Lisp e elisp (che è l'unico lisp che uso attivamente per via di Emacs).

In ogni caso set! non lo trovi in nessuna delle classiche introduzioni alla programmazione che usano Scheme, viene introdotto solo quando c'è l'esigenza di spiegare/implementare qualcosa in modo imperativo (tipicamente alla fine di testi/corsi). In Racket questo è ancora più vero, essendo particolarmente funzionale, mentre altri Scheme lo sono meno pur restando la programmazione funzionale il loro core. E' un pò come con i cuts nel Prolog, è fornito ma non è parte della comune filosofia d'uso, anche se poi in certe situazioni lo usi perché è imprescindibile o comuque l'ideale.

Poi d'accordo che non ti piace il C ma l'uguale che rompe con la matematica c'era già da un bel pezzo prima. Anche lì mi riferivo non al simbolo usato ma al fatto che per uno che ha studiato matematica quella è una equazione senza senso - il concetto di updatable state è il primo classico elemento di rottura con le conoscenze matematiche "della scuola", comunque lo indichi.

Sul (+ x 1) non ho capito. E' x + 1, il valore successivo ad x, come pure lo si trova subito nelle applicazioni numeriche f: x -> y = f(x) = x + 1. Non mi pare ci siano difficoltà, che mi sfugge?

Hum. No, quello appartiene al Perl. In Python _ è un identificatore come un altro se usato da solo, oppure specifica la visibilità per l'esportazione di identificatori, il mangling per le classi, e i magic method, a seconda di come viene usato.

La shell interattiva usa _ per mantenere il risultato dell'ultima espressione valutata, ma è soltanto in questo caso particolare, per facilitare lo smanettamento dell'utente. Non fa parte del linguaggio di per sé, come in Perl (e forse anche in Ruby? Non ricordo bene).

Ricordavo male, giustamente dopo lo statement "x = 0" non c'è nulla da settare in _ nella repl. Decisamente deformazione professionale da sindrome funzionale :-)

Non mi pare sia così. Per lo meno in Python si può utilizzare un approccio funzionale alla risoluzione dei problemi. E' anche per questo che la conversione del SICP è stata semplice.

A naso la mia impressione è questa. Pensi ci siano casi in cui ciò non sia possibile?

Probabilmente la vedi così perché non sei mai stato impiegato come "programmatore funzionale" a tempo pieno, nel senso di usare certi linguaggi, design, tecniche e teorie per risolvere problemi tipici e meno tipici in vari settori. Negli ultimi anni ho lavorato quasi a tempo pieno con OCaml, Haskell e un pò di F# e SML, pur continuando a scrivere un bel pò di C e (correggere/elidere/buttare alle ortiche parecchio) C++ tra gli altri. Risultato: se intravedo una soluzione ti tipo funzionale per un problema, non voglio affrontarla senza il supporto di algebraic data types, higher order nativo, pattern matching, tail recursion, immutabilità dove possibile e possibilità di passare ad uno stile imperativo quando ci calza a pennello e via dicendo. Se non provi e/o ti metti seriamente allo studio delle giuste fonti e delle codebase disponibili rilevanti è difficile che prenderai per buono quanto ti dicono altri, provato in prima persona un buon 12 anni fa oramai. In questo senso Python permette molto poco semplicemente perché non è nato per disegnare soluzioni e programmare in quel modo, sono di contorno e va bene così alla fine. La presenza di first-class functions è quella che ha permesso molto nella conversione in effetti, se c'erano anche le lambda non castrate/semi inutili sarebbe stato ancora meglio e se la tail rec etc.
Allo stesso tempo ho visto un sacco di ottimi risultati nella didattica scegliendo all'inizio un approccio più possibile logico-deduttivo che operazionale. Penso che insegnare da subito le idee dell'informatica con un certo tipo di supporto, e poi subito dopo passare ad insegnare la programmazione oo/procedurale che sia, poi la macchina con il C etc. sia più formativo e da subito spazio nel miglior modo possibile alla concetto più importante su cui si deve battere senza sosta: l'astrazione.

Tornando un attimo a Python mi viene pure da dire che, supporto funzionale incompleto a parte, quegli strumenti non sono mai stati accettati come idiomatici e preferibili ne' da Van Rossum stesso ne' dalla media dei pythonisti. Puoi definire function nelle function che come detto sono una santa cosa all'atto pratico, ma a memoria nelle codebase maggiori (tipo Django) o comunque interessanti non ricordo di averle mai viste usate dove per me erano l'ideale e lo stesso vale per altro. Quello che voglio dire in pratica è che è vero che puoi imparare cose mirabolanti se studi lo stile di Peter Norvig quando scrive in Python, ma quel codice piacerà e sarà accettato come chiaro, succinto e "python idiomatico" solo da una minoranza - e di questo ne ho avuto riprova visto che quando scrivevo abbastanza in Python il mio stile era simile perché lispista anche io (e soprattutto anche perché da lui rubavo diverse finezze ovviamente). Il linguaggio è multi-paradigmatico, la sua user base molto meno - non a caso quanto spiegato nel bel tutorial di Kuchling http://docs.python.org/3.3/howto/functional.html a me pare se lo siano filato storicamente in ben pochi pythonisti (ma i tempi potrebbero essere cambiati e magari mi sbaglio). All'atto pratico lo trovo un ulteriore intoppo.

Credo sia questo il nocciolo della questione. Se vuoi un linguaggio che sposi il modello matematico troverai fra quelli funzionali quello che ti ispira di più, ma non sono convinto che questo possa semplificare la vita a chi inizia.

Ad esempio, quando ho visto mia figlia risolvere i famigerati problemini (o conticini? Boh), seguiva uno schema di individuazione degli elementi "da computare", e i risultati intermedi li andava a scrivere in alcune parti del foglio, fino a ottenere il risultato finale. Da programmatore per me è stato lampante l'associazione "spazio per il risultato" -> "variabile che contiene un valore". Tanti passi eseguiti, con dei calcoli intermedi memorizzati da qualche parte, che portano al risultato finale.

Ma potremmo anche prendere una ricetta della cucina per notare come si faccia uso di contenitori per i composti risultanti, siano essi parziali o totali, e di come tali contenitori vengano sovente "riciclati" (quindi possono contenere sia risultati diversi dello stesso tipo di materiale, sia materiali diversi). Anche qui, tanti passi eseguiti, con composti intermedi conservati in contenitori, che portano al risultato finale.

Penso che il concetto sia chiaro, e non poteva essere altrimenti, visto che siamo di fronte a quello arcinoto (per noi) di algoritmo; che, come sappiamo, non passa necessariamente dal lambda-calcolo...

Personalmente trovo più semplice e naturale il modello imperativo, e non perché questo sia più vicino alla macchina; tutt'altro.

Capito. Vedi SICP come esempio, il primo algoritmo "serio" che introduce è il Newton-Raphson qui http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1.7l , compresa tutta la loro spiegazione su imperative/declarative knowledge. Ad un certo punto trovi la tabella con "Guess Quotient Average" che rappresenta i passi di cui dicevi grossomodo nei tuoi esempi. Per disegnare l'algoritmo si mettono li e individuano la procedura centrale di alto livello che risolve il problema e poi pensano ai dettagli (sotto forma di altre procedure accessorie). Uno che legge quel capitolo dopo probabilmente riscriverà l'algoritmo in una cosa del tipo


; ma perché non c'è emacs come editor nei msg sul forum??!
(define (sqrt x)
(define eps 0.001)
(define guess (/ x 2.0))
(define (sqrt-iter guess)
(if (< (abs (- (sqr guess) x)) eps)
guess
(sqrt-iter (- guess (/ (- (sqr guess) x) (* 2 guess))))))
(sqrt-iter guess))


mentre dall'altra parte un neofita che impara da un testo/corso "tradizionale", in stile più tipicamente imperativo/pythonico, scriverà una cosa del tipo:


def sqrt(x):
eps = 0.001
guess = x / 2.
while abs(guess**2 - x) >= eps:
guess = guess - ((guess ** 2 - x) / (guess * 2))
return guess


(Codice non testato scritto al volo sul forum per mancanza di tempo. Occhio alle parentesi e agli stati!)

Lasciando da parte il fatto che usano tutte quelle piccole funzioni per introdurre vari concetti e che poi a fondo pagina "riassumono" il tutto in un'unica procedura per introdurre il lexical scoping, l'idea del design ricorsivo di fondo è quella che conta di più perché nasconde i dettagli operazionali (lo stato, il vicino alla "macchina" di cui dicevo) e ti fa concentrare sul problema. Io trovo sia una pacchia poter leggerla letteralmente come "se guess è abbastanza buono, guess è la risposta; altrimenti migliorala".
Molti altri invece direbbero che, partendo dalla "tabella" uno deve quindi individuare lo stato di partenza, stabilire se serve un loop e una condizione che ci dica se fare o meno l'update dello stato ad ogni passo, controllare mentalmente che la condizione di uscita dal loop stesso sia corretta, etc. A me questa strada è sempre sembrata quella che oltre a farti pensare al problema, ti costringe anche a pensare a certi dettagli meccanici di cui vorrei non tenere conto. In particolare se uno può sfruttare l'idea ricorsiva e risparmiarsi l'update di guess (che poi è esattamente il punto dove tutti quelli che imparano a programmare si perdono - e non solo loro, a giudicare dagli errori nel software in generale...) è meglio, io dico. E aggiungo che uno potrebbe contestare che a perdersi lo fanno anche nella ricorsione - ma si sbaglia! La maggior parte delle volte, la ricorsione è insegnata in coda al capitolo sulle funzioni/procedure/metodi (se non in fondo al libro) e nel modo più sbagliato possibile ovvero osservando quello che accade allo stack... :_( Ottimo modo per ridurre una delle idee centrali, più utili e affascinanti dell'informatica ad un esercizio da chiedere all'esame (ma nemmeno alla fine). Dovrebbe essere piuttosto insegnata come metodo di risoluzione dei problemi come fanno con successo in SICP (come pure nel divertente e utile The Little Schemer).
Questo per sintetizzare al minimo il nocciolone della questione per me (per non parlare di quant'è difficile scrivere di certe idee a prescindere dal quarto d'ora che si ha a disposizione poi...).

Ho studiato e lavorato per più di 4 mesi con Scheme all'università (all'epoca il corso di Linguaggi di programmazione era annuale; metà si spendeva per Scheme, e l'altra metà per Prolog), per cui ho avuto abbastanza esperienza. Sarà una questione di gusti, ma non mi sono mai trovato bene.

Ironia della sorte, il mio prof. era un fanatico (nel senso buono! Persona rispettabilissima, molto intelligente, e di gran umanità) di Scheme. Ci siamo rivisti qualche anno fa a un seminario, e ho scoperto che è diventato un pythonista. :D Considerato che era, è, e credo rimarrà sempre un grande matematico, è stata una piacevole sorpresa.

Ma qui, lo ribadisco, penso sia una questione di gusti. :)

Ah figurati. Basta pensare che D. J. Bernstein, chiaramente uno dei migliori programmatori della storia dell'informatica, ha scritto e scrive in C software bellissimo esposto da anni agli attacchi del mondo e senza bugs. E' sempre una questione individuale, per me.

Non l'ho mai detto, questo. Rileggendo mi rendo conto che quanto ho scritto è un po' ambiguo e può dare adito a questa interpretazione, per cui preciso.

In quel contesto mi riferivo a C++ e Java principalmente, ma anche C. Sono questi i linguaggi con cui si scontrano ricercatori e scienziati delle altre discipline. I più fortunati posso usare Matlab, per chi ha un background matematico.

Dipende sempre dai settori, tra tutti quelli dove sono stato io fin'ora puoi ridurre drasticamente la presenza di Java, moltissimo Matlab e anche Octave (finanziario, soprattutto), tantissimo C, tanto C++ e oramai anche tanto Python, R, SPSS, parecchio Perl, un pò di Lisp (oncologia, medicale, planning, ...) etc. Capitolo a parte i ricercatori nel software e in particolare nei linguaggi di programmazione, lì da padrone la fanno Scheme, SML, Haskell e C, anche se adesso si pubblica qualcosina anche in altro.

Sicuro? Io non ho visto classi in quei due link che hai passato. E noto, anzi, un approccio molto funzionale rispetto a quello imperativo.

Mi hai fatto venire il dubbio. Si, quello era solo il primo capitolo :-) le classi le trovi già al secondo cap. di composingprograms.

E' anche per questo che all'università hanno insegnato (almeno a me; non conosco il piano di studi utilizzato adesso) tutti i diversi modelli: imperativo, funzionale, logico, e infine a oggetti. Anche se da giovincello ho storto il naso (fissato com'ero con Pascal e assembly), debbo dire quegli studi che mi sono stati imposti li ho apprezzati molto a posteriori.

Oggi, come ho già detto prima, scelgo l'approccio che più mi piace o mi è comodo rispetto al sotto-problema che devo risolvere. Peccato che non possa usare alcuno strumento di pattern-matching del modello logico, che tanto mi piacque col Prolog.

Non dirlo a me sarei perso senza il pattern-matching negli MLs.
Però mmm indentazione significativa, pattern-matching... dovresti provare Haskell :-) estrapolando l'idea ricorsiva del Newton sopra viene


sqrt_iter guess =
if good_enough guess then guess
else sqrt_iter (improve guess)


Lo metto nell'elenco di libri di prendere. "Fortunatamente" per andare a lavoro e tornare impiego almeno un paio d'ore in autobus; tempo che sto impiegando per lo più a divorare libri. ;)

E mi sono ricordato puoi pure giocare con http://docs.hylang.org/en/latest/ che mi sembrava divertentissimo ma non l'ho più seguito.

Non ti preoccupare, l'importante è discutere, e visto l'argomento che è interessante anche aspettare giorni non è assolutamente un problema. Il tempo scarseggia per tutti, e ognuno ha diversi impegni (io devo pure imparare il tedesco :stordita: ).
Poi se rileggo i miei messaggi noto una montagna di errori, ma francamente sono troppo pigro per editare e correggerli; tanto il senso si capisce lo stesso. ;)

T'ha detto bene (ci sono passato anche io), pensa se era olandese! Io da quando ho trovato lavoro da remoto (dall'Italia, tra l'altro) pensavo che avrei recuperato parecchio tempo e invece sono rientrato nel vortice dello sport e della vita all'aria aperta mentre dovrei fare tante di quelle cose che non siano correre/nuotare o pensare davanti al computer... Vabbè. Se sei nel sud della Germania (Friburgo, Monaco, o forse sei in Svizzera?) se ci passo nelle feste tra amici ed ex-colleghi ti scrivo sul forum.

cdimauro
14-12-2013, 21:46
Ti dice bene, considerando che è un testo di CS1 sarebbe stato preoccupante il contrario :-) Sorvolando invece sul fatto che ad un mucchio di programmatori con 10+ anni d'esperienza certe cose suonano aliene... Cosa te ne sembra dell'approccio usato? Se conosci anche un solo altro testo che usa Python/Java/altro d'estrazione procedurale simile sarei curioso di darci un'occhiata.
Non saprei cosa consigliarti. Ho letto pochi libri. Per lo più m'interessano tutorial veloci o reference manual.
Infatti in Scheme è set! con il bang("!") apposta, perché ti vuole ricordare che stai (quasi) sempre per combinare un guaio quando decidi di mutare ;-) set mi pare sia addirittura LISP - mi ricordo bene solo di setq ("quote") in Common Lisp e elisp (che è l'unico lisp che uso attivamente per via di Emacs).

In ogni caso set! non lo trovi in nessuna delle classiche introduzioni alla programmazione che usano Scheme, viene introdotto solo quando c'è l'esigenza di spiegare/implementare qualcosa in modo imperativo (tipicamente alla fine di testi/corsi). In Racket questo è ancora più vero, essendo particolarmente funzionale, mentre altri Scheme lo sono meno pur restando la programmazione funzionale il loro core. E' un pò come con i cuts nel Prolog, è fornito ma non è parte della comune filosofia d'uso, anche se poi in certe situazioni lo usi perché è imprescindibile o comuque l'ideale.
C'è da dire che usando i define e l'elenco di espressioni da calcolare, bene o male con Scheme et similia si rispecchia un comportamento imperativo, con l'eccezione che il risultato dell'ultima espressione calcolata viene restituito.
Poi d'accordo che non ti piace il C ma l'uguale che rompe con la matematica c'era già da un bel pezzo prima.
Beh, sì, ho piacevoli ricordi legati al BASIC. :p
Anche lì mi riferivo non al simbolo usato ma al fatto che per uno che ha studiato matematica quella è una equazione senza senso - il concetto di updatable state è il primo classico elemento di rottura con le conoscenze matematiche "della scuola", comunque lo indichi.
Sì, questo è chiaro. Ma alle equazioni devi esserci arrivato; a volte si comincia a programmare anche prima di averle affrontate, e ciò che sai fare è... eseguire una sequenza di azioni/operazioni per arrivare al risultato finale.
Sul (+ x 1) non ho capito. E' x + 1, il valore successivo ad x, come pure lo si trova subito nelle applicazioni numeriche f: x -> y = f(x) = x + 1. Non mi pare ci siano difficoltà, che mi sfugge?
Che non si scrive f(x) = + x 1 , ma f(x) = x + 1 :)

Tra l'altro è interessante notare come assomiglia a un'assegnazione:
f = lambda x: x + 1
:fiufiu: OK, qui ho voluto forzare un po' la mano. :D Quant'è brutto a vedersi... :stordita:
Probabilmente la vedi così perché non sei mai stato impiegato come "programmatore funzionale" a tempo pieno, nel senso di usare certi linguaggi, design, tecniche e teorie per risolvere problemi tipici e meno tipici in vari settori. Negli ultimi anni ho lavorato quasi a tempo pieno con OCaml, Haskell e un pò di F# e SML, pur continuando a scrivere un bel pò di C e (correggere/elidere/buttare alle ortiche parecchio) C++ tra gli altri. Risultato: se intravedo una soluzione ti tipo funzionale per un problema, non voglio affrontarla senza il supporto di algebraic data types, higher order nativo, pattern matching, tail recursion, immutabilità dove possibile e possibilità di passare ad uno stile imperativo quando ci calza a pennello e via dicendo. Se non provi e/o ti metti seriamente allo studio delle giuste fonti e delle codebase disponibili rilevanti è difficile che prenderai per buono quanto ti dicono altri, provato in prima persona un buon 12 anni fa oramai.
E' chiaro che lo stile cambia a seconda del tipo di lavoro che stai facendo, perché rispolveri vecchi concetti o ne apprendi di nuovi, e sfrutti tutto per modellare i problemi che stai affrontando.

Ma in tutta onestà e col poco tempo a disposizione, la prima cosa che m'interessa è arrivare alla soluzione quanto prima. Ovviamente questo non significa che debba produrre porcate nel codice; anzi, sono abbastanza maniacale nello stile e in come si deve presentare ed essere letto.
In questo senso Python permette molto poco semplicemente perché non è nato per disegnare soluzioni e programmare in quel modo, sono di contorno e va bene così alla fine. La presenza di first-class functions è quella che ha permesso molto nella conversione in effetti, se c'erano anche le lambda non castrate/semi inutili sarebbe stato ancora meglio e se la tail rec etc.
Le lambda sono volutamente castrate perché Guido le ha concesse malvolentieri; anzi, mi sembra che volesse eliminarle da Python 3, o comunque culla l'idea di farle fuori perché le ritiene un'inutile duplicazione della classica def (e questo è sicuramente vero, soprattutto tenendo conto della filosofia/zen di Python) e un peggioramento della leggibilità dovuta al loro utilizzo (qui è una questione di gusti, ma l'idea di definire un'apposita funzione con un nome anziché costruire al volo un'anonima lambda ha i suoi perché, anche se produce codice più lungo/verboso ed è il motivo per cui sono state introdotte le lambda).

Per la tail recursion, Guido ha esposto chiaramente il suo pensiero in un paio di post: Tail Recursion Elimination (http://neopythonic.blogspot.de/2009/04/tail-recursion-elimination.html) e Final Words on Tail Calls (http://neopythonic.blogspot.de/2009/04/final-words-on-tail-calls.html).
Allo stesso tempo ho visto un sacco di ottimi risultati nella didattica scegliendo all'inizio un approccio più possibile logico-deduttivo che operazionale. Penso che insegnare da subito le idee dell'informatica con un certo tipo di supporto, e poi subito dopo passare ad insegnare la programmazione oo/procedurale che sia, poi la macchina con il C etc. sia più formativo e da subito spazio nel miglior modo possibile alla concetto più importante su cui si deve battere senza sosta: l'astrazione.
Sei sicuro che la programmazione procedurale e quella a oggetti (classi) non siano ugualmente importanti per lo sviluppo dell'astrazione?
Tornando un attimo a Python mi viene pure da dire che, supporto funzionale incompleto a parte, quegli strumenti non sono mai stati accettati come idiomatici e preferibili ne' da Van Rossum stesso ne' dalla media dei pythonisti. Puoi definire function nelle function che come detto sono una santa cosa all'atto pratico, ma a memoria nelle codebase maggiori (tipo Django) o comunque interessanti non ricordo di averle mai viste usate dove per me erano l'ideale e lo stesso vale per altro. Quello che voglio dire in pratica è che è vero che puoi imparare cose mirabolanti se studi lo stile di Peter Norvig quando scrive in Python, ma quel codice piacerà e sarà accettato come chiaro, succinto e "python idiomatico" solo da una minoranza - e di questo ne ho avuto riprova visto che quando scrivevo abbastanza in Python il mio stile era simile perché lispista anche io (e soprattutto anche perché da lui rubavo diverse finezze ovviamente). Il linguaggio è multi-paradigmatico, la sua user base molto meno - non a caso quanto spiegato nel bel tutorial di Kuchling http://docs.python.org/3.3/howto/functional.html a me pare se lo siano filato storicamente in ben pochi pythonisti (ma i tempi potrebbero essere cambiati e magari mi sbaglio). All'atto pratico lo trovo un ulteriore intoppo.
Vuol dire che sono uno dei pochi che se l'è spolpato quel link. :D Devo ammettere che è difficile utilizzare tutto, perché ci sono tanti, forse anche troppi strumenti per lavorare funzionalmente.

In ogni caso e come hai detto tu, è una questione individuale. A me non importa se la media dei pythonisti lo usi poco funzionalmente, ma trovo un bene che il linguaggio metta a disposizione tutta quella roba.
Capito. Vedi SICP come esempio, il primo algoritmo "serio" che introduce è il Newton-Raphson qui http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-10.html#%_sec_1.1.7l , compresa tutta la loro spiegazione su imperative/declarative knowledge. Ad un certo punto trovi la tabella con "Guess Quotient Average" che rappresenta i passi di cui dicevi grossomodo nei tuoi esempi. Per disegnare l'algoritmo si mettono li e individuano la procedura centrale di alto livello che risolve il problema e poi pensano ai dettagli (sotto forma di altre procedure accessorie). Uno che legge quel capitolo dopo probabilmente riscriverà l'algoritmo in una cosa del tipo


; ma perché non c'è emacs come editor nei msg sul forum??!
(define (sqrt x)
(define eps 0.001)
(define guess (/ x 2.0))
(define (sqrt-iter guess)
(if (< (abs (- (sqr guess) x)) eps)
guess
(sqrt-iter (- guess (/ (- (sqr guess) x) (* 2 guess))))))
(sqrt-iter guess))


mentre dall'altra parte un neofita che impara da un testo/corso "tradizionale", in stile più tipicamente imperativo/pythonico, scriverà una cosa del tipo:


def sqrt(x):
eps = 0.001
guess = x / 2.
while abs(guess**2 - x) >= eps:
guess = guess - ((guess ** 2 - x) / (guess * 2))
return guess


(Codice non testato scritto al volo sul forum per mancanza di tempo. Occhio alle parentesi e agli stati!)
Sì, è all'incirca quello che un utente che lavora "non funzionalmente" scriverebbe.
Lasciando da parte il fatto che usano tutte quelle piccole funzioni per introdurre vari concetti e che poi a fondo pagina "riassumono" il tutto in un'unica procedura per introdurre il lexical scoping, l'idea del design ricorsivo di fondo è quella che conta di più perché nasconde i dettagli operazionali (lo stato, il vicino alla "macchina" di cui dicevo) e ti fa concentrare sul problema. Io trovo sia una pacchia poter leggerla letteralmente come "se guess è abbastanza buono, guess è la risposta; altrimenti migliorala".
Molti altri invece direbbero che, partendo dalla "tabella" uno deve quindi individuare lo stato di partenza, stabilire se serve un loop e una condizione che ci dica se fare o meno l'update dello stato ad ogni passo, controllare mentalmente che la condizione di uscita dal loop stesso sia corretta, etc. A me questa strada è sempre sembrata quella che oltre a farti pensare al problema, ti costringe anche a pensare a certi dettagli meccanici di cui vorrei non tenere conto. In particolare se uno può sfruttare l'idea ricorsiva e risparmiarsi l'update di guess (che poi è esattamente il punto dove tutti quelli che imparano a programmare si perdono - e non solo loro, a giudicare dagli errori nel software in generale...) è meglio, io dico. E aggiungo che uno potrebbe contestare che a perdersi lo fanno anche nella ricorsione - ma si sbaglia! La maggior parte delle volte, la ricorsione è insegnata in coda al capitolo sulle funzioni/procedure/metodi (se non in fondo al libro) e nel modo più sbagliato possibile ovvero osservando quello che accade allo stack... :_( Ottimo modo per ridurre una delle idee centrali, più utili e affascinanti dell'informatica ad un esercizio da chiedere all'esame (ma nemmeno alla fine). Dovrebbe essere piuttosto insegnata come metodo di risoluzione dei problemi come fanno con successo in SICP (come pure nel divertente e utile The Little Schemer).
Questo per sintetizzare al minimo il nocciolone della questione per me (per non parlare di quant'è difficile scrivere di certe idee a prescindere dal quarto d'ora che si ha a disposizione poi...).
Ti capisco e concordo che sviluppare il concetto di ricorsività è senz'altro qualcosa su cui i programmatori hanno bisogno di spendere tempo per acquisire e affinare la mentalità.

Se, però, confrontiamo le due soluzioni che hai proposto, quella in Scheme la trovo decisamente imperativa, con soltanto la definizione di sqrt_iter che risulta funzionale. Alla fine hai bisogno di eseguire passo passo delle istruzioni, e dove i define simulano l'assegnamento di un valore, come dicevo prima. Per essere chiari, non vedo utilizzate soltanto chiamate a funzione per risolvere il problema; eppure è fattibilissimo in questo senso, ma sarebbe più complicato e meno leggibile.

Ciò che penso è che l'approccio utilizzato per Scheme sia una sorta di compromesso che fa uso del concetto di esecuzione di una sequenza di passi, che è utile per non esasperare al limite l'approccio funzionale. E' un po' come i linguaggi a oggetti che non ti obbligano al message passing per qualunque cosa, ma mettono a disposizione un po' di zucchero sintattico per evitare che a un certo punto ti metti una corda al collo.

D'altra parte l'informatica è, in ultima istanza, una scienza molto pratica. ;)
Non dirlo a me sarei perso senza il pattern-matching negli MLs.
Però mmm indentazione significativa, pattern-matching... dovresti provare Haskell :-) estrapolando l'idea ricorsiva del Newton sopra viene


sqrt_iter guess =
if good_enough guess then guess
else sqrt_iter (improve guess)

Gli ho già dato un'occhiata un paio di volte, ma non riesco proprio a farmelo digerire...
E mi sono ricordato puoi pure giocare con http://docs.hylang.org/en/latest/ che mi sembrava divertentissimo ma non l'ho più seguito.
In effetti ho visto che è una bella trovata per chi vuole sperimentare con Lisp. Grazie per il link. :)
T'ha detto bene (ci sono passato anche io), pensa se era olandese! Io da quando ho trovato lavoro da remoto (dall'Italia, tra l'altro) pensavo che avrei recuperato parecchio tempo e invece sono rientrato nel vortice dello sport e della vita all'aria aperta mentre dovrei fare tante di quelle cose che non siano correre/nuotare o pensare davanti al computer... Vabbè. Se sei nel sud della Germania (Friburgo, Monaco, o forse sei in Svizzera?) se ci passo nelle feste tra amici ed ex-colleghi ti scrivo sul forum.
Mi trovo proprio nel sud della Germania, nella zona di Ulm (Ulma in italiano), all'incirca a metà fra Stoccarda e Monaco. Per cui se ti capita, fammi sapere che andiamo a farci una birra (io una Colaweizen; è il massimo che mi concedo sul fronte alcolico :p).