[Rd] Am I missing something about debugging?

Jeffrey J. Hallman jhallman at frb.gov
Wed Jan 3 16:42:38 CET 2007


Thoughts from a pro-Smalltalk bigot:

"Byron Ellis" <ellis at stat.harvard.edu> writes:
> While a Smalltalk-style debugger would be pretty awesome, I suspect
> R's semantics would make restartable exceptions pretty difficult and
> R's current implementation would make getting the continuation-like
> object you'd need pretty difficult, at least across the range of
> platforms supported by R.
> 
> A solution, of course, would be to implement R's interpreter in
> Smalltalk as a domain-specific language. Vista Smalltalk apparently
> hosts a Lisp/Scheme interpreter and I know of at least one Lisp
> implementation for Squeak, which serve as pretty good starting points
> for an S-like language. :-)

I've programmed extensively in both Splus/R and Smalltalk, and I am much less
enamored of this idea than I used to be.  R and Smalltalk are fundamentally
different and require different mindsets to write decent code.  Here are some
of the differences:

1. Smalltalk objects are passed by reference, while R passes by value.

2. Smalltalk programs consist of messages sent to objects (receivers) and
   assignments.  R programs consist of function calls and assignments. 

3. Smalltalk is single-inheritance and single-dispatch.  R has multiple
   inheritance and multiple dispatch. 

4. The simplicity of the Smalltalk model is in part responsible for the
   fantastic development tools. Single dispatch lets every method belong to a
   particular class.  In fact, everything in the system is an instance of some
   class, including messages, methods, and even classes themselves.  The
   system browser essentially just browses (and lets you edit) classes, and
   that's essentially all that you need.  There are other browsers, but
   they're really just different views into the same thing.

5. The style of programming is different.  One example is how to implement a
   computation with some inputs that have default values.  In R, you would
   write a function like this:

   myFun <- function(arg1, arg2 = default2, arg3 = default3){ 
   ...
   return(aComputedResult)
   }

   and call it any of these ways:

   answer <- myFun(arg1 = 1)
   answer <- myFun(arg1 = 1, arg2 = 2)
   answer <- myFun(arg1 = 1, arg3 = 3)
   answer <- myFun(arg1 = 1, arg2 = 2, arg3 = 3)

   The naive way to do the same in Smalltalk uses 4 methods implemented in the
   class of arg1.  The one that does the actual computing looks like this:

   myFunArg2: firstNumber arg3: secondNumber
     ....
     ^ aComputedResult          "'^' is the return operator."

   The other three methods are:

   myFunArg2: aNumber
     ^ self myFunArg2: aNumber arg3: default3

   myFunArg3: aNumber
     ^ self myFunArg2: default2 arg3: aNumber

   myFun
     ^ self myFunArg2: default2 arg3: default3

   and the four ways you can invoke these are:

   answer := 1 myFun.
   answer := 1 myFunArg2: 2.
   answer := 1 myFunArg3: 3.
   answer := 1 myFunArg2: 2 arg3: 3.

   Compared to R this is kind of clunky, with a combinatoric explosion in the
   number of methods as the number of arguments increases. To avoid that, an
   experienced Smalltalker might instead create the class MyFunArgs to
   implement the idea of "arguments for computing myFun".  MyFunArgs would
   have instance variables arg1, arg2 and arg3, and myFun would be invoked by
   sending the message 'compute' to an instance of myFunArgs.  MyFunArgs would
   have an initialize method that set up the default values, so that 

   MyFunArgs arg1: aNumber

   returned an instance with arg1 set to aNumber, arg2 set to default2, and
   arg3 set to default3.  Then you'd call it in one of these ways:

   answer := (MyFunArgs arg1: 1) compute.
   answer := ((MyFunArgs arg1: 1) arg2: 2) compute.
   answer := ((MyFunArgs arg1: 1) arg3: 3) compute.
   answer := ((MyFunArgs arg1: 1) arg2: 2; arg3: 3) compute.

For all of these reasons and more, R code does not translate cleanly to
Smalltalk, and even writing an R interpreter in Smalltalk does not really take
advantage of the Smalltalk way of programming.

On the other hand, Smalltalk is a very nice language, and with a bit of work
to set up the fundamental classes (e.g., Matrix, Vector, StatisticalModel,
etc...), a very nice data analysis environment could be created using it. The
virtues of such a system would be many.  First and foremost is that, at the
level of 'computing on the language', Smalltalk is easy to understand, as it
really consists of only a few simple ideas consistently exploited to create a
sophisticated system. Second, there are free Smalltalk implementations that
can create complicated GUI applications much more easily than can be done in R
or Splus. Third, even the slowest Smalltalk interpreters are faster than the R
interpreter.  Of course, in many cases this would not matter since R and 
Smalltalk programmers alike can always call out to C or Fortran for
numerically intensive computations.  

Jeff



More information about the R-devel mailing list