Arc Forumnew | comments | leaders | submitlogin
A perl-esque new mutation primitive: shift
2 points by akkartik 3095 days ago | 8 comments

  (with (x 3 y 4)
    (shift x y 5)
    (list x y)) ; => (4 5)
Among other benefits, we can now build rotate in terms of shift:

  (mac rotate places
    (w/uniq tmp
      `(let ,tmp ,car.places
         (shift ,@places ,tmp))))  
(and of course we could always build swap in terms of rotate)

  (mac swap(x y)
    `(rotate ,x ,y))
If people like this I'll put it in anarki in a day or two. Here's what it looks like in wart:

2 points by rocketnia 3094 days ago | link

I don't like that implementation of 'rotate, since it causes subexpressions of car.places to be evaluated twice. (I don't know if 'shift has similar quirks without looking at its code.)

This is something I cared about when working on Penknife that I now realize I don't actually use. (In fact, I don't use 'rotate or 'swap at all; it only comes up in 'zap.) My current way of thinking is that I wouldn't bother to fix it. I'd put a note in the documentation instead, or else detect unsupported usage and raise an error. And then I guess I'd make sure to apologize for that caveat every time I talked about the utility. :-p

If you want to fix it, I've found it's pretty elegant to have a (place ...) form that gives you a getter and a setter.

  (mac rotate args
    `(fn-rotate ,@(map [do `(place ,_)] args)))
It's probably just as elegant with fexprs.


1 point by akkartik 3094 days ago | link

"I'd put a note in the documentation instead.."


  mac shift $args ; multiply-evals to maintain places
    `(= ,@(zip-flat $args cdr.$args))


1 point by rocketnia 3093 days ago | link

I half thought so. :-p Very nice implementation!


2 points by akkartik 3091 days ago | link

You'll like my impl of wipe, then :)

  ; infinite nil generator
  = nils '(nil)   cdr.nils nils

  mac wipe places
    `(= ,@(zip-flat places nils))


1 point by rocketnia 3090 days ago | link

That is pretty nice, yeah. ^_^


1 point by rntz 3094 days ago | link

This is not a good primitive. It can be built using assign, and having this instead of assign be primitive complicates the arc compiler, instead of merely introducing another macro.


2 points by Pauan 3094 days ago | link

If you look at the wart source (linked in the thread), you will see that it is actually a macro. I'm not sure why akkartik called it a primitive.


1 point by akkartik 3094 days ago | link

Yeah I misspoke.