fbpx
Wikipedia

Homoiconicity

In computer programming, homoiconicity (from the Greek words homo- meaning "the same" and icon meaning "representation") is a property of some programming languages. A language is homoiconic if a program written in it can be manipulated as data using the language.[1] The program's internal representation can thus be inferred just by reading the program itself. This property is often summarized by saying that the language treats code as data.

In a homoiconic language, the primary representation of programs is also a data structure in a primitive type of the language itself.[1] This makes metaprogramming easier than in a language without this property: reflection in the language (examining the program's entities at runtime) depends on a single, homogeneous structure, and it does not have to handle several different structures that would appear in a complex syntax. Homoiconic languages typically include full support of syntactic macros, allowing the programmer to express transformations of programs in a concise way.

A commonly cited example is Lisp, which was created to allow for easy list manipulations and where the structure is given by S-expressions that take the form of nested lists, and can be manipulated by other Lisp code.[2] Other examples are the programming languages Clojure (a contemporary dialect of Lisp), Rebol (also its successor Red), Refal, Prolog, and possibly Julia (see the section “Implementation methods” for more details).

History edit

The term first appeared in connection with the TRAC programming language, developed by Calvin Mooers:[3]

One of the main design goals was that the input script of TRAC (what is typed in by the user) should be identical to the text which guides the internal action of the TRAC processor. In other words, TRAC procedures should be stored in memory as a string of characters exactly as the user typed them at the keyboard. If the TRAC procedures themselves evolve new procedures, these new procedures should also be stated in the same script. The TRAC processor in its action interprets this script as its program. In other words, the TRAC translator program (the processor) effectively converts the computer into a new computer with a new program language -- the TRAC language. At any time, it should be possible to display program or procedural information in the same form as the TRAC processor will act upon it during its execution. It is desirable that the internal character code representation be identical to, or very similar to, the external code representation. In the present TRAC implementation, the internal character representation is based upon ASCII. Because TRAC procedures and text have the same representation inside and outside the processor, the term homoiconic is applicable, from homo meaning the same, and icon meaning representation.

The last sentence above is annotated with footnote 4, which gives credit for the origin of the term:[a]

Following suggestion of McCullough W. S., based upon terminology due to Peirce, C. S.

The researchers implicated in this quote might be neurophysiologist and cybernetician Warren Sturgis McCulloch (note the difference in the surname from the note) and philosopher, logician and mathematician Charles Sanders Peirce.[5] Pierce indeed used the term "icon" in his Semiotic Theory. According to Peirce, there are three kinds of sign in communication: the icon, the index and the symbol. The icon is the simplest representation: an icon physically resembles that which it denotes.

Alan Kay used and possibly popularized the term "homoiconic" through his use of the term in his 1969 PhD thesis:[6]

A notable group of exceptions to all the previous systems are Interactive LISP [...] and TRAC. Both are functionally oriented (one list, the other string), both talk to the user with one language, and both are "homoiconic" in that their internal and external representations are essentially the same. They both have the ability to dynamically create new functions which may then be elaborated at the users's pleasure. Their only great drawback is that programs written in them look like King Burniburiach's letter to the Sumerians done in Babylonian cuniform! [...]

Uses and advantages edit

One advantage of homoiconicity is that extending the language with new concepts typically becomes simpler, as data representing code can be passed between the meta and base layer of the program. The abstract syntax tree of a function may be composed and manipulated as a data structure in the meta layer, and then evaluated. It can be much easier to understand how to manipulate the code since it can be more easily understood as simple data (since the format of the language itself is as a data format).

A typical demonstration of homoiconicity is the meta-circular evaluator.

Implementation methods edit

All Von Neumann architecture systems, which includes the vast majority of general purpose computers today, can implicitly be described as homoiconic due to the way that raw machine code executes in memory, the data type being bytes in memory. However, this feature can also be abstracted to the programming language level.

Languages such as Lisp and its dialects,[7] such as Scheme,[8] Clojure, and Racket employ S-expressions to achieve homoiconicity, and are considered the "Purest" forms of homoiconicity, as these languages use the same representation for both data and code.

Other languages provide data structures for easily and efficiently manipulating code. Notable examples of this weaker form of homoiconicity include Julia, Nim, and Elixir.

Languages often considered to be homoiconic include:

In Lisp edit

Lisp uses S-expressions as an external representation for data and code. S-expressions can be read with the primitive Lisp function READ. READ returns Lisp data: lists, symbols, numbers, strings. The primitive Lisp function EVAL uses Lisp code represented as Lisp data, computes side-effects and returns a result. The result will be printed by the primitive function PRINT, which creates an external S-expression from Lisp data.

Lisp data, a list using different data types: (sub)lists, symbols, strings and integer numbers.

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

Lisp code. The example uses lists, symbols and numbers.

(* (sin 1.1) (cos 2.03)) ; in infix: sin(1.1)*cos(2.03) 

Create above expression with the primitive Lisp function LIST and set the variable EXPRESSION to the result

(setf expression (list '* (list 'sin 1.1) (list 'cos 2.03)) )  -> (* (SIN 1.1) (COS 2.03)) ; Lisp returns and prints the result (third expression) ; the third element of the expression -> (COS 2.03) 

Change the COS term to SIN

(setf (first (third expression)) 'SIN) ; The expression is now (* (SIN 1.1) (SIN 2.03)). 

Evaluate the expression

(eval expression) -> 0.7988834 

Print the expression to a string

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

Read the expression from a string

(read-from-string "(* (SIN 1.1) (SIN 2.03))") -> (* (SIN 1.1) (SIN 2.03)) ; returns a list of lists, numbers and symbols 

In Prolog edit

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 ?- 

On line 4 we create a new clause. The operator :- separates the head and the body of a clause. With assert/1* we add it to the existing clauses (add it to the "database"), so we can call it later. In other languages we would call it "creating a function during runtime". We can also remove clauses from the database with abolish/1, or retract/1.

* The number after the clause's name is the number of arguments it can take. It is also called arity.

We can also query the database to get the body of a clause:

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). 

call is analogous to Lisp's eval function.

In Rebol edit

The concept of treating code as data and the manipulation and evaluation thereof can be demonstrated very neatly in Rebol. (Rebol, unlike Lisp, does not require parentheses to separate expressions).

The following is an example of code in Rebol (Note that >> represents the interpreter prompt; spaces between some elements have been added for readability):

>> repeat i 3 [ print [ i "hello" ] ] 1 hello 2 hello 3 hello 

(repeat is in fact a built-in function in Rebol and is not a language construct or keyword).

By enclosing the code in square brackets, the interpreter does not evaluate it, but merely treats it as a block containing words:

[ repeat i 3 [ print [ i "hello" ] ] ] 

This block has the type block! and can furthermore be assigned as the value of a word by using what appears to be a syntax for assignment, but is actually understood by the interpreter as a special type (set-word!) and takes the form of a word followed by a colon:

>> block1: [ repeat i 3 [ print [ i "hello" ] ] ] ;; Assign the value of the block to the word `block1` == [repeat i 3 [print [i "hello"]]] >> type? block1 ;; Evaluate the type of the word `block1` == block! 

The block can still be interpreted by using the do function provided in Rebol (similar to eval in Lisp).

It is possible to interrogate the elements of the block and change their values, thus altering the behavior of the code if it were to be evaluated:

>> block1/3 ;; The third element of the block == 3 >> block1/3: 5 ;; Set the value of the 3rd element to 5 == 5 >> probe block1 ;; Show the changed block == [repeat i 5 [print [i "hello"]]] >> do block1 ;; Evaluate the block 1 hello 2 hello 3 hello 4 hello 5 hello 

See also edit

Notes edit

  1. ^ Previous versions of this Wikipedia page 2006-2023 conflated the unrelated note 5 of the above TRAC paper, resulting in the wrong claim that the term "homoiconic" had origins in a paper on macro processing by Douglas McIlroy. That paper mentions no terminology even remotely similar; its influence on the TRAC work is of a different nature. This claim has since been repeated by some sources.[4]

References edit

  1. ^ a b Ceravola, Antonello; Joublin, Frank (2021). "From JSON to JSEN through Virtual Languages". Open Journal of Web Technologies. 8 (1): 1–15. In a homoiconic language, the primary representation of programs is also a data structure in a primitive type of the language itself
  2. ^ Wheeler, David A. "Readable Lisp S-expressions".
  3. ^ Mooers, C.N.; Deutsch, L.P. (1965). "TRAC, A Text-Handling Language". Proceeding ACM '65 Proceedings of the 1965 20th national conference. pp. 229–246. doi:10.1145/800197.806048.
  4. ^ Mannaert, Herwig; McGroarty, Chris; Gallant, Scott; De Cock, Koen; Gallogly, Jim; Raval, Anup; Snively, Keith (2022). "Toward Scalable Collaborative Metaprogramming: A Case Study to Integrate Two Metaprogramming Environments" (PDF). International Journal on Advances in Software. 15: 128–140. ISSN 1942-2628.
  5. ^ "Don't say "Homoiconic"". Expressions of Change. 1 March 2018.
  6. ^ Kay, Alan (1969). The Reactive Engine (PhD). University of Utah.
  7. ^ a b c d e f g h i Homoiconic Languages
  8. ^ a b , in true Blue blog at Oracle
  9. ^ "Lispy Elixir". 8thlight.com. Elixir, on the surface, is not homoiconic. However, the syntax on the surface is just a facade for the homoiconic structure underneath.
  10. ^ "Why we created Julia". julialang.org. We want a language that's homoiconic, with true macros like Lisp, but with obvious, familiar mathematical notation like Matlab.
  11. ^ "metaprogramming". docs.julialang.org. Like Lisp, Julia represents its own code as a data structure of the language itself.
  12. ^ Shapiro, Ehud Y.; Sterling, Leon (1994). The art of Prolog: advanced programming techniques. MIT Press. ISBN 0-262-19338-8.
  13. ^ Ramsay, S.; Pytlik-Zillig, B. (2012). "Code-Generation Techniques for XML Collections Interoperability". dh2012 Digital Humanities Conference Proceedings.
  14. ^ "Notes for Programming Language Experts". Wolfram Language. Wolfram. 2017.

External links edit

  • Definition of Homoiconic at the C2 Wiki

homoiconicity, computer, programming, homoiconicity, from, greek, words, homo, meaning, same, icon, meaning, representation, property, some, programming, languages, language, homoiconic, program, written, manipulated, data, using, language, program, internal, . In computer programming homoiconicity from the Greek words homo meaning the same and icon meaning representation is a property of some programming languages A language is homoiconic if a program written in it can be manipulated as data using the language 1 The program s internal representation can thus be inferred just by reading the program itself This property is often summarized by saying that the language treats code as data In a homoiconic language the primary representation of programs is also a data structure in a primitive type of the language itself 1 This makes metaprogramming easier than in a language without this property reflection in the language examining the program s entities at runtime depends on a single homogeneous structure and it does not have to handle several different structures that would appear in a complex syntax Homoiconic languages typically include full support of syntactic macros allowing the programmer to express transformations of programs in a concise way A commonly cited example is Lisp which was created to allow for easy list manipulations and where the structure is given by S expressions that take the form of nested lists and can be manipulated by other Lisp code 2 Other examples are the programming languages Clojure a contemporary dialect of Lisp Rebol also its successor Red Refal Prolog and possibly Julia see the section Implementation methods for more details Contents 1 History 2 Uses and advantages 3 Implementation methods 3 1 In Lisp 3 2 In Prolog 3 3 In Rebol 4 See also 5 Notes 6 References 7 External linksHistory editThe term first appeared in connection with the TRAC programming language developed by Calvin Mooers 3 One of the main design goals was that the input script of TRAC what is typed in by the user should be identical to the text which guides the internal action of the TRAC processor In other words TRAC procedures should be stored in memory as a string of characters exactly as the user typed them at the keyboard If the TRAC procedures themselves evolve new procedures these new procedures should also be stated in the same script The TRAC processor in its action interprets this script as its program In other words the TRAC translator program the processor effectively converts the computer into a new computer with a new program language the TRAC language At any time it should be possible to display program or procedural information in the same form as the TRAC processor will act upon it during its execution It is desirable that the internal character code representation be identical to or very similar to the external code representation In the present TRAC implementation the internal character representation is based upon ASCII Because TRAC procedures and text have the same representation inside and outside the processor the term homoiconic is applicable from homo meaning the same and icon meaning representation The last sentence above is annotated with footnote 4 which gives credit for the origin of the term a Following suggestion of McCullough W S based upon terminology due to Peirce C S The researchers implicated in this quote might be neurophysiologist and cybernetician Warren Sturgis McCulloch note the difference in the surname from the note and philosopher logician and mathematician Charles Sanders Peirce 5 Pierce indeed used the term icon in his Semiotic Theory According to Peirce there are three kinds of sign in communication the icon the index and the symbol The icon is the simplest representation an icon physically resembles that which it denotes Alan Kay used and possibly popularized the term homoiconic through his use of the term in his 1969 PhD thesis 6 A notable group of exceptions to all the previous systems are Interactive LISP and TRAC Both are functionally oriented one list the other string both talk to the user with one language and both are homoiconic in that their internal and external representations are essentially the same They both have the ability to dynamically create new functions which may then be elaborated at the users s pleasure Their only great drawback is that programs written in them look like King Burniburiach s letter to the Sumerians done in Babylonian cuniform Uses and advantages editOne advantage of homoiconicity is that extending the language with new concepts typically becomes simpler as data representing code can be passed between the meta and base layer of the program The abstract syntax tree of a function may be composed and manipulated as a data structure in the meta layer and then evaluated It can be much easier to understand how to manipulate the code since it can be more easily understood as simple data since the format of the language itself is as a data format A typical demonstration of homoiconicity is the meta circular evaluator Implementation methods editAll Von Neumann architecture systems which includes the vast majority of general purpose computers today can implicitly be described as homoiconic due to the way that raw machine code executes in memory the data type being bytes in memory However this feature can also be abstracted to the programming language level Languages such as Lisp and its dialects 7 such as Scheme 8 Clojure and Racket employ S expressions to achieve homoiconicity and are considered the Purest forms of homoiconicity as these languages use the same representation for both data and code Other languages provide data structures for easily and efficiently manipulating code Notable examples of this weaker form of homoiconicity include Julia Nim and Elixir Languages often considered to be homoiconic include Adenine APL Nim Curl 7 better source needed Elixir 9 Io 7 Julia 10 11 7 Prolog 7 12 Rebol 7 Red SNOBOL 7 Tcl 8 7 XSLT 13 REFAL 7 Rexx Wolfram Language 14 In Lisp edit Lisp uses S expressions as an external representation for data and code S expressions can be read with the primitive Lisp function READ READ returns Lisp data lists symbols numbers strings The primitive Lisp function EVAL uses Lisp code represented as Lisp data computes side effects and returns a result The result will be printed by the primitive function PRINT which creates an external S expression from Lisp data Lisp data a list using different data types sub lists symbols strings and integer numbers name john age 20 name mary age 18 name alice age 22 Lisp code The example uses lists symbols and numbers sin 1 1 cos 2 03 in infix sin 1 1 cos 2 03 Create above expression with the primitive Lisp function LIST and set the variable EXPRESSION to the result setf expression list list sin 1 1 list cos 2 03 gt SIN 1 1 COS 2 03 Lisp returns and prints the result third expression the third element of the expression gt COS 2 03 Change the COS term to SIN setf first third expression SIN The expression is now SIN 1 1 SIN 2 03 Evaluate the expression eval expression gt 0 7988834 Print the expression to a string print to string expression gt SIN 1 1 SIN 2 03 Read the expression from a string read from string SIN 1 1 SIN 2 03 gt SIN 1 1 SIN 2 03 returns a list of lists numbers and symbols In Prolog edit 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 On line 4 we create a new clause The operator separates the head and the body of a clause With assert 1 we add it to the existing clauses add it to the database so we can call it later In other languages we would call it creating a function during runtime We can also remove clauses from the database with abolish 1 or retract 1 The number after the clause s name is the number of arguments it can take It is also called arity We can also query the database to get the body of a clause 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 call is analogous to Lisp s eval function In Rebol edit The concept of treating code as data and the manipulation and evaluation thereof can be demonstrated very neatly in Rebol Rebol unlike Lisp does not require parentheses to separate expressions The following is an example of code in Rebol Note that gt gt represents the interpreter prompt spaces between some elements have been added for readability gt gt span class nv repeat span span class nf i span span class nf 3 span span class nv print span span class nv i span span class c hello span 1 hello 2 hello 3 hello repeat is in fact a built in function in Rebol and is not a language construct or keyword By enclosing the code in square brackets the interpreter does not evaluate it but merely treats it as a block containing words repeat i 3 print i hello This block has the type block and can furthermore be assigned as the value of a word by using what appears to be a syntax for assignment but is actually understood by the interpreter as a special type set word and takes the form of a word followed by a colon gt gt span class err block span span class m 1 span span class err span span class nv repeat span span class nf i span span class nf 3 span span class nv print span span class nv i span span class c hello span Assign the value of the block to the word block1 repeat i 3 print i hello gt gt span class nv type span span class nf span span class nv block1 span Evaluate the type of the word block1 block The block can still be interpreted by using the do function provided in Rebol similar to eval in Lisp It is possible to interrogate the elements of the block and change their values thus altering the behavior of the code if it were to be evaluated gt gt span class nv block1 span span class nf span span class m 3 span The third element of the block 3 gt gt span class nv block1 span span class nf span span class m 3 span span class err span span class nf 5 span Set the value of the 3rd element to 5 5 gt gt span class nv probe span span class nf block1 span Show the changed block repeat i 5 print i hello gt gt span class nv do span span class nf block1 span Evaluate the block 1 hello 2 hello 3 hello 4 hello 5 helloSee also editCognitive dimensions of notations design principles for programming languages syntax Concatenative programming language Language oriented programming Symbolic programming Self modifying code LISP programming language perhaps the most well known example of a homoiconic language Metaprogramming a programming technique for which homoiconicity is very useful Reification computer science Notes edit Previous versions of this Wikipedia page 2006 2023 conflated the unrelated note 5 of the above TRAC paper resulting in the wrong claim that the term homoiconic had origins in a paper on macro processing by Douglas McIlroy That paper mentions no terminology even remotely similar its influence on the TRAC work is of a different nature This claim has since been repeated by some sources 4 References edit a b Ceravola Antonello Joublin Frank 2021 From JSON to JSEN through Virtual Languages Open Journal of Web Technologies 8 1 1 15 In a homoiconic language the primary representation of programs is also a data structure in a primitive type of the language itself Wheeler David A Readable Lisp S expressions Mooers C N Deutsch L P 1965 TRAC A Text Handling Language Proceeding ACM 65 Proceedings of the 1965 20th national conference pp 229 246 doi 10 1145 800197 806048 Mannaert Herwig McGroarty Chris Gallant Scott De Cock Koen Gallogly Jim Raval Anup Snively Keith 2022 Toward Scalable Collaborative Metaprogramming A Case Study to Integrate Two Metaprogramming Environments PDF International Journal on Advances in Software 15 128 140 ISSN 1942 2628 Don t say Homoiconic Expressions of Change 1 March 2018 Kay Alan 1969 The Reactive Engine PhD University of Utah a b c d e f g h i Homoiconic Languages a b Homoiconic languages archived in true Blue blog at Oracle Lispy Elixir 8thlight com Elixir on the surface is not homoiconic However the syntax on the surface is just a facade for the homoiconic structure underneath Why we created Julia julialang org We want a language that s homoiconic with true macros like Lisp but with obvious familiar mathematical notation like Matlab metaprogramming docs julialang org Like Lisp Julia represents its own code as a data structure of the language itself Shapiro Ehud Y Sterling Leon 1994 The art of Prolog advanced programming techniques MIT Press ISBN 0 262 19338 8 Ramsay S Pytlik Zillig B 2012 Code Generation Techniques for XML Collections Interoperability dh2012 Digital Humanities Conference Proceedings Notes for Programming Language Experts Wolfram Language Wolfram 2017 External links editDefinition of Homoiconic at the C2 Wiki Retrieved from https en wikipedia org w index php title Homoiconicity amp oldid 1186104121, wikipedia, wiki, book, books, library,

article

, read, download, free, free download, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, picture, music, song, movie, book, game, games.