Arc Forumnew | comments | leaders | submitlogin
1 point by rocketnia 4857 days ago | link | parent

Wouldn't that 'aif have (aif t nil) return t?

Hmm, you lost me with delisting.

It's a utility to cut down on nesting (iflet (a . b) ...) forms, a common pattern I use when giving a utiility different behavior depending on the number of arguments. The primary goal is to have the branches lined up on the right side while the local variables are distributed so they don't get in the way. Particularly, a variable is positioned just before the first branch it's bound in. The rest variable is an exception; it makes sense at every level, but I don't want it to be perceived as the first element of the list, so I've put it in a different place. (Note that it doesn't actually make sense everywhere unless the thing being destructured could be a dotted list or non-nil atom.)

The three branches in my 'aif's use of 'delisting are the zero-element branch (just nil), the one-element branch, and the two-or-more-element branch. The "two or more" thing might be tricky to perceive; maybe the utility should be limited to proper lists and the last case should be preceded by both its usual variable and the rest variable.

Meanwhile, the point of 'g-rest is to allow for destructuring. Destructuring an atom might be weird, but most of the time the rest isn't an atom, and nil can be destructured just fine.



1 point by akkartik 4857 days ago | link

Ok, I'm starting to see. So the code in each branch binds all variables upto that point?

When I see:

  first    first
I'm inclined to read this as, "if you just see a variable (call it first) and nothing else after, just return first." I imagine the evaluation going to the next case and saying[1], "oops, nothing left, ok, go back and execute code for the previous case." Am I on the right track? Hmm, I've never seen anything like this.

And the nil is a branch with an empty 'guard'. Ahhhh.. this is cool :)

[1] Dijkstra hated anthropomorphizing code.

-----

2 points by rocketnia 4857 days ago | link

You're on the right track. ^_^ Like I said, 'delisting just exists to better organize a pattern I use all the time.

A visual example would probably work wonders. Here's the pattern:

  (iflet (<var1> . <rest>) body
    (iflet (<var2> . <rest>) <rest>
      (iflet (<var3> . <rest>) <rest>
        <three-or-more-arg case>
        <two-arg case>)
      <one-arg case>)
    <zero-arg case>)
And here's the same code using (this version of) 'delisting:

  (delisting <rest> body
            <zero-arg case>
    <var1>  <one-arg case>
    <var2>  <two-arg case>
    <var3>  <three-or-more-arg case>)
Any version of 'delisting should have basically the same elements. I'm just not sure where to put them.

Incidentally, halfway through writing that post with 'delisting and 'aif, the 'aif code read (decomposing body ...). XD

-----

1 point by akkartik 4857 days ago | link

Ok, I see the light. That explanation suits me perfectly :)

-----

1 point by rocketnia 4857 days ago | link

I just hope my code doesn't all devolve into "decomposing body" and "ifdecap." >< Talk about anthropomorphizing code.

-----

1 point by akkartik 4857 days ago | link

Hmm, (aif t nil) works fine for me. aif perhaps doesn't need that gensym even if delisting does in general.

-----

1 point by akkartik 4851 days ago | link

Ack, I misunderstood you. I've retreated to a version with car/cdr manipulation; looks like there's no way around it (it's still simpler than the original, but that just makes me wonder what bugs remain)

https://github.com/akkartik/wart/commit/9425c4829abb88052d29...

-----

1 point by rocketnia 4851 days ago | link

I haven't tested it, but I don't see any bugs from here.

I'm a bit surprised you broke up the (if branches ...) condition into two places like that, though. I think it would have been simpler just to replace "(or then more-branches)" with "branches". ^^

-----

1 point by akkartik 4851 days ago | link

:) Yeah I thought of that in the next CL.

-----