Arc Forumnew | comments | leaders | submitlogin
Favorite utilities, favorite names - I
1 point by akkartik 5219 days ago | 7 comments
Some of you will have these primitives (or variants) in your toolbox. Can you think of a better name for any of them? (awhile, proc and especially ret seem pretty settled)

  (mac awhile(expr . body)
    `(whilet it ,expr
      ,@body))

  (mac forever body
    `(awhile t ,@body))

  (mac proc(name args . body)
    `(def ,name ,args ,@body nil))

  ; skenney26: http://arclanguage.org/item?id=11068
  (mac ret(var val . body)
   `(let ,var ,val ,@body ,var))

  ; aw: http://awwx.ws/dyn
  (mac dynvar (name (o init))
    (w/uniq (param val)
      `(withs (,val ,init
               ,param (ac-scheme (make-parameter ,val)))
         (defvar ,name ,param))))

  (mac dlet (var value . body)
    (w/uniq (param v f)
      `(with (,param (defvar-impl ,var)
              ,v ,value
              ,f (fn () ,@body))
         (ac-scheme (parameterize ((,param ,v)) (,f))))))

  ; various
  (mac before-exec(fnname args . body)
    `(let old ,fnname
        (def ,fnname ,args
          ,@body
          (old ,@args))))

  (mac after-exec(fnname args . body)
    `(let old ,fnname
        (def ,fnname ,args
          (let result (old ,@args)
            ,@body
            result))))

  ; palsecam: http://arclanguage.org/item?id=10696
  (= buffered-exec-delay* 10)
  (= buffered-execs* (table))
  (def buffered-exec(f)
    (or= buffered-execs*.f
         (thread (sleep buffered-exec-delay*)
                 (wipe buffered-execs*.f)
                 (f))))

  ; http://arclanguage.org/item?id=11103
  (mac init args
    `(unless (bound ',(car args))
       (= ,@args)))

  (mac ifcall(var)
    `(if (bound ',var)
       (,var)))
Feel free to show off your own favorite utilities. The arc community needs a growing shared vocabulary for common operations more than it needs a new compiler or anarki, IMO.


1 point by fallintothis 5219 days ago | link

In no particular order:

Why is forever defined with awhile? I can't imagine wanting it bound to t for the whole loop.

I'm trying to decide whether I like awhile. I understand it as "anaphoric while", but the namespace collision with English rubs me the wrong way.

ret is another one like that. I understand what the name is supposed to mean: it's kind of a portmanteau between "let" and "return", since it's a let block that returns the variable. But the "return" context makes me think ret's like a standard return statement you might have in a loop, which it clearly isn't.

I can't think of any better names for them. I suspect they just take some getting used to.

Do you mean for old and result to be bound in before-exec and after-exec, or should those be gensyms?

init is a good name. You might want to rethink the definition:

  arc> (= x 1)
  1
  arc> (init x 5 y 5)
  nil
  arc> x
  1
  arc> y
  Error: "reference to undefined identifier: _y"
I think ifcall should be named callif or call-if to match carif and consif.

-----

1 point by akkartik 5219 days ago | link

Thanks for those comments. Yes, init could be better.

I'd never noticed the collision with english's awhile! And yes, I shouldn't introduce anaphora needlessly.

I did mean to bind result, that seems useful. old could perhaps be a uniq. (Update: I think I was following the precedent of orig in http://awwx.ws/extend)

I have to disagree on ret, though. It's short, and I'm a sucker for puns of all flavors.

Regarding callif: The comment at the top of arc.arc suggests consif isn't satisfactory to pg/rtm. if at start or end seems about equally pleasing. What I really want is for ifcall to suggest bound. Maybe trycall, but that evokes exceptions.

-----

1 point by fallintothis 5219 days ago | link

Yeah, ret isn't a bad name. And puns are okay. For example, I like the name whilet -- probably because I often do the same thing inadvertently while writing (i.e., adjoin the end of one word with the beginning of the next if they have the same letters). I just usually use ret for

  (point ret
    (while cond
      (ret 5)))
Though I prefer full words if they're short, so I actually use return these days. I'd just need to get used to ret being a let instead of a return.

if at start or end seems about equally pleasing.

I don't really think if at the beginning conveys the same idea. The way I read it, if-something implies "if something, then do..."; but I read something-if as "if this thing, then something it". For instance, which looks clearer?

  (if-empty xs
            0
            (+ 1 (len (cdr xs))))
vs

  (empty-if xs
            0
            (+ 1 (len (cdr xs))))
I say the first, since I read it "if xs is empty, then...", whereas the second says "if xs, then empty it".

As it pertains to callif/ifcall, we mean to say "if var, then call it", which implies callif per the above.

The arc.arc comment seemed more about how consif and conswhen aren't distinguishable enough (how is "when" different from "if"?).

-----

1 point by akkartik 5219 days ago | link

Ah, I just figured out you were referring to the CL return keyword inside loop (?). Something to mull, though it should be ok as long as arc doesn't get a loop keyword (a candidate name for forever)

-----

2 points by fallintothis 5219 days ago | link

Incidentally, Arc does have a loop macro that's kind of like a C for-loop:

  (mac loop (start test update . body)
    (w/uniq (gfn gparm)
      `(do ,start
           ((rfn ,gfn (,gparm) 
              (if ,gparm
                  (do ,@body ,update (,gfn ,test))))
            ,test))))
I like "forever". It's very clear.

-----

1 point by akkartik 5219 days ago | link

lib/util.arc on anarki has some more: http://github.com/nex3/arc/blob/master/lib/util.arc

-----

1 point by akkartik 5219 days ago | link

Update I just remembered that aw prefers to call dynamic variables implicit (http://awwx.ws/implicit)

-----