Questo è un seguito al mio previous question. Non sono convinto che il codice Lisp sia Homoiconic come codice macchina su un'architettura Von Neumann. Mi sembra ovvio che in entrambi i casi il codice sia rappresentato come dati, ma sembra anche evidente che è possibile sfruttare questa proprietà molto più liberamente nel codice macchina di quanto non sia possibile in Lisp.Livelli di omosessualità
Quando si digerisce con il codice macchina, il codice di auto modifica è così facile che accade sempre, spesso per caso e con (nella mia esperienza) risultati esilaranti. Durante la scrittura di un semplice programma "stampa il numero 0-15", potrei avere un errore "uno alla volta" con uno dei miei suggerimenti. Finirò per scaricare accidentalmente tutto ciò che è nel Registro 1 nell'indirizzo in memoria che contiene l'istruzione successiva, e al suo posto viene eseguita un'istruzione casuale. (Sempre fantastico quando si tratta di una sorta di "goto". Dio sa dove finirà e cosa farà dopo).
Non c'è davvero alcuna separazione tra codice e dati. Tutto è simultaneamente un'istruzione (anche se è solo un NOP), un puntatore e un semplice vecchio numero. Ed è possibile che il codice cambi sotto i tuoi occhi.
Per favore aiutatemi con uno scenario Lisp Mi sono grattato la testa. Dire che ho ottenuto il seguente programma:
(defun factorial (n)
(if (<= n 1)
1
(* n (factorial (- n 1)))))
; -- Demonstrate the output of factorial --
; -- The part that does the Self modifying goes here –
; -- Demonstrate the changed output of factorial
Ora quello che voglio che accada è di aggiungere a questo programma un codice Lisp che cambierà il * ad un +, modificare la < = ad un> =, bastone a (+ 1 2 3) da qualche parte lì dentro, e in generale infastidisce la funzione. E poi voglio che il programma esegua il pasticcio assoluto che ne risulta.
Punto chiave: a meno che non si sia verificato un errore irreversibile nel codice di esempio, è possibile modificare solo la parte -– More code goes here –-
. Quello che vedi sopra è il codice. Non voglio che tu citi l'intera lista e la memorizzi in una variabile in modo che possa essere manipolata e sputata come una funzione separata con lo stesso nome; Non voglio una ridefinizione standard di fattoriale come qualcosa di completamente diverso. Voglio quel codice, proprio lì che posso vedere sul mio schermo per cambiare se stesso davanti ai miei occhi, proprio come il codice macchina.
Se questa è una richiesta impossibile/irragionevole, allora consolida ulteriormente nella mia mente l'idea che l'omoiconicità non è una proprietà discreta che un linguaggio ha o non ha, è uno spettro e Lisp non lo è il bordo sanguinante. (In alternativa, il Lisp è come Homoiconic come vengono e sto cercando qualche altro termine per descrivere l'auto-modifica di codice macchina)
inoltre, inb4 commenta che il codice sul mio schermo è improbabile che cambi di fronte ai miei occhi perché è solo un testo su una pagina web. Se sinceramente non capisco cosa intendo e non sto trollando cercherò di chiarire un po 'di più :) – TheIronKnuckle
Il codice macchina tipico non è "omoiconico" e il linguaggio assembly meno. Sebbene il codice macchina sia un array di bit, i linguaggi macchina non hanno gli strumenti per manipolare specificamente matrici di bit che rappresentano programmi di linguaggio macchina. Ad esempio, data una serie di bit, non sai nemmeno dove, diciamo, inizia la diciassettesima istruzione, a meno che non siano tutti della stessa lunghezza. Se inserisci un codice in un modello, le correzioni di diramazione che attraversano il punto di inserimento devono essere ricalcolate e corrette. Hai bisogno di una grande libreria di routine per fare qualsiasi cosa, e non è inclusa nel linguaggio della macchina. – Kaz
I linguaggi delle macchine ** hanno effettivamente ** gli strumenti per manipolare in modo specifico matrici di bit che rappresentano programmi di linguaggio macchina. Ogni volta che usi un'istruzione "store" è esattamente quello che sta succedendo. – TheIronKnuckle