Arc Forumnew | comments | leaders | submitlogin
Bind a value and destructure it, a la Haskell's xs@(x:rest)
5 points by sjs 6104 days ago | 3 comments
It can be useful to bind a name to an argument and destructure it at the same time. Haskell's pattern matching allows this with the syntax:

  f xs@(x1:x2:rest) = ... -- do something with xs, x1, x2 and rest
That receives a list named xs, plucks the first 2 elems into x1 and x2, and leaves the rest in `rest'.

Arc isn't bad at this but it's nice to have it integrated into the definition. Currently:

  (def f (xs)
    (let (x1 x2 . rest) xs
      ...))
I haven't thought up any nice syntax but something like this may work:

  (def f (<xs (x1 x2 . rest)>)
    ...)

An example of this making code shorter is a fn for updating some structure stored in a list.

  (def newstruct (st other args)
    (let (tag a b c d) st
      (if (< a b)
          (struct tag (+ a other) b c (cons d args))
          st)))
could become:

  (def newstruct (<st (tag a b c d)> other args)
    (if (< a b)
        (struct tag (+ a other) b c (cons d args))
        st))
The savings may not be huge but every bit helps.


1 point by ryantmulligan 6103 days ago | link

I may be mistaken, but isn't this destructuring already done by function definitions. I mean you can write:

  (def bob args progn)
and args is properly bound to the list of arguments. Or you can choose to do

  (def bob (a b c . rest) progn)
and it's bound that way.

  arc> (def bob (a b (c d . rest1 ) . rest2) ( prn a b c d rest1 rest2))
  *** redefining bob
  #<procedure: bob>
  arc> (bob 1 2 '(3 4) 5 6 7)
  1234nil(5 6 7)
  1
  arc> (bob 1 2 '(3 4 5 6) 7 8 9)
  1234(5 6)(7 8 9)
You see it's already doing the destructuring you want, without some complex syntax for it. The above code is arc0 I make no claims for it's functioning in arc1.

-----

4 points by drcode 6103 days ago | link

he also wants to assign multiple names at different levels of the destructuring, so it is different.

It's great in Haskell, but I think it is pretty un-arcy, due to the increase in complexity.

-----

3 points by ryantmulligan 6103 days ago | link

Oh I think I see. He has two names for one part of the code. like combining:

  (def bob args progn)
  (def bob (a b c) progn)
then inside the progn you could refer to '(a b c) as args or it's components.

-----