From: Peter Seibel
Subject: Method specialization style question
Date: 
Message-ID: <m3r7vgm9v5.fsf@javamonkey.com>
Suppose I'm writing a piece of banking software. I've defined my class
ACCOUNT (i.e. a bank account) and now I'm implementing the WITHDRAW
method. One way to write it is like this:

  (defmethod withdraw ((account account) amount)
    (if (>= (balance account) amount)
      (decf (balance account) amount)
      (error "Insufficient funds.")))

I.e. specialize on the parameter that I'm using to dispatch on. That
is, I'm planning to write other methods on other classes of account.
But I don't bother specializing the second parameter because I don't
intend to dispatch on it; it's always going to be a number.

On the other hand it had better in fact *be* a number given that I'm
passing it to >= and DECF. So maybe I should write this:

  (defmethod withdraw ((account account) (amount number))
    (if (>= (balance account) amount)
      (decf (balance account) amount)
      (error "Insufficient funds.")))

Anyone have any stylistic preference for one or the other? (I guess
the practical difference is just trading a type-error in for a
no-applicable-method error if withdraw is ever called with a
non-numeric second argument.)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp

From: Kenny Tilton
Subject: Re: Method specialization style question
Date: 
Message-ID: <2fQ8c.7725$DV6.747@twister.nyc.rr.com>
Peter Seibel wrote:

> 
> On the other hand it had better in fact *be* a number given that I'm
> passing it to >= and DECF. So maybe I should write this:
> 
>   (defmethod withdraw ((account account) (amount number))
>     (if (>= (balance account) amount)
>       (decf (balance account) amount)
>       (error "Insufficient funds.")))
> 

I would not even specialize on account. withdraw sounds pretty 
accountish. Well, actually there would not be a withdraw method, there 
would be:

    (defmethod tx-commit ((tx withdrawal) account...

No, hang on, the transaction knows the account as well as the amount, so:

    (defmethod tx-commit ((tx withdrawal))
       (if (or (>= (balance (account tx)) (amount tx))
               (overdraft-cool-p (account tx)))
          (decf ...)
          (if (kid-glove-p (customer (account tx)))
              (tx-kinder-gentler-enqueue tx)
              (error "INF"))))

ie, let special handling arise from other GFs reached in the branches of 
the implementation of any given GF.

Sorry for the digression. This is just more fun than doing scroller 
widgets (for the third time in my life).

kt

-- 
Home? http://tilton-technology.com
Cells? http://www.common-lisp.net/project/cells/
Cello? http://www.common-lisp.net/project/cello/
Why Lisp? http://alu.cliki.net/RtL%20Highlight%20Film
Your Project Here! http://alu.cliki.net/Industry%20Application
From: Pascal Bourguignon
Subject: Re: Method specialization style question
Date: 
Message-ID: <87zna4xh8q.fsf@thalassa.informatimago.com>
Peter Seibel <·····@javamonkey.com> writes:
> On the other hand it had better in fact *be* a number given that I'm
> passing it to >= and DECF. So maybe I should write this:
> 
>   (defmethod withdraw ((account account) (amount number))
>     (if (>= (balance account) amount)
>       (decf (balance account) amount)
>       (error "Insufficient funds.")))
> 
> Anyone have any stylistic preference for one or the other? (I guess
> the practical difference is just trading a type-error in for a
> no-applicable-method error if withdraw is ever called with a
> non-numeric second argument.)

What happens if I try to withdraw #(0.0 100.0) USD ?
What happens if I try to withdraw 100/3 EUR ?
What happens if I try to withdraw PI UKL ?

You don't withdraw numbers, you withdraw money!

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Pascal Bourguignon
Subject: Re: Method specialization style question
Date: 
Message-ID: <87vfksxh3b.fsf@thalassa.informatimago.com>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Peter Seibel <·····@javamonkey.com> writes:
> > On the other hand it had better in fact *be* a number given that I'm
> > passing it to >= and DECF. So maybe I should write this:
> > 
> >   (defmethod withdraw ((account account) (amount number))
> >     (if (>= (balance account) amount)
> >       (decf (balance account) amount)
> >       (error "Insufficient funds.")))
> > 
> > Anyone have any stylistic preference for one or the other? (I guess
> > the practical difference is just trading a type-error in for a
> > no-applicable-method error if withdraw is ever called with a
> > non-numeric second argument.)
> 
> What happens if I try to withdraw #(0.0 100.0) USD ?
I mean:
  What happens if I try to withdraw #C(0.0 100.0) USD ?

> What happens if I try to withdraw 100/3 EUR ?
> What happens if I try to withdraw PI UKL ?
> 
> You don't withdraw numbers, you withdraw money!


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Peter Seibel
Subject: Re: Method specialization style question
Date: 
Message-ID: <m3hdwbmwad.fsf@javamonkey.com>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Peter Seibel <·····@javamonkey.com> writes:
>> On the other hand it had better in fact *be* a number given that I'm
>> passing it to >= and DECF. So maybe I should write this:
>> 
>>   (defmethod withdraw ((account account) (amount number))
>>     (if (>= (balance account) amount)
>>       (decf (balance account) amount)
>>       (error "Insufficient funds.")))
>> 
>> Anyone have any stylistic preference for one or the other? (I guess
>> the practical difference is just trading a type-error in for a
>> no-applicable-method error if withdraw is ever called with a
>> non-numeric second argument.)
>
> What happens if I try to withdraw #(0.0 100.0) USD ?
> What happens if I try to withdraw 100/3 EUR ?
> What happens if I try to withdraw PI UKL ?
>
> You don't withdraw numbers, you withdraw money!

Yeah, yeah. You are, of course, correct. However I'm not *really*
writing a banking app. But I could reframe my question assuming an
appropriate MONEY class with associated functions as:

   (defmethod withdraw ((account account) amount)
     (if (money>= (balance account) amount)
       (cash-decrement (balance account) amount)
       (error "Insufficient funds.")))

vs

   (defmethod withdraw ((account account) (amount money))
     (if (money>= (balance account) amount)
       (cash-decrement (balance account) amount)
       (error "Insufficient funds.")))


-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Thomas F. Burdick
Subject: Re: Method specialization style question
Date: 
Message-ID: <xcv7jx74bs9.fsf@famine.OCF.Berkeley.EDU>
Peter Seibel <·····@javamonkey.com> writes:

> Yeah, yeah. You are, of course, correct. However I'm not *really*
> writing a banking app. But I could reframe my question assuming an
> appropriate MONEY class with associated functions as:
> 
>    (defmethod withdraw ((account account) amount)
>      (if (money>= (balance account) amount)
>        (cash-decrement (balance account) amount)
>        (error "Insufficient funds.")))
> 
> vs
> 
>    (defmethod withdraw ((account account) (amount money))
>      (if (money>= (balance account) amount)
>        (cash-decrement (balance account) amount)
>        (error "Insufficient funds.")))

I'd write it the first way, then later I'd probably switch to:

  (defmethod withdraw ((account account) (amount us-dollars)) ...)

  (defmethod withdraw (account (amount money))
    (withdraw account (convert-to-dollars amount)))

when I realized I better support for AMOUNT.

[ Trolls: of course this is not how a banking app would work, try to
  concentrate on the point of the question. ]

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Kenny Tilton
Subject: Re: Method specialization style question
Date: 
Message-ID: <8k29c.7781$DV6.4073@twister.nyc.rr.com>
Thomas F. Burdick wrote:
> Peter Seibel <·····@javamonkey.com> writes:
> 
> 
>>Yeah, yeah. You are, of course, correct. However I'm not *really*
>>writing a banking app. But I could reframe my question assuming an
>>appropriate MONEY class with associated functions as:
>>
>>   (defmethod withdraw ((account account) amount)
>>     (if (money>= (balance account) amount)
>>       (cash-decrement (balance account) amount)
>>       (error "Insufficient funds.")))
>>
>>vs
>>
>>   (defmethod withdraw ((account account) (amount money))
>>     (if (money>= (balance account) amount)
>>       (cash-decrement (balance account) amount)
>>       (error "Insufficient funds.")))
> 
> 
> I'd write it the first way, then later I'd probably switch to:
> 
>   (defmethod withdraw ((account account) (amount us-dollars)) ...)
> 
>   (defmethod withdraw (account (amount money))
>     (withdraw account (convert-to-dollars amount)))
> 
> when I realized I better support for AMOUNT.
> 
> [ Trolls: of course this is not how a banking app would work, try to
>   concentrate on the point of the question. ]

Troll here. Well, I /did/ say I would not use narrowed specializers to 
validate input. But I always wanted to be a troll, so...

I think technical questions (especially when a language has a kazillion 
ways to do everything, and especially where only a "preferred approach" 
out of competing workables is sought) only make sense in real 
situations. So it is fair to quibble with the example provided.

kt
From: Thomas F. Burdick
Subject: Re: Method specialization style question
Date: 
Message-ID: <xcv1xnd4k0q.fsf@famine.OCF.Berkeley.EDU>
Kenny Tilton <·······@nyc.rr.com> writes:

> Thomas F. Burdick wrote:
>
> > [ Trolls: of course this is not how a banking app would work, try to
> >   concentrate on the point of the question. ]
> 
> Troll here. Well, I /did/ say I would not use narrowed specializers to 
> validate input. But I always wanted to be a troll, so...

Sorry, to get troll points, you'd have to explain why my pseudo-code
would result in a bank erasing or creating money.  Something about how
the banking industry works.

> I think technical questions (especially when a language has a kazillion 
> ways to do everything, and especially where only a "preferred approach" 
> out of competing workables is sought) only make sense in real 
> situations. So it is fair to quibble with the example provided.

I do agree with you here, although succinct real world examples are
tough.  This afternoon, Peter said, "pretend it's a bank in a MUD."
Video-game banking ... that works for me :-)

However you split the methods up, once you go back and refactor, I
always try to make it so that the type errors are recoverable very
close to where the error occured.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | No to Imperialist war |                        
     ,--'    _,'   | Wage class war!       |                        
    /       /      `-----------------------'                        
   (   -.  |                               
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Pascal Bourguignon
Subject: Re: Method specialization style question
Date: 
Message-ID: <87vfkrwda5.fsf@thalassa.informatimago.com>
Peter Seibel <·····@javamonkey.com> writes:
> > You don't withdraw numbers, you withdraw money!
> 
> Yeah, yeah. You are, of course, correct. However I'm not *really*
> writing a banking app. But I could reframe my question assuming an
> appropriate MONEY class with associated functions as:
> 
>    (defmethod withdraw ((account account) amount)
>      (if (money>= (balance account) amount)
>        (cash-decrement (balance account) amount)
>        (error "Insufficient funds.")))
> 
> vs
> 
>    (defmethod withdraw ((account account) (amount money))
>      (if (money>= (balance account) amount)
>        (cash-decrement (balance account) amount)
>        (error "Insufficient funds.")))

But now we've progressed.

There may be several kind of "money". Not only devises that are all of
the same kind of fiat money.  From some account you can withdraw gold,
or shares.

You could have:
    (defclass value ())
    (defclass gold   (value) 
        ((mass  :type integer :documentation "unit mg")))
    (defclass money (value) 
        ((facial-value :type integer)
         (devise       :type devise)))

Then you would definitely want to do:

    (defmethod withdraw ((account account) (amount money))   ...)
    (defmethod withdraw ((account account) (amount gold))    ...)


(But actually, as it has been noted, since there are several kind of
withdrawals (atm, cashier, etc), you want to reify it).


-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Peter Seibel
Subject: Re: Method specialization style question
Date: 
Message-ID: <m3isgrkyi9.fsf@javamonkey.com>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Then you would definitely want to do:
>
>     (defmethod withdraw ((account account) (amount money))   ...)
>     (defmethod withdraw ((account account) (amount gold))    ...)

[You do get, don't you, that I don't actually care about how to write
a banking application? Just checking. Anyway, playing along:]

Would you definitely? It seems more likely that in order to prevent a
combinatorial explosion I'd want to define abstract operations on
MONEY that can be used to implement the semantics of WITHDRAW without
regard to what kind of money it is. That is, do the semantics of
WITHDRAW really vary depending on the type of currency involved in
ways that can't be captured by methods specialized only on the type of
currency, e.g. something like Thomas suggested:

  (defmethod withdraw ((account account) amount)
    (let ((converted-amount (convert (currency-type account) amount)))
      (if (money>= (balance account) converted-amount)
          (decf (balance account) converted-amount)
          (error "Insufficient funds."))))

where CONVERT is then specialized on the various kinds of things with
monetary value (Okay, so I cheat and also use GF dispatching to
specify the type of currency. But it's not a direct function of the
account type):

  (defmethod convert ((currency (eql 'us-dollars) (amount gold))) ...)
  (defmethod convert ((currency (eql 'us-dollars) (amount pounds-sterling))) ...)
  (defmethod convert ((currency (eql 'us-dollars) (amount pounds-of-flesh))) ...)

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Pascal Bourguignon
Subject: Re: Method specialization style question
Date: 
Message-ID: <87ptazw5je.fsf@thalassa.informatimago.com>
Peter Seibel <·····@javamonkey.com> writes:

> Pascal Bourguignon <····@thalassa.informatimago.com> writes:
> 
> > Then you would definitely want to do:
> >
> >     (defmethod withdraw ((account account) (amount money))   ...)
> >     (defmethod withdraw ((account account) (amount gold))    ...)
> 
> [You do get, don't you, that I don't actually care about how to write
> a banking application? Just checking. Anyway, playing along:]
> 
> Would you definitely? It seems more likely that in order to prevent a
> combinatorial explosion I'd want to define abstract operations on
> MONEY that can be used to implement the semantics of WITHDRAW without
> regard to what kind of money it is. 

Yes. But since those abstract operations would not be defined on cons,
on numbers or on T in all generality, you should better define the
method on your abstract monetary-value class:

    (defmethod withdraw ((acount account) (amount monetary-value)) ...)

Alternatively, you may perhaps have a valuation function that would
give a monetary value for a cons or an array, then you could have:

    (defmethod withdraw ((acount account) (amount t))
        (let ((mv-amount (convert-to-monetary-value amount)))
            ...))


> That is, do the semantics of
> WITHDRAW really vary depending on the type of currency involved in
> ways that can't be captured by methods specialized only on the type of
> currency, e.g. something like Thomas suggested:

In the case of accounts and withdrawals, yes. The actual algorithm to
use for an withdrawal depends on the legislation of the account, the
type of withdrawal, the type of monetary value, etc. There are
different taxes, fees, and limits.


So, either you have an abstract argument and you can define the
algorithm generally, (but beware you don't end writing something like:

    (defmethod withdraw ((acount account) (amount monetary-value))
        (case (abstract-kind amount)
          (kind-1 (do-something-1))
          (kind-2 (do-something-2))
          ;; ...
          (kind-n (do-something-n))))

), or you'd better define the method specifically for each kind of
amount or account.

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Cliff Crawford
Subject: Re: Method specialization style question
Date: 
Message-ID: <Hzl9c.255$AY4.61@twister.nyroc.rr.com>
On 2004-03-26, Peter Seibel <·····@javamonkey.com> wrote:
| 
|  Anyone have any stylistic preference for one or the other? (I guess
|  the practical difference is just trading a type-error in for a
|  no-applicable-method error if withdraw is ever called with a
|  non-numeric second argument.)

A third possibility would be to use CHECK-TYPE:

(defmethod withdraw ((account account) amount)
  (check-type amount number)
  (if (>= (balance account) amount)
    (decf (balance amount) amount)
    (error "Insufficient funds.")))

Now if you call WITHDRAW with a non-numeric AMOUNT, the debugger will
give you an opportunity to change it (via the STORE-VALUE restart).


-- 
 Cliff Crawford             ***             ·····@cornell.edu

"The perfection of art is to conceal art."      -- Quintilian
From: Kenny Tilton
Subject: Re: Method specialization style question
Date: 
Message-ID: <e_v9c.12321$DV6.2712@twister.nyc.rr.com>
Peter Seibel wrote:
> Suppose I'm writing a piece of banking software. I've defined my class
> ACCOUNT (i.e. a bank account) and now I'm implementing the WITHDRAW
> method. One way to write it is like this:
> 
>   (defmethod withdraw ((account account) amount)
>     (if (>= (balance account) amount)
>       (decf (balance account) amount)
>       (error "Insufficient funds.")))
> 
> I.e. specialize on the parameter that I'm using to dispatch on. That
> is, I'm planning to write other methods on other classes of account.
> But I don't bother specializing the second parameter because I don't
> intend to dispatch on it; it's always going to be a number.

There ya go: "I don't intend to dispatch on it". I forgot Tilton's Law:

    Don't use a screwdriver to drive a nail.

Parameter specialization exists for method dispatch. ie, for dividing up 
huge, unmaintainable wadges of code into manageable chunks by object 
type. So don't use it for software QA. Especially if the context is 
educational; an example of multiple dispatch should be found which 
honestly motivates the feature.

Consider what happens if you go ahead and validate using dispatch. The 
error the developer sees is "no withdraw method for args (<account> 
'banana). Great. The code now has a specialization on money which 
confuses others into thinking the method is dispatched on that, and the 
programmer sees only "no method for 'banana". A few instructions later 
they would have gotten 'banana is not a number as their error, which is 
just as good, so really nothing has been accomplished with the 
misleading specialization.

The only place to put a better error than "banana is not a number" is in 
the calling routine, where one can offer:

     (assert (numberp wd-amt)()
                  "this ~a and that ~a produced nun-number ~a"
                  this that wd-amt))

It ain't banking, but one framework I did dispatched GUI rendering on 
the output stream as well as the widget, so special requirements of 
hardcopy rendering could be handled neatly. Something like that.

Maybe dispatch on account and transaction type.

kt
From: Peter Seibel
Subject: Re: Method specialization style question
Date: 
Message-ID: <m3vfkoiy33.fsf@javamonkey.com>
Kenny Tilton <·······@nyc.rr.com> writes:

> Peter Seibel wrote:
>> Suppose I'm writing a piece of banking software. I've defined my class
>> ACCOUNT (i.e. a bank account) and now I'm implementing the WITHDRAW
>> method. One way to write it is like this:
>>   (defmethod withdraw ((account account) amount)
>>     (if (>= (balance account) amount)
>>       (decf (balance account) amount)
>>       (error "Insufficient funds.")))
>> I.e. specialize on the parameter that I'm using to dispatch on. That
>> is, I'm planning to write other methods on other classes of account.
>> But I don't bother specializing the second parameter because I don't
>> intend to dispatch on it; it's always going to be a number.
>
> There ya go: "I don't intend to dispatch on it". I forgot Tilton's
> Law:
>
>     Don't use a screwdriver to drive a nail.
>
> Parameter specialization exists for method dispatch. ie, for
> dividing up huge, unmaintainable wadges of code into manageable
> chunks by object type. So don't use it for software QA. Especially
> if the context is educational; an example of multiple dispatch
> should be found which honestly motivates the feature.

Yeah. I think that's where I was heading--method parameter
specialization should be considered purely a tool for dispatch.
Otherwise it's just like a DEFUN where the types are implicit (or
possibly checked with CHECK-TYPE) and it's up to the caller to know
how to use the function.

However I don't see the argument for the exttra specialization as
being about QA, since--as you point out--it only slightly changes the
timing and type of error that will be signaled. Rather it seems to me
to be about about expressing your intent: since the amount argument
actually *does* have to be a particular type, and we have this
opportunity to express that rather than leaving it implicit, there
might be some value in doing so. The programmer writing code to call
WITHDRAW can tell, either by (mop:generic-function-methods #'withdraw)
or 'grep (defmethod withdraw' or by a fancy IDE that in fact WITHDRAW
should be called with an ACCOUNT and a REAL without having to read the
docstring or look at the code of the method. Like I said, I'm not sure
I buy this argument but I don't think it's obviously crazy.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Joe Marshall
Subject: Re: Method specialization style question
Date: 
Message-ID: <65cnr86w.fsf@ccs.neu.edu>
Peter Seibel <·····@javamonkey.com> writes:

> Suppose I'm writing a piece of banking software. I've defined my class
> ACCOUNT (i.e. a bank account) and now I'm implementing the WITHDRAW
> method. One way to write it is like this:
>
>   (defmethod withdraw ((account account) amount)
>     (if (>= (balance account) amount)
>       (decf (balance account) amount)
>       (error "Insufficient funds.")))
>
> I.e. specialize on the parameter that I'm using to dispatch on. That
> is, I'm planning to write other methods on other classes of account.
> But I don't bother specializing the second parameter because I don't
> intend to dispatch on it; it's always going to be a number.
>
> On the other hand it had better in fact *be* a number given that I'm
> passing it to >= and DECF. So maybe I should write this:
>
>   (defmethod withdraw ((account account) (amount number))
>     (if (>= (balance account) amount)
>       (decf (balance account) amount)
>       (error "Insufficient funds.")))
>
> Anyone have any stylistic preference for one or the other? (I guess
> the practical difference is just trading a type-error in for a
> no-applicable-method error if withdraw is ever called with a
> non-numeric second argument.)

Since >= and DECF by default ensure that their argument is a number,
you're doing the type-check twice in the second version.

And supposing that you have extended >= and DECF (and other math
operators) to handle strings in some weird manner.  It would now make
sense to have a bank account based on strings, but the second version
would not permit it.

My *intuition* is that the first is better.
From: Damien Kick
Subject: Re: Method specialization style question
Date: 
Message-ID: <brkty1xk.fsf@email.mot.com>
Joe Marshall <···@ccs.neu.edu> writes:

> Peter Seibel <·····@javamonkey.com> writes:
> 
> > [...] One way to write it is like this: [...] I.e. specialize on
> > the parameter that I'm using to dispatch on.  [...] On the other
> > hand it had better in fact *be* a number given that I'm passing it
> > to >= and DECF. So maybe I should write this: [dispatch on both
> > parameters].
> >
> > Anyone have any stylistic preference for one or the other? (I
> > guess the practical difference is just trading a type-error in for
> > a no-applicable-method error if withdraw is ever called with a
> > non-numeric second argument.)

One can also create a custom specialization for unknown type errors.
For example,

    (defmethod withdraw ((account account) (amount t))
      (error "~A is not a valid amount." amount))

This is more specific than either no-applicable-method or just raw
type-error, though arguably not much better than a raw type error.  Of
course, if one started to use CERROR with different continuations for
the various not-quite-right types, or something along those lines,
perhaps this would start to be more useful than just raw type errors.
Of course, if one were not planning on doing all that work, it would
probably better to simply leave well enough alone.

> Since >= and DECF by default ensure that their argument is a number,
> you're doing the type-check twice in the second version.

Well, expect that there are valid numbers that are not valid monetary
units; e.g. US monetary units only allow one to go to 0.01 because the
cent is the smallest unit of US money while a Japaneese monetary unit
does not have naught but the Yen, IIRC.  I believe that accounting
rules handle things such as whether or not one would round or truncate
a value, etc, though I'm not an accountant and so I don't really know.
As CL's rationals are not susceptible to the problems of floating
point precision/approximation, perhaps one could avoid the issue all
together; however, if there are standard accounting practices that
specify rules that differ from exact rational arithmatic, one might
want to use a monetary type inside of just a NUMBER.