From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3195982690560792@naggum.net>
* ·······@hotmail.com
> How can I make a function defined in labels refer to another function
> defined in the same labels body?

  The same way you refer to functions everywhere else in Common Lisp.

  I honestly do not understand why you are not using a Scheme system to
  learn Scheme when you don't know Common Lisp well enough to know how to
  refer to functions.  Perhaps you think that Scheme is a Lisp and Common
  Lisp is a Lisp, so it should work?  Just because two human languages have
  Indo-European roots doesn't mean that they can be interchanged if you
  want to learn one of them, either.

> For example (this is from SICP page 223):
> (defun make-account (balance)
>   (labels ((withdraw (amount)
>                      (if (>= balance amount)
>                          (progn
>                            (setf balance (- balance amount))
>                            balance)
>                        (format t "Insufficient funds")))
>            (deposit (amount)
>                     (setf balance (+ balance amount))
>                     balance)
>            (dispatch (m)
>                      (cond
>                       ((equal m 'withdraw) withdraw)
>                       ((equal m 'deposit) deposit)
>                       (t (format t "Unknown request -- MAKE-ACCOUNT")))))
>     dispatch))

  This is what object-oriented programming looks like in Scheme, with
  message-passing as the dispatch paradigm, using closures to hold the
  data.  If you want to understand what it does, stick to Scheme and learn
  how it works in Scheme.  Then see if the same concept, once understood,
  is applicable anywhere else and whether it may be grafted into any other
  system.  (IMNSHO, it neither can nor should be.)

  Scheme and Common Lisp are extremely different languages.  You should not
  assume that you can make Scheme code become Common Lisp code with a few
  minor changes.  For instance, set! in Scheme is defined not to have a
  useful value.  setf in Common Lisp is defined to have the value of the
  last value.  This means that any Common Lisp programmer will look at your
  code and wonder why you're doing what you're doing, if there's something
  special going on.  And why use equal with symbols?  I briefly wondered
  whether that meant that m could be a string.  What use is writing out
  error messages that don't even say what's wrong?  This (among a host of
  other things) tells me that the whole example is designed to be used only
  as a simple toy to illustrate something, just as Scheme is.

  Here's how I would have written a similarly skeletal example in (real)
  Common Lisp:

(defclass account ()
  ((balance :initarg :deposit :initform 0 :accessor balance)))

(defmethod withdraw ((account account) amount)
  (decf (balance account) amount))

(defmethod deposit ((account account) amount)
  (incf (balance account) amount))

(defmethod withdraw :before ((account account) amount)
  (unless (<= amount (balance account))
    (error "~A has insufficient funds to withdraw ~A." account amount)))

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:

From: ········@hex.net
Subject: Re: Trouble with labels
Date: 
Message-ID: <Dm2B6.143647$lj4.4435039@news6.giganews.com>
Erik Naggum <····@naggum.net> writes:
> (defmethod withdraw :before ((account account) amount)
>   (unless (<= amount (balance account))
>     (error "~A has insufficient funds to withdraw ~A." account amount)))

.. and THAT is the sort of example that _should_ get used in
textbooks.

OO examples typically take on frivolous applications like "let's
classify animals!" or "let's classify colours!" which go exactly
_nowhere_ towards showing the gentle programmer how the construct
might actually be _useful_.

Graham demonstrates :before and :after methods using a similarly
frivolous "application" where people are saying things, and if it
involves the King, everything gets surrounded by "BOW" and "If the
king pleases," gestures.  (Mind you, this puts a rather different
meaning to the phrase "affecting a lisp"...)
-- 
(reverse (concatenate 'string ··········@" "enworbbc"))
http://www.ntlug.org/~cbbrowne/resume.html
"Necessity is the mother of invention" is a silly proverb.  "Necessity
is the  mother of  futile dodges"  is much closer  to the  truth.  The
basis of growth of modern  invention is science, and science is almost
wholly the outgrowth of pleasurable intellectual curiosity.
-- Alfred N. Whitehead
From: Barry Margolin
Subject: Re: Trouble with labels
Date: 
Message-ID: <4w3B6.364$U4.14767@burlma1-snr2>
In article <························@news6.giganews.com>,
 <········@hex.net> wrote:
>Erik Naggum <····@naggum.net> writes:
>> (defmethod withdraw :before ((account account) amount)
>>   (unless (<= amount (balance account))
>>     (error "~A has insufficient funds to withdraw ~A." account amount)))
>
>.. and THAT is the sort of example that _should_ get used in
>textbooks.
>
>OO examples typically take on frivolous applications like "let's
>classify animals!" or "let's classify colours!" which go exactly
>_nowhere_ towards showing the gentle programmer how the construct
>might actually be _useful_.

Actually, the above example is pretty silly.  :before and :after methods
are mostly useful in subclasses or mixin classes, to add behavior without
totally overriding the primary method that you inherit.  Putting the
:before method in the same class as the primary method doesn't really make
a whole lot of sense -- the error check could just as easily be put in the
primary method.

A better example of a :before method related to this would be something
like:

(defclass overclass-protection-mixin
    ()
  (service-fee :accessor service-fee :type (real 0.0))
  (companion-account :accessor companion-account :type account))

(defmethod withdraw :before ((overdraft-protection-mixin account) amount)
  (let ((comp (companion-account account)))
    (withdraw comp (+ amount (service-fee comp))))
  (deposit amount account))

(defclass account-with-overdraft-protection
    (account overdraft-protection-mixin))

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Vladimir V. Zolotych
Subject: Re: Trouble with labels
Date: 
Message-ID: <3AD55F59.1EF1132D@eurocom.od.ua>
Barry Margolin wrote:
> 
> Actually, the above example is pretty silly. 

Don't think so. I also read the original poster's message but
didn't guess to write something similar. So thanks to Erik and
to you for
 
> A better example of a :before method related to this would be something
> like:
[snip]

examples on very interesting and useful subject
that wouldn't be found somewhere else.

-- 
Vladimir Zolotych                         ······@eurocom.od.ua
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196071405677961@naggum.net>
* Barry Margolin <······@genuity.net>
> Actually, the above example is pretty silly.  :before and :after methods
> are mostly useful in subclasses or mixin classes, to add behavior without
> totally overriding the primary method that you inherit.  Putting the
> :before method in the same class as the primary method doesn't really
> make a whole lot of sense -- the error check could just as easily be put
> in the primary method.

  Sigh.  In real life, how you deal with withdrawal requests in the absence
  of sufficient funds depends on the account.  Add a credit limit, and you
  need more work, for instance.  The reaction to such a request is _not_
  integral to the withdrawal process, and conflating the two processes of
  updating the balance and dealing with insufficient funds is really silly,
  because you need to reimplement the core operation (updating the balance)
  in a subclass with different characteristics.  That's bad design.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Kent M Pitman
Subject: Re: Trouble with labels
Date: 
Message-ID: <sfwitkai07j.fsf@world.std.com>
Erik Naggum <····@naggum.net> writes:

> * Barry Margolin <······@genuity.net>
> > Actually, the above example is pretty silly.  :before and :after methods
> > are mostly useful in subclasses or mixin classes, to add behavior without
> > totally overriding the primary method that you inherit.  Putting the
> > :before method in the same class as the primary method doesn't really
> > make a whole lot of sense -- the error check could just as easily be put
> > in the primary method.
> 
>   Sigh.  In real life, how you deal with withdrawal requests in the absence
>   of sufficient funds depends on the account.

Geez, I had thought this was a good enough example that I set it aside to
look at later.

>   Add a credit limit, and you need more work, for instance.

I particularly thought the example was clever because such could be
hidden in the withdrawal code, which if it erred would implicitly
signal an error.  Accounts could even be cascaded to have this mixin
and it would work.  That's not to say that's the one and only one right 
way, but it does have some very nice and reasonable properties.

It's not necessary that a bank would use this code for it to look nice
as an example and make the issues clear.  Probably no bank would use the
code as given not for this reason but because it uses type REAL, which I
think is wholly unsuitable for money.

Barry also didn't add without-preemption and/or database audit trailing,
but I don't think that hurts anything.  And anyway, with a little
thoughtfulness, someone could probably figure out how to make that
work by mixins, too.

>   The reaction to such a request is _not_
>   integral to the withdrawal process, and conflating the two processes of
>   updating the balance and dealing with insufficient funds is really silly,
>   because you need to reimplement the core operation (updating the balance)
>   in a subclass with different characteristics.  That's bad design.

I've known Barry for a long time and he's no idiot, so almost by definition
in my mind, I'd have to say "silly" was probably overstating.  He might be
wrong from time to time, but when he is it's rarely for superficial reasons.
I'd like to think that of most of us.

But how about we just ignore that part of your remark and move on to its
substance, which is apparently that you don't like this design.  Now you've
got me curious: how would you modularize it?  Not for critique, but so we
can collect some alternate examples for style purposes?  I think seeing 
all of our various points of view will help in a case like this, since I 
think style is about choices.  The more choices people have, the better
informed their ultimate selection will be in the real situations that come
up (instead of the toy ones we all beat each other up over).
From: ········@hex.net
Subject: Re: Trouble with labels
Date: 
Message-ID: <1CkB6.146305$lj4.4501472@news6.giganews.com>
Kent M Pitman <······@world.std.com> writes:
> Erik Naggum <····@naggum.net> writes:
>> * Barry Margolin <······@genuity.net>
>>> Actually, the above example is pretty silly.  :before and :after methods
>>> are mostly useful in subclasses or mixin classes, to add behavior without
>>> totally overriding the primary method that you inherit.  Putting the
>>> :before method in the same class as the primary method doesn't really
>>> make a whole lot of sense -- the error check could just as easily be put
>>> in the primary method.

>> Sigh.  In real life, how you deal with withdrawal requests in the
>> absence of sufficient funds depends on the account.

> Geez, I had thought this was a good enough example that I set it
> aside to look at later.

>>   Add a credit limit, and you need more work, for instance.

> I particularly thought the example was clever because such could be
> hidden in the withdrawal code, which if it erred would implicitly
> signal an error.  Accounts could even be cascaded to have this mixin
> and it would work.  That's not to say that's the one and only one
> right way, but it does have some very nice and reasonable
> properties.

> It's not necessary that a bank would use this code for it to look nice
> as an example and make the issues clear.  Probably no bank would use the
> code as given not for this reason but because it uses type REAL, which I
> think is wholly unsuitable for money.

> Barry also didn't add without-preemption and/or database audit
> trailing, but I don't think that hurts anything.  And anyway, with a
> little thoughtfulness, someone could probably figure out how to make
> that work by mixins, too.

That is actually where it would be interesting to extend the example,
to throw in a way of showing it copes well with having multiple
transactions under way concurrently.

>> The reaction to such a request is _not_ integral to the withdrawal
>> process, and conflating the two processes of updating the balance
>> and dealing with insufficient funds is really silly, because you
>> need to reimplement the core operation (updating the balance) in a
>> subclass with different characteristics. That's bad design.

> I've known Barry for a long time and he's no idiot, so almost by
> definition in my mind, I'd have to say "silly" was probably
> overstating. He might be wrong from time to time, but when he is
> it's rarely for superficial reasons.  I'd like to think that of most
> of us.

Conflating the processes strikes me as a _controversial issue_; in an
ATM system, it might in fact be reasonable to design the methods to
conflate withdrawal and balance confirmation, as it all has to be done
right at the same time [note that the phrase "done right at the same
time" can reasonably be parsed two ways; I actually intend _both_
meanings :-)].

I'd tend to agree with Erik that it would be preferable to separate
the actions, but just as folks denormalize database tables in real
life to try to improve performance, the "real world" might try to
dictate combining the actions.

> But how about we just ignore that part of your remark and move on to
> its substance, which is apparently that you don't like this
> design. Now you've got me curious: how would you modularize it? Not
> for critique, but so we can collect some alternate examples for
> style purposes? I think seeing all of our various points of view
> will help in a case like this, since I think style is about
> choices. The more choices people have, the better informed their
> ultimate selection will be in the real situations that come up
> (instead of the toy ones we all beat each other up over).

I'd think this to be valuable indeed.  Even under the _extreme_
position that Barry's outright _wrong_, and deserves "beating up," he
surely used some vaguely rational criteria to come up with his
approach, and it would surely be valuable to see the fatal flaw in it.

It seems rather more likely to me that Barry's thoughts weren't quite
so fatally flawed; seeing some different positions, and reasons to
distinguish between them, can help people make more informed
selections.
-- 
(concatenate 'string "aa454" ·@freenet.carleton.ca")
http://www.ntlug.org/~cbbrowne/resume.html
Why is it that when you transport something by car, it's called a
shipment, but when you transport something by ship, it's called cargo?
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196084932709125@naggum.net>
* Kent M Pitman
> I've known Barry for a long time and he's no idiot, so almost by definition
> in my mind, I'd have to say "silly" was probably overstating.  He might be
> wrong from time to time, but when he is it's rarely for superficial reasons.
> I'd like to think that of most of us.

  What he said was "Actually, the above example is pretty silly", and goes
  on to argue that you should do the checking inside the withdraw function.
  I'm sorry, but I find it very irritating when someone who obviously has
  not paid much attention to what is going on nor shows any interest in
  finding out what people have thought has the gall to state that it
  _actually_ is "pretty silly".  I don't know why Barry does this, but it's
  a clear pattern with him: If I suggest something that several people like
  or applaud, Barry just _has_ to knock it, sometimes with a bad suggestion
  that confuses a lot of people, apparently just to be contrary.  I don't
  know what this is, but I find it very annoying.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Barry Margolin
Subject: Re: Trouble with labels
Date: 
Message-ID: <NjmB6.385$U4.15082@burlma1-snr2>
In article <················@naggum.net>, Erik Naggum  <····@naggum.net> wrote:
>  What he said was "Actually, the above example is pretty silly", and goes
>  on to argue that you should do the checking inside the withdraw function.
>  I'm sorry, but I find it very irritating when someone who obviously has
>  not paid much attention to what is going on nor shows any interest in
>  finding out what people have thought has the gall to state that it
>  _actually_ is "pretty silly".  I don't know why Barry does this, but it's
>  a clear pattern with him: If I suggest something that several people like
>  or applaud, Barry just _has_ to knock it, sometimes with a bad suggestion
>  that confuses a lot of people, apparently just to be contrary.  I don't
>  know what this is, but I find it very annoying.

I know I'm going to regret this reply, but....

Wow.  I know I've been nasty to you in the past, but I hardly thought
"pretty silly" was in the same league; I consider that a relatively
innocuous comment.  I didn't say it was wrong, stupid, or anything really
derogatory.

My general feeling is that if you put both a :before/:after/:around method
and a primary method in the same class, you aren't making the most
effective use of the class mechanism to split off the modularity.  I
understand why you want the balance checking in a :before method, but I
merely feel that you should then split it off into its own class so that
you can then choose when to mix it in or not.  If you have an account with
a credit limit, you would have a different mixin that would check against
the credit limit rather than just the balance.

BTW, unless it was unconscious, I don't think I considered the source when
I wrote my reply.  As I've mentioned before, if you didn't have a unique
quoting style, such unconscious behavior would be less likely (if I don't
know it's from you, I can hardly bias my reaction because of it).

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196097951867449@naggum.net>
* Barry Margolin
> As I've mentioned before, if you didn't have a unique quoting style, such
> unconscious behavior would be less likely (if I don't know it's from you,
> I can hardly bias my reaction because of it).

  What unique quoting style?  If you're trying to reinfoce my impression
  that paying attention is not one of your stronger qualities, you're doing
  a pretty good job.  Much would be improved if you did pay more attention.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Barry Margolin
Subject: Re: Trouble with labels
Date: 
Message-ID: <gUoB6.397$U4.17335@burlma1-snr2>
In article <················@naggum.net>, Erik Naggum  <····@naggum.net> wrote:
>* Barry Margolin
>> As I've mentioned before, if you didn't have a unique quoting style, such
>> unconscious behavior would be less likely (if I don't know it's from you,
>> I can hardly bias my reaction because of it).
>
>  What unique quoting style?  

The "* Barry Margolin" attribution style is unique to you, AFAIK.  You also
add an extra space after the '>' quoting character.  These make your
replies quite distinctive.

>			       If you're trying to reinfoce my impression
>  that paying attention is not one of your stronger qualities, you're doing
>  a pretty good job.  Much would be improved if you did pay more attention.

It's not a matter of whether I pay attention, it's what I choose to pay
attention to, and "From:" lines are not a high priority to me.  I have my
newsreader configured to clear the screen between displaying the header and
the message body, so I can see the maximum amount of message.  The header
goes by very quickly and I don't bother looking at the author before
hitting Space to see the message.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196100506719377@naggum.net>
* Barry Margolin
> The "* Barry Margolin" attribution style is unique to you, AFAIK.  You also
> add an extra space after the '>' quoting character.  These make your
> replies quite distinctive.

  Previously, it was the | instead of the > that annoyed you so much, and I
  fixed that for a number of reasong.  Now, it's the *, which has not been
  changed.  Several other people do that besides me.  Lots of people quote
  with a space after the >, so that's hardly unique, either.  I get the
  impression that unless I do everything exactly like you do, you will find
  _something_ wrong, and if I did it your way, you would fault me for that,
  too.  It looks like you're having a personal problem with me, regardless
  of what I actually _do_.  It's not like you're "after me" or anything
  like that, it's simply that it looks very much like you cannot even
  _avoid_ finding faults.  I find this very annoying.  I wish you would
  simply stop being so sensitive to what I do.  Just get over it, whatever
  it is, OK?

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Barry Margolin
Subject: Re: Trouble with labels
Date: 
Message-ID: <7FpB6.402$U4.17262@burlma1-snr2>
In article <················@naggum.net>, Erik Naggum  <····@naggum.net> wrote:
>* Barry Margolin
>> The "* Barry Margolin" attribution style is unique to you, AFAIK.  You also
>> add an extra space after the '>' quoting character.  These make your
>> replies quite distinctive.
>
>  Previously, it was the | instead of the > that annoyed you so much, and I
>  fixed that for a number of reasong.  Now, it's the *, which has not been
>  changed.  Several other people do that besides me.  Lots of people quote
>  with a space after the >, so that's hardly unique, either.  I get the
>  impression that unless I do everything exactly like you do, you will find
>  _something_ wrong

Where did I say "annoyed" or "wrong"?  Now who's exaggerating the reaction
(something you accused me of in another post)?

I said it was distinctive; although neither feature by itself may be
unique, the combination is probably more limiting, and also I apparently
don't subscribe to the groups where other *-attributors post, because I
can't recall seeing it from anyone other than you.  So even though I don't
read From: lines, I can tell they're from you, which opens me up to
subconscious bias.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196151839213753@naggum.net>
* Barry Margolin
> So even though I don't read From: lines, I can tell they're from you,
> which opens me up to subconscious bias.

  Work on it, will you?

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Tim Bradshaw
Subject: Re: Trouble with labels
Date: 
Message-ID: <ey37l0lyptp.fsf@cley.com>
* Barry Margolin wrote:

> The "* Barry Margolin" attribution style is unique to you, AFAIK.  You also
> add an extra space after the '>' quoting character.  These make your
> replies quite distinctive.

This quote was what my newsreader did.  I think I hacked it to produce
the citing style (but so long ago I can't remember), I don't think I
hacked the quoting char stuff.

--tim
From: Dave Pearson
Subject: Re: Trouble with labels
Date: 
Message-ID: <slrn9dfthj.dpv.davep.news@hagbard.davep.org>
* Barry Margolin <······@genuity.net>:

> My general feeling is that if you put both a :before/:after/:around method
> and a primary method in the same class, you aren't making the most
> effective use of the class mechanism to split off the modularity.

What if there isn't a good reason for such splitting?

As an example, I've been toying around with an NNTP client class in CL, by
way of having some fun in CL. A couple of the methods that do the talking to
the NNTP server ensure that there is a connection in place and throw an
error if not. I'd not considered a :before method for doing such a check
until I saw Erik's post. I changed the code to work that way and it actually
seems to make more sense like that.

Now, I suppose there could be an argument for writing a base "NNTP with no
connection checks" class and then do that :before checking in a "NNTP with
connection checks" class but I can't really see the point in that.

I can, however, see the point in having a base class that does the
connection checking which simply throws an error if the connection isn't
there, while having a sub class that re-makes a connection if the connection
has been lost.

I did see mention that overriding :before behaviour is tricky so I've made a
mental note to look into this but I think the important point here is that
Erik's example, from my point of view anyway, wasn't silly, it was very
illustrative. Using :before in sub class is an obvious thing but for some
odd reason I'd never considered the use of them in the "same class" as a
method of implementing pre or post checks (for example).

IOW, as I read it, I don't think the example was supposed to make "the most
effective use of the class mechanism". Even if it was and it didn't it did
illustrate a useful point, at least for one reader of this group.

-- 
Dave Pearson:                   |     lbdb.el - LBDB interface.
http://www.davep.org/           |  sawfish.el - Sawfish mode.
Emacs:                          |  uptimes.el - Record emacs uptimes.
http://www.davep.org/emacs/     | quickurl.el - Recall lists of URLs.
From: Kent M Pitman
Subject: Re: Trouble with labels
Date: 
Message-ID: <sfweluyc5yl.fsf@world.std.com>
Erik Naggum <····@naggum.net> writes:

>   If I suggest something that several people like
>   or applaud, Barry just _has_ to knock it, sometimes with a bad suggestion
>   that confuses a lot of people, apparently just to be contrary.  I don't
>   know what this is, but I find it very annoying.

People often say this of me, as well.  Usually in my own case I'm not
trying to knock the original thing but to add an extra viewpoint or
footnote.  But it often comes across as my not being satisfied with
the original point of view.

None of us is perfect, Erik.  We each have our own trademarked ways
of getting under others' skin.  Coping with others' communicational 
shortcomings is sometimes how we earn credit toward their willingness
to do the same for us.

Just my opinion.  

Besides, what I'm still *really* interested in is hearing how you'd write
the code instead.  I hope you'll get to that part...
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196098083218492@naggum.net>
* Kent M Pitman
> Besides, what I'm still *really* interested in is hearing how you'd write
> the code instead.  I hope you'll get to that part...

  I don't follow you.  I posted what I thought was the best solution.  Then
  Barry comes along and calls it "pretty silly", and argues for a different
  style.  That is, what I consider better or would have written instead has
  already been posted.  I hope we don't still have that problem with my
  articles not propagating properly.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Barry Margolin
Subject: Re: Trouble with labels
Date: 
Message-ID: <pYoB6.398$U4.17392@burlma1-snr2>
In article <················@naggum.net>, Erik Naggum  <····@naggum.net> wrote:
>* Kent M Pitman
>> Besides, what I'm still *really* interested in is hearing how you'd write
>> the code instead.  I hope you'll get to that part...
>
>  I don't follow you.  I posted what I thought was the best solution.  Then
>  Barry comes along and calls it "pretty silly", and argues for a different
>  style.  That is, what I consider better or would have written instead has
>  already been posted.  I hope we don't still have that problem with my
>  articles not propagating properly.

I didn't think we were having a discussion on the best way to implement
bank software, but rather examples of OO style.  I still think that a
:before method in a mixin class is a better example of the power of CLOS's
OO system.  Witness that I was not the only one who found it curious that
you put both methods on the same class; I phrased it as "pretty silly"
(which I thought was about as mild a criticism as possible, but you seem to
be conditioned to take offense to anything I write), while the other poster
asked "why?".

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196099966106042@naggum.net>
* Barry Margolin
> Witness that I was not the only one who found it curious that you put
> both methods on the same class; I phrased it as "pretty silly" (which I
> thought was about as mild a criticism as possible, but you seem to be
> conditioned to take offense to anything I write), while the other poster
> asked "why?".

  I also find it annoying that you have to exaggerate what I take offense
  to.  If _you_ had asked "why?", there would have been no reason to react
  at all, except to answer your question.  It is because _you_ seem to be
  unable to deal with me that you continue to post derogatory comments.  I
  don't do that towards you, but you keep doing it towards me.  I do not
  understand why.  That's doubly annoying.  I'm asking you to quit it.  OK?

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Tim Bradshaw
Subject: Re: Trouble with labels
Date: 
Message-ID: <ey33db9yp6w.fsf@cley.com>
* Barry Margolin wrote:
> I didn't think we were having a discussion on the best way to implement
> bank software, but rather examples of OO style.  I still think that a
> :before method in a mixin class is a better example of the power of CLOS's
> OO system.  Witness that I was not the only one who found it curious that
> you put both methods on the same class; I phrased it as "pretty silly"
> (which I thought was about as mild a criticism as possible, but you seem to
> be conditioned to take offense to anything I write), while the other poster
> asked "why?".

Trying to drag this back on topic...  I think that although it's
perhaps a `better example of CLOS' to have non-primary methods and
mixins together, they can be useful in a single class framework too.
I use :before and :after methods for things that need to be done but
are not part of the main `normal' bit of the code.  I find this makes
things easy to read, because the primary method can just assume that
everything is OK.  So rather than:

(defmethod foo ((x bar))
  (boring-checking-code x)
  (more-boring-code x)
  (prog1 (tiny-useful-bit-of-code x)
    (yet-more-rubbish x)))

I write:

(defmethod foo :before ((x bar))
  (boring-checking-code x)
  (more-boring-code x))

(defmethod foo ((x bar))
  (tiny-useful-bit-of-code x))

(defmethod foo :after ((x bar))
  (yet-more-rubbish x))

I suppose the OO purist would argue that I should have mixin classes
that do the checking stuff.  Perhaps so.

--tim
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196418419945434@naggum.net>
* Tim Bradshaw <···@cley.com>
> (defmethod foo ((x bar))
>   (boring-checking-code x)
>   (more-boring-code x)
>   (prog1 (tiny-useful-bit-of-code x)
>     (yet-more-rubbish x)))

  You may want to use multiple-value-prog1 here, which is a gratuitous
  invasion of multiple value.  prog1 should have preserved multiple values
  to begin with, just like :after methods, unwind-protect, etc, do.  This
  is but another reason to use :after methods.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Paolo Amoroso
Subject: Re: Trouble with labels
Date: 
Message-ID: <MYDUOpyFQskTzMTKKPwWma+ZZe26@4ax.com>
On 11 Apr 2001 12:58:10 +0000, Erik Naggum <····@naggum.net> wrote:

> (defclass account ()
>   ((balance :initarg :deposit :initform 0 :accessor balance)))
> 
> (defmethod withdraw ((account account) amount)
>   (decf (balance account) amount))
> 
> (defmethod deposit ((account account) amount)
>   (incf (balance account) amount))
> 
> (defmethod withdraw :before ((account account) amount)
>   (unless (<= amount (balance account))
>     (error "~A has insufficient funds to withdraw ~A." account amount)))

I have a design question: why do you keep the code for checking for the
appropriate balance in a separate :AROUND method instead of adding it to
WITHDRAW's primary method? I can think of a few reasons:

- because performing a withdrawal and checking for an appropriate balance
  are orthogonal operations
- for improving modularization, i.e. for making it easier to later add
  other validation methods
- to emphasize a WITHDRAW protocol


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/
From: Kent M Pitman
Subject: Re: Trouble with labels
Date: 
Message-ID: <sfwd7ajdvcs.fsf@world.std.com>
Paolo Amoroso <·······@mclink.it> writes:

> 
> On 11 Apr 2001 12:58:10 +0000, Erik Naggum <····@naggum.net> wrote:
> 
> > (defclass account ()
> >   ((balance :initarg :deposit :initform 0 :accessor balance)))
> > 
> > (defmethod withdraw ((account account) amount)
> >   (decf (balance account) amount))
> > 
> > (defmethod deposit ((account account) amount)
> >   (incf (balance account) amount))
> > 
> > (defmethod withdraw :before ((account account) amount)
> >   (unless (<= amount (balance account))
> >     (error "~A has insufficient funds to withdraw ~A." account amount)))
> 
> I have a design question: why do you keep the code for checking for the
> appropriate balance in a separate :AROUND method instead of adding it to
> WITHDRAW's primary method? I can think of a few reasons:
> 
> - because performing a withdrawal and checking for an appropriate balance
>   are orthogonal operations
> - for improving modularization, i.e. for making it easier to later add
>   other validation methods
> - to emphasize a WITHDRAW protocol

Because if you do override the primary method, you often don't want to lose
this error checking.  And it's MUCH harder to override before, after, and
around methods than it is to override primary methods.  I tend to put
overridable stuff in the primaries and non-overridable stuff in the 
before/after methods and acts of desperation in the around methods.
From: Marco Antoniotti
Subject: Re: Trouble with labels
Date: 
Message-ID: <y6cn19myxnd.fsf@octagon.mrl.nyu.edu>
Kent M Pitman <······@world.std.com> writes:

> Paolo Amoroso <·······@mclink.it> writes:
> 
> > 
> > I have a design question: why do you keep the code for checking for the
> > appropriate balance in a separate :AROUND method instead of adding it to
> > WITHDRAW's primary method? I can think of a few reasons:
> > 
> > - because performing a withdrawal and checking for an appropriate balance
> >   are orthogonal operations
> > - for improving modularization, i.e. for making it easier to later add
> >   other validation methods
> > - to emphasize a WITHDRAW protocol
> 
> Because if you do override the primary method, you often don't want to lose
> this error checking.  And it's MUCH harder to override before, after, and
> around methods than it is to override primary methods.  I tend to put
> overridable stuff in the primaries and non-overridable stuff in the 
> before/after methods and acts of desperation in the around methods.

I tend to do that too.  I really like the "resort to :around methods
as acts of desperation" part :)

I also find myself splitting classes whenever I realize I need some
specific functionality only in :before and :around methods.

Try that with standard OO languages like the "new PL on the block avec
forced indentation rules".

Cheers

-- 
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group	tel. +1 - 212 - 998 3488
719 Broadway 12th Floor                 fax  +1 - 212 - 995 4122
New York, NY 10003, USA			http://bioinformatics.cat.nyu.edu
	       "Hello New York! We'll do what we can!"
			Bill Murray in `Ghostbusters'.
From: Lieven Marchand
Subject: Re: Trouble with labels
Date: 
Message-ID: <m37l0q6npj.fsf@localhost.localdomain>
Marco Antoniotti <·······@cs.nyu.edu> writes:

> Try that with standard OO languages like the "new PL on the block avec
> forced indentation rules".

You really seem to have something against Python. Why?

I'd prefer CL for most applications but it has saved me a few times
from Perl and I find it more readable, maintainable and better
designed than most of its competitors. 

-- 
Lieven Marchand <···@wyrd.be>
Gla�r ok reifr skyli gumna hverr, unz sinn b��r bana.
From: Paolo Amoroso
Subject: Re: Trouble with labels
Date: 
Message-ID: <rpPVOoc2Btsiv28MzRXaqLe+wBxo@4ax.com>
On Wed, 11 Apr 2001 22:06:04 +0200, Paolo Amoroso <·······@mclink.it>
wrote:

> I have a design question: why do you keep the code for checking for the
> appropriate balance in a separate :AROUND method instead of adding it to
> WITHDRAW's primary method? I can think of a few reasons:

Oooops... Of course I meant :BEFORE. Sorry.


Paolo
-- 
EncyCMUCLopedia * Extensive collection of CMU Common Lisp documentation
http://cvs2.cons.org:8000/cmucl/doc/EncyCMUCLopedia/
From: Erik Naggum
Subject: Re: Trouble with labels
Date: 
Message-ID: <3196071854975641@naggum.net>
* Paolo Amoroso <·······@mclink.it>
> I have a design question: why do you keep the code for checking for the
> appropriate balance in a separate :AROUND method instead of adding it to
> WITHDRAW's primary method? I can think of a few reasons:
> 
> - because performing a withdrawal and checking for an appropriate balance
>   are orthogonal operations
> - for improving modularization, i.e. for making it easier to later add
>   other validation methods
> - to emphasize a WITHDRAW protocol

  All of the above, some of which I think of only after you suggest them. :)

  However, my initial reason for doing this was to show that you might want
  to deal with credit limits without modifying the core operation.  In real
  life, a withdrawal that requests credit is an automatically granted loan,
  with a lot of background work to deal with the loan.  So a :before method
  that took care of the credit approval would update the balance before the
  withdrawal updated it again.

  Anyone who has had to deal with accounts with real money in real life
  knows that the first principle that you never violate is that you never
  affect the money supply.  Maintaining that invariant is hard work in
  banking applications.  Much of the complexity in database transactions
  come from banking requirements not to create or destroy money, no matter
  what happens.

#:Erik
-- 
  I found no peace in solitude.
  I found no chaos in catastrophe.
			-- :wumpscut:
From: Vladimir V. Zolotych
Subject: Re: Trouble with labels
Date: 
Message-ID: <3AD55A25.54BAF21@eurocom.od.ua>
Erik Naggum wrote:
> 
>   Here's how I would have written a similarly skeletal example in (real)
>   Common Lisp:

Thanks for interesting "CL-only" example on subject rarely
(if ever) found in textbooks.

-- 
Vladimir Zolotych                         ······@eurocom.od.ua