make-translator-fun
Paul Werkowski
pw at snoopy.qozzy.com
Sun Jan 10 15:13:04 UTC 2021
The context for my post was this:
(define-presentation-to-command-translator xlate-set-lcursor
(clim:blank-area com-set-cursor plotter
:documentation "Set Left Cursor"
:gesture :select
:tester ((object window)
(declare (ignore object))
(typep window 'basic-chart-pane)))
(object x y window)
(%set-a-cursor (chart-pane-chart window) 'lcursor x y window))
where originally I omitted 'object' from the next to last line resulting
in the wrong values being presented to the %set-a-cursor function. User
error on my part but LispWorks CLIM2 did what I expected anyway thus
keeping me ignorant of my omission. Perhaps LW was able to infer what I
wanted.
On 1/10/2021 2:45 AM, Lauren P wrote:
> Hey,
>
> On Sat, Jan 9, 2021, 11:21 Paul Werkowski <pw at snoopy.qozzy.com
> <mailto:pw at snoopy.qozzy.com>> wrote:
>
> (defun make-translator-fun (args body)
> (cond ((null args)
> (warn "OBJECT parameter is obligatory (adding ignored
> parameter)")
> (let ((object-arg (gensym "OBJECT-ARG")))
> `(lambda (,object-arg &key &allow-other-keys)
> (declare (ignore ,object-arg))
> , at body)))
> (t
> `(lambda (,(car args) &key ,@(cdr args) &allow-other-keys)
> (declare (ignorable ,(car args)))
> , at body))))
>
> I guess the above does the right thing if ARGS is NIL but won't catch
> the case of ARGS incorrectly given as, for instance, (x y window)
> instead of (object x y window).
>
> I would give it an explicit parameter so it takes (OBJECT-ARG ARGS
> BODY) so autodoc shows where the object argument goes without having
> to remember to read the docstring.
>
> I'd put in a destructuring bind at the T case and then test that... it
> should bomb in the compiler if you pass it (NIL X Y WINDOW) as-is:
> you'll need to gensym and DECLARE IGNORE if it's a NIL.
>
> If you wrap it in a macro the way I write that lambda list is
> ((OBJECT-ARG &REST ARGS) &BODY BODY); it is displayed by autodoc and
> the destructuring bind catches it at compile time. If you really want
> to accept a no arguments form, I tend to use NAME* for the alternative
> form and make it a wrapper stub, otherwise I prefer to assume "forgot
> arguments" and error.
>
> I wouldn't set the object argument ignorable in the T case unless it
> was typed in as NIL, as it can hide bugs in the body code. Better to
> let the user specify ignorable in the BODY if they are sure they don't
> need it.
>
> (More of a style thing, I find it cleaner to normalize the argument
> list to replace the empty list with (NIL) so it works with
> destructuring bind: you can get rid of the main branch and only type
> the bulk of the code once, since you need to check for a gensym and
> ignore declaration in the T case as well. Also, leave out
> &ALLOW-OTHER-KEYS unless absolutely necessary... I've found it makes
> it exceedingly difficult to catch typos.)
>
> Hope this is useful for you!
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/mcclim-devel/attachments/20210110/30c2eee0/attachment.html>
More information about the mcclim-devel
mailing list