Arc Forumnew | comments | leaders | submitlogin
dsb redux, with extended macrology tips and promised refactoring (smuglispweeny.blogspot.com)
5 points by kennytilton 6055 days ago | 7 comments


3 points by almkglor 6055 days ago | link

It might have been easier to just do something like this for default values of optional arguments:

  (dsb (&o (p 100)) foo
    (body))

  =>

  ;      put default values here
  (with (p 100
         ,tree foo)
    ; do the checking here
    (if ,tree
      (= p (car tree)))
    (body))
Edit: Personally I'd do a recursive expansion of the optional/keyword part, successively deciding at each sublist whether it should go to an optional or a keyword argument, or if the sublist is empty, to stop parsing. This would probably reduce significantly the overhead of nth, which I think needs to measure the length of the argument list each time. Will think of an alternative method of expressing dsb in a recursive manner which would hopefully just significantly increase the apparent complexity of the generated code while gaining a minor boost in efficiency.

-----

1 point by kennytilton 6055 days ago | link

"Personally I'd do a recursive expansion of the optional/keyword part"

I'll be honest, I am just a simple application programmer, I was stunned for example by the expansion of withs.

And I am just a muddy Common Lisper, I am not smart like the Lisp-1 guys, I do not know how to express the number 3 as a half-dozen nested lambda forms. So...

...that's a long way of saying I think you are right, there is almost definitely a nicer lambda-based solution out there. I would say I would love to see it except I doubt I would understand, I have been to Lisp-1 talks and never understood a word, I've stopped going.

But I would enjoy seeing a recursive solution, your approach sounds promising and even easy to read, more than I can say for mine.

-----

1 point by almkglor 6054 days ago | link

NON-recursive modification of your solution ^^.

Turns out that 'withs is recursive enough for this ^^.

  (mac dsb (params data . body)
    (let (reqs keys opts) (dsb-params-parse params)
      (w/uniq (tree kvs)
        (withs (optfn
                (afn (l)
                  `()))
          ; turn reqs into the argument list, adding
          ; the ,tree as a rest argument
          (if (no reqs)
              (= reqs tree)
              ((afn (l)
                 (aif (cdr l)
                      (self it)
                      (= (cdr l) tree)))
               reqs))
          `(withs (,reqs ,data
                   ,@(mappend [list (carif _)
                                    `(do1 (if ,tree
                                              (car ,tree)
                                              ,(cadrif _))
                                          (= ,tree (cdr ,tree)))]
                              opts)
                   ,kvs (pair ,tree)
                   ,@(mappend [list (carif _)
                                    ; don't use aif - dsb might be
                                    ; used itself in an aif context
                                    (w/uniq it
                                      `(let ,it (assoc ',(carif _) ,kvs)
                                            (if ,it
                                                (cadr ,it)
                                                ,(cadrif _))))]
                              keys))
            ,@body)))))
Yep, I concede. The recursive solution won't easily handle the cases in http://arclanguage.org/item?id=4423 . So this is really the best way to do it ^^.

-----

1 point by almkglor 6054 days ago | link

Ha, ha, yeah right, I don't even use any lisplike programming languages in an application I've ever passed to a client (using a lisplike to generate an application in a non-lisplike is another statement).

...that's a long way of saying no, I'm not even a simple application programmer, I bet you've built more Lisp code that actually reached application level.

Anyway I'll be doing my hacking now, will come back in a few dozen minutes.

-----

1 point by almkglor 6054 days ago | link

Hmm. The current problem I'm facing is with the defaulting expression: what should we do in the following case:

  (dsb (&o (m 100) (p m)) ...)
Or even worse:

  (let var 42
    (dsb (&o (p var) var) ...))
Hmm. Thinking... thinking....

-----

1 point by kennytilton 6054 days ago | link

[WARNING: Common Lisp follows, but I do not think the Arc/CL differences change anything]

No coffee yet, but why is the first one problematic?

  (destructuring-bind (&optional (m 100)(p m)) nil
    (list m p))
  -> (100 100)
In this case, the second optional parameter VAR simply shadows the VAR introduced by LET, so it is not a hard case:

  (let ((var 42))
    (destructuring-bind (&optional (m var) var) nil 
       (list m var)))
-> (42 nil)

Where VAR is used as the default for M, hey, there better be one out there outside the DSB to eat.

-----

1 point by almkglor 6054 days ago | link

It's problematic for a recursive solution. ^^ So is the second. ^^ In the end I decided that the sketch up of your solution is better, since 'withs is, after all, recursive ^^

-----