[pro] The Best Examples of "Code is Data"
Peter Seibel
peter at gigamonkeys.com
Tue Sep 28 22:19:51 UTC 2010
I always liked Erik Naggum's name for your WHEN-BIND: WHEREAS
http://groups.google.com/group/comp.lang.lisp/msg/bc7772aa5ab1f3e4
-Peter
On Tue, Sep 28, 2010 at 3:04 PM, Daniel Weinreb <dlw at itasoftware.com> wrote:
>
>
> Attila Lendvai wrote:
>
> macros that are useful and should be allowed. It is just that
> anaphoric macros, despite all their cuteness, tax code readers
> unnecessarily hard and thus have not been adopted as acceptable
> practice in multi-programmer environments.
>
>
> well, it's one opinion.
>
> there's at least one counter example in our team of 4. and i
> personally do like reasonable usage of anaphoric macros, even when
> done by my colleagues. and the reason is exactly that it *rises* code
> readability for us.
>
> our practice includes special coloring for "it" and avoids any usage
> which is not blatantly trivial.
>
>
> OK, if you're going to do that, that helps a lot.
>
> A problem with this is that code that starts
> blatently trivial can grow. This is one reason
> that you see enormous Perl scripts; people
> thought they'd be simple enough that Perl
> was appropriate, but they grow over time.
>
> Suddenly you have an outer "it" and an inner "it",
> and you need to "let" the outer one if you need
> to access that quantity in the inner one. And
> someone reading the code can get confuse
> about which one you mean.
>
> Instead of "awhen", what we use here is called
> when-bind. Example (real one, from actual
> airline code):
>
> (or (when-bind (dmc (message-dmc (request-task-message rt)))
> (dmc-struct-maximum-number-of-fdrs-in-response dmc))
> (iatci-config :max-response-fdrs rt nil))
>
> You specify the name. It's not anamorphic. The
> name can be meaningful, rather than "it". There
> are no conflicts. It does not get ugly when
> the code gets larger.
>
> The downside is that it's more verbose, because
> you have to put in the name of the variable, and
> there is one more level of paren to keep things
> Lispy.
>
> By the way, there is a sort of anamorphic thing
> in the "Clojure" dialect, where you can write
> little lambdas without arglists, by using
> $1 and $2 and so on to mean first arg,
> second arg, and so on. Again, he's trying
> to make programming with functions more
> friendly by making it more succinct, and I'm
> sure he'd also say "you should only use
> it for simple cases".
>
> If you are following good practices, you'd
> stop using these things when the code
> gets large. Having automatic refactoring
> IDE's that could do that would be one way
> of trying to get the best of both words.
>
> On the other hand, we do have an anmorphic
> macro that we sometimes use, in the sense
> that it makes up its own symbols. It is called
> define-class, and tries to be more like the
> Flavors class definer. The CLOS one, I think
> in an attempt to entirely avoid anamorphism,
> makes you spell out the names of the accessors
> (and/or readers and writers). define-class
> creates these names.
>
> (define-class puma-request-context (migration-request-context)
> ((journey :type qapi-journey)
> (pnr :type qapi-pnr)
> (staged-pnr :type staged-puma-pnr)
> (pax-map :type list) ; a list containing elements of form
> (staged-pax-name . qapi-pnr-passenger)
> (seg-map :type list) ; a list containing elements of form
> (staged-segment . qapi-pnr-segment)
> (slices :type list) ; a list of qapi-pnr-slice
> (staging-to-action-map
> ;; A list of two element sublists associating a staging object with a
> QAPI action.
> :type list
> :initform nil)))
>
> expands into
>
>
> (PROGN (DEFCLASS PUMA-REQUEST-CONTEXT (MIGRATION-REQUEST-CONTEXT)
> ((JOURNEY :ACCESSOR
> PUMA-REQUEST-CONTEXT-JOURNEY
> :INITARG
> :JOURNEY
> :TYPE
> QAPI-JOURNEY)
> (PNR :ACCESSOR PUMA-REQUEST-CONTEXT-PNR :INITARG :PNR :TYPE
> QAPI-PNR)
> (STAGED-PNR :ACCESSOR PUMA-REQUEST-CONTEXT-STAGED-PNR :INITARG
> :STAGED-PNR :TYPE STAGED-PUMA-PNR)
> (PAX-MAP :ACCESSOR PUMA-REQUEST-CONTEXT-PAX-MAP :INITARG :PAX-MAP
> :TYPE LIST)
> (SEG-MAP :ACCESSOR PUMA-REQUEST-CONTEXT-SEG-MAP :INITARG :SEG-MAP
> :TYPE LIST)
> (SLICES :ACCESSOR PUMA-REQUEST-CONTEXT-SLICES :INITARG :SLICES
> :TYPE
> LIST)
> (STAGING-TO-ACTION-MAP :ACCESSOR
> PUMA-REQUEST-CONTEXT-STAGING-TO-ACTION-MAP :INITARG
> :STAGING-TO-ACTION-MAP :TYPE LIST :INITFORM NIL)))
> (DECLARE-LIST-OF PUMA-REQUEST-CONTEXT)
> (DEFUN MAKE-PUMA-REQUEST-CONTEXT (&REST
> QUUX::KEYS
> &KEY
> JOURNEY
> PNR
> STAGED-PNR
> PAX-MAP
> SEG-MAP
> SLICES
> STAGING-TO-ACTION-MAP
> &ALLOW-OTHER-KEYS)
> (DECLARE
> (IGNORABLE JOURNEY PNR STAGED-PNR PAX-MAP SEG-MAP SLICES
> STAGING-TO-ACTION-MAP))
> (DECLARE (DYNAMIC-EXTENT QUUX::KEYS))
> (APPLY #'MAKE-INSTANCE 'PUMA-REQUEST-CONTEXT QUUX::KEYS))
> (DEFINE-COMPILER-MACRO
> MAKE-PUMA-REQUEST-CONTEXT
> (&REST QUUX::ARGS)
> (LIST* 'MAKE-INSTANCE
> (LIST* (LIST* 'QUOTE (LIST 'PUMA-REQUEST-CONTEXT))
> QUUX::ARGS)))
> (FIND-CLASS 'PUMA-REQUEST-CONTEXT))
>
> Some of our code uses this and some does not, at the whim
> of the programmer (perhaps that's poor practice). However,
> I haven't noticed this causing any problems.
>
>
>
> _______________________________________________
> pro mailing list
> pro at common-lisp.net
> http://common-lisp.net/cgi-bin/mailman/listinfo/pro
>
>
--
Peter Seibel
http://www.codequarterly.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/pro/attachments/20100928/4842c622/attachment.html>
More information about the pro
mailing list