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.

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:

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...

$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)

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.