Scheme: Lambda all'interno dell'elenco quotato non è associato

1

Sto programmando un piccolo interprete di lisp / schema e mi sono imbattuto nella seguente situazione:

Quando un elenco quotato contiene lambda, non vengono analizzati come lambda. Ecco un codice di esempio ( live on repl.it ):

(define list1 '(
                   (lambda (x) (+ x 1))
                   (lambda (y) (+ y 2))
                )
)

(define add1 (car list1))
(print (add1 1))

e il risultato è:

Error: ('lambda ('x) ('+ 'x 1)) is not a function [add1]

È un comportamento normale? Pensavo che i lambda fossero forme speciali che dovevano essere sempre legate.

Se è effettivamente il comportamento atteso: quando il mio parser analizza il Lambda e lo avvolge in un oggetto (diciamo, di tipo LambdaWrap) e il mio interprete restituisce quell'oggetto non valutato, allora suppongo che questo sia un comportamento sbagliato perché dovrebbe restituire invece alcuni simboli non vincolati. È giusto?

    
posta Julien__ 29.01.2016 - 13:13
fonte

1 risposta

4

Il problema è: cosa intendi con "analizzato come un lambda"? Supponiamo che scriva questo in Java:

String fun = "() -> 3"; 
int y = fun();

Fallisce, perché non ti aspetti che la stringa venga analizzata, valutata come espressione lambda ed essere direttamente utilizzabile come funzione, vero?

Lo stesso vale per le stringhe in Lisp e in modo simile con quote : il modulo quotato viene letto ma non valutato. Più precisamente, la valutazione di (quote x) restituisce x (l'espressione stessa), e non (eval x) , il valore che questa espressione produce alla valutazione.

Quindi, invece di avere un oggetto funzione, ciò che ottieni dopo aver fatto (car list1) è un elenco di valori, il primo è il simbolo lambda .

Se vuoi creare un elenco di funzioni, usa (list ...) , che valuta i suoi argomenti.

Dici:

Ok but why is the inner list evaluated ? i.e : I get ('lambda ('x) ('+ 'x 1)) instead of : ('lambda '( 'x ') '( '+ 'x 1') )

Il lettore prende le stringhe e produce un valore, che è un'espressione simbolica: ad esempio, un oggetto in memoria con i campi car e cdr .

La tua domanda presuppone che questa sia una lista di token , come le parentesi citate ecc., che non è il caso. A questo punto si manipolano gli alberi di sintassi abstract .

Per vedere questo valore, il tuo sistema deve stamparlo e prova a farlo in modo che il modulo stampato possa essere riletto. Se giochi un po 'con repl.it , puoi vedere come viene stampato un elenco normale, ecc.

Il messaggio specifico che vedi è preso da un messaggio di errore dove onestamente, il modulo è stampato in un modo strano, diverso dal normale output come visto dal REPL. Forse qualcun altro può spiegare perché questo messaggio di errore è formattato così com'è.

    
risposta data 29.01.2016 - 14:51
fonte

Leggi altre domande sui tag