David, hello.
On 21 Nov 2016, at 17:37, David Storrs wrote:
> In Perl I would often write:
>
> sub do_something {
> return unless ( some necessary condition is met );
> ... do the thing ...
> }
One (not-really-an-)answer is that that's an intrinsically procedural
way of thinking about the function, which is therefore 'un-schemey', and
going against the grain. That seems a good answer if you attach a
particular value to idiomatic code, less so otherwise.
Another answer is to write something like
(or (and (necessary-condition-not-met) 'early-return-value)
;; other guards?...
(do-the-thing))
If (necessary-condition-not-met) is true, then this expression will
evaluate to 'early-return-value. That does add the extra level of
indentation you didn't want, but it may look quite natural (or hideous),
depending on the precise circumstances.
A third answer is, as you mentioned, calling with call/cc. Calling
explicitly with call/cc might indeed look untidy, but if this is
something you're using in a couple of places, then it's possible to wrap
it up prettily:
(require racket/stxparam)
(define-syntax-parameter check
(lambda (stx)
(raise-syntax-error (syntax-e stx) "can only be used inside
do-something-while-checking")))
(define-syntax-rule (do-something-while-checking form . forms)
(call/cc (lambda (*bail-out)
(define (check* ok?) ; ok? must be a thunk
(or (ok?) (*bail-out 'early-return-value)))
(syntax-parameterize ((check (make-rename-transformer
#'check*)))
form . forms))))
(define (necessary-condition-met) #f)
(do-something-while-checking
(check necessary-condition-met)
(printf "hello2~%"))
All the best,
Norman
--
Norman Gray :
https://nxg.me.uk
SUPA School of Physics and Astronomy, University of Glasgow, UK