Hi, I'm glad to introduce `cond-feature', a macro that does the exact same thing as `cond-expand' but for Guile's built-in features:
(cond-feature ((and system posix) (system "rm -rf /")) (gettext (gettext "failed")) (else "failed")) Of course, we could keep using code like: (if (provided? 'stuff) (do-stuff) (do-as-if-we-had-stuff)) The main issue with such constructs is that they are evaluated at run-time instead of compile-time, unlike `cond-expand' which is explicitly compiler-friendly [0]. Ok, this makes no difference for our interpreter, but it's better to avoid encouraging reliance on implementation details. What do you think? If no one disagrees, I'd be happy to merge this in HEAD, along with a bit of documentation. Thanks, Ludo'. PS: I also hesitated when choosing the name but this one has the advantage of not being too ambiguous. [0] http://srfi.schemers.org/srfi-0/srfi-0.html
--- orig/ice-9/boot-9.scm +++ mod/ice-9/boot-9.scm @@ -3245,25 +3245,17 @@ (append (hashq-ref %cond-expand-table mod '()) features))))) -(define cond-expand +(define (make-cond-expand-macro feature-available? + syntax-error unfulfilled-error) (procedure->memoizing-macro (lambda (exp env) - (let ((clauses (cdr exp)) - (syntax-error (lambda (cl) - (error "invalid clause in `cond-expand'" cl)))) + (let ((clauses (cdr exp))) (letrec ((test-clause (lambda (clause) (cond ((symbol? clause) - (or (memq clause %cond-expand-features) - (let lp ((uses (module-uses (env-module env)))) - (if (pair? uses) - (or (memq clause - (hashq-ref %cond-expand-table - (car uses) '())) - (lp (cdr uses))) - #f)))) + (feature-available? clause env)) ((pair? clause) (cond ((eq? 'and (car clause)) @@ -3295,7 +3287,7 @@ (let lp ((c clauses)) (cond ((null? c) - (error "Unfulfilled `cond-expand'")) + (unfulfilled-error)) ((not (pair? c)) (syntax-error c)) ((not (pair? (car c))) @@ -3309,6 +3301,21 @@ (else (lp (cdr c)))))))))) +(define cond-expand + (make-cond-expand-macro (lambda (clause env) + (or (memq clause %cond-expand-features) + (let lp ((uses (module-uses (env-module env)))) + (if (pair? uses) + (or (memq clause + (hashq-ref %cond-expand-table + (car uses) '())) + (lp (cdr uses))) + #f)))) + (lambda (clause) + (error "invalid clause in `cond-expand'" clause)) + (lambda () + (error "unfulfilled `cond-expand'")))) + ;; This procedure gets called from the startup code with a list of ;; numbers, which are the numbers of the SRFIs to be loaded on startup. ;; @@ -3323,6 +3330,22 @@ +;;; `cond-feature' +;;; + +(define cond-feature + ;; Provide a mechanism similar to `cond-expand' for Guile's built-in + ;; features. + (make-cond-expand-macro (lambda (clause env) + (provided? clause)) + (lambda (clause) + (error "invalid clause in `cond-feature'" + clause)) + (lambda () + (error "unfulfilled `cond-feature'")))) + + + ;;; srfi-55: require-extension ;;;
_______________________________________________ Guile-devel mailing list Guile-devel@gnu.org http://lists.gnu.org/mailman/listinfo/guile-devel