Arc Forumnew | comments | leaders | submitlogin
Syntax for list ranges
3 points by vladimir 5151 days ago | 8 comments
I'm new to Arc (first day exploring) and so far I like it in many ways more than Racket (though Racket is better on docs, but maybe I'm wrong)

So, I was thinking if you don't mind having a little syntax, why not to have one for list ranges?

In many languages you have this syntax for arrays:

    a[7]
    a[7:12]
Arc has:

    (a 4)
But what about:

    (a 7:12)
Or maybe even:

    ('(1 2 3) 1:)  ;standing for (cdr '(1 2 3)) 

    (('(a (b c d) f) 1) 1:2)  ;for (cdadr '(a (b c d) f)) 

    ('(a (b c d) f) 1,1:2)  ;same
Maybe I'm missing something in Arc that does that already, I didn't explore it yet. What do you think?


2 points by Pauan 5151 days ago | link

"(though Racket is better on docs, but maybe I'm wrong)"

The docs for Arc range from nonexistent to outdated to poor. Racket's docs aren't that much better, but I agree that Arc's documentation is horrible.

However I haven't actually needed Arc documentation, because I can just open up arc.arc and read the definitions themself. My hardest thing with Arc is writing my own custom function/macro, only to realize later that it already exists. An example is `or=` which I didn't know about until rocketnia pointed it out to me. Ditto for `awhen`

---

As for your suggestion for slice syntax, I already did that. You can find it here:

https://github.com/Pauan/ar/blob/lib/slices.arc

It won't work on the latest version of ar. I have a fixed version on my harddrive, but haven't pushed it yet...

With that library, you can now do this:

  (foo 0 1)   ; same as foo[0:1] in Python
  (foo 0 5 2) ; same as foo[0:5:2] in Python
Basically, it takes (foo ...) and converts it into (cut foo ...) so (foo 0 1) is the same as (cut foo 0 1).

It also supports negative indices, just like Python. I tried to keep it very close to Python's semantics, as I think this is one of the (few) awesome things about Python. In fact, the only difference is the following:

  (foo 5 0) -> error: start index must be smaller than the end index
  foo[5:0]  -> []
This is easy to change, if I want to.

-----

1 point by Pauan 5151 days ago | link

I just pushed out the fixed version, so it should work just fine now. One thing I forgot to mention: it works with assignment as well. Thus, this:

  (= (foo 0 1) '(1 2 3))
Is the same as this, in Python:

  foo[0:1] = [1, 2, 3]

-----

1 point by vladimir 5151 days ago | link

Great that it's already there. Is there a way to do foo[5:]?

And about docs - you are right, the best is to read the source-code. But the problem (as you pointed out) is when you have something you want to solve, it's hard to search for it in source-code. If you want to append strings and you don't know that + does it, source code will not give you an answer (unless you read the whole thing carefully). In Racket, you can search using human language in Racket Reference or Racket Guide.

Anyway, is there a centralized page, where you can get most links to Arc resources?

-----

1 point by Pauan 5151 days ago | link

"Is there a way to do foo[5:]?"

Yes. Use (foo 5 nil)

It's not as short as the Python version, but it works well enough. Basically, you can pass nil to mean the "default value".

That means that (foo nil nil) is the same as foo[:] in Python (this creates a copy of the list). The defaults are (foo 0 (len foo) 1)

---

"If you want to append strings and you don't know that + does it, source code will not give you an answer (unless you read the whole thing carefully)."

Right. I was working on solving that as well, by grouping arc.arc into different "sections". So you'd have a section for "assignment", a section for "scripts", a section for "file system", etc. I believe this approach is actually better than English prose documentation. Unfortunately, I have not done this for the latest version of ar... it's only on my old branch[1], which is sorely outdated.

---

"Anyway, is there a centralized page, where you can get most links to Arc resources?"

The closest would probably be this site:

https://sites.google.com/site/arclanguagewiki/home

If you're looking for libraries, you can try Anarki[2], or rocketnia's Lathe[3], or my lib branch[4].

My branch currently has a library that implements slicing (already shown), a lib that implements a very simple and lightweight object system, a lib that implements a hacky (but working!) namespace/module system that uses inheritance, and a compiler that can take an Arc expression and convert it into a JavaScript string, that can then be executed in your favorite JS engine.

I should warn you that my arc2js library is severely outdated. I've made many many changes and improvements, and plan to push them to my branch (eventually). In addition, the import.arc library is very very hacky (in particular, the way it deals with macros), so I personally wouldn't use it just yet. It's mostly a proof-of-concept at this point.

---

* [1]: https://github.com/Pauan/ar/tree/old

* [2]: https://github.com/nex3/arc

* [3]: https://github.com/rocketnia/lathe

* [4]: https://github.com/Pauan/ar/tree/lib

-----

1 point by Pauan 5151 days ago | link

By the way, I just realized that if sref were a macro, you could indeed use this syntax. The problem is that : is already used for composition, and sref is a function, so it would try to compose two numbers (which would of course fail spectacularly if you tried to call it).

On the other hand, if sref were a macro, then I could have it check for (compose ...) and then you could use : syntax for list slices/steps. Alas, that would be a pretty big change, so I think that would be better suited for Arubic, rather than base ar. This did give me the idea to make sref into a macro, so thanks for that.

-----

1 point by vladimir 5151 days ago | link

If not ':' then '..' is also possibility, like (a 5..9), but to be honest i like your version, it's more Lispy. But maybe syntax '..' could improve readability? Compare:

(a b c) (a b..c)

You write (about ar) "Much of Arc remains unimplemented", so is it better to use mzsheme version for now?

-----

1 point by Pauan 5151 days ago | link

"If not ':' then '..' is also possibility"

Nope, no can do. "." is used for ssyntax as well. To be specific, foo.bar is equivalent to (foo bar) Thus, setf would need to be a macro, or we'd need to give up on ssyntax. I like ssyntax, so I'd go the macro route, personally.

---

"You write (about ar) "Much of Arc remains unimplemented", so is it better to use mzsheme version for now?"

Oh, no! I've been using ar for quite some time now, it works beautifully. I think awwx is being silly when he says that "much of Arc" is unimplemented. It's mostly implemented, and the stuff that isn't implemented, I don't use, so I don't notice... I'm at the point where the idea of using Arc 3.1 is absurd: ar is definitely the way to go.

You can find ar here:

https://github.com/awwx/ar

My libraries are designed specifically to work only with ar, though some may work on Arc 3.1 with some tweaks... My apologies for the incredible number of files in the ar branch, there's not much I can do about that...

---

By the way, you shouldn't use my old branch. It's there for historical reasons, and so that I can pull in changes piece-meal into current ar. Using the latest version of ar (I give the link above, in this post) is the way to go. Sorry for the confusion.

-----

1 point by rocketnia 5151 days ago | link

"Nope, no can do. "." is used for ssyntax as well."

Even though . is used for ssyntax, .. isn't, at least in Arc 3.1. While (ssyntax 'a..b) returns t, ssexpanding anything with .. in it throws an error.

You've talked about classifying ssyntax as prefix, postfix, and infix before, so I suspect you'd want a..b to expand through (a .b) to (a (get b)). As for me, I think it's nicer to treat multiple-character sequences like .. as their own operators.

-----