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

The one thing this benchmarks measures is function call overhead, and since every mzscheme function is wrapped in an Arc function, unsurprisingly, Arc is a lot slower. So?

-----


How about a much simpler and less intrusive method? Add a reader method for curly brackets that switches the first and the second argument around. So:

    (a b c) = {b a c}
That means you can write a C-style expression such as this one:

    (f(x) + g(y)) * h(z)
either prefix-wise:

    (* (+ (f x) (g y)) (h z))
or infix-wise:

    {{(f x) + (g y)} * (h z)}
It doesn't give you precedence; worse, you cannot omit any brackets. But it does give you infix, and it's completely optional, and trivial to understand or implement.

-----

2 points by mdemare 5913 days ago | link | parent | on: Cut and Index - Arc and Ruby Side By Side

Maybe there should be another version of cut that takes a length instead of an index as argument. Together with allowing negative second arguments, that should reduce the last example from:

    (cut s (- (len s) j) (+ (- (len s) j) i))
to

    (cutl s -j i)

-----

1 point by nex3 5913 days ago | link

It seems a little weird that the second parameter switches meaning from "end" to "length" if the first parameter is negative, but I suppose it's more useful than the alternative...

-----

3 points by mdemare 5913 days ago | link

No, it's another function. cutl instead of cut.

-----

1 point by nex3 5913 days ago | link

Gotta stop trying to read code at four in the morning...

-----


Good point, I've changed it, but am still using arc1 as reference.

-----

3 points by mdemare 5913 days ago | link | parent | on: Cut and Index - Arc and Ruby Side By Side

I wanted to make Arc's examples as short as possible, but you're right - I've changed it now.

-----

5 points by mdemare 5914 days ago | link | parent | on: New version

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

-----

7 points by mdemare 5914 days ago | link | parent | on: Cut and Index - Arc and Ruby Side By Side

To sum up, Arc wins once, draws three times and loses six times (counting tokens, not characters).

I think the goal for Arc should be to be powerful enough to express all these cases without resorting to expressions (+ - len).

Most obvious improvement - allow negative indices for the second argument. Then you could say:

    (cut s -x)
for

    s[-x .. -1]
Right now, Ruby just has more syntax to express this, e.g. four different forms:

    s[x] ; s[i,j] ; s[i .. j] ; s[i ... j]
Arc only has three:

    (s x) ; (cut s x) ; (cut s i j)

-----

7 points by steadicat 5913 days ago | link

Python only has two forms (s[x] ; s[i:j]), yet it can express the same things more succinctly: see below.

I find Python's model vastly superior. Less syntax to learn, yet more powerful.

Here is the comparison with Python added in as the first one:

The i'th item of s

    s[i]
    s[i]
    (s i)
The i'th item of s from the end

    s[-i]
    s[-i]
    (s (- (len s) i))
The first x items of s

    s[:x]
    s[0,x]
    (cut s 0 x)
The last x items of s

    s[-x:]
    s[-x..-1]
    (cut s (- (len s) x))
The items from position i to the end

    s[i:]
    s[i .. -1]
    (cut s i)
The items from position i to position j (inclusive)

    s[i:j+1]
    s[i .. j]
    (cut s i (+ 1 j))
The items from position i to position j (exclusive)

    s[i:j]
    s[i ... j]
    (cut s i j)
i items beginning at position j.

    s[j:j+i]
    s[j,i]
    (cut s j (+ i j))
The items from position i to the end minus the last j items

    s[i:-j]
    s[i ... -j]
    (cut s i (- -1 j))
i items beginning at the j'th position from the end

    s[-j:-j+i]
    s[-j,i]
    (cut s (- (len s) j) (+ (- (len s) j) i))

-----

2 points by vrk 5913 days ago | link

For reference, here's how you can do it in Perl 5:

The ith item of s:

  $s[i]
The ith item of s from the end:

  $s[-i]
The first x items of s:

  @s[0 .. x-1]
The last x items of s:

  @s[-x .. -1]
The items from position i to the end:

  @s[i .. $#s]
The items from position i to position j (exclusive):

  @s[i .. j-1]
i items beginning at position j:

  @s[j .. j+i]
The items from position i to the end minus the last j items:

  @s[i .. $#s-j]
  # Alternative:
  (@s[i .. $#s])[0 .. j-1]
i items beginning at the jth position from the end:

  @s[-j .. -j-i]
  # Alternative:
  (@s[-j .. -1])[0 .. i-1]
Legend:

  $s[i]  # A scalar at index i
  @s[<something complex>]  # An array slice (i.e. multiple values)
  $#s  # The last index of the array s
  a .. b  # In list context, a list of numbers or letters from a to b, inclusive (can be used outside array indexing)

-----

4 points by pg 5913 days ago | link

If you're comparing for length, at least use dot notation.

-----

6 points by steadicat 5913 days ago | link

I think the key point is that Ruby's power can be achieved with less syntax forms without compromises.

The fact that Python's way also happens to be shorter is not the main point, just an added plus.

-----

2 points by jules 5913 days ago | link

Are you aware that x..y and x...y notation is a Range literal in Ruby? I like Pythons syntax better but range notation isn't special syntax for slices.

obj[a,b,...] is sugar for a method call in Ruby (you can define a [] method for your own classes). So there's really only two syntactic forms here, and arguably no special syntax for slices.

-----

1 point by mdemare 5913 days ago | link

I'm counting each occurrence of i,j and x, each occurrence of 1, and each occurrence of len, + and (binary) -.

That yields the following scores: Python : 1 1 1 1 1 4 2 4 2 4 => 21 Ruby : 1 1 2 2 2 2 2 2 2 2 => 18 Arc : 1 3 2 3 1 4 2 4 4 8 => 32

15 is the best possible score. This is meant as succinctness benchmark for the index and slice/cut operations, which are extremely common.

-----

1 point by jc 5905 days ago | link

I think there's a reccuring mistake in the arc snippet for "The items from position i to the end minus the last j items."

I think it should be

  (cut s i -j)
... but I know I could be missing something

(thanks for the help, cadaver)

-----

1 point by cadaver 5905 days ago | link

Have a look at the little "help" next to the "about" box in your profile.

Also, I noticed that some people use a single ' to quote a function name on its own within a sentence (just like in Arc).

-----


Yes, but of all the characters that need shift, "?" is surely the easiest.

-----

5 points by mdemare 5917 days ago | link | parent | on: Ruby-like in place list expansion

Sometimes, I'm building a list, and want to include an item in the middle only if a condition is true.

    # Ruby 1.8
    insertion = new? ? ['new'] : []
    list = ['hello','brave'] + insertion + ['world']

    # Ruby 1.9
    insertion = new? ? ['new'] : []
    list = ['hello','brave',*insertion,'world']

    # Arc now
    (let insertion (if (is-new) (list "new") nil)
      (join (list "hello" "brave") insertion (list "world")))

    # With @ operation
    (let insertion (if (is-new) (list "new") nil)
      (list "hello" "brave" @insertion "world"))
I think it's worth it.

-----

3 points by shiro 5916 days ago | link

To build a list, you can already use quasiquote---a standard idiom in Lisp-family languages.

    (let insetion (if (is-new) (list "new") nil)
       `("hello" "brave" ,@insertion "world"))
What matters is to expand a given list into an argument list. To do that you have to use 'apply' now.

-----

1 point by mdemare 5919 days ago | link | parent | on: Suggestion for [... _ ...]

What about [... * ...] where all 0 .. N arguments are collected in a list called *?

-----

1 point by bogomipz 5919 days ago | link

Except you're shadowing the multiply operator, so I think you need to pick a different name.

The idea is nice though. You should even be able to mix it with the other implicit arguments;

  [prn "the first two args were " $1 " and " $2 ", and the rest were " $*]

-----

More