From luke at stat.uiowa.edu  Sat Oct 11 04:01:07 2003
From: luke at stat.uiowa.edu (Luke Tierney)
Date: Sat Oct 11 04:00:23 2003
Subject: [Rd] An artifact of base being namespace
In-Reply-To: <uteeov43hd0lg5bjd7k069kdku96oa00t0@4ax.com>
Message-ID: <Pine.LNX.4.44.0310102038040.20816-100000@itasca2.stat.uiowa.edu>

On Fri, 10 Oct 2003, Duncan Murdoch wrote:

> On Fri, 10 Oct 2003 14:35:42 +0200, you wrote:
> 
> >    Saikat> This is most problematic when you are creating a
> >    Saikat> generic for an existing function in base (as you
> >    Saikat> very well could for log). This often makes the
> >    Saikat> ability to make new generics out of existing
> >    Saikat> functions somewhat useless.
> >
> >Assuming you're right, I'm much less sure that this consequence
> >has been intended in all situations.  But I'd need to see
> >concrete examples to understand your last sentence.
> 
> I think this depends on whether we want all simple functions to act
> like generics, or whether we want a distinction.  Does it ever matter
> to a function in base like log10 whether log is a simple function or a
> generic?
> 
> If so, then the current behaviour is right.  Whoever wrote those
> functions back in the mists of time expected log to be a simple
> function, so the namespace should guarantee that it stays as one until
> explicitly changed within the namespace.
> 
> But if the distinction between generics and simple functions is only
> for efficiency (dispatching a generic is slower), then I think the
> generic should be created in the namespace where the simple function
> was originally declared.  Then log10 would call the generic which
> would dispatch to the newly created method for Saikat's data.
> 
> My feeling is that the latter is what we really want.

There are significant subtleties.  On the surface having all functions
be generics would make things simpler.

On the other hand, having lazy evaluation makes other things simpler:
there is no need for special operators, macros or other such stuff;
everything can be done with ordinary functions.  if, for, try,
on.exit, switch are just functions. Some of them happen to be
implemented internally for efficiency, but this isn't essential.

Unfortunately, you can't dispatch on the type of an argument value
without computing the argument value, so lazy evaluation of an
argument and dispatching on that argument are not compatible.

There are other arguments why making every function generic may not be
a good idea and why languages like dylan with a similar concept of
generic functions to the S4 style have not gone down that route.  log
and log10 provide one illustration: With the current definitions there
is a simple relationship between log10, the two argument log and the
single argument log.  Making the single argument log generic may well
make sense, but making the two argument version or log10 generic might
lead to a situation where the basic relation log10(x) == log(x,10) ==
log(x)/log(10) is no longer true and code that depends on that
relationship will fail.

But it would be a good idea, once the design of methods stabilizes a
bit more, to review functions in base and other packages to decide
which ones ought to be generic.

Best,

luke

-- 
Luke Tierney
University of Iowa                  Phone:             319-335-3386
Department of Statistics and        Fax:               319-335-3017
   Actuarial Science
241 Schaeffer Hall                  email:      luke@stat.uiowa.edu
Iowa City, IA 52242                 WWW:  http://www.stat.uiowa.edu


[Rd] An artifact of base being namespace
Luke Tierney