tomhrr / dale

Lisp-flavoured C
BSD 3-Clause "New" or "Revised" License
1.03k stars 48 forks source link

Macro-defining macros #91

Closed porky11 closed 7 years ago

porky11 commented 8 years ago

When defining macro-defining macros in other files, there often will be the problem, that something of the expansion is not in the namespace. (I normally get not-in-scope errors or segfaults when trying to fix it) I tried using the namespaces inside the macro, and I tried prefixes (like (std.assert …)), which causes segfaults. would be nice if the prefix-version worked, so you could define macros, where the user of the macro cannot override the macro (by accident)

tomhrr commented 8 years ago

On Sat, Sep 10, 2016 at 02:12:46PM -0700, Fabio Krapohl wrote:

When defining macro-defining macros in other files, there often will be the problem, that something of the expansion is not in the namespace. (I normally get not-in-scope errors or segfaults when trying to fix it) I tried using the namespaces inside the macro, and I tried prefixes (like (std.assert …)), which causes segfaults. would be nice if the prefix-version worked, so you could define macros, where the user of the macro cannot override the macro (by accident)

The use of qualified names and 'using-namespace' within macro expansions should be fine. Do you have an example program where it fails?

On a related topic, 'import' within procedures was not previously supported, but that has now been added. An example with 'import', 'using-namespace', and qualified names in a macro expansion:

(import macros)

(using-namespace std.macros
  (def test (macro intern (void)
    (qq do
      (import math)
      (printf "%d\n" (std.abs -5))
      (import assert)
      (using-namespace std
        (assert false))))))

(def main (fn extern-c int (void)
  (test)
  0))

which yields:

5
test.dt:10:17: Assertion 'false' failed.
Aborted (core dumped)
porky11 commented 7 years ago

I just thought, that prohibiting overloading a function used by a macro could be useful, which is not possible this way, else something like this could happen

(import macros)

;;;something in unknown lib:
(namespace test
(using-namespace std.macros

(def f (macro extern (val) (qq * 2 (uq val))))

(def x (macro extern ((a int))
  (qq using-namespace test
    (f (uq a)))))
))

;;;something in user code, user only knows about macro x, not f, so he defines f:
(def f (fn intern int ((a int))
  a))

(using-namespace test
(def main (fn extern-c void (void)
  (printf "%i\n" (x 1)))) ;;user doesn't find, why this doesn't work as expected anymore suddenly
)

but I don't think, returning (test.f (uq val)) would be a solution to this problem, but some other things, that may be discussed in another issue