guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Introducing `cond-feature'


From: Ludovic Courtès
Subject: Introducing `cond-feature'
Date: Tue, 05 Dec 2006 22:45:16 +0100
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)

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
 ;;;
 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]