Use #f as a sentinel value. (See also: anaphoric if)
(cond ((return-an-object-or-false)
=> (lambda (the-object)
(do-something-with-object the-object))))
(let ((the-object (or (return-an-object-or-false)
default-object))))
It'd be nice if read-line followed this convention.
(define (anaphoric-read-line port)
(let ((line (read-line port)))
(if (eof? line) #f line)))
Here's a macro for anaphoric cond:
(My attempt at supporting "non-binding" clauses is flawed. I may have to reintroduce some sort of literal symbol to indicate when you want binding. e.g. (line <- (anaphoric-read-line) (display line)))
(define-syntax if*
(syntax-rules ()
((_ "aux" ((var test) form . forms))
(test => (lambda (var) form . forms)))
((_ "aux" (test form . forms))
(test form . forms))
((_ clause ...)
(cond (if* "aux" clause) ...))))
It might be used like this:
(if* ((the-object (return-an-object-or-false))
(do-something-with-object the-object))
((line (anaphoric-read-line))
(display line)
(newline))
(#t
(display "The else case.")
(newline)))
I like predicates that return their argument instead of #t. Useful for anaphoric conds.
(define (make-predicate-better p?)
(lambda (obj)
(if (p? obj)
obj
#f)))
(define symbol?? (make-predicate-better symbol?))
For conditionals, just use cond. Unless it's the simple kind of thing you would use ?: for in C; if is OK for that. In almost all cases, cond doesn't have significantly more overhead than if, when, or unless.
Implicit begin macros
Macros often contain a form . forms in the pattern that expands into a (begin form . forms) or (lambda () form . forms) or something similar.
(define-syntax when
(syntax-rules ()
((when condition form . forms)
(if condition (begin form . forms) #f))))
See JRM's Syntax-rules Primer for the Merely Eccentric
The identity function is spelled values. The values function is equivalent to (lambda (x) x).
last updated 2 years ago
#