A major problem I’ve found with learning scheme in isolation is that it is quite easy to pick up the syntax and then start programming in with a heavy C++ accent. Although this demonstrates the flexibility of scheme, it is not what I’m really after. The question is, how to learn to write in a good style. I can think of a number of possibilities:
- Keep writing programs in scheme and hope my style will improve
- Read books that specifically teach good scheme style
- Read real world code written in scheme
I’ve been inspired to work through some of the exercises in HTDP from various posts I’ve read on Lambda the Ultimate. So far, the book advises a similar approach to designing programs as I have seen before: decide on your data structures before writing the code and define the data structures using (define-struct …). I’ve found it a useful exercise to write functions that convert the data structures into lists that could be evaluated to re-create the original data. Here is an example, more or less from chapter 17.
(define-struct expr (op a1 a2)) (define-struct f-app (name expr)) (define-struct fn (name arg body)) (define f (make-fn 'f 'x (make-expr '+ 3 'x))) (define i (make-fn 'i 'v (make-expr '+ (make-expr '* 'v 'v) (make-expr '* 'v 'v)))) ;;; Convert expressions to lists (define (add-quote s) (string->symbol (string-append "'" (symbol->string s)))) (define (expr->list e) (cond ((expr? e) (list 'make-expr (add-quote (expr-op e)) (expr->list (expr-a1 e)) (expr->list (expr-a2 e)))) ((f-app? e) (list 'make-f-app (add-quote (f-app-name e)) (expr->list (f-app-expr e)))) ((symbol? e) (add-quote e)) ((number? e) e) (else (raise (format "Error: invalid type ~a" e))))) (define (fn->list f) (list 'make-fn (add-quote (fn-name f)) (add-quote (fn-arg f)) (expr->list (fn-body f)))) (for-each (lambda (x) (display (format "~a~%" (fn->list x)))) (list f i))