From: GP lisper
Subject: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <slrnguqsgr.ne8.spambait@phoenix.clouddancer.com>
code fragment:
-------------------------------------------------------
(defun todays-lines
...
	   (when candidate
	     (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) candidate
;	filtering
		   (push (list strt ukey tm pitcher lmo v ml rln aln) results))))))


(defun format-lines() "display active lines"
...
	   (dolist (line (todays-lines))
	     (when line
	       (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) line
-------------------------------------------------------

So that is three places I need to maintain the lambda-list:
  strt ukey tm pitcher lmo v ml rln aln
and only getting two of three changed is not good.

Is there a way, perhaps a macro, to have a single location to control
these elements?  I didn't think a macro would work, since it's name
would be taken for the lambda-list itself.  I could see that writing a
new macro to replace destructuring-bind would work, but I'm not at
that level in macro foo.


-- 
Lisp:  Powering `Impossible Thoughts since 1958

From: Pascal J. Bourguignon
Subject: Re: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <7ciqkye3oz.fsf@pbourguignon.anevia.com>
GP lisper <········@CloudDancer.com> writes:

> code fragment:
> -------------------------------------------------------
> (defun todays-lines
> ...
> 	   (when candidate
> 	     (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) candidate
> ;	filtering
> 		   (push (list strt ukey tm pitcher lmo v ml rln aln) results))))))
>
>
> (defun format-lines() "display active lines"
> ...
> 	   (dolist (line (todays-lines))
> 	     (when line
> 	       (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) line
> -------------------------------------------------------
>
> So that is three places I need to maintain the lambda-list:
>   strt ukey tm pitcher lmo v ml rln aln
> and only getting two of three changed is not good.
>
> Is there a way, perhaps a macro, to have a single location to control
> these elements?  I didn't think a macro would work, since it's name
> would be taken for the lambda-list itself.  I could see that writing a
> new macro to replace destructuring-bind would work, but I'm not at
> that level in macro foo.

Yes, you can do that with macros, but you must be careful about the
time of definition and use of the notion we'll introduce.  Namely, a
named lambda list.  This notion must be present at macroexpansion
time.  

(eval-when (:compile-toplevel :load-toplevel :execute) ; execute is optional
  (defvar *named-lambda-lists* (make-hash-table))
  (defmacro define-lambda-list (name lambda-list)
     `(progn (setf (gethash ',name *named-lambda-lists*) lambda-list)
             ',name))
  (defmacro destructuring-named-lambda-list-bind (lambda-list-name expression &body body)
     (let ((lambda-list (gethash lambda-list-name *named-lambda-list*)))
       (unless lambda-list (error "Unknown lambda-list name ~S" lambda-list-name))
       `(destructuring-bind ,lambda-list ,expression ,@body))))


Now you can write:

(eval-when (:compile-toplevel :load-toplevel :execute)
  (define-lambda-list line-stuff (strt ukey tm pitcher lmo v ml rln aln)))


(defun todays-lines () 
   ...
   (when candidate
       (destructuring-named-lambda-list-bind line-stuff candidate
            ...
            (push (list strt ukey tm pitcher lmo v ml rln aln) results)))
   results)

(defun format-lines ()
   "..."
   (dolist (line (todays-lines))
      (when line
         (destructuring-named-lambda-list-bind line-stuff line
             ...))))


However, I would rather advise you to define a structure and store
your data in structures instead.

If you want to keep the data in a list, you can still have it, with defstruct:


(defstruct (line (:type list))
   strt ukey tm pitcher lmo v ml rln aln)


(defun todays-lines () 
   ...
   (when candidate
        ...
        (push candidate results)))
   results)

(defun format-lines ()
   "..."
   (dolist (line (todays-lines))
      (when line
           (format t "..." (line-strt line) ; O(N)
                           (line-ukey line) ; O(N)
                           (line-tm line)   ; O(N)
                           ...))))          ; ...

Of course, with (:type list) and a lot of field, field access is O(N)
bad.  So you may want to switch to normal or vector structures, so you
keep field access at O(1).


(defstruct line
   strt ukey tm pitcher lmo v ml rln aln)

(defun todays-lines () 
   ...
   (when candidate
        ...
	     (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) candidate
             (push (make-struct :strt strt :ukey ukey :tm tm ...) results)))
   results)

(defun format-lines ()
   "..."
   (dolist (line (todays-lines))
      (when line
           (format t "..." (line-strt line) ; O(1)
                           (line-ukey line) ; O(1)
                           (line-tm line)   ; O(1)
                           ...))))          ; ...


-- 
__Pascal Bourguignon__
From: budden
Subject: Re: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <79919ee8-bc03-48be-afb4-99b2edd03902@r37g2000yqn.googlegroups.com>
You can :include structures. So, if type is determined by a first
symbol, you can add polimorphism.

Also you might try use read-eval for that (I don't use
read-eval extensively so there might be some pitfalls, but
looks ok at the glance).

;; in another file which is loaded before your file is compiled
(defun ~candidate~ () (copy-list '(strt ukey tm pitcher lmo v ml rln
aln)))

;; in your file
(defun todays-lines
...
           (when candidate
             (destructuring-bind #.(~candidate~) candidate
;       filtering
                   (push (list . #.(~candidate~)) results))))))

(defun format-lines() "display active lines"
...
           (dolist (line (todays-lines))
             (when line
               (destructuring-bind #.(~candidate~) line
From: GP lisper
Subject: Re: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <slrngutbv3.t9i.spambait@phoenix.clouddancer.com>
On Tue, 21 Apr 2009 11:50:04 +0200, <···@informatimago.com> wrote:
>
> However, I would rather advise you to define a structure and store
> your data in structures instead.

Yes, thanks for the reminder.  I have that in newer code.
With the :list form, it's an interesting aspect of the language that
any list of the correct length can also be considered a structure.


> (defstruct line
>    strt ukey tm pitcher lmo v ml rln aln)
>
> (defun todays-lines () 
>    ...
>    (when candidate
>         ...
> 	     (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) candidate
>              (push (make-struct :strt strt :ukey ukey :tm tm ...) results)))

naturally, you meant "make-line"


-- 
Lisp:  Powering `Impossible Thoughts since 1958
From: Tobias C. Rittweiler
Subject: Re: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <87zleaz272.fsf@freebits.de>
GP lisper <········@CloudDancer.com> writes:

> code fragment:
> -------------------------------------------------------
> (defun todays-lines
> ...
> 	   (when candidate
> 	     (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) candidate
> ;	filtering
> 		   (push (list strt ukey tm pitcher lmo v ml rln aln) results))))))
>
>
> (defun format-lines() "display active lines"
> ...
> 	   (dolist (line (todays-lines))
> 	     (when line
> 	       (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) line
> -------------------------------------------------------
>
> So that is three places I need to maintain the lambda-list:
>   strt ukey tm pitcher lmo v ml rln aln
> and only getting two of three changed is not good.
>
> Is there a way, perhaps a macro, to have a single location to control
> these elements? ...

Even with such a named destructuring-bind you'd still have to maintain
all the places with respects to the slots you happen to use (or not
use.) There's no gain, just loss of readability.

  -T.
From: GP lisper
Subject: Re: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <slrngurpne.pfi.spambait@phoenix.clouddancer.com>
On Tue, 21 Apr 2009 13:16:49 +0200, <···@freebits.de.invalid> wrote:
>
>
> GP lisper <········@CloudDancer.com> writes:
>
>> code fragment:
>> -------------------------------------------------------
>> (defun todays-lines
>> ...
>> 	   (when candidate
>> 	     (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) candidate
>> ;	filtering
>> 		   (push (list strt ukey tm pitcher lmo v ml rln aln) results))))))
>>
>>
>> (defun format-lines() "display active lines"
>> ...
>> 	   (dolist (line (todays-lines))
>> 	     (when line
>> 	       (destructuring-bind (strt ukey tm pitcher lmo v ml rln aln) line
>> -------------------------------------------------------
>>
>> So that is three places I need to maintain the lambda-list:
>>   strt ukey tm pitcher lmo v ml rln aln
>> and only getting two of three changed is not good.
>>
>> Is there a way, perhaps a macro, to have a single location to control
>> these elements? ...
>
> Even with such a named destructuring-bind you'd still have to maintain
> all the places with respects to the slots you happen to use (or not
> use.) There's no gain, just loss of readability.

Well, that's what is driving changes.  The slots need change, due to a
different concept for information usage, and not all 'usage locations'
get updated.  There should be a way, I cannot be the first noticing this.


-- 
Lisp:  Powering `Impossible Thoughts since 1958
From: ··········@gmail.com
Subject: Re: a macro for destructuring-bind lambda-list ?
Date: 
Message-ID: <983adee3-c466-4a75-a71f-5fbdd8f32395@x5g2000yqk.googlegroups.com>
On 21 abr, 12:31, GP lisper <········@CloudDancer.com> wrote:
>
> Well, that's what is driving changes.  The slots need change, due to a
> different concept for information usage, and not all 'usage locations'
> get updated.  There should be a way, I cannot be the first noticing this.
>
> --
> Lisp:  Powering `Impossible Thoughts since 1958

I run into this kind of problem sometimes, but always manage to
abstract it into some macro or something. Both the use of (defstruct
(line (:type list))) and the use of destructuring-named-lambda-list-
bind (perhaps a shorter name?) seems very good ideas for this problem.
Another aproach to this is to

(defconstant +gp-lisper-lambda-list+ '(strt ukey tm pitcher lmo v ml
rln aln))

and

(destructuring-bind #.+gp-lisper-lambda-list+ candidate
  (do-something))