Cinci întrebări despre proiectarea limbajului de programare

Cinci întrebări despre proiectarea limbajului de programare

Filosofia călăuzitoare

1. Limbaje de programare pentru oameni

Limbajul de programare este modul în care oamenii vorbesc cu computerele. Computerul va fi fericit să vorbească orice limbă care nu este ambiguă. Motivul pentru care avem limbaje de nivel înalt este că oamenii nu pot gestiona limbajul mașinii. Scopul limbajelor de programare este de a preveni bietele noastre creiere umane fragile să fie copleșite de prea multe detalii.

Arhitecții știu că unele probleme de design sunt mai banale decât altele. Unele dintre cele mai clare și mai abstracte probleme de proiectare sunt proiectarea podurilor. În acest caz, treaba dumneavoastră este să acoperiți distanța necesară cu cât mai puțin material. La celălalt capăt al spectrului se află designul scaunelor. Designerii de scaune ar trebui să-și petreacă timpul gândindu-se la fundul oamenilor.

Dezvoltarea de software are o diferență similară. Proiectarea algoritmilor pentru rutarea datelor printr-o rețea este o problemă frumoasă, abstractă, precum proiectarea podurilor. În timp ce proiectarea limbajelor de programare este ca și proiectarea scaunelor: trebuie să faci față slăbiciunilor umane.

Acest lucru este greu de realizat pentru majoritatea dintre noi. Proiectarea sistemelor matematice elegante sună mult mai atrăgătoare pentru cei mai mulți dintre noi decât să ne răsfoim cu slăbiciunile umane. Rolul eleganței matematice este că un anumit grad de eleganță face programele mai ușor de înțeles. Dar nu totul este despre eleganță.

Și când spun că limbajele ar trebui să fie concepute pentru a se adapta slăbiciunilor umane, nu mă refer la faptul că limbajele ar trebui să fie concepute pentru programatori răi. În realitate, ar trebui să proiectați software pentru cei mai buni programatori, dar chiar și cei mai buni programatori au limitele lor. Nu cred că nimănui i-ar plăcea să programeze într-un limbaj în care toate variabilele au fost notate cu litera „x” cu indice întregi.

2. Design pentru tine și prietenii tăi

Dacă te uiți la istoria limbajelor de programare, majoritatea celor mai bune limbaje au fost concepute pentru a fi folosite de proprii autori, iar cele mai rele au fost concepute pentru a fi folosite de alți oameni.

Când limbile sunt concepute pentru alți oameni, este întotdeauna un anumit grup de oameni: oamenii nu sunt la fel de inteligenți ca creatorii limbii. Așa obții o limbă care îți vorbește. Cobol este cel mai proeminent exemplu, dar majoritatea limbilor sunt impregnate de acest spirit.

Nu are nimic de-a face cu cât de înalt este limbajul. C este un nivel destul de scăzut, dar a fost creat pentru a fi folosit de autorii săi, motiv pentru care hackerii îl iubesc.

Argumentul pentru proiectarea limbajelor pentru programatori răi este că există mai mulți programatori răi decât cei buni. Poate că așa este. Dar acest număr mic de programatori buni scrie disproporționat mai mult software.

Întrebarea mea este cum să creezi un limbaj care să atragă cei mai buni hackeri? Mi se pare că această întrebare este identică cu întrebarea cum se creează un limbaj de programare bun?, dar chiar dacă nu este, este cel puțin o întrebare interesantă.

3. Oferiți programatorului cât mai mult control posibil

Multe limbi (în special cele concepute pentru alți oameni) acționează ca niște bone: încearcă să te avertizeze de lucrurile despre care nu cred că te vor aduce beneficii. Eu cred opusul: dați programatorului cât mai mult control posibil.

Când am învățat prima oară Lisp, ceea ce mi-a plăcut cel mai mult a fost că am vorbit în egală măsură. În celelalte limbi pe care le învățasem până în acel moment, exista o limbă și era programul meu în acea limbă și existau destul de separat. Dar în Lisp, funcțiile și macrocomenzile pe care le-am scris erau aceleași în care era scris limba în sine. Aș putea rescrie limba în sine dacă aș vrea. Avea același atractiv ca și software-ul open source.

4. Concizia este sora talentului

Concizia este subestimată și chiar disprețuită. Dar dacă te uiți în inimile hackerilor, vei vedea că le place foarte mult concizia. De câte ori i-ați auzit pe hackeri vorbind cu drag despre cum, de exemplu, în APL, pot face lucruri uimitoare cu doar câteva linii de cod? Bănuiesc că oamenilor cu adevărat inteligenți le place să acorde atenție acestui lucru.

Cred că aproape orice face programele mai scurte este un lucru bun. Ar trebui să existe o mulțime de funcții de bibliotecă, tot ceea ce poate fi implicit ar trebui să fie așa; sintaxa ar trebui să fie mai concisă; chiar și numele de entități ar trebui să fie scurte.

Și nu numai programele ar trebui să fie scurte. Manualele ar trebui să fie, de asemenea, scurte. O bună parte din manuale este plină de explicații, declinări de răspundere, avertismente și cazuri speciale. Dacă trebuie să scurtați manualul, cea mai bună opțiune este să corectați limba care necesită atât de multe explicații.

5. Recunoașteți ce este hacking-ul

Mulți oameni ar dori ca hackingul să fie matematică sau cel puțin ceva asemănător științei. Cred că hacking-ul seamănă mai mult cu arhitectura. Arhitectura este despre fizică în sensul că un arhitect trebuie să proiecteze o clădire care să nu cadă, dar adevăratul obiectiv al unui arhitect este să creeze o clădire grozavă, nu să facă descoperiri în domeniul staticii.

Ceea ce le place hackerilor este să creeze programe grozave. Și cred că, cel puțin în propriile noastre gânduri, ar trebui să ne amintim că a scrie programe grozave este un lucru minunat, chiar și atunci când acea lucrare nu se traduce cu ușurință în moneda intelectuală obișnuită a lucrărilor științifice. Din punct de vedere intelectual, este la fel de important să proiectați un limbaj pe care programatorii îl vor iubi, precum este să proiectați unul groaznic care întruchipează o idee despre care puteți publica o lucrare.

Probleme deschise

1. Cum se organizează biblioteci mari?

Bibliotecile devin o parte importantă a limbajelor de programare. Devin atât de mari încât poate fi periculos. Dacă este nevoie de mai mult pentru a găsi o funcție într-o bibliotecă care face ceea ce aveți nevoie decât să scrieți singur acea funcție, atunci tot codul nu face altceva decât să vă îngroașe manualul. (Manualele Symbolics au fost un exemplu în acest sens.) Așa că va trebui să rezolvăm problema organizării bibliotecii. În mod ideal, proiectați-le astfel încât programatorul să poată ghici ce funcție de bibliotecă este potrivită.

2. Oamenii chiar se tem de sintaxa prefixelor?

Aceasta este o problemă deschisă în sensul că mă gândesc la ea de câțiva ani și încă nu știu răspunsul. Sintaxa prefixelor mi se pare complet firească, cu excepția poate pentru utilizarea ei în matematică. Dar s-ar putea ca o mare parte din impopularitatea lui Lisp să se datoreze pur și simplu sintaxei necunoscute... Dacă merită să faci ceva în privința asta, dacă este adevărat, este o altă chestiune.

3. De ce aveți nevoie pentru software-ul server?

Cred că majoritatea aplicațiilor care vor fi scrise în următorii douăzeci de ani vor fi aplicații web, în ​​sensul că programele vor locui pe un server și vor comunica cu tine printr-un browser web. Și pentru a scrie astfel de aplicații avem nevoie de lucruri noi.

Unul dintre aceste lucruri este suportul pentru o nouă modalitate de a lansa aplicații server. În loc de una sau două versiuni mari pe an, cum ar fi software-ul desktop, software-ul pentru server va fi lansat într-o serie de mici modificări. S-ar putea să aveți cinci sau zece lansări pe zi. Și toată lumea va avea întotdeauna cea mai recentă versiune.

Știți cum să proiectați programe pentru a putea fi întreținute? Software-ul serverului trebuie să fie proiectat să poată fi schimbat. Ar trebui să îl poți schimba cu ușurință sau cel puțin să știi ce înseamnă o schimbare minoră și ce este important.

Un alt lucru care poate fi util în software-ul serverului este, brusc, continuitatea livrării. Într-o aplicație web puteți folosi ceva de genul CPSpentru a obține efectul rutinelor în lumea fără stat a sesiunilor web. A avea continuitate a aprovizionării poate merita dacă funcția nu este prea scumpă.

4. Ce noi abstractizări mai rămân de descoperit?

Nu sunt sigur cât de rezonabilă este această speranță, dar personal mi-ar plăcea să descopăr o nouă abstracție - ceva care ar putea fi la fel de semnificativ ca funcțiile de primă clasă sau recursiunea sau cel puțin parametrii impliciti. Poate că acesta este un vis imposibil. Asemenea lucruri nu sunt descoperite adesea. Dar nu îmi pierd speranța.

Secrete puțin cunoscute

1. Puteți folosi orice limbă doriți

Anterior, crearea de aplicații însemna crearea de software desktop. Și în software-ul desktop există o mare părtinire către scrierea aplicațiilor în aceeași limbă cu sistemul de operare. Deci în urmă cu zece ani, scrierea de software în general însemna scrierea de software în C. În cele din urmă, tradiția a evoluat: aplicațiile nu trebuie scrise în limbi neobișnuite. Și această tradiție a evoluat atât de mult încât oamenii netehnici precum managerii și capitaliștii de risc au învățat-o și ei.

Software-ul serverului distruge complet acest model. Cu software-ul server puteți folosi orice limbă doriți. Aproape nimeni nu înțelege acest lucru încă (în special managerii și capitaliștii de risc). Dar unii hackeri înțeleg acest lucru, motiv pentru care auzim despre limbi indiy precum Perl și Python. Nu auzim de Perl și Python pentru că oamenii le folosesc pentru a scrie aplicații Windows.

Ce înseamnă asta pentru noi, oameni interesați de proiectarea limbajului de programare, că există un public potențial pentru munca noastră.

2. Viteza vine de la profileri

Dezvoltatorilor de limbi, sau cel puțin implementatorilor de limbi, le place să scrie compilatoare care generează cod rapid. Dar cred că nu asta face ca limbile să fie rapide pentru utilizatori. Knuth a remarcat cu mult timp în urmă că viteza depinde doar de câteva blocaje. Și oricine a încercat să accelereze un program știe că nu poți ghici unde este blocajul. Profiler este răspunsul.

Dezvoltatorii de limbaje rezolvă problema greșită. Utilizatorii nu au nevoie de benchmark-uri pentru a rula rapid. Au nevoie de un limbaj care să arate ce părți ale programului lor trebuie rescrise. În acest moment, viteza este necesară în practică. Așa că poate ar fi mai bine dacă implementatorii de limbaj ar petrece jumătate din timpul pe care îl petrec optimizând compilatorul și îl petrec pentru a scrie un profiler bun.

3. Ai nevoie de o aplicație care să-ți facă limbajul să evolueze

Poate că acesta nu este adevărul suprem, dar se pare că cele mai bune limbi au evoluat odată cu aplicațiile în care au fost folosite. C a fost scris de oameni care aveau nevoie de programare de sisteme. Lisp a fost proiectat parțial pentru diferențierea simbolică, iar McCarthy era atât de dornic să înceapă încât a început chiar să scrie programe de diferențiere în prima lucrare Lisp în 1960.

Acest lucru este deosebit de bun dacă aplicația dvs. rezolvă unele probleme noi. Acest lucru împinge limbajul să aibă noi funcții pe care le doresc programatorii. Personal, sunt interesat să scriu un limbaj care să fie bun pentru aplicațiile server.

[În timpul discuției, Guy Steele a menționat și el acest punct, adăugând că aplicația nu ar trebui să constea în scrierea unui compilator pentru limba dvs., cu excepția cazului în care limba dvs. este concepută pentru a scrie compilatoare.]

4. Limba trebuie să fie potrivită pentru scrierea de programe unice.

Știi ce înseamnă un program one-shot: este atunci când trebuie să rezolvi rapid o problemă limitată. Cred că, dacă te uiți în jur, vei găsi multe programe serioase care au început ca fiind unice. Nu aș fi surprins dacă majoritatea programelor au început ca unic. Astfel, dacă doriți să creați un limbaj care să fie potrivit pentru scrierea de software în general, atunci ar trebui să fie potrivit și pentru scrierea de programe unice, deoarece aceasta este etapa inițială a multor programe.

5. Sintaxa este legată de semantică

În mod tradițional se crede că sintaxa și semantica sunt lucruri foarte diferite. Acest lucru poate suna șocant, dar nu este. Cred că ceea ce vrei să obții în programul tău are de-a face cu modul în care îl exprimi.

Am vorbit recent cu Robert Morris și a remarcat că supraîncărcarea operatorului este un mare plus pentru victoria limbilor cu sintaxă infixă. În limbile cu sintaxă de prefix, orice funcție pe care o definiți este de fapt un operator. Dacă doriți să adăugați un nou tip de număr pe care l-ați creat, puteți defini pur și simplu o nouă funcție pentru a-l adăuga. Dacă faceți acest lucru într-o limbă cu sintaxă infixă, veți vedea că există o mare diferență între utilizarea unui operator supraîncărcat și apelarea unei funcții.

Idei care revin de-a lungul timpului

1. Noi limbaje de programare

Privind înapoi la anii 1970, era la modă să se dezvolte noi limbaje de programare. Acesta nu este cazul acum. Dar cred că software-ul server va readuce din nou moda pentru crearea de noi limbi. Cu software-ul server puteți folosi orice limbă doriți, așa că dacă cineva creează o limbă care pare mai bună decât restul, vor exista oameni care vor decide să o folosească.

2. Împărțirea timpului

Richard Kelsey a venit cu această idee al cărei timp a sosit din nou și o susțin pe deplin. Bănuiala mea (și și cea a Microsoft) este că o mulțime de calculatoare se va muta de la desktop la serverele de la distanță. Cu alte cuvinte, împărțirea timpului a revenit. Cred că acest lucru va avea nevoie de sprijin la nivel de limbă. De exemplu, Richard și Jonathan Reeves au depus multă muncă pentru a implementa programarea proceselor în Schema 48.

3. Eficiență

Recent, se părea că computerele erau deja suficient de rapide. Auzim din ce în ce mai multe despre bytecode, ceea ce cel puțin pentru mine înseamnă că avem puțină putere în rezervă. Dar cred că, cu software-ul server, nu îl avem. Cineva va trebui să plătească pentru serverele care rulează software-ul, iar numărul de utilizatori pe care serverul îi poate suporta pe mașină va fi un divizor al costurilor lor de capital.

Cred că eficiența va conta, cel puțin în blocajele de calcul. Acest lucru va fi deosebit de important pentru operațiunile I/O, deoarece aplicațiile server efectuează o mulțime de astfel de operațiuni.

În cele din urmă, se poate dovedi că bytecode nu este răspunsul. Sun și Microsoft par să meargă cap la cap în câmpul bytecode în acest moment. Dar fac acest lucru pentru că bytecode este un loc convenabil pentru a se încorpora într-un proces, nu pentru că bytecode în sine este o idee bună. Se poate dovedi că toată această bătălie va trece neobservată. Ar fi amuzant.

Capcane si capcane

1. Clienții

Aceasta este doar o presupunere, dar este că singurele aplicații care vor beneficia sunt cele care sunt complet pe partea serverului. Proiectarea unui software care funcționează pe ipoteza că toată lumea va avea un client este ca și cum ai proiecta o societate bazată pe presupunerea că toată lumea va fi sinceră. Cu siguranță ar fi convenabil, dar trebuie să presupunem că nu se va întâmpla niciodată.

Cred că va exista o creștere rapidă a dispozitivelor activate pentru web și putem presupune că vor accepta html și formulare de bază. Ai un browser pe telefon? PalmPilot-ul tău va avea un telefon? Blackberry-ul tău va avea un ecran mai mare? Vei putea accesa internetul de la gameboy-ul tău? Din ceasul tau? Nu știu. Și nu va trebui să aflu dacă pun pariu că totul va fi pe server. Este mult mai fiabil să ai toate creierele pe server. .

2. Programare orientată pe obiecte

Îmi dau seama că aceasta este o declarație controversată, dar nu cred că OOP este atât de importantă. Cred că aceasta este o paradigmă potrivită pentru aplicații specifice care au nevoie de structuri de date specifice, cum ar fi sisteme de ferestre, simulări, sisteme CAD. Dar nu înțeleg de ce ar trebui să fie potrivit pentru toate programele.

Cred că oamenii din marile companii iubesc OOP, în parte, pentru că face o mulțime de lucruri care arată ca de lucru. Ceea ce ar putea fi în mod natural reprezentat ca, să zicem, o listă de numere întregi, poate fi acum reprezentat ca o sală de clasă cu tot felul de schele, forfotă.

O altă caracteristică atractivă a OOP este că metodele vă oferă o parte din efectul funcțiilor de primă clasă. Dar aceasta nu este o știre pentru programatorii Lisp. Când aveți funcții adevărate de primă clasă, le puteți utiliza pur și simplu în orice mod care se potrivește sarcinii în cauză, în loc să împinge totul într-un complex de clase și metode.

Cred că ceea ce înseamnă acest lucru pentru proiectarea limbajului este că nu ar trebui să încorporați OOP prea profund în el. Poate că răspunsul este de a oferi lucruri mai generale, de bază și de a lăsa oamenii să proiecteze orice sisteme de obiecte ca biblioteci.

3. Proiectare de către comitet

Dacă limbajul tău este conceput de un comitet, atunci ești prins, și nu doar din motive pe care toată lumea le cunoaște. Toată lumea știe că comitetele tind să creeze modele lingvistice neconsistente și inconsistente. Dar cred că marele pericol este că nu își asumă riscuri. Când o persoană este la conducere, el își asumă riscuri pe care comitetul nu ar fi de acord să le asume niciodată.

Trebuie să vă asumați riscuri pentru a crea un limbaj bun? Mulți oameni ar putea bănui că designul lingvistic este locul în care trebuie să rămâneți destul de aproape de înțelepciunea tradițională. Pun pariu că nu este cazul. În tot ceea ce fac oamenii, recompensa este proporțională cu riscul. Deci, de ce ar trebui să fie diferit designul limbajului?

Sursa: www.habr.com

Adauga un comentariu