Citire - evaluare - buclă de imprimare

De la Wikipedia, enciclopedia liberă.
Salt la navigare Salt la căutare

Un Read-Eval - Print Loop ( REPL ), cunoscut și ca limbaj interactiv de nivel superior sau shell , este un mediu de programare interactiv simplu, care acceptă intrări de la un singur utilizator (adică expresii simple), le evaluează și returnează rezultatul la utilizator; un program scris într-un mediu REPL este executat în bucăți. Termenul este de obicei folosit pentru a se referi la interfețe de programare similare cu mediul clasic al mașinii interactive Lisp . Exemple obișnuite includ shell-uri de linie de comandă și medii similare pentru limbaje de programare și este o caracteristică specială a limbajelor de scriptare . [1]

Prezentare generală

Într-un REPL, utilizatorul introduce una sau mai multe expresii (mai degrabă decât o întreagă unitate de compilare ), iar REPL le evaluează și afișează rezultatele. Bucla de citire-evaluare-printare a numelui provine de la numele funcțiilor primitive Lisp care implementează această funcționalitate:

  • Funcția de citire acceptă o expresie de la utilizator și o analizează într-o structură de date în memorie. De exemplu, utilizatorul poate introduce expresia s (+ 1 2 3) , care este analizată într-o listă legată care conține patru elemente de date.
  • Funcția eval ia această structură internă de date și o evaluează. În Lisp, evaluarea unei expresii s începând cu un nume de funcție înseamnă apelarea acelei funcții pe argumentele care alcătuiesc restul expresiei. Apoi funcția + este apelată la argumentele 1 2 3 , returnând rezultatul 6 .
  • Funcția de imprimare preia rezultatul obținut de la eval și îl imprimă utilizatorului. Dacă este o expresie complexă, ar putea fi destul de tipărită pentru a ușura înțelegerea. Cu toate acestea, în acest exemplu, numărul 6 nu are nevoie de multă formatare pentru a imprima.

Mediul de dezvoltare revine apoi la starea de citire, creând o buclă , care se termină când programul este închis.

REPL facilitează programarea și depanarea exploratorie, deoarece programatorul poate inspecta rezultatul tipărit înainte de a decide ce expresie să furnizeze pentru următoarea citire. Bucla read-eval-print implică programatorul mai frecvent decât bucla clasică edit-compile-run-debug.

Deoarece funcția de imprimare este afișată în același format de text utilizat de funcția de citire pentru introducere, majoritatea rezultatelor sunt tipărite într-o formă care ar putea (dacă este utilă) să fie copiată și lipită în REPL. Cu toate acestea, uneori este necesar să imprimați reprezentări ale elementelor care nu pot fi citite sensibil, cum ar fi un mâner de soclu sau o instanță de clasă complexă. În aceste cazuri, trebuie să existe o sintaxă pentru obiectele necitite. În Python, este notația <__module__.class instance> și în Common Lisp, forma #<whatever> . REPL-ul CLIM , SLIME și Symbolics Lisp Machine poate citi, de asemenea, obiecte necitite. Înregistrează pentru fiecare ieșire ce obiect a fost tipărit. Mai târziu, când se recitește codul, obiectul va fi recuperat din rezultatul tipărit.

REPL-urile pot fi create pentru a susține orice limbaj bazat pe text. Suportul REPL pentru limbile compilate se obține de obicei prin implementarea unui interpret pe o mașină virtuală care oferă o interfață compilatorului. De exemplu, începând cu JDK 9, Java a inclus JShell ca o interfață de linie de comandă pentru limbă. Diverse alte limbi au instrumente terțe disponibile pentru descărcare, care oferă o interacțiune similară a shell-ului cu limba.

Utilizare

La fel ca un shell , un mediu REPL permite utilizatorilor să acceseze funcționalitatea relevantă a unui sistem de operare, precum și să ofere acces la funcționalitatea de programare.

Cea mai obișnuită utilizare a REPL-urilor în afara shell-urilor sistemului de operare este prototiparea instantanee. Alte utilizări includ calculul matematic, crearea de documente care integrează analiza științifică (de exemplu, IPython ), întreținerea software-ului interactiv, analiza comparativă și explorarea algoritmilor.

Un REPL poate deveni o parte esențială a învățării unei noi limbi, deoarece oferă feedback rapid începătorului.

Specificații Lisp

Implementare

Pentru a implementa un Lisp REPL, trebuie doar să implementați aceste trei funcții și o funcție de buclă infinită . (Bineînțeles, implementarea evalului va fi dificilă, deoarece trebuie să implementeze și toate funcțiile primitive, cum ar fi mașina și + și operatorii speciali, cum ar fi.) În acest caz, un REPL de bază nu este altceva decât o singură linie de cod:

 ( buclă ( print ( eval ( citire ))))

O posibilă implementare a evalului este ca un interpret recursiv care acționează pe arborele sintaxei abstracte creat de read . O altă posibilitate este de a compila arborele de sintaxă în codul mașinii și de a-l rula.

Funcționalitate

Caracteristici tipice oferite de Lisp REPL:

  • Istoricul intrărilor și ieșirilor.
  • Variabilele sunt setate pentru expresii de intrare și rezultate. Aceste variabile sunt disponibile și în REPL. De exemplu, în Common Lisp * se referă la ultimul rezultat, ** și *** la rezultatele anterioare.
  • Niveluri de REPL. În multe sisteme Lisp, dacă apare o eroare în timp ce citiți, evaluați sau tipăriți o expresie, sistemul nu este recuperat cu un mesaj de eroare. În schimb, în ​​noul REPL la nivel mai profund, acesta este început în contextul erorii. Utilizatorul poate apoi să inspecteze problema, să o corecteze și să continue dacă este posibil. Dacă apare o eroare, cum ar fi un REPL de depanare, este pornit un alt REPL, din nou cu un nivel mai adânc. REPL oferă deseori comenzi speciale de depanare.
  • Tratarea erorilor . REPL oferă reporniri. Aceste reporniri pot fi utilizate, atunci când apare o eroare, pentru a reveni la un anumit nivel REPL.
  • Intrare sensibilă la mouse și ieșire obiect de date.
  • Procesarea și completarea intrărilor specifice contextului pentru simboluri, nume de căi, nume de clase și alte obiecte.
  • Ajutor și documentație pentru comenzi.
  • Variabile pentru controlul jucătorului. De exemplu, variabila * read-base * controlează unde numerele de bază sunt citite în mod implicit.
  • Variabile pentru controlul imprimantei. Exemplu: lungimea maximă sau adâncimea maximă a expresiilor de tipărit.
  • Sintaxă de comandă suplimentară. Unele REPL-uri au comenzi care nu respectă sintaxa expresiei s, dar lucrează adesea cu date Lisp ca argumente.
  • Diagramele REPL. Unele Lisp REPL (CLIM Listener este un exemplu) acceptă, de asemenea, intrări și ieșiri grafice.

Notă

  1. ^ ISBN 978-1-31612322-5 .

linkuri externe