chicken-users
[Top][All Lists]
Advanced

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

Re: [Chicken-users] Some syntax help?


From: Peter Bex
Subject: Re: [Chicken-users] Some syntax help?
Date: Sat, 2 May 2015 21:36:15 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

On Sat, May 02, 2015 at 08:01:29AM -0700, Dan Leslie wrote:
> Here's the wierdness: this works magnificently in CSI, but fails in CSC.
> 
> Moreover, if I replace /m! with a broken variant then /m works great in
> both CSI and CSC! I know, it doesn't make much sense to me either. My
> best guess is that /m! failing somehow short-circuits a code path in the
> compiler and so allows /m to function as I expect.

Hello Dan,

This is a red herring.  I can't really explain why it "works", though.

> The correct code that CSC breaks on:
> https://github.com/dleslie/monad-egg/blob/compiler-import-bug/monad.scm#L58-L61
> And test output:
> https://gist.github.com/71cc934fbc9fc7fa2d86

I'm sorry to say it, but this egg contains a lot of strange mistakes and
weird things; for example, the setup-file tries to emit a module named
"funky", which does not exist.  Also, the renaming procedure from
explicit renaming macro transformers is referred to as "inject", which
is extremely misleading: that's the _opposite_ of what it does!

And, because this code is introducing new identifiers in an unhygienic
fashion, you most definitely do *not* want to rename them, so the macros
that introduce these identifiers are wrong.  However, they might work by
accident, that's what makes macrology so difficult to get right and be
sure that macros are 100% correct.

Finally, defining two modules in one file, and then having only the
second emitted and installed, which then reexports the former module
is very confusing, in my opinion.  I suppose it works, but I'm not sure
this is how it's supposed to be used.  Feel free to correct me if I'm
wrong, though!

I found the code to be extremely (I would say needlessly) complex.
Because there's so much weird stuff going on, I decided to whittle away
all the distractions and boil it down to a minimum, correct(!) macro that
failed.  This was what I ended up with in monad.scm:


(module monad (<id>-unit)
  (import scheme chicken)

  (define-syntax %define-monad
    (er-macro-transformer
      (lambda (expression rename compare)
        (let* ((monad (cadr expression))
               (unit-function (caddr expression))
               (%define (rename 'define)))
          ;; MONAD-unit should _NOT_ be renamed, because the macro is
          ;; supposed to be unhygienic!  We do rename define because
          ;; the calling site could redefine it, but we want the one
          ;; from scheme, which is its value in the macro definition.
          `(,%define ,(symbol-append (strip-syntax monad) '-unit)
             ,unit-function)))))
  
  (%define-monad <id> (lambda (a) a)))


If you install this, and then compile and run the following test program,
it will fail while interpreted it works fine (it should print the name
and signature of the generated function):


(use monad)
(print <id>-unit)


This makes no sense; this should simply work.  After some puzzling,
I figured out the reason: the setup file declares the extension as
being purely syntactical, through ((syntax) (version 3.2)) in the
install-extension's third argument.  This causes the compiler to omit
loading the module body when you compile a program that uses it.

Of course, <id>-unit is a procedure defined by the "monad" module, which
will therefore not be loaded when running the program.  That's why it
compiles (the import library is included when compiling, and it contains
the declaration of this procedure), but if you run it, it refers to an
undefined identifier.

The reason this works in csi is that it won't distinguish between a
purely syntactic module and a module imported for code: it always needs
to load the entire module because "compilation"/macro expansion and
evaluation are interleaved within the same process.

Very tricky, but it behaves exactly as it should.  The solution for this
particular problem is simply to remove (syntax) from monad.setup.

Cheers,
Peter

Attachment: signature.asc
Description: Digital signature


reply via email to

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