Arc Forumnew | comments | leaders | submitlogin
Printing squares
4 points by skenney26 6014 days ago | 12 comments
Today there's a link on Hacker News to an interesting article by Steve Yegge (http://steve.yegge.googlepages.com/lisp-wins). In the article he compares two solutions to a simple problem, one written in Perl, the other in Java. I was wondering what the solution would look like in Arc:

  (= squares (map [* _ _] (range 1 5)))
  (prall squares "" " ")
  (prn)
This is the most pedantic solution to Steve's criteria. Since I was bored at work I started playing around with it by adding a couple utilities:

  (def prsp (xs)
    (prall xs "" " ")
    (prn))

  (def sqr (x) (* x x))
prsp and sqr solve common enough problems that its possible to imagine them being included in arc's standard library.

Leaving aside the creation of a variable we now have:

  (prsp:map sqr (range 1 5))
The range expression is pretty verbose compared to other languages such as Ruby and Haskell. What if an integer in functional position created a range? I wasn't sure how to hack ar-apply in ac.scm to get that to work.

Any ideas?

With that the final solution would be:

  (prsp:map sqr (1 5))


3 points by sacado 6014 days ago | link

I'd rather see some ssyntax here, e.g. expanding 1..5 to (range 1 5). Well, that's a matter of taste, but I don't really like the (1 5) approach, and the ssyntax version looks more usual and more explicit (it looks like what you find in others languages).

Anyway, for your solution, you have to hack ar-apply or ar-funcall if I remember well. That's where ac.scm is dispatching between real functions and collection accesses.

Anyway, on Anarki 'defcall should do it :

  (defcall int (a b) (range a b))
  (1 5)
  ==> (1 2 3 4 5)

-----

7 points by absz 6014 days ago | link

On Anarki, you can add the ssyntax:

  (add-ssyntax-top
    ".." (range L r))
Then you have

  arc> 1..10
  (1 2 3 4 5 6 7 8 9 10)
.

EDIT: Actually, it's slightly nicer to do

  (add-ssyntax-top
    ".." (range ...))
so that you can then specify the step size:

  arc> 1..10
  (1 2 3 4 5 6 7 8 9 10)
  arc> 1..10..2
  (1 3 5 7 9)

.

-----

1 point by almkglor 6013 days ago | link

As an aside, this appears to be popular, it might be possible to add this to the ssyntax extension.

As an aside, I suspect that much of the slowdown from the new ssyntax/ssexpand comes from scheme-side 'ac emitting a lot of 'ar-eval calls, but I'm not sure, since I haven't studied 'ac output much yet.

-----

1 point by almkglor 6014 days ago | link

Where'd you implement 'add-ssyntax-top ? I can't seem to find it anywhere in Anarki.

-----

1 point by absz 6013 days ago | link

Whoops, forgot about that. It's just a thin wrapper around a-ssyntax-top:

  (mac add-ssyntax-top body
    `(a-ssyntax-top ',(pair body [list (string _1) _2])))
. It's just quoting and pairing things. It'd be nice to have a-ssyntax-bottom, too...

-----

1 point by almkglor 6013 days ago | link

I suggest you push this onto Anarki (and possibly implement a-ssyntax-bottom). ^^

-----

1 point by absz 6013 days ago | link

I will do so soon, and hopefully when I get a chance to study ssyntax.arc a little more, I will add a-ssyntax-bottom.

What might be nice would be to have numerical precedence levels (reals, not integers), so that you could add an operator later with the right precedence without redefining everything.

-----

1 point by sacado 6014 days ago | link

Oh, great, I forgot this one...

-----

1 point by absz 6014 days ago | link

I'm not sure what you mean by this: forgot that this functionality existed?

-----

1 point by sacado 6014 days ago | link

yep, that's it. I never used the ssyntax-definer, so I forgot it was existing. Sorry, but it's a little late here, so I can hardly even understand myself :)

-----

1 point by skenney26 6014 days ago | link

defcall looks interesting. Is there any documentation on other uses of it?

I like the idea of using the .. syntax:

  (spaces:map sq 1..5)

-----

4 points by absz 6014 days ago | link

defcall is pretty simple to use. The syntax is the same as that of def, except instead of a function name, you provide the type of the object. The function receives both the objects and its "arguments". E.g.

  arc> (defcall sym (self n)
         (repeat n (prn self))
  #<procedure>
  arc> ('a 3)
  a
  a
  a
  nil

.

-----