
Filosofia guida
1. Linguaggi di programmazione per gli esseri umani
I linguaggi di programmazione sono il modo in cui gli esseri umani comunicano con i computer. Un computer parlerà felicemente con qualsiasi linguaggio che non sia ambiguo. Il motivo per cui abbiamo linguaggi di alto livello è che gli esseri umani non sono in grado di gestire il linguaggio macchina. Lo scopo dei linguaggi di programmazione è impedire che i nostri poveri e fragili cervelli umani vengano sopraffatti da troppi dettagli.
Gli architetti sanno che alcuni problemi di progettazione sono più banali di altri. Uno dei problemi di progettazione più chiari e astratti è la progettazione di ponti. In questo caso, il compito è coprire una determinata distanza con il minor materiale possibile. All'estremo opposto dello spettro c'è la progettazione di sedie. I progettisti di sedie devono dedicare il loro tempo a pensare ai glutei delle persone.
Lo sviluppo del software presenta una distinzione simile. Progettare algoritmi per l'instradamento dei dati attraverso una rete è un problema astratto e piacevole, come progettare ponti. Mentre progettare linguaggi di programmazione è come progettare sedie: bisogna fare i conti con le debolezze umane.
Per la maggior parte di noi è difficile da accettare. Progettare sistemi matematici eleganti sembra molto più allettante per la maggior parte di noi che assecondare le debolezze umane. Il ruolo dell'eleganza matematica è che un certo grado di eleganza rende i programmi più facili da capire. Ma l'eleganza non è tutto.
E quando dico che i linguaggi dovrebbero essere progettati per adattarsi alle debolezze umane, non intendo dire che dovrebbero essere progettati per programmatori scarsi. Anzi, si dovrebbe progettare software per i migliori programmatori, ma anche i migliori programmatori hanno i loro limiti. Non credo che a nessuno piacerebbe programmare in un linguaggio in cui tutte le variabili fossero rappresentate dalla lettera "x" con indici interi.
2. Progetta per te stesso e per i tuoi amici
Se si considera la storia dei linguaggi di programmazione, la maggior parte dei linguaggi migliori sono stati progettati per essere utilizzati dai loro autori, mentre la maggior parte dei linguaggi peggiori sono stati progettati per altre persone.
Quando i linguaggi vengono progettati per altre persone, si tratta sempre di un gruppo specifico di persone: persone che non sono intelligenti quanto i progettisti del linguaggio. Quindi si ottiene un linguaggio che ti parla dall'alto in basso. Cobol è l'esempio più estremo, ma la maggior parte dei linguaggi ha questo spirito.
Non ha nulla a che fare con l'alto livello del linguaggio. Il C è piuttosto di basso livello, ma è stato creato per essere utilizzato dai suoi autori, ed è per questo che gli hacker lo adorano.
La tesi a favore della progettazione di linguaggi per programmatori incompetenti è che ci sono più programmatori incompetenti che bravi. Questo potrebbe essere vero. Ma questo piccolo numero di bravi programmatori scrive una quantità di software sproporzionatamente maggiore.
Mi interessa la domanda: come si crea un linguaggio che piaccia ai migliori hacker? Credo che questa domanda sia identica a "come si crea un buon linguaggio di programmazione?", ma anche se non lo fosse, è comunque una domanda interessante.
3. Dare al programmatore il maggior controllo possibile
Molti linguaggi (soprattutto quelli progettati per altre persone) si comportano come delle tate: cercano di impedirti di fare cose che ritengono non utili. Io la penso diversamente: dai al programmatore tutto il controllo possibile.
Quando ho imparato il Lisp per la prima volta, ciò che mi è piaciuto di più è stato il fatto che parlassimo da pari a pari. Negli altri linguaggi che avevo imparato fino a quel momento, c'era il linguaggio e c'era il mio programma in quel linguaggio, ed erano piuttosto separati. Ma in Lisp, le funzioni e le macro che scrivevo erano le stesse in cui era scritto il linguaggio stesso. Avrei potuto riscrivere il linguaggio stesso se avessi voluto. Aveva lo stesso fascino del software open source.
4. La brevità è sorella dell'arguzia
La brevità è sottovalutata e persino disprezzata. Ma se guardate nel cuore degli hacker, vedrete che la amano. Quante volte avete sentito gli hacker parlare con affetto di come, ad esempio, in APL possano fare cose incredibili con solo un paio di righe di codice? Credo che le persone davvero intelligenti amino prestare attenzione a questo aspetto.
Penso che quasi tutto ciò che rende i programmi più brevi sia positivo. Dovrebbero esserci molte funzioni di libreria, tutto ciò che può essere implicito dovrebbe esserlo; la sintassi dovrebbe essere più concisa; persino i nomi delle entità dovrebbero essere brevi.
E non sono solo i programmi a dover essere brevi. Anche i manuali devono esserlo. Buona parte dei manuali è piena di spiegazioni, avvertenze, avvertenze e casi speciali. Se è necessario accorciare un manuale, l'opzione migliore è correggere il linguaggio che richiede così tante spiegazioni.
5. Riconoscere cosa è l'hacking
Molti vorrebbero che l'hacking fosse matematica, o almeno qualcosa di simile alla scienza. Credo che l'hacking sia più simile all'architettura. L'architettura è legata alla fisica, nel senso che un architetto deve progettare un edificio che non crolli, ma il vero obiettivo di un architetto è creare un edificio grandioso, non fare scoperte sulla statica.
Ciò che gli hacker amano è scrivere ottimi programmi. E penso che, almeno nella nostra mente, dovremmo ricordare che scrivere ottimi programmi è fantastico, anche quando quel lavoro non si traduce facilmente nel consueto valore intellettuale degli articoli accademici. Progettare un linguaggio che i programmatori amino è altrettanto importante dal punto di vista intellettuale quanto progettarne uno pessimo che incarni un'idea su cui si possa pubblicare un articolo.
Problemi aperti
1. Come organizzare le grandi biblioteche?
Le librerie stanno diventando una parte importante dei linguaggi di programmazione. Stanno diventando così grandi che può essere pericoloso. Se ci vuole più tempo per trovare una funzione in una libreria che faccia ciò che si desidera rispetto a scriverla da soli, allora tutto quel codice non fa altro che appesantire il manuale. (I manuali di Symbolics ne erano un esempio.) Quindi dobbiamo risolvere il problema di come sono organizzate le librerie. Idealmente, progettarle in modo che il programmatore possa indovinare quale funzione di libreria funzionerà.
2. Le persone hanno davvero paura della sintassi dei prefissi?
Questo è un problema aperto, nel senso che ci penso da anni e ancora non conosco la risposta. La sintassi del prefisso mi sembra del tutto naturale, tranne forse per il suo utilizzo in matematica. Ma potrebbe essere che gran parte dell'impopolarità del Lisp sia dovuta semplicemente a una sintassi non familiare... Se si debba fare qualcosa al riguardo, se è vero, è un'altra questione.
3. Di cosa hai bisogno per il software del server?
Penso che la maggior parte delle applicazioni che verranno scritte nei prossimi vent'anni saranno applicazioni web, il che significa che i programmi saranno su un server e comunicheranno con l'utente tramite un browser web. E per scrivere queste applicazioni, abbiamo bisogno di cose nuove.
Una di queste è supportare un nuovo modo di rilasciare le applicazioni server. Invece di una o due grandi release all'anno, come il software desktop, il software server verrà rilasciato con una serie di piccole modifiche. Si potrebbero avere cinque o dieci release al giorno. E tutti avranno sempre la versione più recente.
Sai come progettare un software che sia manutenibile? Il software server dovrebbe essere progettato per essere modificabile. Dovresti essere in grado di modificarlo facilmente, o almeno sapere cosa si intende per piccola modifica e cosa per modifica sostanziale.
Un'altra cosa che può essere utile nel software server è, improvvisamente, la continuità di distribuzione. In un'applicazione web, potresti usare qualcosa come per ottenere l'effetto delle routine in un mondo senza stato di sessioni web. Potrebbe valere la pena garantire la continuità di fornitura, se la funzionalità non è troppo costosa.
4. Quali nuove astrazioni restano da scoprire?
Non so quanto sia ragionevole questa speranza, ma personalmente mi piacerebbe davvero scoprire una nuova astrazione, qualcosa che possa fare la stessa differenza delle funzioni di prima classe, della ricorsione o almeno dei parametri predefiniti. Forse è un sogno irrealizzabile. Cose del genere spesso non vengono scoperte. Ma non perdo la speranza.
Segreti poco conosciuti
1. Puoi usare qualsiasi lingua tu voglia.
Un tempo, scrivere app significava scrivere software desktop. E il software desktop ha una forte propensione a scrivere app nello stesso linguaggio del sistema operativo. Quindi, dieci anni fa, scrivere software significava generalmente scrivere software in C. Col tempo, la tradizione si è evoluta: le app non devono essere scritte in linguaggi sofisticati. E questa tradizione si è evoluta a tal punto che anche persone non tecniche come manager e investitori di capitale di rischio l'hanno imparata.
Il software lato server distrugge completamente questo modello. Con il software lato server, puoi usare qualsiasi linguaggio tu voglia. Quasi nessuno lo capisce ancora (soprattutto manager e venture capitalist). Ma alcuni hacker sì, ed è per questo che sentiamo parlare di linguaggi indipendenti come Perl e Python. Non sentiamo parlare di Perl e Python perché le persone li usano per scrivere applicazioni per Windows.
Per noi, persone interessate alla progettazione di linguaggi di programmazione, questo significa che esiste un potenziale pubblico per il nostro lavoro.
2. La velocità deriva dai profiler
I progettisti di linguaggi, o almeno gli implementatori di linguaggi, amano scrivere compilatori che generino codice veloce. Ma non credo che sia questo a rendere i linguaggi veloci per gli utenti. Knuth ha notato molto tempo fa che la velocità dipende solo da pochi colli di bottiglia. E chiunque abbia provato a velocizzare un programma sa che non è possibile indovinare dove si trovi il collo di bottiglia. Un profiler è la soluzione.
I progettisti del linguaggio stanno risolvendo il problema sbagliato. Gli utenti non vogliono che i benchmark siano veloci. Vogliono un linguaggio che sappia indicare loro quali parti del programma devono essere riscritte. A questo punto, la velocità è ciò che serve nella pratica. Quindi forse sarebbe meglio se gli implementatori del linguaggio dedicassero metà del tempo impiegato nell'ottimizzazione del compilatore alla scrittura di un buon profiler.
3. Hai bisogno di un'app che ti aiuti a sviluppare il linguaggio
Forse non è la verità assoluta, ma i linguaggi migliori sembrano essersi evoluti insieme alle applicazioni che li utilizzano. Il C è stato scritto da persone che volevano programmare sistemi. Il Lisp è stato progettato in parte per la differenziazione simbolica; McCarthy era così impaziente di iniziare che iniziò a scrivere programmi di differenziazione già nel primo articolo sul Lisp del 1960.
Questo è particolarmente utile se la tua applicazione risolve un nuovo problema. Questo spinge il tuo linguaggio ad avere nuove funzionalità che i programmatori desiderano. Personalmente, sono interessato a scrivere un linguaggio che sia adatto alle applicazioni server.
[Durante la discussione, anche Guy Steele ha sottolineato questo punto, aggiungendo che l'applicazione non dovrebbe consistere nella scrittura di un compilatore per il tuo linguaggio, a meno che il tuo linguaggio non sia progettato per scrivere compilatori.]
4. Il linguaggio dovrebbe essere adatto alla scrittura di programmi una tantum.
Sapete cosa significa un programma usa e getta: quando si deve svolgere un compito molto limitato molto velocemente. Credo che se vi guardate intorno, troverete molti programmi seri che sono nati come programmi usa e getta. Non mi sorprenderei se la maggior parte dei programmi nascesse come programmi usa e getta. Quindi, se volete creare un linguaggio che sia adatto alla scrittura di software in generale, dovrebbe essere adatto alla scrittura di programmi usa e getta, perché quello è l'inizio di molti software.
5. La sintassi è correlata alla semantica
La saggezza popolare vuole che sintassi e semantica siano cose molto diverse. Può sembrare scioccante, ma non lo è. Credo che ciò che si desidera ottenere da un programma dipenda da come lo si esprime.
Di recente ho parlato con Robert Morris, che mi ha fatto notare che l'overload degli operatori è una grande vittoria per i linguaggi infissi. Nei linguaggi con prefissi, qualsiasi funzione definita è di fatto un operatore. Se si desidera sommare un nuovo tipo di numero creato in precedenza, è sufficiente definire una nuova funzione per sommarlo. Se lo si fa in un linguaggio infisso, si noterà che c'è una grande differenza tra l'utilizzo di un operatore overloaded e la chiamata di una funzione.
Idee che ritornano nel tempo
1. Nuovi linguaggi di programmazione
Ripensando agli anni '1970, era di moda sviluppare nuovi linguaggi di programmazione. Non è più così. Ma credo che il software per server riporterà in auge la creazione di nuovi linguaggi. Con il software per server, si può usare qualsiasi linguaggio si voglia, quindi se qualcuno crea un linguaggio che sembra migliore degli altri, ci saranno persone che decideranno di usarlo.
2. Condivisione del tempo
Richard Kelsey ha questa idea, il cui momento è tornato, e la sostengo pienamente. La mia ipotesi (e anche quella di Microsoft) è che gran parte dell'elaborazione si sposterà dal desktop ai server remoti. In altre parole, il time-sharing è tornato. Credo che avremo bisogno di un supporto linguistico per questo. Ad esempio, Richard e Jonathan Reeves hanno lavorato molto per implementare la schedulazione dei processi in Scheme 48.
3. Efficienza
Di recente, sembrava che i computer fossero abbastanza veloci. Sentiamo parlare sempre più spesso di bytecode, il che, almeno per me, significa che abbiamo potenza da vendere. Ma credo che con il software server non sia così. Qualcuno dovrà pagarlo. server, su cui gira il software, e il numero di utenti che il server può supportare per macchina sarà il divisore dei loro costi di capitale.
Penso che l'efficienza sarà fondamentale, almeno per quanto riguarda i colli di bottiglia dell'elaborazione. Sarà particolarmente importante per le operazioni di I/O, perché le applicazioni server ne eseguono molte.
Alla fine, potrebbe rivelarsi che il bytecode non sia la soluzione. Sun e Microsoft sembrano combattere testa a testa nell'arena del bytecode. Ma lo fanno perché il bytecode è un modo comodo per inserirsi in un processo, non perché il bytecode in sé sia una buona idea. Potrebbe anche succedere che tutta questa battaglia passi inosservata. Sarebbe divertente.
Trappole e insidie
1. Clienti
È solo un'ipotesi, ma il punto è che le uniche applicazioni che vinceranno saranno quelle interamente lato server. Progettare software che opera partendo dal presupposto che tutti avranno il tuo client è come costruire una società basata sul presupposto che tutti saranno onesti. Sarebbe certamente comodo, ma bisogna accettare che non accadrà mai.
Penso che ci sarà una proliferazione di dispositivi abilitati al web e presumo che supporteranno HTML e moduli di base. Hai un browser sul tuo telefono? Il tuo PalmPilot avrà un telefono? Il tuo Blackberry avrà uno schermo più grande? Potrai connetterti online dal tuo Gameboy? Dal tuo orologio? Non lo so. E non dovrò scoprirlo se scommetto che tutto è sul server. È semplicemente molto più sicuro avere tutti i cervelli sul server.
2. Programmazione orientata agli oggetti
So che è un'affermazione controversa, ma non credo che la programmazione orientata agli oggetti sia importante. Penso che sia un buon paradigma per applicazioni specifiche che richiedono strutture dati specifiche, come sistemi a finestre, simulazioni, sistemi CAD. Ma non vedo perché dovrebbe essere valido per tutti i programmi.
Credo che le persone nelle grandi aziende apprezzino la programmazione orientata agli oggetti anche perché offre loro molte cose che sembrano lavoro. Ciò che potrebbe essere rappresentato naturalmente come, ad esempio, un elenco di numeri interi, ora può essere rappresentato come una classe con ogni sorta di impalcatura, rumore e confusione.
Un'altra caratteristica interessante della programmazione orientata agli oggetti è che i metodi forniscono l'effetto di funzioni di prima classe. Ma questa non è una novità per i programmatori Lisp. Quando si hanno a disposizione vere funzioni di prima classe, è possibile utilizzarle semplicemente nel modo più adatto al compito da svolgere, anziché forzare tutto in un modello di classi e metodi.
Penso che questo significhi per la progettazione di un linguaggio di programmazione che non si dovrebbe integrare la programmazione orientata agli oggetti troppo a fondo. Forse la soluzione è offrire elementi più generali e fondamentali, e lasciare che le persone progettino qualsiasi sistema di oggetti desiderino come librerie.
3. Progettazione da parte del comitato
Se il tuo linguaggio è progettato da un comitato, sei in trappola, e non solo per i motivi ben noti. Tutti sanno che i comitati tendono a produrre progetti linguistici disomogenei e incoerenti. Ma credo che il pericolo maggiore sia che non si assumano rischi. Quando una persona è responsabile, quella persona si assume rischi che un comitato non accetterebbe mai di correre.
Dovresti correre dei rischi per creare un buon linguaggio? Molti potrebbero sospettare che la progettazione di un linguaggio sia qualcosa in cui ci si debba attenere piuttosto fedelmente al buon senso. Io sostengo che non sia vero. In ogni altra cosa che le persone fanno, la ricompensa è proporzionale al rischio. Quindi perché la progettazione di un linguaggio dovrebbe essere diversa?
Fonte: habr.com
