COS 333: Chapter 9, Part 2

Willem van Heerden
19 Sept 202164:16

Summary

TLDRThis lecture delves into advanced sub-program concepts, exploring parameter parsing methods such as in, out, and in-out modes, and their implementations like pass by value and pass by reference. It discusses the efficiency and safety trade-offs in parameter passing and touches on the complexities of multi-dimensional array parameters. The lecture also addresses the design issues related to sub-programs, including type checking, indirect calls, and the referencing environment of passed sub-programs, with examples in various programming languages.

Takeaways

  • πŸ“š The lecture delves into Chapter 9, continuing the discussion on sub-programs, their design issues, and parameter parsing methods.
  • πŸ” It differentiates between 'in', 'out', and 'in-out' modes for formal parameters, explaining how data is passed between the caller and the sub-program.
  • πŸ“ˆ The lecture introduces five implementation models for parameter passing: pass by value, pass by result, pass by reference, pass by value-result, and pass by name.
  • πŸ‘‰ Pass by value is demonstrated with an example in C++, highlighting how the actual parameter's value initializes the formal parameter within a sub-program.
  • πŸ”„ Discusses the disadvantages of pass by value, such as the need for additional storage and potential high cost for large parameters due to copying.
  • πŸ”§ Pass by result is explained with an ADA example, showing how the sub-program can modify the actual parameter's value through the formal parameter.
  • πŸ”€ Pass by value-result combines both pass by value and pass by result, allowing data to be passed into and out of the sub-program.
  • πŸ’‘ The advantages of pass by reference are highlighted, including efficiency in processing time and memory usage due to passing a reference instead of a copy.
  • 🚧 The potential downsides of pass by reference are also discussed, such as slower access to formal parameters due to indirect addressing and the possibility of unwanted side effects.
  • 🌐 The lecture provides insights into how different programming languages handle parameter passing, with examples from C, C++, Java, ADA, and others.
  • πŸ”‘ The concept of 'pass by name' is introduced as an older parameter parsing technique, which uses textual substitution and can lead to late binding of variables at runtime.

Q & A

  • What are the three modes for parameters in sub-programs?

    -The three modes for parameters in sub-programs are 'in' mode, 'out' mode, and 'in-out' mode. 'In' mode formal parameters receive data from actual parameters in a subprogram call. 'Out' mode formal parameters send data to actual parameters. 'In-out' mode formal parameters both receive data from and send data to actual parameters.

  • What is the difference between pass by value and pass by reference?

    -Pass by value involves copying the actual parameter's value into the formal parameter, creating two separate copies of the data. Pass by reference, on the other hand, involves passing the memory address of the actual parameter to the formal parameter, allowing the sub-program to access and modify the original data directly.

  • Why might pass by value be implemented using an access path?

    -Pass by value can be implemented using an access path, typically through a pointer or reference, to avoid the overhead of copying large data structures. However, this approach is not commonly recommended due to the difficulty in enforcing write protection within the called sub-program, which could lead to unintended modifications of the actual parameter.

  • What are the advantages of pass by reference over pass by value?

    -Pass by reference is more efficient in terms of processing time and memory usage. It avoids the need for copying large amounts of data, thus reducing processing time and memory overhead. However, it can introduce potential issues such as unwanted side effects and aliases.

  • How does pass by result differ from pass by value?

    -Pass by result is an 'out' mode parameter parsing technique where the value of the formal parameter is used to change the corresponding actual parameter's value. Unlike pass by value, no value is transmitted to the sub-program; instead, data is only transmitted back to the caller when control is returned.

  • What is the concept of 'pass by name' in parameter passing?

    -Pass by name involves textual substitution where all occurrences of a formal parameter are replaced by the corresponding actual parameter. The binding to a value or address only occurs when the formal parameter is used in the sub-program, allowing for late binding and flexibility in how parameters are accessed.

  • Why is parameter type checking important in programming languages?

    -Parameter type checking is important for ensuring the reliability of a program. It verifies that the types of actual and formal parameters match, preventing type mismatches that could lead to unexpected behavior or errors at runtime.

  • How do programming languages handle multi-dimensional arrays as parameters?

    -Languages like C and C++ require specifying the sizes of all dimensions except the first in the function parameter list. Java and C# handle multi-dimensional arrays as objects with a length property, allowing the size to be dynamically determined at runtime without needing explicit size declarations in the parameter list.

  • What is the difference between shallow binding and deep binding for sub-programs?

    -Shallow binding uses the calling environment of the sub-program that actually performs the call, while deep binding uses the definition environment of the sub-program being called. Shallow binding is natural for dynamically scoped languages, whereas deep binding is for statically scoped languages.

  • What are the considerations for passing sub-programs as parameters?

    -When passing sub-programs as parameters, considerations include whether parameter types are checked and determining the referencing environment for the passed sub-program, which can be influenced by shallow binding, deep binding, or ad-hoc binding.

  • How do function pointers in C++ allow for calling sub-programs indirectly?

    -Function pointers in C++ are pointers to functions that include parameter and return types. They can be assigned to any function that matches the specified requirements, allowing for indirect calls to functions through the pointer.

  • What is the role of delegates in C# for calling sub-programs indirectly?

    -In C#, delegates are objects that can be used to call sub-programs indirectly. They are created by defining a delegate type with a specific method signature and then instantiating delegate objects with methods that match this signature.

Outlines

00:00

πŸ“˜ Lecture Overview on Sub-programs and Parameter Passing

The lecture delves into chapter 9, continuing the discussion on sub-programs from the previous session. It revisits fundamental concepts and terminology before exploring parameter parsing methods, including in, out, and in-out modes. The lecture also introduces various implementation models for parameter passing, such as pass by value, pass by reference, and pass by name, highlighting their use cases and implications for programming.

05:03

πŸ” In-Depth Analysis of Parameter Passing Mechanisms

This section provides a detailed examination of parameter passing mechanisms, starting with pass by value, which involves copying the actual parameter's value into the formal parameter. It discusses the implications of this method, including the need for additional storage and potential performance costs for large data structures. The explanation also covers pass by result, which changes the actual parameter's value based on the formal parameter, and its challenges, such as the order of parameter copying back to the caller.

10:04

πŸ”„ Exploring Pass by Value-Result and Pass by Reference

The paragraph discusses pass by value-result, which combines elements of both pass by value and pass by result, allowing data to be passed into and out of a sub-program. It also explains pass by reference, where an access path to the data is passed, leading to efficiency in memory and processing time but introducing complexities like indirect addressing and potential side effects. The potential issues with aliasing and unwanted side effects in pass by reference are also highlighted.

15:04

πŸ“š Understanding Pass by Name and Its Implementation

This part of the lecture introduces pass by name, a less common method that involves textual substitution of formal parameters with actual parameters at call time. It allows for late binding, where the value accessed depends on the variable's runtime value. The explanation clarifies how pass by name works with an example, demonstrating how the output can change based on the variable's value at runtime.

20:06

🌐 Real-World Programming Languages' Parameter Passing Techniques

The script provides insights into how various real-world programming languages implement parameter passing. It covers languages like C, C++, Java, Ada, Fortran 95, C#, PHP, Perl, Python, and Ruby, explaining their default parameter parsing methods and any special considerations, such as Java's behavior with objects and references, or Python and Ruby's pass by assignment due to their object-oriented nature.

25:09

πŸ”‘ Parameter Type Checking and Its Impact on Programming Languages

This section discusses the importance of parameter type checking for ensuring program reliability. It contrasts older languages like Fortran 77 and early C, which lacked type checking, with modern languages that enforce it. The explanation also covers the implications of type checking on programming language design and safety, emphasizing the benefits of type-checked approaches.

30:09

πŸ“Š Multi-Dimensional Arrays in Sub-Program Parameters

The lecture addresses the complexities of passing multi-dimensional arrays to sub-programs, explaining the need for the compiler to know array dimensions for correct mapping. It discusses the limitations and solutions in languages like C and C++, which require specifying dimensions in the function definition, and the more flexible approaches in Java and C#, where array lengths are intrinsic properties of the array objects.

35:12

πŸ›  Design Considerations for Parameter Parsing in Programming Languages

This part explores the trade-offs between efficiency and good programming practices in parameter parsing techniques. It examines the advantages of pass by reference in terms of processing time and memory usage, but also its conflict with one-way data transfer preferences. The discussion also touches on languages that support a mix of techniques, like C++, and the rationale behind their design choices.

40:12

πŸ”‘ Indirect Sub-Program Calls and Function Pointers

The script explains the concept of indirect sub-program calls, where the exact sub-program to be called is determined at runtime, using function pointers in C and C++ and delegates in C#. It provides examples of how these mechanisms work, allowing for dynamic event handling and flexibility in programming, and also introduces the concept of multicast delegates in C#.

45:13

πŸ”„ Passing Sub-Programs as Parameters Across Languages

This section discusses the ability to pass sub-programs as parameters in different programming languages, highlighting support in C and Fortran 95, and the lack thereof in Ada and Java. It also introduces the concept of referencing environments for passed sub-programs, explaining shallow, deep, and ad hoc binding, and their implications for variable visibility and scoping rules.

50:15

🏞 Referencing Environments for Passed Sub-Programs

The final part of the lecture focuses on the referencing environment for sub-programs passed as parameters, illustrating the concept with an example and explaining how different binding strategiesβ€”shallow, deep, and ad hocβ€”affect which variable is referenced within the sub-program. It concludes the lecture with a look forward to the next session, which will continue the discussion on sub-programs.

Mindmap

Keywords

πŸ’‘Sub-programs

Sub-programs, also known as functions or procedures, are blocks of code designed to perform a specific task. They are central to the theme of the video, which discusses various aspects of sub-programs, including their design, calling mechanisms, and parameter passing. For example, the script mentions 'sub-programs' in the context of parameter parsing methods and how they can be called indirectly.

πŸ’‘Parameter Parsing

Parameter parsing refers to the way in which function parameters are handled in terms of data transfer between the caller and the callee. The video script delves into different modes of parameter parsing, such as 'in', 'out', and 'in-out', and their implementation models like 'pass by value' and 'pass by reference'. It is a fundamental concept for understanding data flow and manipulation within and across sub-programs.

πŸ’‘Formal Parameters

Formal parameters are the variables declared within a sub-program's definition that represent the values passed into the sub-program. They are crucial for defining what data a sub-program expects and how it interacts with the outside environment. The script uses the term in the context of explaining 'in mode', 'out mode', and 'in-out mode' parameters.

πŸ’‘Actual Parameters

Actual parameters are the specific values or variables that are passed to a sub-program when it is called. They correspond to the formal parameters within the sub-program's definition. The script explains how actual parameters interact with formal parameters during the sub-program call process.

πŸ’‘Pass by Value

Pass by value is a parameter passing technique where a copy of the actual parameter's value is made and passed to the sub-program. This method is discussed in the script as an 'in mode' parameter parsing technique, ensuring that changes made to the parameter within the sub-program do not affect the original value in the caller.

πŸ’‘Pass by Reference

Pass by reference allows a sub-program to access and modify the actual parameter directly, using a reference or pointer to the original data. The script explains this as a more efficient method in terms of memory and processing time, but it also introduces potential issues with side effects and unwanted aliases.

πŸ’‘Indirect Calling

Indirect calling of sub-programs occurs when the specific sub-program to be executed is determined at runtime rather than at compile time. The script mentions this in the context of event handling and demonstrates how function pointers in C++ and delegates in C# enable indirect calls, allowing for more dynamic and flexible code execution.

πŸ’‘Function Pointers

Function pointers in C++ are variables that store the address of a function, allowing for indirect function calls. The script provides an example of how function pointers can be declared, assigned, and used to call functions indirectly, which is essential for scenarios like implementing callbacks or event handlers.

πŸ’‘Delegates

Delegates in C# are types that reference methods with a particular signature, enabling method calls to be made indirectly. The script explains how delegates can be instantiated and used similarly to function pointers, but with the added feature of multicast delegates, which can chain multiple method calls.

πŸ’‘Shallow Binding

Shallow binding, also known as dynamic scoping, determines the referencing environment of a passed sub-program based on the most recent call in the execution stack. The script illustrates this concept by showing which variable's value would be printed when a sub-program is passed as a parameter and called within another sub-program.

πŸ’‘Deep Binding

Deep binding, or static scoping, resolves references to variables in a passed sub-program by looking up the variable in its defining scope, regardless of the current execution context. The script contrasts this with shallow binding, showing how the referencing environment affects which variable's value is accessed when a sub-program is called.

πŸ’‘Ad-Hoc Binding

Ad-hoc binding is a method for determining the referencing environment of a passed sub-program based on the specific call that passed the sub-program. Unlike shallow or deep binding, ad-hoc binding does not follow static or dynamic scoping rules but rather the context of the call itself. The script uses this concept to demonstrate different variable resolution behaviors when sub-programs are passed as parameters.

Highlights

Fundamental concepts of sub-programs and important terminology were covered, setting the stage for deeper discussion.

Design issues relevant to sub-programs, including local stack dynamic and static variables, were examined.

Parameter parsing methods were introduced, highlighting three modes: in mode, out mode, and in-out mode parameters.

Diagrams were used to illustrate the direction of data flow in in mode, out mode, and in-out mode parameters.

Two primary approaches for data transfer between caller and callee were discussed: physical copy of a value and transmission of an access path.

Five implementation models for parameter passing were presented, including pass by value, pass by result, and others.

Pass by value was explained with an example in C++, demonstrating how the actual parameter's value is copied into the formal parameter.

The disadvantages of pass by value, such as additional storage requirements and potential costly moves for large parameters, were discussed.

Pass by result was introduced as an auto mode parameter parsing technique, with an example in Ada illustrating its usage.

Potential problems associated with pass by result, including additional storage and order of parameters copying back, were highlighted.

Pass by value result, combining features of pass by value and pass by result, was explained with an example in Ada.

Pass by reference, an in-out mode parameter passing technique, was discussed with examples in C++ using pointers and references.

Efficiency of pass by reference was emphasized, noting its advantages in processing time and memory usage.

Disadvantages of pass by reference, such as slower access times and potential for unwanted side effects, were covered.

Pass by name, an in-out mode parameter parsing method using textual substitution, was introduced as an older approach.

An example was provided to illustrate the concept of pass by name, demonstrating late binding and its effects on runtime behavior.

Support for parameter parsing methods in various real-world programming languages was reviewed, comparing their approaches and limitations.

The importance of parameter type checking for reliability was discussed, contrasting older languages with modern ones.

The handling of multi-dimensional arrays as parameters, including mapping functions and dimension sizes, was explained.

Design considerations for parameter parsing, including efficiency and data transfer direction, were analyzed in terms of trade-offs.

The capability of passing sub-programs as parameters and the considerations for type checking and referencing environments was explored.

Different binding strategies for sub-programs, such as shallow, deep, and ad-hoc binding, were presented with examples.

Transcripts

play00:00

welcome to the second lecture on chapter

play00:03

nine of the textbook in the previous

play00:06

lecture we covered primarily some

play00:09

fundamental concepts related to

play00:11

sub-programs and also went through some

play00:14

important terminology that we'll be

play00:16

using through the remainder of the

play00:18

discussion on this chapter

play00:20

we also looked at a number of design

play00:23

issues that were relevant for sub

play00:24

programs and then finished off by

play00:27

looking at local stack dynamic as well

play00:31

as static variables within a local

play00:34

referencing environment of a sub program

play00:38

in this lecture we'll be continuing with

play00:40

our discussion on chapter 9.

play00:44

these are the topics that we'll be

play00:46

discussing in today's lecture we'll

play00:48

start off by looking at a variety of

play00:51

different parameter parsing methods

play00:54

in the most important aspect of the work

play00:57

that we'll be discussing today relates

play00:59

to parameters that are sub-programs in

play01:02

other words when a sub-program receives

play01:05

another sub-program as a parameter

play01:09

then related to parameters that are

play01:11

sub-programs we'll look at how

play01:14

sub-programs can be called indirectly

play01:17

especially when they've been passed to

play01:19

another sub-program

play01:23

we'll start off by discussing semantic

play01:25

models for parameter parsing

play01:28

so broadly speaking there are three

play01:30

modes for parameters

play01:33

we firstly have in mode formal

play01:35

parameters which are parameters within a

play01:38

subprogram definition that receive data

play01:42

from an actual parameter in a call to

play01:46

the sub program so this is the standard

play01:49

model for parameter parsing where we are

play01:52

sending data from the call into the body

play01:57

of the

play01:58

sub program by means of a parameter

play02:02

secondly we have out mode formal

play02:04

parameters which send data to an actual

play02:07

parameter

play02:08

in the subprogram call

play02:10

so these are essentially parameters that

play02:13

are used to send back a value to the

play02:17

caller

play02:18

and then in the third place we have in

play02:20

out formal parameters which both receive

play02:24

data from and send data to

play02:26

an actual parameter in a sub-program

play02:29

call

play02:32

here we have three diagrams that

play02:34

illustrate in mode out mode and in out

play02:38

mode parameters

play02:40

so for in mode parameters we see that we

play02:43

are sending data from the caller through

play02:46

to the callee

play02:48

in other words we are sending data from

play02:51

the actual parameters a b and c in this

play02:54

case to the formal parameters x y and z

play02:58

in the definition of the sum program

play03:02

out mode parameters work in the opposite

play03:04

direction so we're sending data from the

play03:06

callee

play03:07

out to the

play03:10

caller

play03:11

and in this case we are then sending

play03:13

data from the dummy variables in the

play03:16

definition of the sub program in other

play03:18

words x y and z

play03:20

to the caller by means of the actual

play03:23

parameters a b and c

play03:26

and then in out mode parameters work in

play03:29

both directions so they receive data

play03:31

from the caller into the callee and then

play03:34

send data back from the callee to the

play03:37

caller

play03:40

now that we've discussed the various

play03:42

modes available for parameters we have

play03:45

to consider how the actual transfer of

play03:48

data takes place between the caller and

play03:52

the cooli or vice versa

play03:55

so there are basically two approaches

play03:56

that can be used

play03:58

the first is a physical copy of a value

play04:02

so in this case two copies of the value

play04:04

exist at the same time both in the

play04:07

caller and the callee regardless of

play04:10

which direction the data transfer is

play04:12

happening in

play04:14

then secondly we have transmission of an

play04:17

access path to a value and in this case

play04:20

we have only one value that exists and

play04:23

we are essentially then passing through

play04:25

a reference or a pointer to that value

play04:30

so this gives us then five

play04:31

implementation models for parameter

play04:34

passing namely pass by value passed by

play04:37

result passed by value result passed by

play04:41

reference and pause by name and we'll be

play04:44

looking at each of these separately in

play04:46

the coming slides

play04:50

we'll start by looking at pause by value

play04:53

which is an in mode parameter parsing

play04:55

technique

play04:57

so with pass by value the value of the

play04:59

actual parameter is used to initialize

play05:02

the corresponding formal parameter

play05:05

so here we have an example in c plus

play05:08

plus of pass by value

play05:10

and up here we can see we have a

play05:12

definition of a sub program in this case

play05:15

a function its name is foo and it

play05:18

receives a single parameter which is an

play05:20

integer and is named a

play05:23

so a then is the formal parameter in

play05:26

this case

play05:27

here we have our main function

play05:30

and in it we have a variable called b

play05:33

which is an integer variable defined and

play05:35

it has an initial value of 12.

play05:39

now we call the foo function over here

play05:42

and pass through the variable b

play05:44

b being the actual parameter

play05:48

so inside the body of the foo function

play05:50

we take then our parameter that we have

play05:53

received namely a

play05:55

and we increment this by 2.

play05:59

now what's important to understand here

play06:01

is that in the call

play06:04

the value 12

play06:06

is copied from the variable b

play06:09

into the formal parameter a

play06:13

and then if we try to modify a inside

play06:16

the body of the foo function then this

play06:19

doesn't affect the variable b

play06:25

so how can pause by value be implemented

play06:28

well the normal approach is that it's

play06:31

done by means of copying which we saw on

play06:34

the previous slide so in other words we

play06:37

copy a value from the caller into the

play06:41

called sub program

play06:44

now it is also possible for us to

play06:46

achieve past by value by means of

play06:48

transmitting an access path in which

play06:51

case we would do it through a pointer or

play06:55

a reference however this approach is

play06:58

generally speaking not recommended

play07:00

because it's not easy to enforce right

play07:03

protection inside the called sub program

play07:07

rights protection is necessary because

play07:09

we don't want any modification in the

play07:12

call sub program to change the actual

play07:15

parameter where the call takes place so

play07:19

there has to be some mechanism for right

play07:21

protecting that parameters so that

play07:23

modifications can't be done inside the

play07:26

call sub program

play07:28

now disadvantages associated with

play07:32

physically copying

play07:34

the value from the caller to the call

play07:37

sub program is that additional storage

play07:40

is required and this is because as i

play07:42

previously mentioned

play07:44

we have the parameters stored two times

play07:48

once in the actual parameter and once in

play07:52

the formal parameter

play07:54

also the move can potentially be costly

play07:58

and this is especially the case for very

play08:01

large parameters so for example if we're

play08:04

passing a struct or a class that has a

play08:07

lot of fields within it each of those

play08:09

fields needs to be copied from the

play08:11

caller

play08:12

into the formal parameter in the call

play08:15

sub program and all of that copying can

play08:18

take up a lot of processing time

play08:21

now if we use an access path instead

play08:24

then there are also disadvantages

play08:26

associated with that approach so firstly

play08:29

as i previously mentioned we need to

play08:32

write protect

play08:33

the parameter in the called sub program

play08:37

also access can potentially be more

play08:40

costly in terms of processing time and

play08:44

this is because we are using a pointer

play08:46

or a reference and therefore we have to

play08:49

use indirect addressing to access the

play08:52

value and this then can take up some

play08:57

additional processing time

play09:02

next we'll look at pass by result which

play09:05

is an auto mode parameter parsing

play09:07

technique

play09:08

so with pass by result the value of the

play09:11

formal parameter is used to change the

play09:14

corresponding actual parameters value

play09:18

so over here we have an example in ada

play09:20

we are defining a procedure

play09:22

named a test

play09:24

and because it's a procedure this means

play09:26

that a test does not return a result but

play09:30

rather produces results through

play09:32

modifications to its

play09:34

parameters here we have in integer

play09:37

specified which tells us that the

play09:40

parameters a and b

play09:42

are in mode parameters that are passed

play09:46

by value as we discussed a moment ago

play09:49

we also have art integer which appears

play09:52

here which specifies that the c

play09:54

parameter

play09:55

is an out mode pass by result parameter

play10:00

inside the body of our a test procedure

play10:03

we have an assignment that takes place

play10:05

we are assigning a plus b

play10:08

to the variable c

play10:10

so this is allowed because a and b are

play10:12

in mode passed by value parameters so

play10:15

the data just gets then sent in to the

play10:18

procedure

play10:19

by means of its formal parameters and

play10:23

those values are then just used in this

play10:25

computation over here producing a result

play10:28

c can be assigned to because it is an

play10:32

out mode pass by result parameter

play10:36

so c is treated like an uninitialized

play10:39

local variable that we simply assign to

play10:42

so now let's look at the school over

play10:44

here where we are calling the a test

play10:47

procedure

play10:48

and we pass through these parameters

play10:51

over here

play10:52

so 5 plus p is computed and that's seen

play10:55

through as the parameter a

play10:58

and 48 is passed through as the

play11:01

parameter b

play11:03

q is a variable which is passed through

play11:06

as the third parameter the result of

play11:08

this thing is that the

play11:11

addition is performed inside the body of

play11:14

the a test procedure

play11:17

adding the first two parameters together

play11:20

we then assign the result to c

play11:23

which is then copied back to q

play11:26

and q's value is then overwritten by the

play11:29

value that has been assigned to c

play11:34

now let's look at how pause by result is

play11:37

implemented

play11:39

so as we saw on the previous slide the

play11:41

value of the formal parameter is used to

play11:44

change the corresponding value of the

play11:46

actual parameter

play11:48

what this means is no value is

play11:50

transmitted to the sub program and

play11:53

instead we only transmit data out of the

play11:56

subprogram to the caller

play11:59

so the pass then of data happens when

play12:02

control is returned to the caller

play12:06

and we implement this by means of a copy

play12:08

from the formal parameter in the sub

play12:11

program to the actual parameter in the

play12:15

call to the sub program

play12:17

so what i would like you to do now is to

play12:20

try to

play12:22

answer

play12:23

whether an access path can be

play12:25

transferred instead of performing a copy

play12:33

all right so i'll answer the previous

play12:35

question

play12:36

and the answer is that it is in fact

play12:39

impossible to transfer an access path we

play12:43

have to use a copy so what i would like

play12:45

you to do once again is to pause the

play12:47

video and try to explain why this is the

play12:51

case

play12:55

now there are some potential problems

play12:57

that are also associated with pass by

play13:00

result

play13:02

firstly

play13:03

we require additional storage space in

play13:06

memory and also potentially an expensive

play13:09

copy operation that needs to be

play13:11

performed

play13:12

this is exactly the same as the main

play13:15

drawback associated with pass by value

play13:19

and this is because we are using a copy

play13:22

operation

play13:23

we have some more subtle issues though

play13:25

as well

play13:26

so let's assume that we have a sub

play13:28

program called sub and we perform this

play13:31

call to sub you can see that we are

play13:34

passing through p1 both as the first

play13:37

parameter and as the second parameter

play13:40

now let's also assume that in the

play13:42

implementation for the sub sub program

play13:46

we have different names for the two

play13:49

formal parameters so for example we

play13:51

might have sub and then the first

play13:54

parameter would be called a and the

play13:56

second parameter would be called b

play13:58

so the question is then which value does

play14:01

p1 have after the score has completed

play14:05

and this depends on the order that the

play14:08

parameters are copied back in

play14:11

so do we copy the first parameter first

play14:14

and the second parameter second

play14:16

or vice versa

play14:18

now this may seem like an obvious

play14:21

question we might just

play14:23

handle it from left to right so then it

play14:26

will be the right most

play14:29

parameters value that will be copied

play14:31

back

play14:32

but this depends on the specific

play14:34

implementation sometimes due to compiler

play14:37

optimizations we will copy back the

play14:40

values in a different order so we need

play14:43

to address this somehow by at least

play14:45

making it appear consistent to the

play14:48

programmer who would be using this

play14:51

sub-program call

play14:54

here we have another potential issue and

play14:56

that may arise again illustrated by

play14:59

means of a simple example here we are

play15:01

calling a sub program called sub once

play15:04

again and again we are assuming

play15:06

different names for the two formal

play15:09

parameters

play15:10

but we are then passing through the list

play15:12

array at subscript sub and then passing

play15:16

through sub as the second parameter as

play15:19

you can see over here

play15:21

so the question then is what value does

play15:25

list at subscript sub have

play15:29

and this will be decided at either the

play15:33

start of the sub program or the end of

play15:35

the sub program so we may determine it

play15:39

by means of the subscript value that sub

play15:42

originally has before the call or we may

play15:46

be determining it based on the value of

play15:49

sub that is returned by means of the

play15:52

parameter at the end of the subprogram

play15:55

call

play15:58

next we have pass by value result which

play16:01

is used for in-out mode parameters

play16:05

so pass by value result combines pause

play16:08

by value and pause by result and it's

play16:11

sometimes also called pause by copy

play16:15

so in this case data is passed by means

play16:19

of the pause by value result parameter

play16:22

into the sub-program but we also then

play16:25

transmit data from the sub-program back

play16:29

to the caller

play16:31

so for this to happen formal parameters

play16:33

must have local storage that we can

play16:35

assign to

play16:38

so the drawbacks associated with pass by

play16:40

value results are a combination of the

play16:43

drawbacks associated with pass by result

play16:46

and pass by value

play16:49

now here we have

play16:50

a simple example in ada which is quite

play16:53

similar to the previous example that we

play16:56

looked at again here we've defined a

play16:59

procedure called a test

play17:02

and we are sending an in-mode parameter

play17:06

called a as the first parameter and an

play17:09

in-out mode parameter called c

play17:13

so c is a pass by value result parameter

play17:17

because it is used for in-out mode

play17:19

parameter parsing

play17:21

so now if we look at the body of our

play17:24

procedure

play17:25

we see that we are computing a result by

play17:29

adding c

play17:30

to a this is allowed because c is an in

play17:34

mode as well as an out mode parameter

play17:37

we can also assign 2c in which case the

play17:41

value will then be assigned to the

play17:44

formal parameter and copied to the

play17:46

actual parameter and this is also legal

play17:50

because once again c is a combination of

play17:53

an in mode and out mode parameter

play17:57

so in this case then the formal

play17:58

parameter c is used for two things

play18:01

it passes a value into the a test

play18:04

procedure but it can also be assigned to

play18:07

in which case we are then copying from

play18:10

the formal parameter to the actual

play18:13

parameter in the subprogram call

play18:18

the second last parameter passing

play18:20

technique that we'll look at is called

play18:23

pass by reference and you should also be

play18:25

fairly familiar with this technique

play18:28

pause by reference is also an in auto

play18:31

mode parameter passing technique

play18:34

so pass by reference passes an access

play18:36

path and it can do this by means of

play18:39

either a pointer or a reference pass by

play18:43

reference is also sometimes called pass

play18:46

by sharing

play18:48

so over here we have an example of pass

play18:51

by reference both by means of a pointer

play18:54

and a reference in c

play18:56

plus

play18:57

we have a sub program in this case a

play19:00

function called foo

play19:02

and it receives two parameters firstly p

play19:05

which is defined as an integer pointer

play19:07

in other words an integer memory address

play19:10

secondly we have r which is defined as

play19:13

an integer reference by means of the

play19:17

ampersand notation you can see over

play19:19

there

play19:20

so we can use then both the pointer or

play19:23

the reference inside the body of the foo

play19:26

function

play19:27

in the case of the pointer we must

play19:29

de-reference it first using the asterisk

play19:31

notation and then we can assign a value

play19:34

to it in this case 23. in the case of

play19:37

the reference r we can simply assign to

play19:40

it as though it's a normal variable and

play19:43

it doesn't require any dereferencing and

play19:45

here we're just assigning the value 19

play19:47

to this reference

play19:50

so both p and r in this example then can

play19:53

be used to pass data into the foo

play19:56

function whichever values the points or

play20:00

the reference have from the caller in

play20:03

other words derived from the actual

play20:06

parameter

play20:07

in the function call

play20:09

and both then p and r can also be used

play20:13

to send data back to the caller in other

play20:16

words through the formal parameters to

play20:19

the actual parameters in the function

play20:22

call

play20:25

now of course the big advantage

play20:26

associated with pass by reference is

play20:29

that it is very efficient

play20:31

and this is efficiency in terms of

play20:33

processing time but also in terms of

play20:36

memory usage

play20:38

so it is efficient in terms of memory

play20:41

usage because we don't have two copies

play20:44

of the data that is being passed to the

play20:47

sub program that exists in memory at the

play20:50

same time instead there's only one copy

play20:52

of the data and we simply pass through a

play20:55

reference to that data hence using less

play20:59

memory

play21:00

secondly it is more efficient in terms

play21:03

of processing time because we don't have

play21:06

to perform a copy on the data that is

play21:09

being passed because once again there is

play21:12

only one copy in existence and only a

play21:15

reference to it is passed to the sub

play21:18

program in question

play21:20

now this is of course not to say that

play21:22

there aren't drawbacks associated with

play21:25

pass by reference and this slide lists

play21:28

three such disadvantages

play21:30

so firstly if we compare pass by

play21:32

reference to pass by value then pass by

play21:35

reference is slower in terms of accesses

play21:39

to formal parameters and the reason for

play21:42

this is that we are using indirect

play21:44

addressing in order to retrieve a value

play21:48

rather than just accessing the value

play21:50

directly as we would in the case of pass

play21:53

by value

play21:55

secondly pause by reference introduces

play21:58

potential problems associated with

play22:00

unwanted side effects and we discussed

play22:03

this in quite a lot of detail in chapter

play22:05

15 so i won't spend time recapping this

play22:09

now however please refer to chapter 15

play22:12

if you need to refresh your memory about

play22:14

side effects

play22:16

in the third place pause by reference

play22:18

introduces the possibility of unwanted

play22:20

aliases and these aliases broaden access

play22:24

to values and allow for potential

play22:27

collisions to take place as a result

play22:30

so let's look at this function over here

play22:33

which is a function sub program in c

play22:37

plus

play22:38

the function is called fun and it has

play22:41

two parameters

play22:43

first and second which are both formal

play22:46

parameters and they are both integer

play22:48

references by virtue of the fact that

play22:51

they use the ampersand notation so now

play22:54

let's look at this call to the function

play22:57

where we are calling the fun function

play23:00

but we are passing through

play23:02

two

play23:03

actual parameters that are exactly the

play23:06

same total in both cases over here

play23:10

so what this means then is that first

play23:12

and second both refer to the same actual

play23:15

parameter namely total and are therefore

play23:19

aliases for the value of total

play23:22

so what i would like you to do at this

play23:24

point is to pause the video and try to

play23:26

explain what potential problems this

play23:29

aliasing could result in

play23:37

the last parameter parsing technique

play23:39

that we'll look at is also an in-out

play23:42

mode parameter parsing method named

play23:45

pause by name and this is definitely the

play23:48

most interesting out of the techniques

play23:50

that we've discussed so far

play23:52

so past by name uses textual

play23:55

substitution and it's a far older

play23:57

approach than the others and therefore

play24:00

not very widely used in modern

play24:02

programming languages now on this slide

play24:05

i'll define how pause by name works but

play24:08

it will become a lot clearer once we

play24:10

work through an example on the next two

play24:12

slides

play24:14

so essentially post by name works by

play24:17

taking all formal parameter occurrences

play24:21

and replacing them by the appropriate

play24:23

actual parameter

play24:25

now the formal parameters which have

play24:28

been replaced

play24:30

are then bound to an access method at

play24:32

call time and this axis method could

play24:35

either be a copy or a reference

play24:39

now the actual binding to a value or

play24:41

address only occurs when the formal

play24:44

parameters actually used in the sub

play24:46

program and this is very important

play24:48

because this allows us quite a lot of

play24:51

additional flexibility because it allows

play24:54

for a kind of late binding which will

play24:57

illustrate by means of the next example

play25:03

so let's illustrate pause by name by

play25:05

means of a simple example

play25:08

what we're going to do first of all is

play25:11

look at this example in terms of

play25:13

standard pass by value which we will

play25:16

then compare on the next slide to pass

play25:18

by name in order to illustrate the

play25:21

difference

play25:22

so in this example we have a sub program

play25:25

which is a c

play25:26

function named foo

play25:28

and it receives two parameters where the

play25:31

formal parameters are named a and b and

play25:34

both of them are integer values we'll

play25:37

get to the body of the free function in

play25:39

a moment so now let's look at our main

play25:42

function over here and our main function

play25:45

has a variable named vowel which has an

play25:47

initial value of zero

play25:50

then we have an array named arr which

play25:54

contains three values and these values

play25:57

are the values 2 8 and 9.

play26:00

so now we call our view function we pass

play26:03

through val as our first parameter

play26:06

and our array at subscript val as our

play26:10

second parameter

play26:12

so now if we assume normal pass by value

play26:14

what this means is we'll be passing

play26:16

through for our first parameter a value

play26:20

of 0 and for our second parameter will

play26:23

be accessing our array at subscript

play26:26

vowel which is zero so in other words we

play26:30

will be retrieving the first value which

play26:32

is two and passing that through as the

play26:36

second actual parameter

play26:39

so now inside the body of our view

play26:41

function we then receive a and b

play26:45

which we've just seen are the values 0

play26:48

and 2.

play26:50

and because this is passed by value

play26:52

we'll assume that these values have been

play26:54

copied into the foo function

play26:57

so now we set a's value to 1 and then we

play27:01

print out a and b

play27:03

so of course printing a out will print

play27:06

out 1 because we updated a's value by

play27:09

means of an assignment

play27:11

and then when we print out b we will be

play27:15

printing out the value 2 because that

play27:18

was the value that was sent through the

play27:20

actual parameter

play27:22

in the call to foo in the second

play27:25

parameter position over here

play27:29

so let's look at our previous example

play27:31

but this time assume that we are using

play27:33

pass by name rather than pass by value

play27:37

so what does it mean if we are using

play27:39

pass by name well it means we will

play27:42

perform textual substitutions where we

play27:45

substitute every occurrence of a formal

play27:48

parameter

play27:49

with the corresponding actual parameter

play27:52

so what this means is every occurrence

play27:55

of a in our foo function

play27:58

must be replaced with the corresponding

play28:01

actual parameter which is vel and

play28:04

similarly every occurrence of b

play28:08

must be replaced with the corresponding

play28:10

actual parameter which is the array

play28:13

accessed at subscript vowel

play28:16

so what does this thing mean well it

play28:19

means that the body of our

play28:22

foo function

play28:23

will change such that we are assigning

play28:26

one

play28:27

to vowel rather than a

play28:30

which i've noted at the bottom over here

play28:33

similarly the first parameter for our

play28:36

print becomes val as i've indicated at

play28:39

the bottom over here

play28:40

and the second parameter for our print

play28:43

becomes our array access that subscript

play28:46

val which i've indicated over here at

play28:49

the bottom again

play28:51

so what does this mean then for the

play28:53

output of our example

play28:55

well we are printing out firstly the

play28:58

value of the vowel variable as we've

play29:01

seen we've just assigned a value of 1 to

play29:03

it so that means our first output will

play29:06

be 1.

play29:08

our second output however will differ

play29:10

because we are accessing our array at

play29:13

subscript val and val currently has a

play29:16

value of 1 meaning that we're accessing

play29:19

our array at the second position

play29:22

namely the value 8 and that will then be

play29:26

the second value that we will print out

play29:28

to the screen

play29:30

now this is a kind of a late binding and

play29:33

it's a late binding in the sense that

play29:36

the access to our array which we are

play29:38

going to use to retrieve a value for

play29:41

printing is based on a variable called

play29:44

val and the value of this variable can

play29:47

obviously change at runtime based on

play29:50

this assignment so in other words the

play29:52

value that is accessed depends on what

play29:56

variable val has at runtime and is not

play29:59

determined prior to runtime for example

play30:02

at compile time

play30:04

so therefore this is a kind of a late

play30:06

binding in the sense that it is late

play30:08

because it happens at run time

play30:12

what's also important to understand is

play30:14

that the access mechanism used for the

play30:17

formal parameters can either be a copy

play30:21

or a reference

play30:23

now if it is a copy what this means is

play30:25

that this vowel that is being assigned

play30:28

to in the body of our foo function is in

play30:31

fact a copy of the vowel in our main

play30:36

function so what that means is that this

play30:38

assignment of one two vowel will not

play30:41

affect the vowel in main

play30:44

alternatively if a reference is used

play30:48

then the vowel that we are assigning to

play30:51

is in fact an alias for the vowel in the

play30:54

main which means that that variable's

play30:56

value will then also be changed now this

play31:00

of course doesn't affect this example

play31:02

but if we were to for example have an

play31:04

output of a val that occurs after the

play31:08

call to foo then that would differ

play31:11

depending on whether we were using a

play31:14

copy or a reference

play31:18

so that concludes our discussion on

play31:21

various parameter parsing methods

play31:23

and now we will look at some examples of

play31:26

real-world programming languages and how

play31:29

they provide support for a subset of the

play31:32

parameter parsing methods

play31:35

so in c we of course have standard pass

play31:38

by value and this takes place whenever

play31:41

we pass a variable

play31:43

to a function by means of a parameter

play31:46

and we don't use a pointer

play31:49

pass by reference is achieved when we

play31:51

use a pointer as a parameter

play31:54

now in c plus we also have pass by value

play31:57

but additionally we then also have

play31:59

pointers and references which can also

play32:02

be used for pass by reference parameter

play32:06

passing

play32:09

now java is interesting in the sense

play32:12

that you might have heard that

play32:14

everything in java is passed by value

play32:17

except for objects which are passed by

play32:19

reference now it turns out that this is

play32:22

not in fact strictly speaking true

play32:25

all parameters are passed by value in

play32:28

java now when it comes to objects then

play32:31

object parameters seem as though they

play32:33

are being passed by reference but what's

play32:35

actually happening is that object

play32:37

references are being passed by value

play32:41

now generally speaking for all intents

play32:43

and purposes this doesn't have any kind

play32:46

of impact and it seems that objects are

play32:49

being passed by reference however it

play32:52

does come into play if for instance we

play32:54

try to update an object reference that

play32:57

has been passed to a method and make

play33:00

that point to a new object in that case

play33:04

we are then assigning a new object to a

play33:07

copy of a reference which will not

play33:09

modify the original reference for

play33:11

further details on this i refer you to

play33:14

the notes on this slide where i have a

play33:16

worked example that illustrates why this

play33:20

concept is important to understand in

play33:22

java

play33:24

now ada has three transmission modes for

play33:27

formal parameters it has in mode

play33:29

parameters which can be referenced but

play33:32

not assigned to and this is the default

play33:35

mode so this is a pass by value

play33:38

pass by result is handled by means of

play33:41

out mode parameters and these can be

play33:45

assigned to but not referenced and then

play33:48

we have in out mode parameters which can

play33:51

be referenced

play33:53

and assigned to

play33:54

and these are pause by value result

play33:57

parameters

play33:59

fortran 95 and newer has a similar

play34:02

approach to what we see in ada where

play34:05

parameters can also be in mode art mode

play34:08

or in out mode parameters

play34:13

now c sharp uses pass by value as its

play34:17

default parameter parsing method it's

play34:20

also possible to use parts by reference

play34:22

and in this case both the formal

play34:24

parameter and the actual parameter must

play34:28

both be preceded by the special word ref

play34:31

php uses a similar approach to c-sharp

play34:35

so what i would like you to do now is

play34:37

once again pause the video and try to

play34:40

explain what effect the requirement that

play34:43

riff must appear before both the formal

play34:45

parameter and the actual parameter

play34:48

has on the programming language

play34:50

evaluation criteria we've been using

play34:52

through this course

play34:57

now perl is interesting in that it

play35:00

differs from the previously mentioned

play35:02

programming languages by implicitly

play35:05

placing all of the actual parameters

play35:08

from a subprogram call into a built-in

play35:11

array called at underscore

play35:15

now the elements of this at underscore

play35:17

array are then aliases for the actual

play35:21

parameters from the sub program call so

play35:24

what i would like you to do at this

play35:26

point is again pause the video and try

play35:28

to explain which parameter parsing

play35:31

method this implies

play35:33

in the sense that aliases are used for

play35:36

the elements in this built-in

play35:42

array finally both python and ruby use

play35:47

pause by assignment

play35:49

so with pause by assignment the actual

play35:52

parameter is assigned to the formal

play35:55

parameter

play35:57

now remember in both of these languages

play35:59

that all data values are objects and

play36:01

that assigning one object to another is

play36:05

simply a reference change so because we

play36:08

are assigning from the actual parameters

play36:12

in the call to a sub program

play36:15

and to the formal parameters in the

play36:19

definition of the sub program this means

play36:22

that we are essentially performing a

play36:24

pass by reference parameter pass and

play36:28

this is because a reference change is

play36:31

used in all cases

play36:33

now this can only not be the case when

play36:36

assigning to immutable objects as formal

play36:40

parameters so what i would like you to

play36:42

do at this point is to pause the video

play36:45

and try to explain what happens if we

play36:47

have an immutable parameter as a formal

play36:51

parameter in either python or ruby

play37:00

next we get onto the design issue of

play37:03

whether parameter type checking is

play37:05

required in a programming language

play37:09

so parameter type checking is a test to

play37:12

see whether an actual and a formal

play37:15

parameters types match one another this

play37:18

kind of match is very important for

play37:21

reliability

play37:22

now in older programming languages such

play37:25

as fortran 77

play37:27

early

play37:28

pre-1989 c

play37:30

perl javascript and php we see that no

play37:35

type checking was performed at all

play37:38

so what i would like you to do is to

play37:40

pause the video at this point and try to

play37:42

explain what effect this lack of type

play37:44

checking had on these programming

play37:47

languages

play37:52

all right so to answer this question

play37:54

let's look at early versions of c as

play37:58

well as c89 where it's maintained as a

play38:02

possible alternative versus c

play38:06

plus work in terms of type checking of

play38:10

parameters

play38:11

so in this initial approach on the left

play38:14

over here there's no type checking that

play38:16

is performed we can see

play38:18

that in the header for our sub program

play38:22

we've specified that the sign function

play38:24

has a return type of double it receives

play38:26

a single parameter called x

play38:29

in the following line we specify that x

play38:31

is a double value but this is not an

play38:34

enforcement so essentially what we are

play38:37

telling the compiler is that you should

play38:39

expect a double value but there is in

play38:42

fact no guarantee at all

play38:45

so what this means is that a value other

play38:47

than a double value could be seen

play38:49

through as a parameter and what would

play38:52

happen inside the body of this function

play38:55

would be that on a bit level the

play38:58

parameter value that had been sent

play39:00

through would be interpreted as a double

play39:02

value if in fact it wasn't a double

play39:05

value then the value that would be

play39:07

interpreted would bear no resemblance to

play39:10

the original value

play39:12

so this approach was used exclusively in

play39:16

the older versions of c and it's still

play39:18

maintained in c89 as an option however

play39:22

it's generally speaking not used in

play39:25

practice due to the fact that it is

play39:27

unsafe

play39:29

now the second approach over here is

play39:32

then also supported in c89 as well as in

play39:36

c

play39:38

so here again we can see that we have a

play39:40

sub program called sign it returns a

play39:43

double value and it has a single

play39:46

parameter called x but we've specified

play39:48

that the type of this parameter is a

play39:50

double

play39:51

so what happens here now is type

play39:54

checking is performed for this parameter

play39:57

if we try to pass a type that doesn't

play40:00

match for example a student object then

play40:03

an error will be raised at that point

play40:06

if we try to pass another numeric type

play40:09

that is not a double then the compiler

play40:12

will attempt to perform a coercion to

play40:14

convert it into a double value if the

play40:17

coercion can't be successfully performed

play40:19

then again there will be an error that

play40:21

will be raised but if the coercion can

play40:24

be performed then the program will

play40:26

simply continue assuming that that type

play40:28

conversion has taken place

play40:31

now what's important to understand is

play40:33

that this type checked approach is much

play40:36

safer than the original non-type checked

play40:40

approach and this is because the value

play40:43

will always be interpreted as a double

play40:46

it won't just simply be a conversion on

play40:49

a bit level

play40:52

now more modern programming languages

play40:54

like pascal fortran 90 java and ada

play40:58

always require parameter type checking

play41:01

to be performed so what i would like you

play41:03

to do at this point is to pause the

play41:05

video and explain what the effect of

play41:07

this requirement is

play41:12

now python and ruby

play41:14

are interesting in that variables don't

play41:16

have types but objects do

play41:19

so for example if we look at this line

play41:22

of code over here we have an assignment

play41:24

that is taking place and we are

play41:26

assigning to p

play41:28

a new person object now the object that

play41:31

is assigned to p has the type of person

play41:34

but the variable p has no type it is

play41:37

simply a reference to an object of some

play41:41

generic type

play41:43

so the formal parameters then are

play41:46

typeless for any subprogram and what

play41:49

this thing means is that formal

play41:51

parameters can't be type checked because

play41:54

they don't have types associated with

play41:57

them

play41:58

a similar kind of thing happens in java

play42:00

if we were to write a method that

play42:02

receives an object now we can pause to

play42:05

this method any particular object it

play42:08

could be a list it could be a person and

play42:11

there is no way that that can be type

play42:14

checked by the method what this means is

play42:17

that inside the method we could perform

play42:19

a cost which would then turn out to be

play42:21

an invalid cost at runtime

play42:24

so in that sense objects that are passed

play42:27

through two methods in java also can't

play42:30

be type checked exactly the same way as

play42:33

objects in python and ruby can't be type

play42:36

checked

play42:39

next we'll take a look at how

play42:40

multi-dimensional arrays can be passed

play42:43

as parameters to sub-programs

play42:46

so multi-dimensional arrays are

play42:48

obviously arrays of two dimensions or

play42:51

more

play42:52

now the compiler needs to be able to map

play42:55

array subscript references to values

play42:58

within the multi-dimensional array and

play43:01

in order to do this the compiler

play43:03

constructs a mapping function

play43:06

now this mapping function must know the

play43:08

size of all of the dimensions except for

play43:11

the first dimension which is equivalent

play43:13

to the number of rows in the structure

play43:16

within this multi-dimensional array

play43:19

now the reasoning behind this is the

play43:21

fact that arrays are stored in row major

play43:25

format so each row is stored as a single

play43:29

fixed length entity in memory and this

play43:31

is why the dimensions making up these

play43:34

rows must be known ahead of time

play43:37

again in the notes for this slide i

play43:40

provide a more concrete example of how

play43:43

this works in practice so please refer

play43:45

to that if you'd like more background

play43:47

detail

play43:48

now if the sub program can be separately

play43:51

compiled which is the case in languages

play43:54

like c and c plus plus then the array

play43:57

name on its own doesn't tell the

play44:00

compiler these dimension sizes that it

play44:03

needs to know in order to be able to

play44:05

correctly reference values in the

play44:07

multi-dimensional array structure and

play44:10

the compiler can only know the size of

play44:12

these dimensions from the sub-program

play44:15

text

play44:16

so what this means then is that the

play44:18

compiler needs to know the declared

play44:20

dimension sizes and these sizes must be

play44:24

provided within the program text itself

play44:30

so let's look at what this looks like in

play44:33

c and c plus in both of these languages

play44:36

we must include the sizes of all of the

play44:39

subscripts except for the first which

play44:42

represents the number of rows in the

play44:43

structure so here we have an example of

play44:46

a function definition and we can see

play44:49

that this function receives a

play44:51

two-dimensional array called matrix it

play44:53

stores integer values and we can see

play44:56

that for our first subscript we haven't

play44:59

provided a size but for the second

play45:01

subscript we have provided a size of 10

play45:05

that tin must be there in order for the

play45:08

compiler to be able to correctly

play45:10

reference values stored within the

play45:13

matrix

play45:14

now the big disadvantage associated with

play45:16

this is that it reduces the flexibility

play45:19

of our programming language and the

play45:21

reason for this is that in this example

play45:24

we can only receive a matrix that has 10

play45:28

columns if we want to be able to receive

play45:30

a matrix with 20 columns we need to

play45:33

define a new sub program with a

play45:35

different parameter in order to do that

play45:41

the solution in c and c plus plus to

play45:45

this problem of lack of flexibility is

play45:48

of course to pass our two-dimensional

play45:52

array as a pointer

play45:54

so we can then pass the dimension sizes

play45:57

as separate parameters as we see in this

play46:00

example over here so here we've passed

play46:03

through an integer pointer and this is a

play46:06

pointer to our multi-dimensional array

play46:09

we assume that it's a two-dimensional

play46:11

array and we then pass through integer

play46:14

parameters for both the number of rows

play46:17

and the number of columns in our

play46:19

two-dimensional structure

play46:21

inside the body of our function

play46:23

definition then we use pointer

play46:25

arithmetic in order to access the values

play46:29

that are stored within the

play46:30

two-dimensional array so what i would

play46:33

like you to do at this point is to pause

play46:35

the video and try to think of any

play46:37

disadvantages associated with this

play46:40

approach and how these disadvantages

play46:42

will affect the programming language

play46:44

evaluation criteria

play46:52

in java and c-sharp arrays are objects

play46:55

and are all single dimensional

play46:58

now of course arrays can be stored

play47:00

within arrays allowing us to create

play47:03

multi-dimensional array structures and

play47:06

therefore we are using an orthogonal

play47:08

approach to define our multi-dimensional

play47:11

array structures

play47:13

now each array in java or c-sharp has a

play47:18

named constant and this named constant

play47:20

represents the length of the array when

play47:23

the array is created the named constant

play47:26

in the case of java is length all

play47:29

lowercase letters and in the case of c

play47:32

sharp its length with an uppercase l

play47:35

so what this means is we can then by

play47:37

means of code actually query the array

play47:41

to find its length and therefore no

play47:44

sizes need to be specified in the formal

play47:48

parameters as was the case in c and c

play47:51

plus

play47:54

now there are two design considerations

play47:57

that come into play when we talk about

play47:59

parameter parsing

play48:01

the first is the relative efficiency of

play48:04

the parameter parsing technique or

play48:06

techniques supported by a programming

play48:08

language and the second relates to

play48:11

whether one-way or two-way data transfer

play48:14

is supported by the parameter passing

play48:17

technique or techniques supported by a

play48:20

programming language now unfortunately

play48:22

these two considerations are in conflict

play48:25

with one another and therefore there's

play48:27

usually a trade off between the two

play48:30

now good programming practice suggests

play48:32

that we should try to limit access to

play48:35

variables and therefore one-way

play48:38

parameters are generally preferable so

play48:41

what this implies is that we should

play48:43

rather use either pass by value or pass

play48:46

by result in order to send values into

play48:49

or retrieve values from a sub program

play48:53

however if we look at pass by reference

play48:56

we see that it is much more efficient

play48:58

than pass by value it is more efficient

play49:01

in terms of processing time because we

play49:03

don't have to go through an expensive

play49:05

copy operation each time that a

play49:07

parameter is passed and it's also more

play49:10

efficient in terms of memory space used

play49:13

because we don't have to maintain two

play49:16

copies of a past value at the same time

play49:19

however past by reference usually

play49:22

implies two-way parameters which is in

play49:25

conflict with our good programming

play49:27

practices

play49:29

so generally speaking some programming

play49:31

languages will choose to support only

play49:34

pass by value and possibly pass by

play49:36

result

play49:37

whereas other programming languages will

play49:40

support only pass by reference some

play49:43

languages support a mix of the two

play49:46

and c

play49:47

plus finds a good middle ground by

play49:50

allowing for references to constant

play49:53

values to be passed through

play49:55

two functions

play49:57

what this means then is that we have the

play50:00

general behavior of pass by value

play50:03

because we're not working with a memory

play50:05

address

play50:06

but we also then don't have the issue

play50:11

of two-way parameters because we are not

play50:15

allowed to modify the value that the

play50:18

reference refers to seeing as it is a

play50:21

constant value

play50:24

please refer to the notes for this slide

play50:26

for a practical example of how this

play50:29

approach would work in practice

play50:33

the next design issue related to some

play50:36

programs that we need to talk about

play50:38

relates to whether sub-programs can be

play50:41

passed as parameters but before we can

play50:44

get to that we need to talk about

play50:47

calling sub-programs indirectly

play50:50

so sub-programs are called indirectly

play50:52

when there are several possible

play50:54

sub-programs we can call and the correct

play50:57

one is not known until execution time

play51:01

a good example of this in practice is

play51:03

during event handling

play51:05

where we have a number of different

play51:07

events that can occur at run time for

play51:10

example a user may click on a button or

play51:13

they may press enter within a text entry

play51:17

field

play51:18

the exact course of action that the user

play51:21

will take cannot be known at compile

play51:23

time and therefore only occurs at run

play51:26

time at which point the correct event

play51:29

needs to be triggered and the event

play51:31

would be encapsulated inside a sub

play51:34

program so cnc plus plus supports

play51:38

calling sub programs indirectly through

play51:41

what are called function pointers

play51:44

and these are pointers to functions that

play51:46

include parameter and return types so

play51:49

over here we have a simple example of

play51:51

this in c plus

play51:54

we have a function called myfunc its

play51:57

return type is float and it has two

play52:00

parameters firstly a float parameter and

play52:03

then that's followed by an int parameter

play52:06

next we define a pointer called ptr we

play52:09

can see it's pointed because we use this

play52:11

asterisk notation and also notice that

play52:14

the pointer's name is surrounded by

play52:17

parentheses

play52:18

this is the function pointer we specify

play52:21

that the return type for the function

play52:23

pointer is a float and the parameters

play52:26

are a float followed by an int

play52:29

so now we can assign to this pointer any

play52:32

function as long as it satisfies the

play52:35

requirements that have been specified

play52:37

for the pointer in other words the

play52:39

return type must be a float and the

play52:42

first parameter must be float while the

play52:44

second parameter is an int now this of

play52:46

course is the case for my func and

play52:50

therefore we can assign my func to our

play52:53

function pointer ptr

play52:55

now what we can do is we can call ptr

play52:58

and we can pass through parameter values

play53:00

for that and this is then effectively

play53:03

indirectly calling the myfunc function

play53:07

through the pointer that we have defined

play53:11

which is a function pointer

play53:15

in c-sharp sub-programs are called

play53:18

indirectly through method pointers which

play53:21

are implemented as objects called

play53:23

delegates so in order to implement a

play53:27

delegate we first need to create a

play53:29

delegate type which we do in this

play53:32

example over here

play53:33

how our delegate type is called change

play53:37

and we specify that this is a public

play53:40

delegate with a return type of int and a

play53:43

parameter type of int as well

play53:47

so now we can instantiate a delegate

play53:50

object

play53:51

with a method that has the appropriate

play53:54

protocol that matches what has been

play53:56

defined for the delegate type so over

play53:59

here we have a static method called fun

play54:02

one it has a return type of int and a

play54:06

single parameter which is an int so

play54:08

therefore matches with our delegate type

play54:12

now we can create an instance of our

play54:14

delegate type this instance which is the

play54:17

delegate is called my change function

play54:20

its type is change which is the same

play54:23

type as the delegate type that we just

play54:25

defined

play54:26

and we can then assign to that a new

play54:29

change object and pass through fun1 as a

play54:33

parameter at this point my change

play54:36

function is now an alias for fun one so

play54:40

now much as we did with function

play54:43

pointers that we looked at on the

play54:44

previous slide we can call my change

play54:47

function which is the delegate pass

play54:49

through a parameter value of 12 and that

play54:53

is then an alias

play54:55

for a direct call to the fun one method

play55:00

now c sharp also supports multicast

play55:02

delegates and these are delegates that

play55:05

store several method pointers which are

play55:08

run in sequence

play55:10

so we can for example add another

play55:12

function to my change function we just

play55:15

use the plus

play55:17

equals operator and then specify a

play55:20

second method this method will then be

play55:23

added to the delegate and when we

play55:25

execute the delegate then fund one will

play55:28

be called first and then fund two

play55:30

afterwards it's important to note that

play55:32

fund fund2 must also return an integer

play55:35

value and receive only a single integer

play55:38

as a parameter

play55:41

now it is sometimes convenient for us to

play55:44

pass a subprogram name as a parameter

play55:48

and this allows us to pass one

play55:50

sub-program to another sub-program where

play55:52

the second sub-program will execute the

play55:55

first sub-program

play55:57

this of course then requires a way to

play55:59

call a sub-program indirectly which

play56:02

we've just discussed

play56:04

so there are two issues associated with

play56:07

passing sub programs as parameters

play56:10

firstly are the parameter types checked

play56:14

and secondly and most importantly what

play56:16

is the referencing environment for the

play56:19

past sub program we'll look at each of

play56:22

these in turn in the next few slides

play56:27

now of course support for parameters

play56:30

that are sub-programs differ from

play56:32

programming language to programming

play56:34

language

play56:35

cnc plus allow for a function to receive

play56:39

a function pointer as a parameter and

play56:42

this allows for functions to be passed

play56:45

to other functions

play56:47

the fact that function pointers are used

play56:49

allow for the parameters to be type

play56:52

checked and so what i would like you to

play56:54

do at this point is to pause the video

play56:56

and try to explain why this is the case

play57:02

now fortran 95 allows subprograms to be

play57:05

passed as parameters and it also type

play57:08

checks these parameters

play57:10

however ada and java don't allow

play57:12

parameters that are sub programs

play57:17

now we come to the most important part

play57:20

of this lecture which relates to the

play57:23

referencing environment of past

play57:25

subprograms

play57:26

so recall that a referencing environment

play57:29

is the set of all of the variables that

play57:32

are visible to a statement so in other

play57:34

words it's a set of the variables that

play57:37

the statement can reference now a past

play57:41

sub-program also has a referencing

play57:44

environment and this becomes important

play57:47

when the past sub-program refers to a

play57:50

variable but this variable is defined

play57:53

outside of the past sub-program and in

play57:56

this case we need to be able to

play57:58

disambiguate which variable is actually

play58:01

being referred to

play58:05

so we'll now illustrate the options

play58:07

available for the referencing

play58:09

environment of a past sub-program by

play58:12

means of a simple example

play58:15

in this example we have a sub-program

play58:17

called sub-one and sub-one has defined

play58:20

within it a variable called x which has

play58:23

a value of 1. it also has a number of

play58:26

nested sub programs defined within it

play58:29

namely sub 2

play58:31

sub 3 and sub 4. we then have at the

play58:35

bottom of sub 1 a call to sub 3.

play58:39

in sub 3 we have another variable x

play58:42

defined which has a value of 3 and we

play58:45

then call sub 4 but importantly we pass

play58:48

through sub 2 as a parameter 2 sub 4.

play58:53

sub 4 is defined over here and this

play58:56

receives a sub program as a parameter

play58:59

which is called sub x it also defines a

play59:03

variable called x which has a value of 4

play59:06

and it calls sub x

play59:09

now sub 2 that has been passed through

play59:11

in the call to sub 4 is defined up here

play59:16

and all that this does is it prints x

play59:19

out

play59:20

so the question now is which value of x

play59:23

is the one that is printed we can see

play59:25

that x hasn't been defined locally

play59:28

within sub two

play59:29

so one of the three initializations of x

play59:34

will be the one that will be referred to

play59:38

in sub two and this depends on the

play59:41

referencing environment for sub two so

play59:44

there are three possible approaches that

play59:47

can be used for determining the

play59:49

referencing environment for step two and

play59:52

these are shallow binding deep binding

play59:55

and ad-hoc binding we'll be looking at

play59:58

each of these in turn on the next three

play60:00

slides

play60:04

we'll first look at shallow binding

play60:07

so with shadow binding the referencing

play60:09

environment of the past sub program is

play60:11

the call that enacts the past sub

play60:14

program

play60:15

now in our example over here we can see

play60:18

that sub 3 calls sub 4 and passes

play60:22

through sub 2 as a parameter but sub 4

play60:26

is responsible for actually calling sub

play60:29

2 by means of its parameter sub x so sub

play60:33

4 is the sub program in acting the call

play60:37

to the past sub program so what this

play60:40

means is that the x that is referred to

play60:44

in sub 2 will be the x defined in sub 4

play60:48

which gives us a value of 4 that is then

play60:51

printed out to the screen

play60:54

now shadow binding is natural for

play60:56

dynamically scoped programming languages

play60:59

so what is the case in dynamically

play61:02

scoped programming languages we move

play61:04

backwards through the chain of called

play61:07

sub-programs until we encounter the

play61:10

variable that we are looking for now the

play61:12

order of the chord sub programs goes

play61:15

from sub 1 to sub 3 and then from sub 3

play61:18

to sub 4 and then from sub 4 to sub 2.

play61:22

so if the variable x is not defined in

play61:24

sub 2 then we look in the

play61:28

previous

play61:29

subprogram call in the chain which is 4

play61:32

and that gives us our variable value of

play61:35

4 4x which then gets printed out so this

play61:39

is why shallow binding is natural for a

play61:42

dynamically scoped programming language

play61:47

next we'll look at deep binding so with

play61:50

deep binding the referencing environment

play61:53

of the past stutter program

play61:55

is the past sub-programs definition

play61:58

itself

play61:59

so

play62:00

let's then look at our example over here

play62:03

the past sub-program is of course sub 2.

play62:08

so therefore we're looking at the

play62:09

referencing environment for sub 2. now

play62:12

of course x isn't defined within sub 2

play62:16

and therefore we need to look outside of

play62:19

sub 2's scope so let's assume that we

play62:22

use static scoping what this means then

play62:25

is that we need to look in the static

play62:27

ancestor of sub 2 which is of course sub

play62:31

1 because sub 2 is nested within sub 1.

play62:35

so in this case then we will be

play62:37

referring to the variable x defined in

play62:40

sub 1 which means we will be printing

play62:43

out the value of 1.

play62:46

now deep binding is natural for

play62:49

statically scoped programming languages

play62:52

and this is because we follow static

play62:55

scoping rules we look in the current

play62:59

scope and if the variable is not

play63:01

contained within that scope we look at

play63:03

the next static ancestor and then

play63:06

continue our search until eventually we

play63:08

find the variable that we are looking

play63:11

for

play63:13

finally we have ad hoc binding and here

play63:16

the referencing environment of the past

play63:19

sub program is the call statement that

play63:22

actually passed this other program

play63:25

so let's look at our example over here

play63:28

this is the call that actually passes

play63:31

the sub program to sub 4. so sub 2 is

play63:35

passed as a parameter to the sub 4 sub

play63:39

program

play63:40

so this will then be the referencing

play63:42

environment for sub 2 which means that

play63:45

this print for x will refer to the x

play63:49

defined within sub 3 and this will then

play63:52

be the value 3 that will be printed out

play63:56

to the screen

play63:57

ad hoc binding doesn't relate to either

play64:00

static or dynamic scoping at all

play64:04

all right so that concludes this lecture

play64:06

in the next lecture we will be

play64:08

continuing and concluding our discussion

play64:12

on sub programs

Rate This
β˜…
β˜…
β˜…
β˜…
β˜…

5.0 / 5 (0 votes)

Related Tags
Parameter ParsingSub-ProgramsProgramming ConceptsLecture SeriesDynamic ScopeStatic ScopeFunction PointersDelegatesType CheckingMulti-Dimensional Arrays