Arc Forumnew | comments | leaders | submit | conanite's commentslogin

"afnwith" is an ugly name, and not at all accessible to new users; it describes its behaviour in terms of implementation, but "loop" captures the purpose of the macro. Purposeful naming is usually a lot more useful.

-----


well spotted :)

-----

2 points by conanite 5783 days ago | link | parent | on: A Lisp Concise: 'while' in arc and eight

Could you show us an example of code that calls "while"? I'm not sure it's quite exactly correct to say a velcro can take "unevaluated code" as an argument; it looks more like it takes a closure (you seem to say so yourself); and perhaps Eight syntax is such that closures are completely transparent and require no extra decoration. The magic of course is dealing with variable capture.

For example, an Eight-like 'while in arc could look like this:

  (def while (test body)
    (when (test) (body) (while test body)))
invoked thusly displays 10 9 8 ... 1:

  (let n 10
    (while (fn () (> n 0))
           (fn () (prn n) (-- n))))
I'm guessing Eight allows you write the above without the (fn () ), like this:

  (let n 10
    (while (> n 0) (prn n) (-- n)))
Am I close? I like the idea of a syntax for making closures more transparent; arc's [ ... _ ...] helps, as do macros.

As for the question of whether Eight is compilable, I don't see why not; an arc compiler needs to look at expressions to see if the car refers to a macro; an Eight compiler could look at the car of each expression to see if it refers to a "velcro", in which case it should wrap the relevant invocation parameters in a closure-creation instruction, instead of wrapping them in a nested invocation instruction.

-----

1 point by diiq 5783 days ago | link

Right, so the major difference between a traditional closure and a closure in Eight is that a closure in Eight still looks and acts just like a list. I can do this:

     (def foo ('bar)
        (print (car bar)))

     (foo (+ 2 3))
And what would be printed is:

+

Which is not useful, but it's how you'd expect a macro to work. But in Arc, once you've wrapped something in (fn) to make a closure, it becomes inaccessible; I can't do:

    (pr (car (fn () (+ 2 3))))
EDIT: I didn't answer the question.

    (set! a 10)
    (while (> a 3) (print "hello") (set! a (- a 1)))
Which outputs:

hellohellohellohellohellohellohello()

[Warning to those you want to try this in the Eight interpreter, - and + are not implemented yet, use 'minus' and 'plus']

-----

1 point by conanite 5785 days ago | link | parent | on: Macros are a menace

He makes some interesting points, but macros are like everything else that's useful (fire, nuclear power ...), they can be abused. It's fair to warn people about macros, just as people are warned repeatedly about multi-threading; but it doesn't mean macros, or multi-threading, are wrong or bad. Having a few years of practicing "Don't Repeat Yourself" in java, perhaps, you have finally hit the limit, and realise that removing more duplication means a net increase in volume of code. Arc and assembly are the only non-condescending languages I know, and I love the freedom of writing unfettered code in arc.

I notice that arc's macros are mostly very short and to the point, and are strictly hygienic even though the core language doesn't impose it. As for me, I'm still learning this discipline, just as it took me a while to understand why short methods and small classes are "better".

-----


The great thing about macros is that they can inspect their arguments and decide what to do with them; this is what anarki's 'def does in order to generate doc-strings. If the first element of the 'body arg is a string, use that to document the function currently being defined. Similarly, we could say if the first element of paginate's 'body arg is, say, a hash, use that hash as keyword args, and use (cdr body) for the body.

Using {...} syntax for the hash, this could even be elegant:

  (paginate '/search' 10
    { nextcopy "Next →" prevcopy "← Prev" }
    (each doc (cut docs start-index end-index)
      (render-doc doc)))
Without {...} you would have to fall back to some kind of keyword, but even so I would prefer

  (paginate '/search' 10
    (opts nextcopy "Next →" prevcopy "← Prev" )
    (each doc (cut docs start-index end-index)
      (render-doc doc)))
, in this case 'paginate checks if the first element of its 'body arg is a list beginning with 'opts. Something like the following (completely untested)

  (mac paginage (url numitems . body)
    (let (opts body) (extract-opts body)
      (etc etc)))

  (def extract-opts (body)
    (if (is (caar body) 'opts) 
        (list (cdar body) (cdr body))
        (list nil body)))
Would you consider this compromises the rest parameters?

-----

3 points by akkartik 5785 days ago | link

Yes, I thought about adding a set of parens around either keyword or rest params. The brace syntax sounds decent. I think it works just as well; it's just a question of what syntax people prefer.

You'd still need support for defaults in extract-opts. Complexity-wise I think the two implementations would be equivalent.

Hmm, one benefit of using a separator like :do: In macros that need just keyword args the opts approach would add redundant syntax to each call.

I don't understand the entire state space here, but I used to think arguments should go into rest params by default, and now I think they should go into keyword args. What do you think?

-----


Just to be clear: do you mean that an arc reader, on encountering

  #table(a 1 b 2)
should create an object equivalent to that returned by

  (obj a 1 b 2)
?

I see the difficulty with data vs code; I would expect a table literal in data to contain only other literals; but a table literal in code should also contain other code to be executed at runtime. At least, that's how table literals work in javascript, and it seems sensible. How would you go about advising the arc reader to differentiate between code and data? Or maybe the reader doesn't differentiate, but the compiler steps in when it encounters a table literal in code?

I use literal table syntax in javascript and ruby all the time, and wish I could in java ... so it would be great to have it in arc. And I prefer {...} to #table(...). What other uses might be better for "{..}" ? And couldn't we overload {} syntax anyway, if necessary?

-----

2 points by aw 5790 days ago | link

> Just to be clear: do you mean that an arc reader, on encountering #table(a 1 b 2) should create an object equivalent to that returned by (obj a 1 b 2)

Yes, for that example. Though with #table(...) the values are always literals, so #table(a (+ 1 2)) wouldn't be (obj a (+ 1 2)) but instead would return the same value as (obj a '(+ 1 2))

a table literal in code should also contain other code to be executed at runtime ... I prefer {...} to #table(...)

right, if you want your table literal to be able to act like a "template" in the sense that you can insert expressions to be evaluated, then we'd need some kind of syntax to "unquote" the expression.

But I don't know how to do that and get everything to work.

I'm certainly open to suggestions, I'd just need working syntax to implement it.

The other option is not to try to get the syntax you like for constructing tables to be the same one as the writer/reader uses to output/read literal tables.

You could come up with a {...} syntax you like to use while programming, and that would be easier than coming up with a {...} syntax that the writer would also use to output tables, because that has the complication that every table needs to be able to be written out in a way that can be read back in.

For example, suppose you wanted a {...} syntax that worked like obj. Then, in regular Arc:

  arc> {a (+ 3 7)}
  #hash((a . 10))
or, using #table as the read/write syntax:

  arc> {a (+ 3 7)}
  #table(a 10)
That's easy to do. Now, if you also wanted your {...} to be used as the read/write syntax, that would be a lot more difficult, maybe impossible. At least I don't know how to design a syntax that would work for both, and still be able to read/write any table value.

-----

3 points by conanite 5798 days ago | link | parent | on: "Magical" on-disk persistence

Nice - ActiveRecord for arc? But why does it make 'assign slower - unless I've missed something, assign doesn't depend on sref?

-----

2 points by rntz 5795 days ago | link

You are correct. 'assign doesn't depend on 'sref. '= does.

-----

3 points by conanite 5799 days ago | link | parent | on: The power of function combinators

This is an awesome piece of work - not just the code, but the whole tutorial/guide.

Previously (iirc) you simply used the input stream to keep track of the parse position - now you manage the input as a list of characters. I presume this is to allow backtracking from failed matches, or is there another reason?

My gut reaction to the idea of converting the input to a list was "OMG scaling issues!!!" but I must admit I've never had to deal with a really big json object.

-----

4 points by aw 5799 days ago | link

Thanks!

Actually, all the various versions of my JSON parser have converted the input to a list of characters. I wouldn't be surprised if it did in fact turn to be slow, but I see it as an optimization issue: until I have (or someone else has) a program that's actually slow because of it, then I don't know if it's a useful optimization to work on. For example, if JSON parsing were a thousand times faster if I wasn't using lists, but JSON parsing was only 0.1% of the program's total execution time, then I might not care.

-----


curious - does the browser not handle cookies, or do you know why this is an issue? Do you mean every web app that requires a login needs a custom app in order to be usable on an android? (I know nothing about android, count me a total noob)

-----

1 point by thaddeus 5803 days ago | link

ugh - I had thought it was the browser:

http://news.ycombinator.com/item?id=849521

but I am not sure anymore. I can log into google docs and such, but google makes android so not sure what magic they make.

I only got the phone yesterday. And naturally I tried to see if any of my arc apps or the arc forum worked.

The webpages load great, it's only the login...hmmm guess I'll keep googlin :)

-----

2 points by thaddeus 5801 days ago | link

Looks like I was correct:

Google has bugs:

http://code.google.com/p/android/issues/detail?can=2&q=1...

http://code.google.com/p/android/issues/detail?id=4305

-----


You could call

  (errsafe:load-table filename)
which is the half of 'safe-load-table that returns nil

-----

1 point by idoh 5804 days ago | link

Thanks!

-----

More