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
signature.asc
Description: Digital signature
_______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users