<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>The context for my post was this:</p>
    <font face="monospace">(define-presentation-to-command-translator
      xlate-set-lcursor<br>
          (clim:blank-area com-set-cursor plotter <br>
                           :documentation "Set Left Cursor"<br>
                           :gesture :select<br>
                           :tester ((object window)<br>
                                    (declare (ignore object))<br>
                                    (typep window 'basic-chart-pane)))<br>
          (object x y window)<br>
        (%set-a-cursor (chart-pane-chart window) 'lcursor x y window))<br>
    </font>
    <p>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.<br>
    </p>
    <div class="moz-cite-prefix">On 1/10/2021 2:45 AM, Lauren P wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CANAQNuxCVoSksW17OsOwkejcsnVHZ+3vS1vKP_BOayQNA0ExeA@mail.gmail.com">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <div dir="auto">
        <div>
          <div class="gmail_quote">
            <div dir="ltr" class="gmail_attr">Hey,</div>
            <div dir="ltr" class="gmail_attr"><br>
            </div>
            <div dir="ltr" class="gmail_attr">On Sat, Jan 9, 2021, 11:21
              Paul Werkowski <<a href="mailto:pw@snoopy.qozzy.com"
                moz-do-not-send="true">pw@snoopy.qozzy.com</a>>
              wrote:<br>
            </div>
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">(defun
              make-translator-fun (args body)<br>
                 (cond ((null args)<br>
                        (warn "OBJECT parameter is obligatory (adding
              ignored parameter)")<br>
                        (let ((object-arg (gensym "OBJECT-ARG")))<br>
                          `(lambda (,object-arg &key
              &allow-other-keys)<br>
                             (declare (ignore ,object-arg))<br>
                             ,@body)))<br>
                       (t<br>
                        `(lambda (,(car args) &key ,@(cdr args)
              &allow-other-keys)<br>
                           (declare (ignorable ,(car args)))<br>
                           ,@body))))<br>
              <br>
              I guess the above does the right thing if ARGS is NIL but
              won't catch <br>
              the case of ARGS incorrectly given as, for instance, (x y
              window) <br>
              instead of (object x y window).<br>
            </blockquote>
          </div>
        </div>
        <div dir="auto">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.</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">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.</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">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.</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">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.</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">(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.)</div>
        <div dir="auto"><br>
        </div>
        <div dir="auto">Hope this is useful for you!</div>
        <div dir="auto">
          <div class="gmail_quote">
            <blockquote class="gmail_quote" style="margin:0 0 0
              .8ex;border-left:1px #ccc solid;padding-left:1ex">
            </blockquote>
          </div>
        </div>
      </div>
    </blockquote>
  </body>
</html>