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

Re: [Scheme-reports] Formal Response #382: Allow "if" to accept arbitrarily many if-then pairs

The difficulty is using the newly defined "if" in the definition of low-level macros, or otherwise at compile-time.  This seems to be due to Racket's phase separation.  Is there a way to turn that off?

#lang racket

(require syntax/parse/define)
(define-simple-macro (if (~seq test result) ... final)
  (cond [test result] ... [else final]))

(if (even? 7) "seven" (odd? 8) "eight" "neither")

(require mzlib/defmacro)

(defmacro meh (x)
  (if (> x 5)
      (> x 2)

Running this in DrRacket produces:

if: bad syntax;
 has 5 parts after keyword in: (if (> x 5) 1 (> x 2) 2 3)

The same happens if you put (begin-for-syntax (if #f 1 #f 2 3)) or (define-for-syntax n (if #f 1 #f 2 #f 3)) after your supplied definition.  (For those not familiar, the "-for-syntax" forms in Racket execute things at compile-time, or I believe "phase 1" rather than "phase 0".)  However, it works to use "if" with three arguments there: it is using the built-in definition of "if", which appears to be present at all of Racket's compilation phases by default.

What I want is the intermixing of runtime and compilation time that the phase separation seems determined to prevent (e.g. define a macro, use that macro in the definition--not expansion--of another macro, use that macro in the definition of another macro, and so on).  I tried this a long time ago and became convinced it was impossible without insane workarounds.
--John Boyle
Science is what we understand well enough to explain to a computer. Art is everything else we do. --Knuth

On Thu, Oct 11, 2012 at 6:54 PM, Sam Tobin-Hochstadt <samth@x> wrote:
On Thu, Oct 11, 2012 at 9:29 PM, John Boyle <johnthescavenger@x> wrote:
> While all Schemes I've tested that support define-syntax do allow
> redefinition of "if"... on Racket, it does not play well with low-level
> macros (using datum->syntax, or the "mzlib/defmacro" library) due to their
> phase-separation.

This is somewhat off-topic for the formal comment, but it's quite easy
to do this in Racket:

#lang racket ;; https://gist.github.com/3876906

(require syntax/parse/define)
(define-simple-macro (if (~seq test result) ... final)
  (cond [test result] ... [else final]))

(if (even? 7) "seven" (odd? 8) "eight" "neither")

I'm not sure what difficulty you ran into, but it shouldn't be
necessary to use `datum->syntax`, `defmacro`, or any other low-level
sam th

Scheme-reports mailing list