absz


17 points by absz over 2 years ago | link | top
cached 4 days ago
The macro you want is

  (mac check args
    `(do
        ,@(map [list 'report-result _ `',_] args)))
There are a couple of things wrong with your macro. The first is that your (list ,@args) is inside ,(each ...) which is inside `(do ...); you can only have as many unquotes (,s or ,@s) as you have quasiquotes (`s), and you have two within one. The second is that "each" is only run for its side-effects. The return value of "each" is always nil. Thus, even if your macro worked, it would expand to (do nil), which isn't what you want. To replace "each", you want (map func lst), which returns a list where func has been applied to each element of lst, e.g. (map - '(1 2 3)) returns '(-1 -2 -3). In my macro, the function returns a list of the form (report-result ARGUMENT 'ARGUMENT); the `',_ construct means "quote the value of _," since ,_ is within a `. Splicing this (map ...) into the (do ...) block will give you what you want. Is that clear?

Also, a handy tip for debugging macros: (macex1 '(an-expression ...)) will expand the first macro call in (an-expression), which can help you see what's going wrong.

I can't tell you if this is the right place to ask these questions, but having some place for them would definitely be a good thing. I'm usually happy to answer them, though.


16 points by absz over 2 years ago | link | top
cached 22 days ago
Not quite. Arc has various bits of (gasp!) syntax. There are 10 pieces of syntax: () [] ' ` , ,@ ~ : . and ! . A quick breakdown:

1. () you know--function application, macro application, or a list. Basic stuff.

2. [] creates an anonymous function of 1 (or, on the Anarki, n) arguments. [...] is transformed (more or less) into (fn (_) ...).

3. '... is the same as (quote ...); whatever is inside becomes a literal. 'a is a symbol, '(a) is a list....

4. `... is the same as (quasiquote ...); the same as (quote ...), but evaluated things can be inserted with (unquote ...) and (unquote-splicing ...).

5. ,... is the same as (unquote ...); as observed, `(.1. ,... .2.) is similar to (list '.1. ... '.2.).

6. ,@... is the same as (unquote-splicing ...); the same as unquote, but ... must be a list and is spliced in. `(.1. ,@... .2.) is similar to (join '(.1.) ... '(.2.)).

7. ~func is the same as (complement func), which returns a function which is conceptually similar to (fn __ (no (apply func __))), i.e. which returns the boolean opposite of whatever the original returned.

8. f1:f2 is the same as (compose f1 f2), which returns a function which is conceptually similar to (fn __ (f1 (apply f2 __))), i.e. which applies f1 to the return value of f2 applied to the arguments.

9. x.y is the same as (x y); it's designed for nice structure access, e.g. lst.3 instead of (lst 3).

10. x!y is the same as (x 'y); it's also designed for nice structure access, e.g. my-table!password instead of (my-table 'password).


12 points by absz over 2 years ago | link | top
cached 4 days ago
As cchooper observed, macros are expanded at compile time, not runtime. This means that they cannot see lexical variables like k. (Since x was a global variable, it could be seen at compile time, thus making your first example work.) In order to look at the lexical environment, you need an ordinary function:

  (def assign (name expr)
    (eval `(= ,name ',expr)))
The reason you don't need a macro here is that you aren't actually suppressing evaluation, which is what macros do; you want the values of name and expr. Thus, assign should be a function, which runs at runtime. Also note that expr needs to be quoted, or you attempt to evaluate it, which fails if it is a symbol.

The one thing that might trip you up with this function is that it (like =) will not create lexical variables, but only globals, unless lexicals of the names you are about to assign are already declared.

Also, a formatting tip: to get text to appear as code, surround it by blank lines and indent it by two spaces.


10 points by absz over 2 years ago | link | parent | top
cached 4 days ago
I had been under the impression that it was supposed to last for one hundred years, not languish for one hundred years, but I suppose I might have misread something :/

8 points by absz over 2 years ago | link | top
cached 22 days ago
On some level, the answer is "yes, of course."

  (mac delay body
    `(annotate 'promise (fn () ,@body)))
  
  (def force (promise)
    ((rep promise)))
This was lightly adapted from http://cadrlife.blogspot.com/2008/02/lazy-lists-in-arc.html which I found on this forum -- read it for a more complete version with various supporting functions, etc. It's not primitive lazy evaluation, but it should work for many of the same things that delay/force work for.

8 points by absz over 2 years ago | link | top
cached 1 day ago
You are correct that it's readtables you want, but they are an mzscheme feature; unfortunately, there is no way (yet?) to use them in Arc. Using readtables, you can customize certain things, but I don't know that there's an easy way to do $(...) because of how they work (though I am by no means an expert). If you want to hack on ac.scm or brackets.scm to extend the readtables, the best resources I can recommend are the PLT Scheme language manual (the relevant chapter is here: http://download.plt-scheme.org/doc/mzscheme/mzscheme-Z-H-11....) and just Googling for it. (I didn't have very much luck when I tried, but go for it all the same!)

Also, note that intra-symbol syntax (a:b, a.b, a!b, ~a) is implemented separately in ac.scm, in the functions expand-ssyntax and expand-compose (though you also have to modify some predicates if you add things, e.g. ssyntax?). Again, this is not (yet?) available in Arc.

I do hope that ways to extend syntax will be available in Arc soon, but they aren't yet, and I couldn't figure out readtables well enough to generate a workable solution. Hopefully arc2.tar will include this. Good luck!


7 points by absz over 2 years ago | link | parent | top
cached 11 days ago
While Unix did win, that doesn't mean that Unix's names won. It's Unix's features that won. So it's reasonable to provide certain operations, but implementing them in terms of (system "unix-command-name ...") is not.

Of course, I use Mac OS X, so it's not like I'm adversely impacted. But the point still stands.


7 points by absz over 2 years ago | link | top
cached 8 days ago
You raise some interesting points, but first, I have to address a confusion I've seem come up before. It is this: arrays are not lists. Arrays are a data structure with O(1) indexing, designed to be accessed and not iterated over. Cons cells/linked lists are a data structure with O(n) indexing, designed to be iterated over and not accessed. What's more, if we have a dotted pair be an array of length two, we get

  Cons             vs.          Array
  -----------------------------------
  (a . b)         <---> [a, b]
  nil / ()        <---> nil / []
  (a . nil) / (a) <---> [a, []]
  (a . (b . nil)) <---> [a, [b, nil]]
Arrays and lists have fundamentally different structures (one emphasizes first vs. rest, the other emphasizes here vs. there), and this is why mzscheme / PLT Scheme separates vectors (its arrays) and cons cells.

As for content: it seems to me that your title overstates your point. You appear to be arguing for the removal of hash tables as an axiom, which is different from arguing that they are "unnecessary". (To be fair, your second argument does propose to eliminate them, but you replace them with something with equivalent access "terminology" (though not speed nor mutability).) Hash tables (or really any sort of dictionary) and closures/anonymous functions are, in my opinion, the two most useful things in programming, so I feel that they should be part of the language; whether in ac.scm or in arc.arc doesn't matter to me as an Arc user. However, as someone who cares about the implementation, your point about simplifying the axioms and examining speed tradeoffs is a good one, and is worth considering (though I'll leave it for wiser heads than mine). It would be nice if we could get all our complex data structures out of one (or a few) axiom(s), and perhaps arrays would suffice; after all, they do for C.


7 points by absz over 2 years ago | link | parent | top
cached 5 days ago
On Anarki, you can add the ssyntax:

  (add-ssyntax-top
    ".." (range L r))
Then you have

  arc> 1..10
  (1 2 3 4 5 6 7 8 9 10)
.

EDIT: Actually, it's slightly nicer to do

  (add-ssyntax-top
    ".." (range ...))
so that you can then specify the step size:

  arc> 1..10
  (1 2 3 4 5 6 7 8 9 10)
  arc> 1..10..2
  (1 3 5 7 9)

.

7 points by absz over 2 years ago | link | top
cached 1 day ago
To be pedantic, '() and nil are synonyms. It's not that nil means #f, it's that the empty list is considered false.