Structure and Interpretation of Computer Programs has the following footnote:
Another way to define the selectors and constructor is
(define make-rat cons)
(define numer car)
(define denom cdr)
The first definition associates the name
make-rat
with the value of the expressioncons
, which is the primitive procedure that constructs pairs. Thusmake-rat
andcons
are names for the same primitive constructor.Defining selectors and constructors in this way is efficient: Instead of
make-rat
callingcons
,make-rat
iscons
, so there is only one procedure called, not two, whenmake-rat
is called. On the other hand, doing this defeats debugging aids that trace procedure calls or put breakpoints on procedure calls: You may want to watchmake-rat
being called, but you certainly don't want to watch every call tocons
.
Does this advice still apply? For example, are modern debugging aids still defeated in this way?
Quite often they will be. For instance imagine some debugger which is trying to print a backtrace in a useful way. It's going to want to map between the procedure objects sitting in the backtrace and their names. And that map is either going to point at the 'wrong' name, or it's going to point at all the names and you then have to know which one you actually used.
Here's an example in Racket:
> (object-name cons)
'cons
> (define make-thingy cons)
> (object-name make-thingy)
'cons