Please send questions to st10@humboldt.edu .

Week 10 - Lecture 1 -- putting together some notes to post
                       after lecture...

*   so far: we've set up names, and given them values...

    in Racket:

    (define WIDTH 300)

    in C++:

    const int WIDTH = 300;

    in Racket:

    (define (tank-volume length width height)
        (* length width height)
    )

    in C++:
 
    double tank_volume(double length, double width, double height)
    {
        return length * width * height;
    }

    in Racket:  (tank-volume 2 4 6)
        for THIS call of tank-volume, length is 2, width is 4,
	height is 6;

    in C++: tank_volume(3, 6, 9)
        for THIS call of tank_volume, length is 3, width is 6,
	height is 9;

    We've done this for C++ class instances -- objects -- also:

    boa george("blue", 7.5, "cheetos");
    ...then we know that boa george has a color data field of "blue",
                                          length data field of 7.5,
					  food data field of "cheetos"

    boa harold("green", 6.0, "fritos");
    ...then we know that boa harold has a color data field of "green",
                                          length data field of 6.0,
					  food data field of "fritos"

*   so far, we've been programming in a rather FUNCTIONAL style
    of programming --
    once we assign a value to a name, we don't change that value;
    *   (each time we call a function, we get a "new" instance of
        its parameters...)

    AND our functions have usually been "pure" -- they expect
    values, and produce/return a value based on those argument values;

    (our functions have mostly been free of "side-effects"...)

*   Now, we're going to venture into a more IMPERATIVE style of
    programming 
    (note: you can program in C++ in a functional and an imperative
    style; you can program in Racket in a functional and an
    imperative style. We just left Racket before getting to the
    imperative style...)

    *   we WILL change the values associated with names to
        get the results we want (we hope);
    *   we WILL program with "side-effects" --> consequences
        BESIDES just a function returning a value;
	...a name's value might be changed;
	...something might be printed to the screen;

*   some would call changing the value associated with a name
    MUTATION...

    useful mental model:
    think of a name as being a location in the computer's memory
       a box that can hold a value, if you will;

       consider this local declaration:
       int quantity;

       ...you could think of a box with the label quantity being
          created for you, just the right size for an int;
       ...when you give the simple expression:

       quantity

       ...you get the value in that box.

       I can assign a value to quantity with the assignment operator, =

       quantity = 13;  // an ASSIGNMENT statement, puts 13 in quantity's box

       quantity = 47;  // now quantity's box contains 47

       ...make sure this is clear: the previous value 13 is GONE,
          overwritten, no longer grabbable, no longer there;

*   consider this little goofy function:

    *   note: both amount and look_at_me are local to playing;
        they "come into existence" whenever playing is called;

        BUT, amount, being a parameter, is then assigned to 
        the argument expression's value,
	and look_at_me has its box created, and is awaiting
	assignment, etc.

    int playing(int amount)
    {
        int look_at_me; 

        look_at_me = 3;

        look_at_me = 5;

        return amount + look_at_me;
    }

    what is the value of 
    playing(10) ... 15 (we talked through why in lecture)

*   terminology: we talk about SCOPE as being the parts of a
    program for which a name has meaning;

    ...the SCOPE of a parameter is the function body of the function
       it is a parameter for;

    ...the SCOPE of a local variable is that block, starting where
       it is declared;

*   a class's data fields, properly declared them as private within
    the private part of a class definition,
    has as its scope that class ;

    an instance's data fields can be used within that instance's
    methods, but no where else; their scope is LIMITED to the instance's
    methods, thus the method implementations as well;

    blocks within blocks? local variables from the outer block
    can typically be "seen" in the inner blocks:

    double abs_value(double value)
    {
       if (value < 0)
       {
           return value * -1;
       }
       else
       {
           return value;
       }
    }

    *   this is just fine, because value's scope includes
        the if and else blocks...

*   KEEP IN MIND: in any expression (mostly), you use the CURRENT
    value of that expression;

*   semantics/meaning of the assignment statement:

    variable = expr;

    *   we call the part to the left of the = the "left hand side" (LHS)
        of this assignment statement; -- the C++ compiler sometimes
	calls this the lvalue

    *   we call the part to the right of = the "right hand side" (RHS)
        of this assignment statement;

    *   FIRST, the expression on the RHS is evaluated;
        THEN, that value becomes (is assigned to) the name on the LHS

        THOU SHALT NOT write this "backwards"...

        look_at_me = 3;   // this is syntactically correct
	3 = look_at_me;   // NOT CORRECT, NOT LEGAL SYNTAX ...you can't
	                  //    assign to/change a literal 3

    *   int i;

        i = 7;
	i = i + 1;

        THIS IS FINE -- you FIRST evaluate the expression i + 1, 
	     	which is 7 + 1, or 8
		THEN you CHANGE the value of i to 8

int amount;
amount = 10;
amount = amount * 3;

SOME C++ SHORTCUTS...

*   because adjustments of some value are so
    frequent, C++ provides some shorthand assignment
    operators...

*   two sets of COMMON SHORTCUTS for changing the current value
    of a variable -- here is the first set:

    +=   -=  *=  /=
        
    count += 1;   means:   count = count + 1;
    value += abs(sqrt(abs(-4) * pow(3.0, 27.0)));
       means:  value = value + abs(sqrt(abs(-4) * pow(3.0, 27.0)));

    count -= 3;   means: count = count - 3;
    count += -3;  means: count = count + -3;

    count *= 27;  means: count = count * 27;

    count /= 3.5; means: count = count / 3.5;

int value = 3;
int quantity = 20;

quantity += value;

ANOTHER set of C++ shortcuts: the increment and decrement
operators

++ --

*   the ++ operator is used to increase something by 1;

    quantity++;

    ...the same as
    quantity = quantity + 1;
    quantity += 1;

    so does:

    ++quantity;

    Hey! it can be prefix or postfix! but with a SUBTLE difference,
    to be mentioned in a moment;

    *   what if you say:

        int value1;
        int value2;

	value1 = 3;
	value2 = 100;

        // these two are DIFFERENT...

	value2 = (value1++) + 7;   // after this, value1 is 4 and value2 is 10

        // if INSTEAD you did

	value2 = (++value1) + 7;   // after this, value1 is 4 and value2 is 11
  
        when you put ++value1, you ADD to value1, THEN you use it in
	the expression;

	when you put value1++, you USE value1 in the expression,
	THEN you add to value1;