#\x is just the character literal for the letter x -- each element of a string being a character. What the parent means is that you forgot to put a quotation mark before the mentioned line. You don't need to use #\ in this context, but in writing it makes more sense than saying you forgot a " before bottle".
Not sure if this is exactly like the bug noted in the top comments of arc.arc, but it seems to me that perhaps it could be boiled down to the problem of inserting literal objects into macroexpansions:
arc> (= pusher cons)
#<primitive:cons>
arc> (pusher 'a 'b)
(a . b)
arc> (mac my-push (e ls)
(let pusher-alias pusher
`(,pusher-alias ,e ,ls)))
#3(tagged mac #<procedure>)
arc> (let pusher (fn (x ls) (+ ls (list x)))
(prn (my-push 'a '(b c d)))
(prn (pusher 'd '(a b c))))
Error: "Bad object in expression #<primitive:cons>"
arc> (macex '(my-push 'a '(b c d)))
(#<primitive:cons> (quote a) (quote (b c d)))
arc> (mac my-push (e ls)
(let pusher-alias pusher
`(list ',pusher-alias ,e ,ls)))
*** redefining my-push
#3(tagged mac #<procedure>)
arc> (let pusher (fn (x ls) (+ ls (list x)))
(prn (my-push 'a '(b c d)))
(prn (pusher 'd '(a b c))))
(#<primitive:cons> a (b c d))
(a b c d)
As you note, this solution then turns into combing through and aliasing every free variable -- doing so automatically would then be the makings for some hygiene, ostensibly. This is an area of contention, as I'm sure you're well aware. It still crops up fairly frequently, generally from someone vying for such a system. But as it stands, Arc doesn't seem to be going for hygienic macros (except perhaps as a library).
is it possible for a macro library to provide hygienic macros? I suppose you could port the "portable syntax case" implementation from scheme to arc... but I don't know how much help, if any, you'll need from the expander
You would need help from the compiler. Basically a macro would be called with a list of bound variables as an extra argument. For a compiler, this would be quite easy. Now a macro would look like:
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 ^^
This is a solution, but I consider this cheating, because it is nearly as tedious as manually inserting symeval around global functions.
w/var:do in my mexpr.arc is an example of a macro/dsl which can not take a free-var list as 1st arg (it could be changed, but that would make it useless)
This, however, conflicts with regular assignment. It's ambiguous in that it's quite context-dependent. For instance:
arc> (= y '(1 2 3))
(1 2 3)
arc> y
(1 2 3)
arc> (= (car y) (list 1 2)) ;we're accessing y, not assigning to car
(1 2)
arc> y
((1 2) 2 3)
arc> ;but what of this? x isn't a function, though
;the syntax is kind of inconsistent if used for both purposes
(= (x y) (list 1 2))
Error: "reference to undefined identifier: _x"
However, you can still do multiple assignment; just not destructuring assignment:
arc> (= x 1 y 2)
2
arc> x
1
arc> y
2
You could instead define, e.g.:
(mac ds= (vars vals)
`(set ,@(apply + nil (map list vars vals))))
Then:
arc> (ds= (x y) (1 2))
2
arc> x
1
arc> y
2
Which, confidentially, doesn't work for using literal lists in the 'vals position as you did, but that should still be doable. Could also use '= instead of 'set, if you still wanted to do something like:
arc> (ds= (x y) ((list 1 2 3) (list 4 5 6)))
(4 5 6)
arc> x
(1 2 3)
arc> y
(4 5 6)
arc> (ds= ((car x) (cdr y)) ('a 2))
2
arc> x
(a 2 3)
arc> y
(4 . 2)
I do like the idea of conceptually merging hash tables and arrays, or at least think it should be explored.
Views differ, but personally I don't like to think of strings as aggregate collections of characters (but then, I also don't really like the character as a data-type), so using 'is seems conceptually simpler. It makes sense to me, as often as I bandy about strings and compare them, that 'is treats them as a simply-compared type. Granted, they are not. It's something I guess I've gotten used to by using symbols, as drcode points out (yay, link to a post in the same thread!): http://arclanguage.org/item?id=7965. To each their own.
Ah, I guess my bit-twiddling background is showing, because I don't like to think of strings as single entities. Symbols exist for that and are more efficient all-round, if I understand right.
Why would it be? Are you that incapable of learning new things? I doubt it. The differences between releases, no less, is going to be smaller than the differences between Lisps and other languages as a whole. It strikes me as something rather foreign to say, being of the general form "I want to learn X, but I'm afraid that something new will come along." So? The learning process is continuous. It's like being worried that Python 2.5 is going to be obsoleted by Python 3.0. Of course it will; the point is to run a mental diff and adapt, which isn't difficult because at its core it's still Python. Now, if the question is whether to learn Arc or some more well-established dialect, I see you've already commented on this thread: http://arclanguage.org/item?id=7876. Although, the same logic applies in the whole Lisps vs Others thing -- choose one and go with it; the differences are easy to pick up when you have experience in a Lisp.
I am not incapable of learning new things, but it's foolish to waste time with something that will be obsolete in 3 months (or whatever insignificant time). I'd rather play with something a little more stable. Take into account that py3k came along after 16 years of Python. It breaks backward-compatibility and hackers must relearn a bunch of things, yes, but that only happened after a really long time. I'm concerned that this kind of major change will happen with every Arc release, which is the impression I get when I read pg's announcement ("we will continue to work as if we were the only users").
To be clear, I didn't mean offense with the comment about learning new things (hence saying "I doubt it").
Moreover, my point was that the differences between releases are relatively easy to cope with -- yes, even for py3k. Sure, there are a hefty number of changes, but they mostly occur in a more "library" level (if you will) rather than at the base language, and much of it is just cleaning up inconsistencies. It's not as though the entire "16 years of Python" flies out the window with an overhaul like this. It'll be something of a pain in the ass to update code, but it won't make your collected knowledge obsolete, per se.
On a less contentious matter, Arc is also a tiny language. Its changes won't be all that drastic at this point. This is little consolation, as the aim is probably to build up a respectable library base. To that end, my overarching point is that you should learn Lisp in a more platonic sense (hardly a waste of time, break-prone versions aside). This can be done with pretty much any dialect, for the record. Libraries may become obsolete, but this sort of philosophical knowledge will not.
Whether this entails using Arc needn't be a grueling decision: it's a small, simple dialect (cf the responses in the aforementioned thread), and still a Lisp. The impression I get from the announcement is more of a heads-up "we reserve the right to..." thing. Besides which, changes to Arc entail, to a significant enough extent, code written in Arc itself. What better way to understand and play with the language than to read over the definition of 'trav (as a real example of a change between arc1 and arc2; http://arclanguage.org/item?id=2504)? Regardless, as Arc stands it's stable enough for learning, but this education has far more impact than being some sort of fleeting "woops, new version, guess I don't understand Lisp anymore." I focus on this idealized learning-experience viewpoint because that's the reason I tend to play with other languages: to expand my mind.
If, however, it comes down to consistency that you'd like for a Lisp in a production environment, well:
It's not a coincidence that we wrote a language for exploratory programming rather than the sort where an army of programmers builds a big, bureaucratic piece of software for a big, bureaucratic organization.
No matter how easy to cope with changes are, if they happen all the time, they are annoying. You are supposed to mess around with programs for a while to really get to know a language, but if at mid-point you are forced to stop and rewrite everything, it's like being stuck on 2nd gear.
However, I now understand three things: (1) Arc releases don't really come that often, (2) changes won't be neither numerous nor drastic and (3, really important) former versions of Arc will have taught you a bunch of valuable lessons. 3 is pretty obvious, but I was totally failing to see it. Thanks for that.
Guess I will learn Arc :)
P.S Arc's aim at this point is not to build a respectable library base, it is to improve the core language.
"It has threads and a way to say a chunk of code should be executed atomically. No more than that at the moment. Nor is there any explicit notion of a processor. I'm not sure how that will turn out."
Re: "chunk of code should be executed atomically" - I'm not 100% sure but I think it's possible that (from the way 'atom is implemented) a sequence that is not protected within an 'atom scope will be able to see an "atomic" operation in progress.
Basically 'atom just acquires a Global Interpreter Lock around the function it executes. I'm not sure, but from the semantics of locking, I think that another thread may see the "atomic" operation step-by-step unless it is itself protected by 'atom (and then there is potential contention for a single global lock!)
Of course, mzscheme uses green threads, so maybe it won't work that way.
Besides the other solutions noted that are more "classic" answers to the problem, I think it's important to ask: why does this have to be a macro? Using eval within a macro, in my experience, is often a sign that you don't need it; you want a function instead. I can't see any signs of the need here either. To say nothing of the soundness of the original solution's method, I believe that this would work:
Also: the reason it needs ints is because of the 'rand function. We could also define a rand-float function which creates a random floating point number and use that instead:
the above now works with weight expressions that return real numbers. Also as specified, only the chosen expression is executed; however, all weight expressions are executed.
Ah, I misread that you wanted something akin to random-elt rather than rand-choice -- i.e., you'd want to use this as a control structure, in which case a macro indeed is what you'd need. My bad. That's what I get for commenting on an empty stomach (well, empty brain is more like it, but excuses are entertaining).
Previously mentioned many times, actually. This does not seem to be the current plan, as those characters could be reserved for future syntax: http://arclanguage.org/item?id=3145