Arc Forumnew | comments | leaders | submitlogin
11 points by EliAndrewC 2357 days ago | link | parent

I like that "subseq" was renamed to "cut" and that it now takes negative indices.

However, I wish we could say (x 1 -1) instead of (cut x 1 -1). And since x.0.0 expands to (x 0 0) then that would let us say x.1.-1 which is what languages such as Python and Ruby already allow.

I hope that this is coming; I image that Arc's creators don't want to introduce too many changes all at once, so maybe they'll add this after they see how the x.y syntax works out.



8 points by sjs 2357 days ago | link

I would prefer it if (cut "abcde" 1 -1) returned "bcd" rather than "bcde". Other than that I like the new cut.

-----

8 points by pg 2356 days ago | link

Hmm, yes, so would I. I should fix that. I just did what Emmett suggested, which must have been based on Ruby, but it doesn't actually seem like a good idea.

-----

5 points by pg 2356 days ago | link

Fixed. http://arclanguage.org/item?id=2304

-----

4 points by nex3 2356 days ago | link

Given this, I've changed it to 0-based reverse indexing in the Anarki.

-----

3 points by jules 2356 days ago | link

In Ruby you use Ranges for this.

    (1..4).to_a => [1,2,3,4]
    (1...4).to_a => [1,2,3]
str[a..b] is a substring from a to b, inclusive.

str[a...b] is a substring from a to b, exclusive.

With negative indices:

    str[a..-b] == str[a..str.length-b]
    "abcde"[1..-1] == "abcde"[1..5-1] == "abcde"[1..4] == "bcde"

    str[a...-b] == str[a...str.length-b]
    "abcde"[1...-1] == "bcd"

-----

1 point by carpal 2356 days ago | link

How else would you specify "the end of the string"? -1 seems natural for me. Anything else (0?) makes it kind of foggy.

-----

5 points by nex3 2356 days ago | link

"End of string" is specified by not passing a fourth parameter:

  > (cut "abcde" 1)
  "bcde"
See http://arclanguage.org/item?id=2267.

-----

2 points by maxwell 2355 days ago | link

-0

-----

2 points by nex3 2357 days ago | link

Agreed. Ruby does it the other way ("abcde"[1..-1] is "bcd"), but that's only because there's no other way to specify "until the end." But that's the default in Arc; the following are equivalent right now:

  (cut "abcde" 1 -1)
  (cut "abcde" 1)

-----

3 points by lsb 2357 days ago | link

Nope, Ruby has -1 at the end:

    $ irb
    >> "abcde"[1..-1]
    => "bcde"
    >>

-----

4 points by nex3 2356 days ago | link

Oh, right. That's what I meant.

So, to clarify: I think arc should not do it Ruby-style, but rather have

  arc> (cut "abcde" 1 -1)
  "bcd"

-----

2 points by mec 2356 days ago | link

How would you then decide 0 0?

  arc> (cut "abcde" 0 0)
  "a"
  arc> (cut "abcde" 0 0)
  "abcde"
-1 should deffinitly refer to the last elemental or I don't see a way to get it.

-----

3 points by nex3 2356 days ago | link

(cut s 0 0) should return the empty string, just like (cut s 1 1) and (cut s 42 42). Which it does in either implementation.

-----

2 points by vincenz 2356 days ago | link

Then you would need -0 to get the full string. You're not making sense.

How do you propose to get "bcde" from "abcde"?

Either you need -0, or your final 0 is ambiguous.

-----

3 points by nex3 2356 days ago | link

No you don't - the full string is the default.

  > (cut "abcde" 1)
  "bcde"

-----

3 points by tokipin 2356 days ago | link

i was thinking that too, but how would you do it dynamically (eg with variables) ?

  (cut "abcde" begin end)
what would i need to put in end to get the full string? nil?

-----

3 points by sjs 2356 days ago | link

Both nil and (len str) work. I see both sides of the argument as counting from -1 eliminates the 0 corner case.

I like indices that are intuitive with literal numbers. Counting from 0 at one end and from 1 at the other is jarring. When -1 points to the end of string rather than before the last char (cut str 0 (- (len str))) returns the first char instead of the empty string.

With -1 -> before last char:

  (def chop ((o str "abcdef"))
    (pr "Chop how many chars off the end of \"" str "\"? ")
    (= n (coerce (cut (readline) 1) 'int)) ; bug in readline prepends #\newline
    (prn "Chopped: \"" (if (is n 0) str (cut str 0 (- n))) "\"")) ; handle corner case
With -1 -> end of string:

  (def chop ((o str "abcdef"))
    (pr "Chop how many chars off the end of \"" str "\"? ")
    (= n (coerce (cut (readline) 1) 'int)) ; bug in readline prepends #\newline
    (prn "Chopped: \"" (cut str 0 (- -1 n)) "\"")) ; no corner case, but there's this -1 there
I probably made a stronger argument for -1 pointing to the end of string as it leads to shorter code.

-----

2 points by nex3 2356 days ago | link

If you absolutely need to do that, you can just use (len str).

-----

3 points by akkartik 2356 days ago | link

Yup. Which is how python does it.

-----

2 points by jules 2356 days ago | link

    $ irb
    >> "abcde"[1...-1]
    => "bcd"

-----

5 points by mdemare 2356 days ago | link

I've started a new thread with cut compared in Ruby and Arc: http://arclanguage.org/item?id=2257

-----

2 points by nex3 2356 days ago | link

Agreed. On a related note, I also wish the first parameter could be negative as well.

-----

3 points by chandler 2357 days ago | link

What you're proposing is an alternate non-parenthetical syntax (i.e. x.y.z => (x y z)). Careful! Down this road lies ruin.

-----

4 points by EliAndrewC 2357 days ago | link

While I agree that this shouldn't be abused, I'm not actually proposing this syntax; Arc already lets you say cut.x.1.3 as an alternative to (cut x 1 3).

I suspect that the only time I'd ever want to chain together several different things with . is when I'm doing list slices. Which is why I'd like the x.1.3 syntax to work, since in my opinion cut.x.1.3 is a lot uglier, perhaps enough that I'd rather not do it.

-----