2013-07-29 8 views
5

Per il seguente codice:Come passare `and` come funzione in Racket?

(foldl and #t '(#t #f)) 

Racket ritorna:

and: bad syntax in: and 

So and non è una funzione. E posso aggirare questo problema utilizzando lambda:

(foldl (lambda (a b) (and a b)) #t '(#t #f)) 

Ho 2 domande qui:

  1. and non è una funzione. Allora cos'è? È una macro?

  2. La mia soluzione con lambda sembra brutta. C'è un modo migliore per risolvere questo problema?

Grazie.

+0

si può sempre abbellire con SRFI-26 (taglio) – jozefg

+1

@jozefg vuoi dire '(foldl (taglio e <><>) #t '(#t #f)) '? Ma [SRFI-26] (http://docs.racket-lang.org/srfi-std/srfi-26.html?q=cut#cut) dice anche che '(cut se <> 0 1)' è illegale perché "se" non è "un'espressione nel senso di R5RS" - che sembrerebbe rendere "e" illegale anche lì. –

+0

@WillNess Prove bene per me con la racchetta 5.3. Se questo è specifico o meno dell'implementazione, non sono sicuro – jozefg

risposta

7

È un conditionalsyntactic form o potrebbe essere implementato come una macro che si espande a qualche core syntax form, che viene considerato come un caso speciale dal compilatore/interprete.

The list there in Racket's docs include if come un modulo speciale ma non include and, quindi quest'ultimo molto probabilmente è implementato in termini del primo. Ma R5RS does list and as a syntactic keyword. Quindi, meglio possiamo dire, è una sintassi speciale o una macro.

È facile riscrivere qualsiasi forma and(and a b c ...) come if forma, (if a (if b (if C#t #f) #f) #f).

lambda mi sta bene, ma si può anche utilizzare every from SRFI-1 (o Racket's andmap):

(every identity '(#t #f)) 

should return #f.

edit: eccezione, as Joshua Taylor points out, chiamare il tuo lambda attraverso una funzione come foldl non lo fa corto circuito. Che sconfigge lo scopo di chiamare lo and in primo luogo.

Un'altra cosa è, in Racket's foldl l'argomento ultimo a lambda è quello che riceve il risultato precedente nella catena di applicazioni; così l'attuazione in realtà dovrebbe essere

(foldl (lambda (a b) (and b a)) #t '(#t #f))