2012-02-11 3 views
11

Appena avviato con Scheme. Sto avendo problemi con la stampa su console. Un semplice esempio stampa lista:Stampa console schema

(define factorial 
    (lambda (n) 
    (cond 
     ((= 0 n) 1) 
     (#t (* n (factorial (- n 1))))))) 

voglio stampare n, ogni volta che la funzione viene chiamata. Ho pensato che non posso farlo all'interno della stessa funzione? Devo chiamare un'altra funzione solo così posso stampare?

risposta

22

Stampa in schema funziona chiamando display (e possibilmente, newline). Dal momento che si desidera chiamarlo in sequenza prima/dopo qualcos'altro (che, in un linguaggio funzionale (o nel caso di Scheme, functional-ish) ha senso solo per gli effetti secondari delle funzioni chiamate), normalmente si dovrebbe usare begin, che valuta a sua volta gli argomenti e quindi restituisce il valore dell'ultima sottoespressione. Tuttavia, lambda contiene implicitamente tale espressione begin.

Quindi nel tuo caso, sarebbe andata in questo modo:

(lambda (n) 
    (display n) (newline) 
    (cond [...])) 

Due osservazioni:

  1. È possibile utilizzare (define (factorial n) [...]) come una scorciatoia per (define factorial (lambda (n) [...])).
  2. Il modo in cui si implementa factorial proibisce tail call-optimization, pertanto il programma utilizzerà un bel po 'di spazio di stack per valori maggiori di n. Tuttavia, è possibile riscriverlo in una forma ottimizzata usando un accumulatore.

Se si desidera stampare solo n una volta, quando l'utente chiama la funzione, sarete davvero bisogno di scrivere un wrapper, come questo:

(define (factorial n) 
    (display n) (newline) 
    (inner-factorial n)) 

e rinominare la funzione di inner-factorial.

+0

Non è necessario un inizio all'interno di un corpo lambda. –

+0

Oh thx! Ma che ne dici di stampare dopo la condizione? In realtà non sto lavorando a factorial, ma è più facile spiegarlo. Qualcosa come la stampa solo se la condizione è vera, cioè stampa se n! = 0. – ercliou

+1

Ho risolto la parte su 'begin'. Il corpo di una clausola 'cond' può anche contenere più espressioni, quindi puoi semplicemente chiamare' display' lì. – fnl