Arc Forumnew | comments | leaders | submitlogin
Pipes and s-expressions
3 points by akkartik 4830 days ago | 16 comments
Here's a speculative idea:

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

  | 34 | * _ _ | + _ 1 ; => ([+ _ 1] ([* _ _] 34))
Basically get the reader to process everything between '|' and newline. And perhaps we shortcut [x] to [x _]. Append a trailing '_' if there's no '_'.

(I know we use | for other things right now.)

Anybody interested in an arc-based shell? :)



1 point by Pauan 4829 days ago | link

Yes! I've written shell scripts in Arc, and I've noticed that the Unix concept of pipes (and especially the syntax for them) is very elegant and concise.

But why not just make it a binary operator, like in Unix?

  x | y | z
  (z (x y))
I'll note that this would solve a problem I've been having... In particular, notice this pattern:

  (w/foo 1 (w/bar 2 (qux)))
The above could be written as this, instead:

  (qux) | w/bar 2 | w/foo 1
Hm... perhaps the bars should be reversed, so it would be like this:

  w/foo 1 | w/bar 2 | (qux)
I've had some situations where I kept wishing I had some syntax to make them shorter, but I wasn't sure exactly what kind of syntax would help...

-----

1 point by akkartik 4828 days ago | link

..why not just make it a binary operator..?

Hmm, you mean an infix operator, right? I'm not sure how to fit an infix operator into an otherwise prefix language. I'm sure lots of questions arise. Operator precedence, where the right-hand arg terminates. If there's a simple model that answers those questions well that would be great.

-----

1 point by Pauan 4828 days ago | link

Yes. One potential solution is the curly infix system described here (scroll down a bit):

http://www.dwheeler.com/readable/sweet-expressions.html

Though that does add two extra characters:

  {x | y | z}

-----

1 point by akkartik 4828 days ago | link

Ah, I keep losing that page, thanks!

But for this particular case I'd rather just add an extra '|' and make it all prefix.

-----

2 points by akkartik 4818 days ago | link

The new wart interpreter (http://arclanguage.org/item?id=14881) no longer reserves '|' for syms. It also lets you skip parens and use indent if you choose.

  wart> assign f 3
  wart> f
  3
  wart> assign f (lambda() 34)
  wart> (f)
  34
  wart> def f()
    35

  ; extra <enter> like python
  wart> (f)
  35

-----

3 points by davidx 4819 days ago | link

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 4819 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 4819 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 4818 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 4818 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 4818 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 4817 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 4817 days ago | link

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

-----

1 point by akkartik 4817 days ago | link

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

-----

1 point by davidx 4816 days ago | link

I think that was a duplicate that I deleted.

-----

1 point by Pauan 4819 days ago | link

I agree.

-----