home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / bob / doc / Tutorial / 03 < prev    next >
Encoding:
Text File  |  1994-06-06  |  5.8 KB  |  170 lines

  1. ArmBob v.1.02 Tutorial 3                               GCW 06/06/94
  2.  
  3. Accounts   2
  4. ------------
  5. Now we look at Bob:main.account. In main, the variable 'account_no' is
  6. used to count the number of accounts that have been created. The
  7. maximum is given by the variable 'enough'. The statement
  8.  
  9.                     client = newvector(enough);
  10.  
  11. creates a vector called 'client' with enough components. The term
  12. "vector" is used, rather than "array", for two reasons. First,arrays 
  13. in Basic, C, Pascal, etc are homogeneous - all their components must 
  14. have the same type. Vectors are inhomogeneous - their components
  15. can have quite different types. Second, one is often tempted to think
  16. of arrays as occupying a sequential block of memory. This would be
  17. misleading for vectors. Strings in ArmBob are closer to arrays in this
  18. sense. In fact vectors correspond more closely with structs of pointers
  19. in C, or with records in Pascal.
  20.  
  21. The components of an n-component vector v are denoted
  22.  
  23.               v[0], v[1], .... v[n-1]    
  24.  
  25. It is legitimate for a vector to be a component of itself! When a vector
  26. is first created, its components all have the value nil.
  27.  
  28. The components of client are to be the instance objects of the class
  29. account. The function 'banner' informs the user of the services that the
  30. Toy Town Bank can offer. It produces the output
  31.  
  32.           Welcome to the Toy Town Bank.
  33.  
  34.              0 Quit
  35.              1 Open an account
  36.              2 Make a withdrawal or deposit
  37.              3 Get a statement
  38.              4 Change your password
  39.  
  40.           Press one of the above numbers then press RETURN.
  41.  
  42. Then follows the main loop of the program
  43.  
  44.  while ((i = input()) != "0")         /* Top level interaction loop */
  45.  { ...... }
  46.  
  47. which gets input from the user with the function 'input', and responds
  48. accordingly with a switch statement. Those new to C should realise
  49. that in C, and ArmBob, assignments, like
  50.  
  51.                       i = input()
  52.  
  53. are actually expressions, which return a value as well as produce a
  54. side-effect, and so this value can be part of a larger expression
  55.  
  56.                   (i = input()) != "0"
  57.  
  58. This is not the case in Basic. Remember that Basic uses '=' with two
  59. meanings - assignment and test for equality. In C, and ArmBob, these
  60. two uses are distinguished. Assignment uses '=', test for equality uses
  61. '=='. Another catch for the Basic programmer unused to C lurks in
  62. the switch statement. In Basic's CASE ... WHEN .... ENDCASE construction
  63. execution automatically jumps to after the ENDCASE from the end of
  64. the code following a WHEN condition. On the other hand in C's, and 
  65. ArmBob's, switch (..){ .... case .... } construction, execution does
  66. NOT automatically jump to after the closing brace, unless specifically
  67. directed to do so with a 'break;' statement. Forgetting the 'break;'
  68. is a frequent source of error.
  69.  
  70. The switch statement in main is used to dispatch execution to various
  71. alternative functions, the first of which is new_account. Note the line
  72.  
  73.                 amount = val(input());
  74.  
  75. The 'input' function always produces a string. The function 'val' 
  76. converts a string to a number, as far as possible. The next line
  77.  
  78.        client[account_no++] = new account(amount,name);
  79.  
  80. uses the post-increment operator '++'. This is an example of a unary
  81. assignment operator. The effect of this one line is equivalent to
  82.  
  83.        client[account_no] = new account(amount,name);
  84.        account_no = account_no + 1;
  85.  
  86. The vector 'client' is being used to store all the accounts in a single
  87. structure.
  88.  
  89. Note that we have functions 'withdraw', 'statement', 'change_password'
  90. despite the fact that these are names of methods for the 'account'
  91. class. There is no clash, because methods are private to the class
  92. they belong to. All these functions use the function 'get_account'
  93. which uses the 'has_owner' method to find which accounts, if any, have
  94. an owner 'name'. It returns 'the_account', so that the operator
  95.  
  96.            client[the_account]->
  97.  
  98. can be applied to the appropriate method to do what has been requested.
  99.  
  100. The heart of get_account is the search for the account owned by 'name':
  101.  
  102.  while ((the_account<account_no)
  103.         && !(client[the_account]->has_owner(name)))
  104.     the_account++;
  105.  
  106. The && operator corresponds to Basic's AND, but it has an important
  107. advantage - it is lazy! Compare these two programs, the first in Basic,
  108. the second in ArmBob.
  109.  
  110. The Basic version:
  111.  
  112.           REM AND is strict
  113.           IF FNf AND FNg THEN PRINT "yes" ELSE PRINT "no"
  114.           END
  115.  
  116.           DEF FNf
  117.           PRINT "<<Evaluating f>>"
  118.           = 0
  119.  
  120.           DEF FNg
  121.           PRINT "<<Evaluating g>>"
  122.           = 0
  123.  
  124. The ArmBob version:
  125.  
  126.           /* && is NOT strict */
  127.           main()
  128.           {
  129.            if ( f() && g() ) print("yes\n");
  130.            else print("no\n");
  131.            }
  132.  
  133.            f()
  134.            {
  135.             print("<<Evaluating f>>\n");
  136.             return 0;
  137.            }
  138.  
  139.            g()
  140.            {
  141.             print("<<Evaluating g>>\n");
  142.             return 0;
  143.            }
  144.  
  145. The Basic program produces as output
  146.  
  147.           <<Evaluating f>>
  148.           <<Evaluating g>>
  149.           no
  150.  
  151. whereas the ArmBob program produces
  152.  
  153.           <<Evaluating f>>
  154.           no
  155.           
  156. In other words, && does not bother to evaluate its right hand argument
  157. when it finds that its left hand argument is zero, whereas AND always
  158. evaluates both. This is smart of && and dumb of AND because you often
  159. need, as here in get_account, to test two conditions where error-free
  160. evaluation of the second condition is contingent upon the success of
  161. the first condition. This usually happens with vectors or arrays, where
  162. the first condition checks that an index lies within its bounds, and
  163. if it is, the second condition checks some expression involving the 
  164. component given by the index.
  165.  
  166. In the same way C's and ArmBob's || is lazy where Basic's OR is strict.
  167. If the left hand argument of || is true, the right hand argument does
  168. not get evaluated.
  169.  
  170.