Homoikonitás ( homoikonitás , angol homoikonitás , angol homoikonikus , görögből ὁμός - egyenlő, azonos + „ikonitás” - a jel és a tárgy közötti hasonlósági viszony, amelyre ez a jel mutat (lásd szemiotika ) - viszont, vö. A görög εἰκόνα - „kép”, „kép”) néhány programozási nyelv olyan tulajdonsága , amelyben a program felépítése hasonló a szintaxisához , ezért a program belső reprezentációja a szövegjelölés olvasásával határozható meg [ 1] . Ha egy nyelv homoikonikus, az azt jelenti, hogy a program szövegének szerkezete megegyezik az absztrakt szintaxisfával (azaz az AST és a szintaxis izomorf ). Ez lehetővé teszi, hogy a nyelven lévő összes kódot adatként lehessen elérni és feldolgozni ugyanazzal a reprezentációval.
A homoikonikus nyelvben a programok elsődleges reprezentációja magának a nyelvnek a primitív típusában is egy adatstruktúra . Ez megkönnyíti a metaprogramozást , mint egy ilyen tulajdonság nélküli nyelvben, mivel a kód adatként is tekinthető : a nyelvben való tükrözés (a program futás közbeni szerkezetének meghatározása ) egyetlen, homogén struktúrán alapul, és nem kell kezelni. több különböző konstrukció, amelyek összetett szintaktikai struktúrákban keletkeznek. Más szóval a homoikonitás az, amikor egy program forráskódja alapvető adatstruktúraként van megírva, és a programozási nyelv tudja, hogyan lehet hozzáférni.
Tipikus példa erre a Lisp programozási nyelv , amelyet úgy terveztek, hogy könnyen kezelhető legyen a listákon, és ahol a struktúrát S-kifejezésekként adják meg , amelyek beágyazott listák formájában vannak. A Lisp programok listákként vannak megírva; az eredmény az, hogy a program futás közben hozzáférhet saját funkcióihoz, valamint menet közben újraprogramozhatja magát. A homoikonikus nyelvek általában teljes mértékben támogatják a szintaktikai makrókat , lehetővé téve a programozó számára a programozási átalakítások tömör kifejezését. Ilyen programozási nyelvek például a Clojure (a Lisp modern dialektusa), a Rebol és a Refal .
A kifejezést először Doug McIlroy [2] 1960-as cikkében említette, amelyre Calvin Moores és Peter Deutsch 1965-ös cikkében hivatkoztak, amelyben az ingatlant a TRAC programozás kulcsaként mutatták be. általuk kifejlesztett nyelv [3] .
Alan Kay használta és népszerűsíthette a "homoikonitás" kifejezést, felhasználva a Lisp és a TRAC nyelv tulajdonságairól szóló Ph.D. értekezésében [4] , megjegyezve a programok olvashatósági költségeit ebben a megközelítésben: "a nyelven írt programok úgy néznek ki, mint Burna-Buriash királynak a sumérokhoz írt, babiloni ékírással nyomtatott levele .
A homoikonikusság egyik előnye, hogy a nyelv új fogalmakkal való bővítése általában egyszerűbb, mivel a kódot reprezentáló adatok átadhatók a program meta- és alaprétege között. Egy függvény absztrakt szintaktikai fája létrehozható és módosítható fémréteg adatstruktúraként, majd végrehajtható . Lehet, hogy sokkal könnyebb kitalálni, hogyan kell kezelni a kódot, mivel egyszerűbb adatként érthetőbb (hiszen egy nyelv formátuma megegyezik az adatformátumával).
Hátránya az ezt lehetővé tevő egyszerűség is: legalábbis a Lisp-szerű lista-orientált nyelvek esetében ez megszabadulhat számos olyan vizuális jelzéstől, amelyek segítenek az embereknek a nyelv konstrukcióinak vizuális elemzésében, és ez növekedéshez vezethet. a nyelv tanulási görbéjében [5] . A hiányosságok leírását lásd még a „The Curse of Lisp” [6] című esszében.
A homoikonitás tipikus demonstrációja a metacircularis számológép .
Homoikonikus programozási nyelvek:
A von Neumann architektúrarendszerekben (beleértve a modern számítógépek túlnyomó többségét) a gépi kód is rendelkezik ezzel a tulajdonsággal, a memóriában bájtok adattípussal.
A Lisp S-kifejezéseket használ az adatok és kódok külső reprezentációjaként. Az S-kifejezések egy primitív függvény segítségével olvashatók, amely READaz alapvető Lisp típusokat adja vissza: listák, karakterek, számok, karakterláncok. A Lisp primitív függvény EVALezt a Lisp-adatként ábrázolt kódot használja a mellékhatások értékelésére és az eredmény visszaadására.
Példa a Lisp-ben található adatokra egy lista, amely különféle típusú adatokat használ: (al)listákat, karaktereket, karakterláncokat és egész számokat:
(( :név "john" :életkor 20 ) ( :név "mária" : 18 éves ) ( :név "alice" : 22 éves ))Lisp kód. A példa listákat, szimbólumokat és számokat használ:
( * ( sin 1.1 ) ( cos 2.03 )) ; infixben: sin(1.1)*cos(2.03)Egy ilyen kifejezés létrehozása primitív függvénnyel LISTés az eredmény hozzárendelése egy változóhoz expression:
( setf kifejezés ( lista '* ( lista 'sin 1.1 ) ( lista 'cos 2.03 ) ) -> ( * ( SIN 1.1 ) ( COS 2.03 )) ; Lisp visszaküldi és kinyomtatja az eredményt ( harmadik kifejezés ) ; a -> kifejezés harmadik eleme ( COS 2.03 )A kifejezés lecserélése COSa SINkövetkezőre:
( setf ( első ( harmadik kifejezés )) 'SIN ) ; A kifejezés most (* (SIN 1.1) (SIN 2.03)).Kifejezés futtatása:
( eval kifejezés ) -> 0,7988834Nyomtassa ki ezt a kifejezést egy karakterláncba:
( karakterláncba nyomtatás kifejezés ) -> "(* (SIN 1.1) (SIN 2.03)"Egy kifejezés kivonása egy karakterláncból:
( read-from-string "(* (SIN 1.1) (SIN 2.03))" ) -> ( * ( SIN 1.1 ) ( SIN 2.03 )) ; listák, számok és szimbólumok listáját adja vissza