Homoikoničnost (od grčkih reči homo što znači isto i ikone što znači predstavljanje) u programiranju je vlasništvo pojedinih programskih jezika u kojima je programska struktura slična njegovoj sintaksi, a samim tim interna reprezentacija ovog programa može se zaključiti čitanjem teksta rasporeda.[1] Ako je jezik homoiconicity, to znači da tekst jezika ima istu strukturu kao apstraktno sintaksno stablo (tj AST i sintakse su izomorfne). Ovo omogućava da se svim kodovima u jeziku može pristupiti i i da mogu da se transformišu kao podaci, koristeći istu reprezentaciju.

U homoiconic jeziku primarno predstavljanje programa je takođe struktura podataka u primitivnom tipu samog jezika. To čini metaprogramiranje lakše nego u jeziku bez ovog svojstva, jer kod može da se tretira kao podatak: refleksija u jeziku (ispitivanje programskih lica na rantajmu zavisi od jedne, homogene strukture, i ne mora da sredi nekoliko različitih struktura da će se pojaviti u složenoj sintaksi. Na drugačiji način, homoiconicity je mesto gde je izvorni kod programa napisan kao osnovna struktura podataka da bi programski jezik znao kako da mu pristupi.

Tipičan, često citirani primer je programski jezik Lisp, koji je stvoren da bude lak za manipulaciju lista i gde je strukturu dao S-izrazima koji su u obliku ugnježdenih lista. Lisp programi su pisani u obliku spiskova; rezultat je da program može pristupiti svoje funkcije i procedure u toku rada, i programski reprogram je u hodu. Homoiconic jezici obično uključuju punu podršku sintaksnih makroa omogućavajući programeru da izrazi program transformaciju na koncizan način. Primeri su programski jezici Clojure, što je savremeni dijalekt Lisp-a, Rebol-a i Refal-a.

Istorija

uredi

Originalni izvor je papir Makro instrukcja proširenja kompajler jezika,[2] prema prvom i uticajnom papiru TRAC, tekst za rukovanje jezikom:[3]

Jedan od glavnih ciljeva dizajna je da ulaz skripta za TRAC (što se otkuca od strane korisnika) bude identičan sa tekstom koji vodi unutrašnju akciju TRAC procesora. Drugim rečima,  TRAC procedure treba čuvati u memoriji kao niz znakova tačno onako kako ih korisnik otkuca na tastaturi. Ako TRAC procedure same razvijaju nove procedure, te nove procedure treba da budu navedene u istom scenariju. TRAC procesor u svojoj akciji tumači ovaj scenario kao svoj program. Drugim rečima, TRAC prevodilac programa (procesor) efektivno pretvara računar u novi računar sa novim programskim jezikom - TRAC jezik. U svakom trenutku, trebalo bi da bude moguće da se prikaže program ili proceduralne informacije u istom obliku po kom će TRAC procesor postupiti tokom svog izvršenja. Poželjno je da unutrašnji karakter kod bude identičan, ili vrlo sličan, spoljnoj reprezentaciji koda. U ovoj implementaciji TRAC-a, predstavljanje internog karaktera se zasniva na ASCII-u. Zbog TRAC procedure i tekst ima istu zastupljenost unutar i izvan procesora, termin homoiconic se primenjuje, od reči homo što znači isto i ikone što znači predstavljanje.

[...]

Nakon predloga McCullough-a, W. S. na osnovu terminologije zbog Peirce, C. S. s McIlroy. M. D. "Makro instikcja proširenja kompajler jezika", Comm. ACM. str. 214-220; April, 1960.

Alan Kej je koristio i eventualno popularizovao termin "homoiconic" kroz njegovu upotrebu termina u njegovoj doktorskoj disertaciji 1969-e:[4]

{{quote|Značajna grupa izuzetaka svih prethodnih sistema su interaktivni LISP [...] i TRAC. Oba su funkcionalno orijentisana (jednoj listi, a drugi string), oba razgovaraju sa korisnikom sa jednog jezika, i oba su "homoiconic" u njihovoj unutrašnjoj i spoljašnjoj reprezentacija što je u suštini isto. Oba imaju sposobnost da dinamički stvore nove funkcije koje se tada mogu razraditi na zadovoljstvo korisnika.

Njihova jedina velika mana je da programi pisani u njima izgledaju kao pismo kralja Burna-Buriaša na Sumerskom rađeno kao vavilonsko klinasto pismo![...]

Koristi, prednosti i mane,

uredi

Jedna od prednosti homoiconicity-a je da prošireni jezik sa novim konceptima obično postaje jednostavniji, jer podaci koji predstavljaju broj se mogu preneti između meta i podloge programa. Apstraktno sintaksno stablo funkcije može se sastaviti i manipulisti njime kao struktura podataka u meta sloju, a zatim onda proceniti. To može biti mnogo lakše da se razume kako se manipuliše kodom jer se može lakše razumeti kao jednostavniji podatak (od formata jezika sama je kao format podataka).

Jednostavnost koja omogućava ovo takođe predstavlja nedostatak: jedan bloger je tvrdio da, barem u slučaju LISP-a-poput list-orijentisanih jezika, to može da uradi u gostima sa mnogim vizuelnim znakovima koji pomažu da ljudi vizuelno analiziraju i poimanju jezik, i da to može dovesti do strmog učenja  krive za jezik.[5] Pogledajte takođe esej "Lisp kletva"[6] za nedostatke. Tipična demonstracija homoiconicity-a je meta-circula evaluator.

Primeri

uredi

Jezici koje su smatrani da su homoiconic uključuju

U Fon Nojmanovoj arhitekturi sistema (uključujući veliku većinu opšte namene računara danas), sirova kod mašina ima ovu osobinu, tip podataka koji se bajtuje u memoriji.

Homoikoničnost u Lisp-u

uredi

Lisp koristi S-izraze kao spoljna reprezentacija za podatke i kod.  S-izrazi se mogu pročitati sa primitivne Lisp funkcije READ. READ vraća Lisp podatke: liste, simboli, brojevi, stringovi. Primitivna READ funkcija EVAL koristi Lisp kod predstavljen kao Lisp podatak, izračunava nuspojave i vraća rezultat. Rezultat će biti odštampan na primitivnoj funkciji PRINT, čime se stvara spoljni S-izraz iz Lisp podataka.

Lisp podatak, lista upotrebom različitih tipova podataka (sub)liste, simboli, stringovi i celi brojevi.

((:name "john" :age 20) (:name "mary" :age 18) (:name "alice" :age 22))

Lisp kod. Ovaj primer koristi liste, simbole i brojeve.

(* (sin 1.1) (cos 2.03)) ; у infix-у: sin(1.1)*cos(2.03)

Napravite nad izrazom sa primitivnom Lisp listom funkcije i postavite promenljivu EXPRESSION na rezultat

(setf expression (list '* (list 'sin 1.1) (list 'cos 2.03)) ) 
-> (* (SIN 1.1) (COS 2.03)) ; Лисп враћа и штампа резултат

(third expression) ; Трећи елемент израза
-> (COS 2.03)

Promena COS termina za SIN

(setf (first (third expression)) 'SIN)
; Израз је сада (* (SIN 1.1) (SIN 2.03)).

Procenite izraz

(eval expression)
-> 0.7988834

Štampa izraz u nizu

(print-to-string expression)
-> "(* (SIN 1.1) (SIN 2.03))"

Čitanje izraza niza

(read-from-string "(* (SIN 1.1) (SIN 2.03))")
-> (* (SIN 1.1) (SIN 2.03)) ; враћа списак листе, бројева и симбола

Homoiconicity u Prolog-u

uredi
1 ?- X is 2*5.
X = 10.

2 ?- L = (X is 2*5), write_canonical(L).
is(_, *(2, 5))
L = (X is 2*5).

3 ?- L = (ten(X):-(X is 2*5)), write_canonical(L).
:-(ten(A), is(A, *(2, 5)))
L = (ten(X):-X is 2*5).

4 ?- L = (ten(X):-(X is 2*5)), assert(L).
L = (ten(X):-X is 2*5).

5 ?- ten(X).
X = 10.

6 ?-

Na liniji 4 stvaramo novu klauzulu. Operator ": -" odvaja glavu i telo klauzule. Sa tvrdnjom/1* mi je dodajemo u postojećim klauzulama (da je dodate u "bazu"), tako da je možemo nazvati kasnije. U drugim jezicima bismo je nazvali "stvaranjem neke funkcije u rantajmu". Takođe možemo ukloniti klauzule iz baze podataka sa ukinutom/1, ili povučenom/1.

  • Broj nakon imena klauzule je broj argumenata koji možemo uzeti. (to se naziva ariti.)

Takođe možemo upitati bazu podataka da dobije telo klauzulom:

7 ?- clause(ten(X),Y).
Y = (X is 2*5).

8 ?- clause(ten(X),Y), Y = (X is Z).
Y = (X is 2*5),
Z = 2*5.

9 ?- clause(ten(X),Y), call(Y).
X = 10,
Y = (10 is 2*5).

"poziv" je analogan Lisp's "eval" funkcije.

Homoiconicity u Rebo-u

uredi

Koncept lečenja koda kao podatak i manipulacija i evaluacija njega može dokazati vrlo uredno u Rebol.. (Rebol, za razliku od Lisp-a, ne zahteva da se zagradama razdvoje izrazi).

Sledi primer koda u Rebol-u (Imajte na umu da '>>' predstavlja tumača upita; razmaci između pojedinih elemenata su dodati za čitljivosti):

>> понављање i 3 [ стампање [ i "здраво" ] ]

Ovo ocenjuje sledeći izlaz:

1 здраво
2 здраво
3 здраво

(ponavljanje je, u stvari, ugrađena funkcija u Rebol i nije jezik konstrukcija ili ključne reči). Staviti kod u zagrade, prevodilac to ne procenjuje, ali samo ga tretira kao blok koji sadrži reči:

[ понављање i 3 [ стампање [ i "здраво" ] ] ]

Ovaj blok ima tip bloka! i može dalje biti dodeljen kao vrednost reči koristeći ono što se čini da je sintaksa za zadatak, ali zapravo razume prevodioca kao posebnu vrstu (set-reč!) i ima oblik reči, praćeno dvotačkom :

>> блок1: [ понављање i 3 [ стампање [ i "здраво" ] ] ] ;; Додела вредности блок на реч `блок1`
== [repeat i 3 [print [i "hello"]]]
>> тип? блок1 ;; Процените врсту речи `блок1`
== блок!

Blok se i dalje može tumačiti pomoću funkcionalne obezbeđenosti u Rebol-u (kao "eval" u Lisp).

Moguće je da ispita elemente bloka i promeni njihove vrednosti, čime menjaju ponašanje koda ako je trebalo da se oceni:

>> блок1/3 ;; Трећи елемент блока
== 3
>> блок1/3: 5 ;; Подесите вредност 3. елемента у 5
== 5
>> проба блок1 ;; Показати промену блока
[ понављање i 5 [ стампање [ i "здраво" ] ] ]
== [ понављање i 5 [ стампање [ i "здраво" ] ] ]
>> до блок1 ;; Процените блок
1 здраво
2 здраво
3 здраво
4 здраво
5 здраво

Vidi još

uredi
  • Concatenative programski jezik
  • Kognitivne dimenzije notacija, principi dizajna za sintakse programskih jezika '

Reference

uredi
  1. ^ Wheeler, David A. „Readable Lisp S-expressions”. 
  2. ^ Douglas McIlroy (1960) Macro Instruction Extensions of Compiler Languages”. doi:10.1145/367177.367223. 
  3. ^ Calvin Mooers and L. Peter Deutsch (1965) „TRAC, A Text-Handling Language”. doi:10.1145/800197.806048. 
  4. ^ Alan Kay (1969) The Reactive Engine, PhD thesis (Accessed 20061229)
  5. ^ a b v Homoiconic languages Arhivirano na sajtu Wayback Machine (2. februar 2013), in true Blue blog at Oracle
  6. ^ The Lisp Curse, at Winestock Webdesign
  7. ^ a b v g d đ e ž Homoiconic Languages
  8. ^ Shapiro, Ehud Y.; Sterling, Leon (1994). The art of Prolog: advanced programming techniques. Cambridge, Mass: MIT Press. ISBN 978-0-262-19338-2. 
  9. ^ S. Ramsay and B. Pytlik-Zillig, Code-Generation Techniques for XML Collections Interoperability Arhivirano na sajtu Wayback Machine (3. mart 2016), Digital Humanities 2012 conference proceedings.
  10. ^ Wolfram Language Notes for Programming Language Experts

Literatura

uredi