Cinci întrebări despre proiectarea limbajelor de programare

Cinci întrebări despre proiectarea limbajelor de programare

Filozofia de bază

1. Limbajele de programare pentru oameni

Limbajele de programare sunt modul în care oamenii comunică cu computerele. Un computer ar fi bucuros să converseze în orice limbaj care nu este ambiguu. Motivul pentru care avem limbaje de nivel înalt este că oamenii nu pot face față limbajului mașinii. Esența limbajelor de programare este de a preveni supraîncărcarea creierului nostru uman fragil cu un volum mare de detalii.

Arhitecții știu că unele probleme de proiectare sunt mai concrete decât altele. Unele dintre cele mai clare și abstracte probleme de proiectare sunt construcția podurilor. În acest caz, sarcina ta este să acoperi distanța necesară cu cât mai puțin material posibil. La celălalt capăt al spectrului se află proiectarea scaunelor. Proiectanții de scaune trebuie să-și petreacă timpul gândindu-se la fundurile umane.

Dezvoltarea software-ului are o distincție similară. Proiectarea algoritmilor pentru rutarea datelor printr-o rețea este o problemă bună, abstractă, similară cu proiectarea podurilor. Pe de altă parte, proiectarea limbajelor de programare este asemănătoare cu proiectarea scaunelor: trebuie să facem față slăbiciunilor umane.

Majoritatea dintre noi avem dificultăți în a realiza asta. Proiectarea unor sisteme matematice elegante sună mult mai atrăgător pentru majoritatea dintre noi decât a ceda slăbiciunilor umane. Rolul eleganței matematice este că un anumit grad de eleganță face programele mai ușor de înțeles. Dar eleganța nu se limitează la atât.

Și când spun că limbajele ar trebui concepute având în vedere slăbiciunile umane, nu vreau să zic că limbajele trebuie să fie concepute pentru programatori slabi. De fapt, ar trebui să proiectezi software pentru cei mai buni programatori, dar chiar și cei mai buni programatori au limitările lor. Nu cred că nimănui i-ar plăcea să programeze într-un limbaj în care toate variabilele ar fi denumite „x” cu indecși întregi.

2. Proiectați pentru voi și pentru prietenii voștri

Dacă privești istoria limbajelor de programare, majoritatea dintre cele mai bune limbaje au fost concepute pentru a fi folosite de creatorii lor, iar majoritatea dintre cele mai slabe au fost concepute pentru alte persoane.

Atunci când limbajele sunt concepute pentru alte persoane, aceasta se referă întotdeauna la un grup specific: oamenii nu sunt la fel de inteligenți ca cei care creează limbajul. Așa că obții un limbaj care îți vorbește cu superioritate. Cobol este cel mai evident exemplu, dar majoritatea limbajelor sunt impregnate de acest spirit.

Aceasta nu are legătură cu cât de high-level este limbajul. C este destul de low-level, dar a fost creat pentru a fi folosit de autorii săi, de aceea hackerii îl preferă.

Argumentul în favoarea conceperii limbajelor pentru programatorii slabi este că programatorii slabi sunt mai mulți decât cei buni. Probabil că este adevărat. Însă este un număr mic de programatori buni care scriu un software disproporționat mai mare.

Mă interesează întrebarea cum să creezi un limbaj care să placă celor mai buni hackeri? Mi se pare că această întrebare este identică cu întrebarea cum să creezi un limbaj de programare bun?, dar chiar dacă nu este așa, este cel puțin o întrebare interesantă.

3. Oferă programatorului cât mai mult control posibil

Multe limbaje (în special cele concepute pentru alte persoane) se comportă ca un bonă: încearcă să te protejeze de lucruri pe care cred că nu îți vor fi utile. Eu susțin opina opusă: oferă programatorului cât mai mult control posibil.

Când am studiat pentru prima dată Lisp, cel mai mult mi-a plăcut că discutam de la egal la egal. În alte limbaje pe care le studiasem până atunci, existau limbajul și programul meu în acel limbaj, care existau destul de separat. Dar în Lisp funcțiile și macrocomenzile pe care le-am scris erau la fel ca cele pe care era construit limbajul însuși. Puteam să refac limbajul dacă aș fi dorit. Avea aceeași atracție ca software-ul cu sursă deschisă.

4. Scurtătatea este sora talentului

Concizia este subestimată și chiar disprețuită. Dar dacă aruncați o privire în inimile hackerilor, veți observa că aceștia iubesc foarte mult concizia. Câteodată ați auzit hackerii vorbind cu drag despre cât de multe lucruri minunate pot face în APL cu doar câteva linii de cod? Cred că oamenii cu adevărat inteligenți iubesc, de fapt, să acorde atenție acestui aspect.

Cred că aproape tot ce permite reducerea dimensiunii programelor este bun. Trebuie să existe numeroase funcții din biblioteci, tot ce poate fi implicit ar trebui să fie așa; sintaxa ar trebui să fie în mare parte concisă; chiar și numele entităților ar trebui să fie scurte.

Și nu doar programele ar trebui să fie scurte. Manualele ar trebui să fie scurte și ele. O mare parte din manuale este plină de explicații, precizări, avertismente și cazuri speciale. Dacă va trebui să reduceți un manual, cea mai bună opțiune este să corectați limbajul care necesită atât de multe explicații.

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

Multor oameni le-ar plăcea ca hacking-ul să fie matematică sau, măcar, ceva similar cu științele naturale. Cred că hacking-ul seamănă mai mult cu arhitectura. Arhitectura este legată de fizică, în sensul că arhitectul trebuie să proiecteze o clădire care să nu se prăbușească, dar adevărata țintă a arhitectului este să creeze o clădire mare, nu să descopere secrete în domeniul statica.

Ceea ce hackerii iubesc este să creeze programe mari. Și cred că, măcar în gândurile noastre, ar trebui să ne amintim că a scrie programe extraordinare este fantastic, chiar și atunci când acest lucru nu se traduce ușor în moneda intelectuală obișnuită a lucrărilor științifice. Din punct de vedere intelectual, nu este mai puțin important să dezvolți un limbaj pe care programatorii să-l iubească, precum și să creezi un haos în care să întruchipezi ideea despre care poți publica un articol.

Probleme deschise

1. Cum să organizați biblioteci mari?

Bibliotecile devin o parte importantă a limbajelor de programare. Ele devin atât de mari încât acest lucru poate fi periculos. Dacă îți ia mai mult timp să găsești o funcție în bibliotecă care să facă ceea ce ai nevoie decât să scrii tu însuți acea funcție, atunci întreg codul nu face altceva decât să îngroașe manualul tău. (Ghidurile Symbolics au fost un exemplu în acest sens.) Așadar, va trebui să rezolvăm problema organizării bibliotecilor. Ideal ar fi să le proiectăm astfel încât programatorul să poată ghici care funcție a bibliotecii este potrivită.

2. Oamenii sunt realmente speriați de sintaxa prefixată?

Aceasta este o problemă deschisă în sensul că am reflectat la ea câțiva ani și încă nu știu răspunsul. Sintaxa prefixată mi se pare absolut naturală, poate cu excepția utilizării sale în matematică. Dar ar putea fi că cea mai mare parte a nepopularității Lisp-urilor se datorează pur și simplu sintaxei necunoscute... Merită să facem ceva în legătură cu asta, dacă este adevărat, este o altă întrebare.

3. Ce ai 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 fi găzduite pe un server și vor comunica cu tine prin intermediul unui browser web. Și pentru a scrie astfel de aplicații avem nevoie de lucruri noi.

Unul dintre aceste lucruri este susținerea unei noi modalități de lansare a aplicațiilor server. În loc de una sau două lansări mari pe an, ca în cazul software-ului desktop, software-ul server va fi lansat printr-o serie de modificări mai mici. Poți avea cinci sau zece lansări pe zi. Și toată lumea va avea întotdeauna cea mai recentă versiune.

Știi cum să proiectezi programe astfel încât să fie ușor de întreținut? Software-ul server trebuie să fie proiectat pentru a fi modificabil. Trebuie să ai capacitatea de a-l modifica ușor, sau cel puțin să știi ce înseamnă o modificare minoră și ce este important.

Î încă un lucru care poate fi util în software-ul server este, surprinzător, continuitatea livrării. Într-o aplicație web poți folosi ceva precum CPS, pentru a obține efectul subprogramelor într-o lume fără stare a sesiunilor web. Poate că continuitatea livrării merită, dacă această capacitate nu va fi prea costisitoare.

4. Ce noi abstrații mai rămân de descoperit?

Nu sunt sigur cât de rezonabilă este această speranță, dar personal mi-ar plăcea foarte mult să descopăr o nouă abstracție - ceva care ar putea avea o importanță la fel de mare ca funcțiile de primă clasă sau recursul sau măcar parametrii prestabiliți. Poate că este un vis imposibil. Astfel de lucruri sunt adesea neîmplinite. Dar nu-mi pierd speranța.

Secrete puțin cunoscute

1. Puteți utiliza orice limbaj doriți

Anterior, crearea de aplicații se referea la dezvoltarea software-ului desktop. Iar în software-ul desktop există o tendință puternică de a scrie aplicații în același limbaj ca și sistemul de operare. Așa că acum zece ani, scrierea de software în general însemna a scrie software în C. În cele din urmă, tradiția a evoluat: aplicațiile nu trebuie să fie scrise în limbaje neobișnuite. Și această tradiție s-a dezvoltat atât de mult, încât persoanele non-tehnice, precum managerii și investitorii de capital de risc, au învățat și ele acest lucru.

Software-ul de server distruge complet acest model. Cu software-ul de server, poți lua orice limbaj dorești. Aproape nimeni nu mai înțelege asta (în special managerii și investitorii de capital de risc). Dar anumiți hackeri înțeleg, de aceea am auzit despre limbajele indie precum Perl și Python. Nu auzim despre Perl și Python pentru că oamenii le folosesc pentru a scrie aplicații pentru Windows.

Ce înseamnă asta pentru noi, oamenii interesați de proiectarea limbajelor de programare, este că există o audiență potențială pentru munca noastră.

2. Viteza provine din profilatoare

Dezvoltatorii limbajului sau, cel puțin, cei care îl implementează, iubesc să scrie compilatoare care generează cod rapid. Dar cred că nu aceasta este ceea ce face limbajele rapide pentru utilizatori. Knuth a observat demult că viteza depinde de doar câteva puncte vulnerabile. Și oricine a încercat să accelereze un program știe că nu poți ghici unde este acest punct de congestie. Profilatorul este răspunsul.

Dezvoltatorii limbajului nu rezolvă problema corectă. Utilizatorii nu au nevoie ca benchmark-urile să funcționeze rapid. Ei au nevoie de un limbaj care poate arăta ce părți ale programului lor trebuie să fie rescrise. În acel moment, viteza este necesară în practică. Poate că ar fi mai bine ca implementatorii limbajului să petreacă jumătate din timpul pe care îl dedică optimizării compilatorului pentru a scrie un profiler bun.

3. Ai nevoie de o aplicație care să facă limbajul tău să evolueze

Poate că nu este o adevăr cert, dar pare că cele mai bune limbaje au evoluat împreună cu aplicațiile în care au fost folosite. C a fost scris de oameni care au avut nevoie de programare de sistem. Lisp a fost dezvoltat parțial pentru diferențiere simbolică, McCarthy era atât de nerăbdător să înceapă încât a început să scrie programe de diferențiere chiar în primul document despre Lisp din 1960.

Aceasta este în special valabil dacă aplicația ta rezolvă probleme noi. Aceasta determină limbajul tău să aibă noi caracteristici necesare programatorilor. Personal, mă interesează să scriu un limbaj care să fie bun pentru aplicații de server.

[În timpul discuției, Guy Steele a exprimat de asemenea această idee, adăugând că aplicația nu ar trebui să constea din scrierea compilatorului pentru limbajul tău, cu excepția cazului în care limbajul tău este destinat scrierii compilatoarelor.]

4. Limbajul trebuie să fie potrivit pentru scrierea programelor de unică folosință.

Știi ce înseamnă o programă de unică folosință: aceasta este atunci când trebuie să rezolvi rapid o sarcină limitată. Cred că dacă te uiți în jur, vei descoperi multe programe serioase care au început ca programe de unică folosință. Nu m-ar suprinde dacă majoritatea programelor au început astfel. Așadar, dacă vrei să creezi un limbaj care să fie potrivit pentru scrierea de software în general, atunci trebuie să fie și potrivit pentru scrierea programelor de unică folosință, deoarece aceasta este etapa inițială a multor programe.

5. Sintaxa este legată de semantica

Se consideră în mod tradițional că sintaxa și semantica sunt lucruri foarte diferite. Poate suna șocant, dar nu este așa. Cred că ceea ce dorești să obții în programul tău este legat de modul în care o exprimi.

Recent am discutat cu Robert Morris și el a remarcat că suprasarcina operatorilor este un mare avantaj în limbajele cu sintaxă infixă. În limbajele cu sintaxă prefixă, orice funcție definită de tine este, de fapt, un operator. Dacă vrei să aduni un nou tip de număr pe care l-ai inventat, poți pur și simplu să definești o funcție nouă pentru a-l adăuga. Dacă faci asta într-un limbaj cu sintaxă infixă, vei observa că există o mare diferență între utilizarea unui operator suprasaturat și apelarea unei funcții.

Ideile care revin în timp

1. Limbaje de programare noi

Privind înapoi la anii '70, era la modă să dezvolți limbaje de programare noi. Acum nu este la fel. Dar cred că software-ul serverului va readuce moda de a crea limbaje noi. Cu software-ul de server, poți folosi orice limbaj dorești, astfel încât, dacă cineva creează un limbaj care pare mai bun decât celelalte, vor exista oameni care vor decide să-l folosească.

2. Partajarea timpului

Richard Kelsey a propus această idee, iar timpul ei a venit din nou, și o susțin pe deplin. Presupunerea mea (și a Microsoft de asemenea) este că multe calcule se vor muta de pe desktop-uri pe servere externe. Cu alte cuvinte, partajarea timpului s-a întors. Cred că va fi necesară o susținere pentru asta la nivel de limbaj. De exemplu, Richard și Jonathan Reeves au făcut multe pentru a implementa planificarea proceselor în Scheme 48.

3. Eficiența

Recent părea că computerele sunt deja suficient de rapide. Tot mai des auzim despre bytecode, ceea ce, cel puțin pentru mine, înseamnă că avem puterea în rezervă. Dar cred că, cu software-ul serverului, nu o avem. Cineva va trebui să plătească pentru servere, pe care rulează software-ul, iar numărul de utilizatori pe care serverul poate susține pe o mașină va fi un divizor al cheltuielilor lor de capital.

Cred că eficiența va conta, cel puțin în gâturile de sticlă ale calculului. Acest lucru va fi deosebit de important pentru operațiile de input-output, deoarece aplicațiile serverului generează o mulțime de astfel de operații.

În cele din urmă, s-ar putea să descoperim că bytecode-ul nu este soluția. Sun și Microsoft par să se confrunte în prezent pe terenul bytecode-ului. Dar o fac pentru că bytecode-ul este un loc convenabil pentru a se integra în proces, nu pentru că bytecode-ul în sine este o idee bună. S-ar putea să se dovedească că întreaga bătălie va trece neobservată. Ar fi amuzant.

Capcane și capcane

1. Clienți

Aceasta este doar o presupunere, dar cred că vor câștiga doar acele aplicații care vor fi complet server-side. Proiectarea de software bazat pe presupunerea că fiecare va avea clientul vostru seamănă cu crearea unei societăți bazate pe presupunerea că toți vor fi cinstiți. Ar fi, desigur, convenabil, dar va trebui să acceptați că acest lucru nu se va întâmpla niciodată.

Cred că va exista o creștere rapidă a dispozitivelor cu acces la web, și se poate presupune că acestea vor suporta HTML de bază și formulare. Ai un browser pe telefon? Va avea telefonul tău un PalmPilot? Blackberry-ul tău va avea un ecran mai mare? Vei avea posibilitatea să te conectezi la internet de pe gameboy-ul tău? De pe ceasurile tale? Nu știu. Și nu va trebui să aflu asta, dacă pariez că totul va fi pe server. Este mult mai sigur să ai toate procesele pe server.

2. Programare orientată pe obiect

Înțeleg că aceasta este o afirmație controversată, dar nu consider că OOP este ceva important. Cred că este o paradigmă adecvată pentru aplicații specifice care au nevoie de structuri de date specifice, cum ar fi sistemele de feronerie, simulările sau CAD. Dar nu înțeleg de ce ar trebui să fie potrivită pentru toate programele.

Cred că oamenii din companii mari iubesc OOP, parțial pentru că oferă mult din ceea ce pare a fi muncă reală. Ceea ce, în mod natural, poate fi reprezentat ca, să zicem, o listă de numere întregi, acum poate fi reprezentat ca o clasă cu tot felul de schele, cu zgomot și agitație.

O altă trăsătură interesantă a OOP este că metodele vă oferă un fel de efect de funcții de primă clasă. Dar aceasta nu este o noutate pentru programatorii care folosesc Lisp. Când aveți funcții de primă clasă adevărate, le puteți folosi în orice mod care se potrivește sarcinii, în loc să împingeți totul într-un șablon de clase și metode.

Cred că asta înseamnă pentru designul limbajului că nu ar trebui să încorporați prea profund OOP în el. Răspunsul ar putea fi să oferiți lucruri mai generale, fundamentale și să permiteți oamenilor să proiecteze orice sisteme de obiecte sub forma unor biblioteci.

3. Proiectarea comitetului

Dacă limbajul vostru este proiectat de un comitet, atunci sunteți într-o capcană, și nu doar din motivele bine cunoscute. Toată lumea știe că comitetele tind să creeze un design al limbajului care este inconsistent și greoi. Dar cred că pericolul mai mare este că nu își asumă riscuri. Când este un singur lider, acesta își asumă riscurile pe care comitetul nu le-ar accepta niciodată.

Trebuie să ne asumăm riscuri pentru a crea un limbaj bun? Mulți oameni ar putea suspecta că proiectarea unui limbaj este ceva de care trebuie să te ții destul de aproape de înțelepciunea tradițională. Aș putea argumenta că nu este așa. În tot ceea ce fac oamenii, recompensa este proporțională cu riscul. Așadar, de ce ar trebui ca în proiectarea limbajelor să fie diferit?

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster