[plt-scheme] Re: to define, or to let

From: Bill Richter (richter at math.northwestern.edu)
Date: Wed Apr 21 20:49:27 EDT 2004

[Sorry, I just sent this with a bad Subject, so I'm resending it.]

Bradd, thanks for the 2 responses, I don't know enough C++ to argue
about it with you.  I'd like you & Anton to answer a question for me.
Anton said he wanted the documentation to say something, and you say
there are R5RS constructions already for sequential stuff.  I bet MF
would respond, "We wrote a whole book about how to program in Scheme!"
So my question is: What does HtDP advise us to do about these issues:
sequential, or order of eval issues, etc.  One thing I can respond to:

   Yes, I do mean it!

But you misunderstood me.  I'm sorry if I wasn't clear.

   >> In the engineering contexts I'm used to, an implementation that
   >> doesn't match the design or that's fragile is almost as buggy as one
   >> that's more obviously incorrect. 

   > So why is this formerly-buggy coding now always fragile?

   What do you mean by "formerly-buggy"? 

A procedure call (foo goo) where the side-effects of foo affect goo.
In R5RS Scheme, that's a bug, because you don't know the eval order.

In Mzscheme, that's "formerly-buggy", because Mzscheme specifies
left->right evaluation.  We know that foo is gonna get evaluated
first, and so we can count on that, and know what the effect on goo's
evaluation is gonna be.

   Order of evaluation bugs are still bugs even if the compiler sets
   things up so that they're predictable or so that they do less
   damage. 

Right, but if they change the language, they change some bugs.  My
(foo goo) is always buggy in R5RS Scheme, but it's not a bug in
Mzscheme if we're deliberately taking advantage of a feature.

   Sequentiality (or lack of it) is an important design decision. A
   design that fails to consider it is fragile. An implementation that
   doesn't match the design decision is too. The only difference
   unspecified/right->left/perverse eval order does is increase the
   odds that the fragile code will break sooner (during design and
   coding) rather than later (after shipping).

Yeah, if we don't know what we're doing!  But what if we counted on
it?  Knowing about left->right eval, I don't see the difference
between

(foo goo)

and 

(let ([eval-function-1st foo])
  (let ([eval-argument-2nd goo])
    (eval-function-1st eval-argument-2nd)))

I mean, the 2nd is driving home the point that we really want to
evaluate foo first.   And in R5RS, you have to do that!  But in
Mzscheme, you don't have to, and it's "the same" as (foo goo).


Posted on the users mailing list.