1 / 46

TL: Subroutines

TL: Subroutines. Programming Fundamentals 14 Feliks Klu ź niak. There are two kinds of subroutines in TL: procedures and functions . There are two kinds of subroutines in TL: procedures and functions . Procedures are invoked in procedure call statements , e.g.,

kapono
Download Presentation

TL: Subroutines

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. TL: Subroutines Programming Fundamentals 14 Feliks Kluźniak TL: Subroutines

  2. There are two kinds of subroutines in TL: procedures and functions. TL: Subroutines

  3. There are two kinds of subroutines in TL: procedures and functions. Procedures are invoked in procedure call statements, e.g., write_string( stdout, “Hello!” ); do_it() these are arguments TL: Subroutines

  4. There are two kinds of subroutines in TL: procedures and functions. Procedures are invoked in procedure call statements, e.g., write_string( stdout, “Hello!” ); do_it() A very useful predefined procedure is called assert. It takes one boolean argument: if the argument is false, you will get an error message and the program will halt. Example: assert( 0 =< i and i < size( a ) ) TL: Subroutines

  5. There are two kinds of subroutines in TL: procedures and functions. Procedures are invoked in procedure call statements, e.g., write_string( stdout, “Hello!” ); do_it() A very useful predefined procedure is called assert. It takes one boolean argument: if the argument is false, you will get an error message and the program will halt. Example: assert( 0 =< i and i < size( a ) ) Do sprinkle your programs liberally with such assertions: when some of them fail, you will be glad you did! TL: Subroutines

  6. There are two kinds of subroutines in TL: procedures and functions. Procedures are invoked in procedure call statements, e.g., write_string( stdout, “Hello!” ); do_it() Functions are invoked within expressions, e.g., high_bit := power( 2, word_size – 1 ); euler_ok := exp( i * pi() ) + 1 = 0 TL: Subroutines

  7. There are two kinds of subroutines in TL: procedures and functions. Procedures are invoked in procedure call statements, e.g., write_string( stdout, “Hello!” ); do_it() Functions are invoked within expressions, e.g., high_bit := power( 2, word_size – 1 ); euler_ok := exp( i * pi() ) – 1 = 0 Notice that we must use parentheses even when there are no arguments. This distinguishes a subroutine invocation from an occurrence of the name of a variable. TL: Subroutines

  8. Declaring a procedure: procname(arg1,arg2, … ) begin imports of global variables and constants local declarations statements end TL: Subroutines

  9. Declaring a procedure: procname(arg1,arg2, … ) begin imports of global variables and constants local declarations statements end The body of a procedure is similar to the body of a program, and forms a new scope. Body of the procedure TL: Subroutines

  10. Declaring a procedure: • procname(arg1,arg2, … ) • begin • imports of global variables and constants • local declarations • statements • end • The body of a procedure is similar to the body of a program, and forms a new scope. • Local declarations are not “visible” outside the body. Body of the procedure TL: Subroutines

  11. Declaring a procedure: • procname(arg1,arg2, … ) • begin • imports of global variables and constants • local declarations • statements • end • The body of a procedure is similar to the body of a program, and forms a new scope. • Local declarations are not “visible” outside the body. • Global variables and constants (but not subroutines or types) must • be explicitly imported. Body of the procedure TL: Subroutines

  12. Declaring a procedure: • procname(arg1,arg2, … ) • begin • imports of global variables and constants • local declarations • statements • end • The body of a procedure is similar to the body of a program, and forms a new scope. • Local declarations are not “visible” outside the body. • Global variables and constants (but not subroutines or types) must • be explicitly imported. • The names from the list of arguments are also visible in (and local to) this scope. Body of the procedure TL: Subroutines

  13. Declaring a procedure: procname(arg1,arg2, … ) begin … end This is the list of formal arguments. The list may be empty (but the parentheses must be there.) TL: Subroutines

  14. Declaring a procedure: procname(arg1,arg2, … ) begin … end This is the list of formal arguments. The list may be empty (but the parentheses must be there.) When the procedure is invoked, the names of the formal arguments will represent the actual arguments in the invocation (i.e., the procedure call statement). The details must be explained … TL: Subroutines

  15. Declaring a procedure: procname(arg1,arg2, … ) begin … end The simplest declaration of a formal argument has the following form: nameOfArgument:NameOfType Such an argument is said to be passed by value. It represents a memory location that is filled by a copy of the value of the actual argument. TL: Subroutines

  16. Declaring a procedure: procname(arg1,arg2, … ) begin … end The simplest declaration of a formal argument has the following form: nameOfArgument:NameOfType Such an argument is said to be passed by value. It represents a memory location that is filled by a copy of the value of the actual argument. The actual argument may be an arbitrary expression of the type named in the declaration. TL: Subroutines

  17. Declaring a procedure: procname(arg1,arg2, … ) begin … end The simplest declaration of a formal argument has the following form: nameOfArgument:NameOfType Such an argument is said to be passed by value. It represents a memory location that is filled by a copy of the value of the actual argument. The actual argument may be an arbitrary expression of the type named in the declaration. NOTE: In TL, the type of an argument passed by value must fit in one machine word (i.e., it must be a basic type or a pointer type). So it cannot be an array type, for example.

  18. Declaring a procedure: Example: procPrintChar ( c : char ) begin globalvarstdout; write( stdout, c ) end TL: Subroutines

  19. Declaring a procedure: Example: procPrintChar ( c : char ) begin globalvarstdout; write( stdout, c ) end This can be invoked, e.g., by PrintChar( chr( ord( ‘0’ ) + 5 ) ) During execution of the statement in PrintChar, the name c will represent … What? TL: Subroutines

  20. Declaring a procedure: procname(arg1,arg2, … ) begin … end A formal argument can also be declared like this: refnameOfArgument:NameOfType Such an argument is said to be passed by reference. It represents a memory location that is filled by the address of the actual argument. TL: Subroutines

  21. Declaring a procedure: procname(arg1,arg2, … ) begin … end A formal argument can also be declared like this: refnameOfArgument:NameOfType Such an argument is said to be passed by reference. It represents a memory location that is filled by the address of the actual argument. The actual argument must be a variable of the type named in the declaration. TL: Subroutines

  22. Declaring a procedure: procname(arg1,arg2, … ) begin … end A formal argument can also be declared like this: refnameOfArgument:NameOfType Such an argument is said to be passed by reference. It represents a memory location that is filled by the address of the actual argument. The actual argument must be a variable of the type named in the declaration. An element of an array variable, such as a[ i ] , is also a variable. TL: Subroutines

  23. Declaring a procedure: Example: proc Swap ( ref a : int, ref b : int ) begin a , b := b , a end This can be invoked, e.g., by Swap( alpha, beta ) but not by Swap( 3, alpha + 1 ) TL: Subroutines

  24. Declaring a procedure: Example: proc Swap ( ref a : int, ref b : int ) begin a , b := b , a end This can be invoked, e.g., by Swap( alpha, beta ) but not by Swap( 3, alpha + 1 ) What will be the result of Swap( alpha, beta ) ? TL: Subroutines

  25. Declaring a procedure: • Example: • procSwapV ( a : int, b : int ) • begin • a , b := b , a • end • In this procedure the arguments are passed by value. • What will be the result of SwapV( alpha, beta ) ? TL: Subroutines

  26. Declaring a procedure: • Example: • procSwapV ( a : int, b : int ) • begin • a , b := b , a • end • In this procedure the arguments are passed by value. • What will be the result of SwapV( alpha, beta ) ? • Note that in Swap() the assignment a, b := b, a is compiled to code that is very different from the code to which it is compiled in SwapV() . TL: Subroutines

  27. procSwapV ( a : int, b : int ) begin a , b := b , a end The value of b is 2. The value of a is 1. Store the value 2 in a. Store the value 1 in b. So the values of a and b are swapped, but alpha and beta don’t change. proc Swap( ref a : int, ref b : int ) begin a , b := b , a end 1. The value of the variable whose address is in b is 2. 2. The value of the variable whose address is in a is 1. 3. Store the value 2 in the variable whose address is in a. 4. Store the value 1 in the variable whose address is in b. So the values of alpha and beta are swapped. a: 1 b: 2 a: 101 b: 220 (alpha) 101: 1 (beta) 220: 2 (alpha) 101: 1 (beta) 220: 2 TL: Subroutines

  28. Declaring a procedure: procname(arg1,arg2, … ) begin … end Finally, the third form of declaring an argument: ref constnameOfArgument:NameOfType Such an argument is said to be passed by constant reference. It represents a memory location that is filled by the address of the actual argument. The actual argument must be a variable of the type named in the declaration. However, the procedure cannot modify such an argument! TL: Subroutines

  29. Declaring a procedure: procname(arg1,arg2, … ) begin … end Finally, the third form of declaring an argument: ref constnameOfArgument:NameOfType Such an argument is said to be passed by constant reference. It represents a memory location that is filled by the address of the actual argument. The actual argument must be a variable of the type named in the declaration. However, the procedure cannot modify such an argument! This is mostly used to pass arguments that are to be treated as constants, but that cannot be passed by value (e.g., arrays). TL: Subroutines

  30. Declaring a procedure: Example: procSwapC ( refconst a : int, refconst b : int ) begin a , b := b , a end The compiler will detect an error! TL: Subroutines

  31. Declaring a procedure: The problem of aliasing: When an argument is passed by reference, we may run into the problem of having the same variable represented by different names. Consider: proc Assign ( ref a : int, ref const b : int ) begin a := a + 1; a := b end We expect a call like Assign( v, w ) to assign the value of w to v, i.e., to be equivalent to v := w . Indeed, it will be so. TL: Subroutines

  32. Declaring a procedure: The problem of aliasing: When an argument is passed by reference, we may run into the problem of having the same variable represented by different names. Consider: proc Assign ( ref a : int, ref const b : int ) begin a := a + 1; a := b end We expect a call like Assign( v, w ) to assign the value of w to v, i.e., to be equivalent to v := w . Indeed, it will be so. However, the effect of Assign( v, v ) will be quite different from that of v := v . Why? TL: Subroutines

  33. Declaring a procedure: The problem of aliasing: A similar problem arises when a procedure imports a global variable: proc P ( ref a : int ) begin globalvar v; a := v + 1; v := v + 1 end Here we expect the global variable v to be incremented, and the argument to be assigned this new value of v. TL: Subroutines

  34. Declaring a procedure: The problem of aliasing: A similar problem arises when a procedure imports a global variable: proc P ( ref a : int ) begin globalvar v; a := v + 1; v := v + 1 end Here we expect the global variable v to be incremented, and the argument to be assigned this new value of v. But the effect of P( v ) will be … What? TL: Subroutines

  35. Declaring a procedure: • Good advice: • Be aware of the pitfalls. • Avoid importing global variables if you can. • If you must import, import it as a constant, if you can. • Do not pass arguments by non-constant reference, unless it is the • explicit purpose of the procedure to modify them. TL: Subroutines

  36. Declaring a function: funcname(arg1,arg2, … ) :type of value begin imports of global variables and constants local declarations statements return expression end Since a function call will appear in an expression, the function must return a value . The type of that value must be declared, and the function must end with an expression that is to be its value. TL: Subroutines

  37. Declaring a function: Example: func square ( a : int ) : int begin return a * a end This can be invoked, for example, by v := square( square( w + 1 ) ) % the fourth power of (w + 1) TL: Subroutines

  38. Declaring a function: Example: func square ( a : int ) : int begin return a * a end This can be invoked, for example, by v := square( square( w + 1 ) ) % the fourth power of (w + 1) Please note that there is no recursion here. What happens is this: the value of w + 1 is computed and passed to square(); TL: Subroutines

  39. Declaring a function: Example: func square ( a : int ) : int begin return a * a end This can be invoked, for example, by v := square( square( w + 1 ) ) % the fourth power of (w + 1) Please note that there is no recursion here. What happens is this: the value of w + 1 is computed and passed to square(); square() returns its value; TL: Subroutines

  40. Declaring a function: Example: func square ( a : int ) : int begin return a * a end This can be invoked, for example, by v := square( square( w + 1 ) ) % the fourth power of (w + 1) Please note that there is no recursion here. What happens is this: the value of w + 1 is computed and passed to square(); square() returns its value; that value is passed to a new invocation of square() . TL: Subroutines

  41. Declaring a function: • Example: • func square ( a : int ) : int • begin • return a * a • end • This can be invoked, for example, by • v := square( square( w + 1 ) ) % the fourth power of (w + 1) • Please note that there is no recursion here. What happens is this: • the value of w + 1 is computed and passed to square(); • square() returns its value; • that value is passed to a new invocation of square() . • A widely-used convention is that when we refer to a procedure or a function, we add empty parentheses to its name (even if argument list would not be empty in an invocation). TL: Subroutines

  42. Declaring a function: In TL a function cannot have side effects. This means that it cannot make assignments to global variables, and cannot invoke procedures. TL: Subroutines

  43. Declaring a function: • In TL a function cannot have side effects. • This means that it cannot make assignments to global variables, and cannot invoke procedures. • For convenience, there are some exceptions to this rule: • You are allowed to use assert() . • You are allowed to use TRACE • (but these, remember, should be removed from the • final version of your program) TL: Subroutines

  44. Declaring a function: In TL a function cannot have side effects. This means that it cannot make assignments to global variables, and cannot invoke procedures. So the arguments of a function must be passed either by value or by constant reference… TL: Subroutines

  45. Declaring a function: In TL a function cannot have side effects. This means that it cannot make assignments to global variables, and cannot invoke procedures. So the arguments of a function must be passed either by value or by constant reference… and a function can import variables only as constants: global const variable_name, … TL: Subroutines

  46. Declaring a function: Example: % Sum of the elements of an integer array. % func Sum ( refconst a : ArrayOfInteger ) : int begin var sum : int; “sum” is not “Sum” var k : int; k := 0; sum := 0; while k != size( a ) do sum := sum + a[ k ]; k := k + 1 od; return sum end TL: Subroutines

More Related