Arc Forumnew | comments | leaders | submit | davidx's commentslogin
3 points by davidx 4886 days ago | link | parent | on: Pipes and s-expressions

It would probably be better to keep the shell semantics so that

  ( x | y | z )
  =>
  (z (y (x)))
and

  ( a b c | x y z )
  =>
  (x y z (a b c))
Ie, first subexpression is also treated as a function call.

-----

4 points by rocketnia 4886 days ago | link

Well, in that case I've got some deja vu. :-p http://arclanguage.org/item?id=13450

Here's a quick macro to emulate this syntax:

  (mac // body
    (aif (pos ': body)
      (let (before (nil . after)) (split body it)
        `(,@before (// ,@after)))
      body))
Now instead of writing this:

  (accum acc
    (each x args
      (acc (* 2 x))))
You can write this:

  (// accum acc :
     each x args :
       acc : * 2 x)
I've also put this macro in a gist at https://gist.github.com/1078269.

Better naming ideas are welcome. :-p

-----

1 point by davidx 4886 days ago | link

Well, I prefer the left-to-right dataflow, but that might just be force of habit, and this version is a lot cleaner and simpler to implement. Not sure about '//' for the macro name (looks like division), but this looks the best way to do this.

-----

1 point by rocketnia 4886 days ago | link

Ah, make that deja vu and egocentrism-based dyslexia. ><;

Implementing the pipeline left-to-right order is just a matter of switching "before" and "after," I think.

Hmm, macros and special forms seem a bit confusing that way around... but maybe they'd just look like list comprehensions or something. What about having both operators? What might their precedence be like?

As far as naming goes, I was trying to pick something unused that would appear to be part of the parenthesis in some way. :-p

-----

3 points by davidx 4885 days ago | link

Maybe

  (<< a b c : x y z) => (a b c (x y z))
  (>> a b c : x y z) => (x y z (a b c))
then? Still looks slightly like less-than/greater-than, but this gives a visual cue for data direction, and avoids needing to care about relative precedence.

-----

1 point by rocketnia 4885 days ago | link

Reminds me a bit of monads, bit shifting, and strict comparison. >.>; I guess maybe there's not an unimpeachable choice here. :-p

I was thinking along the lines of putting them in the same syntax:

  (// a b c :
    x y z ! i j k)
  =>
  (a b c (i j k (x y z)))
Then again, yours does allow for this:

  (<< a b c :
    >> x y z : i j k)

-----

1 point by zck 4884 days ago | link

Fyi, your other comment on this thread (http://arclanguage.org/item?id=14886) is dead. It was obviously a valid post, but it apparently tripped the detector.

-----

1 point by rocketnia 4884 days ago | link

I didn't see it while it was alive, so I'm curious. ^_^

-----

1 point by akkartik 4884 days ago | link

Perhaps it was deliberately deleted? I can resuscitate it if not.

-----

1 point by davidx 4883 days ago | link

I think that was a duplicate that I deleted.

-----

1 point by Pauan 4886 days ago | link

I agree.

-----


(reduce + (map * x y))

http://en.wikipedia.org/wiki/Map_%28higher-order_function%29 and http://en.wikipedia.org/wiki/Reduce_%28higher-order_function... should be helpful if you dont know what those mean.

-----

1 point by alimoeeny 5166 days ago | link

any help with this one: xy = 0; for ( i ...) { xy += (x(i) - mean(x)) * (y(i)- mean(y)) } .

-----

1 point by alimoeeny 5166 days ago | link

Any ideas why this doesn't work: (def s (x y) ( (= mx (avg x)) (= my (avg y)) (reduce + (map * (map [- _ mx] x) (map [- _ my] y)))))

-----

4 points by fallintothis 5166 days ago | link

For one, you have an extra set of parentheses around the body of the function. Parenthetical expressions like

  (expr1 expr2 expr3 ...)
by default will evaluate expr1 and try to call it with the arguments expr2, expr3, .... E.g.,

  arc> (+ 1 2 3)
  6
This sort of rule applies recursively, so

  ((if (> 1 2) - +) 1 2 3)
first evaluates

  (if (> 1 2) - +)
which returns the function + (since (> 1 2) is false), meaning the original evaluates to

  (+ 1 2 3)
There are a few places where parenthetical expressions don't evaluate this way, but they're usually pretty obvious -- like the argument list in a def. For more details, the tutorial is a decent place to start learning about Arc & Lisp programming: http://ycombinator.com/arc/tut.txt.

To fix your code immediately, you'd just need to get rid of the extra parens. Expressions in the body of a function evaluate one after the other, returning the value of the last expression, so given

  (def f (x)
    (+ x 1)
    (+ x 2))
a call to f will calculate (+ x 1) and (+ x 2), returning the latter.

But you should (generally) only use = for global variables. For local ones, you'll want with or let.

  arc> (let x 1 (+ x 1))
  2
  arc> (with (x 1 y 2) (+ x y))
  3
So, the function

  (def s (x y)
    (with (mx (avg x) my (avg y))
      (reduce + (map *
                     (map [- _ mx] x)
                     (map [- _ my] y)))))
should do what you want. You could still perform some "map fusion". Roughly speaking,

  (map f (map g xs))
is equivalent to

  (map [f (g _)] xs)
and you save on doing multiple passes through your lists. Thus,

  (def s (xs ys)
    (with (mx (avg xs) my (avg ys))
      (reduce + (map (fn (x y) (* (- x mx) (- y my)))
                     xs
                     ys))))
is arguably cleaner, though the two-argument function does clutter stuff up a bit.

You can also write the same "destructive" style of code in Arc, though it's normally frowned upon.

  (def s (x y)
    (let xy 0
      (for i 0 (- (min (len x) (len y)) 1)
        (++ xy (* (- (x i) (avg x))
                  (- (y i) (avg y)))))
      xy))
Finally, to format code,

  put a blank line, then at least two spaces before the line of code
  (similarly for subsequent lines)
See http://arclanguage.org/formatdoc for details.

-----

2 points by alimoeeny 5166 days ago | link

Thanks a lot, that was great help, I never felt so excited about coding in a new language since Commodore 64's BASIC!

-----

1 point by alimoeeny 5166 days ago | link

That was quite helpful.

-----