Then insert stuff in Scheme-side 'ac to use (apply macro the-free-list-or-whatever (cdr ex)) instead of (apply macro (cdr ex))
That way macros that need it can get it, while macros which don't need it can ignore it.
We can potentially define 'expansion-context as a table or function, and potentially we could allow an implementation to have expansion-context!line, say provide line number etc. information so that the macro can give decent error messages. Of course if we have a dorky backend (like mzscheme) then we can just have it return expansion-context!line as nil, because it can't somehow extract line numbers, but for implementations that can, then good.
edit: Oh and ye: the 'ac compiler on scheme-side really does keep a list of bound variables ^^
I suggested adding "interfaces" to packages. So A might require <B>v1, while C requires <B>v1-modified. At the very least, loading C would fail if the copy of B available on the user's machine is the original that does not provide <B>v1-modified.
OF course, it still requires that the modified B provide the semantics for the original B so that it provides <B>v1 seamlessly.
An alternative method of distributing individual libraries other than by dumping them all on Anarki.
Say we make a convention that we can make a new post on arclanguage.com with the post title "<library>my-library" in order to define a new library called "my-library". Library code must be indented by two spaces as normal to differentiate commentary on the library from the library code itself.
Then when 'require can't find my-library on the local copy, it uses http-get, trawls through http://www.google.com/search?q=site:arclanguage.com+%22<... , and searches for the newest post on arclanguage.com, downloads it, then parses out the library code.
LOL.
That would be cool, but probably stupid.
Basically, a really nice way to package and distribute individual libraries, a really nice way to specify dependencies.
With pack.arc you can pack a library in a directory, and then you can distribute that directory and put it wherever you like. I don't like too much the method of abusing the forum to distribute libraries. I would really like an ad-hoc application (maybe at arclanguage.org/libs), so that if require doesn't find a lib it tries to install it from arclanguage.org/libs?name=my-lib or something similar. As of today, dependencies are already handled, but the needed package must be in the search path of pack.arc.
Well, I did propose a hackish extension, 'symeval, some time back. I should probably push the extension onto Anarki. T.T
(= pusher cons)
; push is defined in arc.arc
(mac my-push (e l)
`(symeval!pusher ,e ,l))
(let pusher (fn (x ls) (+ ls (list x)))
(prn (my-push 'a '(b c d)))
(prn (pusher 'd '(a b c))))
Basically symeval is a non-overrideable special form (on the same level as 'set, 'if, etc.)
I think 'symeval is a possible solution to this problem, and I'm glad somebody thought of it before me. But the question is why you wouldn't use 'symeval on every free variable in your macro template, just in case some newbie decides to let bind one of your "global but internal" names. If you did use 'symeval everywhere (or automatically) you would have something closer (but still a poor approximation) to scheme's hygienic macro system. I think the automatic solution to be found there is more interesting.
I tried that. It doesn't work without knowing which variables are local and arc currently has no way of finding out, what the binding forms are, because all macros are unhygienic.
example:
(let list '(foo bar) (do (prn list)))
| | unbound | | |
mac | mac | function
function function
=>(let (global list) '(foo bar) (do ((global prn) (global list))))
We know that let binds its first argument and aif binds self, but since macros are turing-complete, this cannot be automatically inferred.
expand any macros in sub-expressions, then look at them. That's the advantage of avoiding "first-class macros", whatever their imagined advantages might be. ^^
It's enforced. For example, you can assign a macro to 'if, but it'll never be used: 'eval will always interpret 'if in its sense, and will never look at your macro.
@drcode & stefano: I somehow doubt that "whole interpreter environment may be saved to a file and loaded back" can be implemented with continuations.
Well, maybe, but we'd probably need 1) destructurable functions (so we can serialize functions), 2) some way of iterating over global variables, 3) a decent sense of 'eq?, one which returns false for distinct mutable strings, preferably in an easy eq?-key-compare association table (so we can properly/easily serialize recursive structures).
Arc-on-mzscheme actually maintains a table of globals that have been ever assigned, together with the last known arc-side assignment (IIRC it actually keeps two copies of the global, one in the table and one in the actual mzscheme global variable space).
edit:
@lboard: I also somehow doubt you want to save the whole interpreter environment; probably you just want something like this:
(mac restartable body
`(*restartable-f (fn (restart) ,@body)))
(def *restartable-f (bf)
(bf (point ret (afn () (ret self)))))
This is the "continuation" solution that stefano and drcode are referring to; in general you probably want this, not necessarily saving the whole interpreter state.
Seems a good idea. When require sees a string it would have its standard behavior, and when it sees a symbol it loads it as a packaged library. I'll add it. I'd also like to integrate it with a namespace system, but there is none yet. You've been working on a system based on symbols, right? What's its current state? Is it usable?
This is becoming unavoidable. This is really a pity, but the official Arc development is simply too slow (assuming it is moving, a quite optimistic assumption).
Integrating it into my forked Arc, but sadly something is interacting badly with the compiler and some macro is getting stuck in an infinite loop (which, if I don't catch with a ^C early enough, will force me to actually restart my computer T.T), probably from an incorrect compile. I'm debugging it currently >.<
Debugged! Now I just need to rewrite bits and pieces of arc.arc to clean it up and make it follow a more "axiomatic" path that will allow you to do neat things, like define how (+ (your-type 1 2) 42) will be (and adding hacks into ac.scm so that the axiomatic path isn't so slow).
(def >> args
; throw an error here so that user won't get
; mysterious errors in the 'reduce part
(if (no args)
(err "'>> requires at least one argument"))
(reduce (fn (a b) b.a) args))