COS 333: Chapter 6, Part 2

Willem van Heerden
26 Aug 202159:30

Summary

TLDRThis lecture delves into various data types, focusing on arrays and their operations across different programming languages. It discusses heterogeneous arrays, array types like jagged and rectangular, and introduces associative arrays. The lecture also explores record types, tuple types, and list types, highlighting their uses and differences. It touches on performance implications of dynamic versus static data access and concludes with a look at list comprehensions and their applications in functional programming languages.

Takeaways

  • 📚 The lecture delves into various data types, continuing from the previous lecture, focusing on array types and their advanced operations.
  • 🔍 It differentiates between standard arrays and special types like associative arrays, which use keys for indexing instead of numerical indices.
  • 🌐 The concept of heterogeneous arrays is introduced, where elements can be of different data types, in contrast to the homogeneous nature of standard arrays.
  • 🤖 Programming languages like Perl, Python, JavaScript, and Ruby natively support heterogeneous arrays, while others can simulate them through object-oriented techniques.
  • 🧩 The lecture explains array operations across different programming languages, including APL, Ada, Python, Java, and Ruby, highlighting unique features like elemental operations.
  • 📏 A distinction is made between rectangular and jagged arrays, with the latter allowing rows of varying lengths, a feature supported by languages like C, C++, and Java.
  • 📉 The concept of array slices is explored, which allows for the extraction of substructures from an array, applicable mainly in languages that support rectangular arrays.
  • 🔑 Associative arrays are described as unordered collections indexed by keys, often implemented using hash tables for efficient data retrieval.
  • 🏷️ Records, or structs, are introduced as named fields aggregates, fixed in structure unlike the flexible key-value pairs in associative arrays.
  • 🔄 Records can be manipulated with operations like assignment, comparison, and initialization, with some languages like Ada supporting complex nested record structures.
  • 🔗 The lecture concludes with a discussion on list types, central to languages like Lisp, Scheme, ML, and F#, and the use of list comprehensions for sophisticated list initialization.

Q & A

  • What are the main topics covered in the second lecture on chapter 2 about data types?

    -The lecture continues the discussion on data types, focusing on special kinds of arrays, advanced array operations, associative arrays, record types, tuple types, and list data types.

  • What is a heterogeneous array and how can it be simulated in languages that do not natively support them?

    -A heterogeneous array is an array that can store elements of different data types. It can be simulated in other languages by using arrays that contain a generic data value, often through the use of polymorphism and object inheritance.

  • Can you explain the difference between rectangular and jagged arrays?

    -Rectangular arrays are two-dimensional structures where all rows and columns have the same number of elements, while jagged arrays allow rows to have varying numbers of elements, often represented as an array of arrays.

  • What is an array slice and in which types of arrays does it make sense to use it?

    -An array slice is a substructure of an array that retrieves part of the array as a single unit. It is applicable to rectangular arrays but not to jagged arrays due to their different internal representation.

  • How are associative arrays different from regular arrays?

    -Associative arrays are unordered collections of data elements indexed by keys, rather than having fixed numerical indices like regular arrays. They often use more complex data structures like hash tables for efficient data retrieval.

  • What are the two main design issues associated with associative arrays?

    -The two main design issues are the syntactic form of references to elements (how to specify the key for the value to be retrieved) and whether associative arrays have dynamic or static sizes.

  • What is a record type and how does it differ from an array?

    -A record type is a possibly heterogeneous aggregate of data elements referred to as fields, identified by names. Unlike arrays, records do not require elements to be of the same type, and access to fields is by name rather than by numerical index.

  • What is the purpose of the 'move corresponding' operation in the Ada programming language?

    -The 'move corresponding' operation is used to copy all fields from a source record to the corresponding fields in a target record. It does not require the two records to be of the same type, allowing for partial copying of data where only corresponding fields are copied.

  • Why is accessing fields within a record generally faster than subscripting in an array?

    -Accessing fields within a record is faster because field names are static and their memory locations are determined at compile time. In contrast, array subscripts are dynamic and require runtime computation to determine the memory location.

  • What are tuples and how do they differ from records?

    -Tuples are similar to records in that they store a number of fields, potentially of different types. However, the fields in a tuple do not have names associated with them, making tuples suitable for temporary storage of grouped values without the need for individual field access.

  • Can you describe the use of list comprehensions in Python and their advantage over regular list initialization?

    -List comprehensions in Python allow for sophisticated list initialization, including the ability to add conditions for the values to be placed into the list. This is more flexible and concise compared to regular list initialization, which often requires multiple steps and separate assignments.

Outlines

00:00

📚 Introduction to Advanced Data Types

The script begins the second lecture on chapter 2, focusing on data types. It recaps the concept of data types and the discussion from the previous lecture on primitive data types, character strings, user-defined ordinal types like enumerations, and an introduction to array types. The lecture will continue with an in-depth look at array types, including non-standard arrays and advanced operations, associative arrays, record types, tuple types, and list data types. The script also touches on the concept of heterogeneous arrays supported by scripting languages like Perl, Python, JavaScript, and Ruby, which contrast with the homogeneous nature of arrays in other programming languages.

05:02

🔍 Exploring Array Operations Across Languages

This paragraph delves into the array operations supported by various programming languages. It starts with APL, which has a wide range of operators for vectors, matrices, and scalars, including those for reversing, inverting, and transposing matrices. The Ada language is highlighted for its array assignment feature, which is a copy operation, and array catenation. Python's array assignments are discussed as reference changes without copying, and it is noted that Python, like Java, supports array catenation and element membership operations. Ruby's array operations, including catenation and elemental operations, are also mentioned, with an example of adding two arrays element-wise. The paragraph concludes with a discussion on the differences between rectangular and jagged arrays, explaining that rectangular arrays have uniform row and column sizes, while jagged arrays allow rows of varying lengths.

10:02

📈 Array Slices and Associative Arrays

The script introduces the concept of array slices, which are substructures of an array that can be extracted as single units, applicable to rectangular arrays. It explains that languages like C do not support slices due to their use of jagged arrays, while C++ simulates rectangular arrays through the 'valarray' class. Examples of array slicing in Fortran 95 for two-dimensional and three-dimensional arrays are provided. The paragraph then shifts to associative arrays, which are unordered collections of data elements indexed by keys. The differences in accessing data through keys versus traditional array indexing are discussed, and the use of hash tables as the underlying data structure for associative arrays is mentioned. Perl's implementation of associative arrays, called hashes, is used as an example to illustrate how key-value pairs are assigned, accessed, and deleted.

15:06

🏷️ Understanding Records and Their Syntax

This paragraph explores record types, which are heterogeneous aggregates of data elements identified by field names. It contrasts records with arrays and associative arrays, emphasizing that records have a fixed structure once defined. The paragraph discusses design issues related to records, such as the syntactic form of field references and whether records have dynamic or static sizes. Examples from COBOL, which uses level numbers for hierarchical record structures, and Ada, which supports nested records without enforced hierarchical structures, are provided. The discussion also covers how different programming languages reference fields within records, with COBOL using a nested notation and other languages like Ada using a dot notation.

20:08

🔄 Record Operations and Their Implications

The script discusses operations that can be performed on records, such as assignment, which copies corresponding fields from one record to another, and the requirement for matching record types on both sides of the assignment. It also touches on the concept of 'move corresponding' in the Global programming language, which allows for partial copying of data between records of different types based on matching fields. The paragraph concludes with a comparison between records and arrays, noting that arrays are typically used for homogeneous data and records for heterogeneous data, and that accessing fields in a record is generally faster than array element access due to the static nature of field names.

25:09

🎓 Records and Tuples in Various Programming Languages

This paragraph continues the discussion on data types by comparing records and tuples. It explains that tuples store heterogeneous data but differ from records in that their elements are not named. The use of tuples for temporary storage and their immutability in languages like Python is highlighted. Examples of tuple creation and manipulation in Python, ML, and F# are provided, showing how tuples can be created, accessed, and used in assignments and pattern matching. The paragraph also discusses the use of tuples in functional programming languages to return multiple values from functions.

30:11

📝 Diving into List Data Types and Their Operations

The script concludes the lecture by discussing list data types, which are ordered sequences of often heterogeneous values, typically represented as linked lists. It emphasizes the importance of lists in functional programming languages like Lisp, Scheme, ML, and F#, and provides examples of list operations in these languages, such as cons, car, and cdr equivalents. The paragraph also covers Python's list comprehensions, which allow for sophisticated list initialization with conditions and operations, and mentions the support for lists in C# and Java as generic heap dynamic collection classes.

Mindmap

Keywords

💡Data Types

Data types define the kind of data that can be stored in a variable and how the data is manipulated. In the context of this video, data types are the central theme, with various types such as primitive, character strings, enumerations, and arrays being discussed. The script delves into how different programming languages handle data types and the operations that can be performed on them, such as assignments and catenations.

💡Heterogeneous Arrays

Heterogeneous arrays are a type of array that can hold elements of different data types. The script mentions that languages like Perl, Python, JavaScript, and Ruby natively support these arrays, allowing for a mixture of element types within a single array structure. This is contrasted with the more common homogeneous arrays, which can only store values of one particular type.

💡Polymorphism

Polymorphism is a concept where a single interface can represent different underlying forms (data types). In the script, it is used to explain how languages that do not natively support heterogeneous arrays can simulate them using arrays of a generic data type, often an object type from which other classes inherit, allowing for the storage of any object that is a subtype of the object class.

💡Elemental Operations

Elemental operations refer to operations performed element-wise between corresponding elements of two arrays. The script provides an example of elemental operations in the context of Ruby, where the addition of two arrays results in a new array containing the sums of the corresponding element pairs from the original arrays.

💡Rectangular and Jagged Arrays

Rectangular arrays are two-dimensional arrays where all rows and columns have the same number of elements, while jagged arrays allow rows to have varying numbers of elements. The script explains that jagged arrays are internally represented as arrays of arrays, and languages like C, C++, and Java support them, contrasting them with the simpler rectangular arrays supported by FORTRAN and Ada.

💡Array Slices

Array slices are substructures of an array that allow a portion of the array to be referenced as a single unit. The script notes that array slices are useful in languages that treat arrays as single units, such as Fortran, and are not applicable to jagged arrays. It also explains that languages like C do not support slices because they only support jagged arrays.

💡Associative Arrays

Associative arrays, also known as hashes or dictionaries, are collections of data elements indexed by keys rather than numeric indices. The script discusses how these arrays are unordered and often implemented using hash tables for efficient data retrieval. Examples of associative arrays are given in Perl, where they are referred to as hashes.

💡Record Types

Record types are composite data types that allow the storage of multiple fields, each identified by a name. The script explains that records are fixed in structure once defined, with fields referred to by name rather than by index. It contrasts records with arrays, where elements are accessed by numeric indices.

💡Tuple Types

Tuples are similar to records in that they store a number of fields, potentially of different types, but differ in that the fields in a tuple are not named. The script mentions that tuples are often used for temporary storage in languages like Python and ML, where they allow functions to return multiple values easily.

💡List Types

List types, as discussed in the script, are ordered sequences of potentially heterogeneous values, often implemented as linked lists. The script highlights the importance of lists in functional programming languages like Lisp, Scheme, ML, and F#, where they are central to the language's operations and can be manipulated with functions like 'cons', 'car', and 'cdr'.

Highlights

Introduction to advanced data types, including array types, associative arrays, record types, tuple types, and list data types.

Discussion on heterogeneous arrays and how they differ from homogeneous arrays found in some programming languages.

Explanation of how scripting languages natively support heterogeneous arrays and the simulation of such structures in other languages.

Overview of array operations across different programming languages, including APL, Ada, Python, Java, and Ruby.

Introduction to the concept of elemental operations in array manipulation, as demonstrated with Ruby.

Differentiation between rectangular and jagged arrays, with examples and language support explanations.

The concept of array slices and their utility in languages that manipulate arrays as single units.

Associative arrays explained, focusing on their unordered nature and indexing by keys.

Design issues related to associative arrays, including syntactic form and dynamic or static sizes.

Support for associative arrays in scripting languages like Perl, Python, Ruby, and Lua.

Introduction to record types, their structure, and how they differ from associative arrays.

The use of level numbers in COBOL for hierarchical record structure and its impact on language evaluation criteria.

Orthogonal records in Ada and their implementation without enforced hierarchical structure.

Discussion on record field references and elliptical references in programming languages.

Operations on records, including assignment, comparison, and initialization with aggregate literals.

Comparison between arrays and records in terms of use cases, access speed, and simulation of records with arrays.

Introduction to tuple types, their similarities to records, and their use for temporary storage in functional programming languages.

Explanation of tuple immutability in Python and their use in functions returning multiple values.

List data types discussed, including their ordered sequence nature and representation as linked lists.

Support for lists in functional programming languages like ML, Lisp, Scheme, and their operations.

Python lists as heterogeneous arrays and their mutability compared to lists in other languages.

List comprehensions in Python, Haskell, and F# for sophisticated list initialization.

Support for lists in C# and Java as generic heap dynamic collection classes.

Transcripts

play00:01

this is the second lecture on chapter 2

play00:04

which deals with data types

play00:07

in the previous lecture we introduced

play00:09

the concept of data types and looked at

play00:12

a number of primitive data types

play00:15

we also covered character string types

play00:18

user-defined ordinal types where we

play00:20

specifically looked at enumerations

play00:23

and then finally we began our discussion

play00:27

on array types in this lecture we will

play00:30

continue with our discussion on data

play00:32

types

play00:35

this is an overview of what we'll be

play00:37

talking about in this lecture

play00:40

we'll begin by continuing our discussion

play00:43

on array types focusing on specific

play00:47

kinds of arrays

play00:49

that deviate slightly from the standard

play00:52

arrays that we looked at in the previous

play00:54

lecture and then we'll also look at some

play00:56

of the more advanced operations that are

play00:58

valid for array types

play01:01

we'll also then look at a special kind

play01:04

of array referred to as an associative

play01:07

array which departs quite substantially

play01:09

from standard arrays

play01:11

then we'll move on to record types

play01:15

tuple types and then we'll finish the

play01:16

lecture off with a coverage of list data

play01:20

types

play01:23

so we saw in the previous lecture that

play01:26

arrays are homogeneous in nature

play01:30

meaning that they can store values of

play01:34

one particular type and each value in

play01:37

the array must have the same type so

play01:40

some programming languages notably

play01:42

scripting languages such as perl python

play01:45

javascript and ruby will natively

play01:48

support what are referred to as

play01:50

heterogeneous arrays and these are

play01:53

arrays in which the elements do not need

play01:57

to be of the same type so in other words

play01:59

these arrays can store a mixture of

play02:02

elements each of which can have a

play02:04

different data type

play02:06

now

play02:07

these scripting languages that i

play02:09

mentioned before natively supports

play02:12

heterogeneous arrays but it is also

play02:15

possible to simulate this kind of array

play02:17

structure in a programming language that

play02:19

doesn't natively support them

play02:22

the reason for this is that these

play02:25

heterogeneous arrays are actually

play02:27

implemented as homogeneous arrays that

play02:30

contain a generic data value of some

play02:33

sort so for example we may have an array

play02:37

that contains object values

play02:40

now because

play02:41

we would typically have a situation

play02:43

where we have an object class

play02:46

and then a large number possibly all of

play02:49

the remaining classes in the programming

play02:51

language would inherit from this object

play02:54

class so what this means is if we create

play02:57

an array that contains instances of

play03:01

objects

play03:02

then this means that one can store any

play03:06

particular object that inherits from the

play03:08

object class in this array so this is a

play03:11

mechanism that is used then by means of

play03:13

polymorphism to simulate a heterogeneous

play03:17

array even though the array is actually

play03:19

behind the scenes still storing values

play03:22

that are all of exactly the same type

play03:27

we'll now take a brief look at the array

play03:30

operations that are supported in a

play03:33

variety of different programming

play03:35

languages

play03:36

first of all we'll look at the apl or

play03:39

apple programming language which we have

play03:42

already discussed earlier in this course

play03:45

so there we saw that apl or apple

play03:48

supports a very wide variety of

play03:51

different operators in fact there are so

play03:53

many operators

play03:54

that

play03:56

additional characters are required to

play03:58

represent these operators and these

play04:00

characters do not appear on a standard

play04:03

keyboard

play04:05

so apl or apple supports a very powerful

play04:09

set of operations for

play04:11

vectors matrices and scalars and these

play04:14

are all considered to be array

play04:16

operations so for example there's a

play04:19

single operator that can reverse column

play04:23

elements

play04:24

within a matrix there are also operators

play04:29

for inverting or transposing matrices

play04:32

for instance

play04:35

then if we look at the ada programming

play04:37

language we see that it supports array

play04:39

assignment now in ada array assignment

play04:43

is a copying operation

play04:45

so for instance if we assign an array b

play04:48

to an array named a

play04:50

then the result of this will be that the

play04:53

contents of b will be copied into array

play04:57

a

play04:59

it also supports array catenation so

play05:02

this is an operator that allows two

play05:05

arrays to be joined to create a new

play05:08

array which contains the union of the

play05:10

elements in the two previously existing

play05:13

arrays

play05:15

the python scripting language also has

play05:18

array assignments however in the case of

play05:20

python these assignments are only

play05:23

reference changes so in this case

play05:25

if we assign an array b to an array a

play05:29

then a will simply be an alias that

play05:32

refers to b

play05:35

and there is no copying operation that

play05:37

is performed through the assignment

play05:40

operation

play05:41

python also supports array catenation

play05:44

and element membership operations

play05:50

in a similar fashion to python which

play05:52

we've just discussed java also supports

play05:55

array assignments which are reference

play05:58

changes

play05:59

now if one wishes to create a copy of an

play06:01

array then java provides a clone method

play06:04

which can be called on an existing array

play06:07

and this will then create a duplicate

play06:10

copy of this array and this will be a

play06:13

deep copy that's entirely separate of

play06:15

the original array

play06:18

ruby also provides a variety

play06:20

of array operations including array

play06:23

catenation

play06:25

now fortune is relatively interesting in

play06:27

that it provides what are referred to as

play06:30

elemental operations

play06:32

so elemental operations are operations

play06:35

between pairs of array elements

play06:38

so for example if we use the addition

play06:41

operator to add two arrays then the

play06:44

result of this will be a third array

play06:47

which contains the sum of the element

play06:49

pairs in the two arrays that are being

play06:52

added

play06:53

so over here we have an example of a

play06:57

simple addition operation which is an

play06:59

elemental operation between two arrays

play07:02

here we have declared three arrays a b

play07:07

and c

play07:08

and we've specified that these arrays

play07:10

contain integer values and that they

play07:13

contain spaces for a total of three

play07:16

elements in each of these arrays

play07:20

so here we then initialize arrays a and

play07:24

b a contains the values 3 8 and 5

play07:28

whereas b contains the values 2 1 and 3.

play07:32

then finally we perform an addition

play07:34

operation between arrays a and b and

play07:37

this addition is an elemental operation

play07:41

we assign the result to c and what this

play07:45

will then produce is an array which will

play07:49

be stored in c and this array will

play07:51

contain the values 5 9 and 8. 5 is

play07:55

produced by adding three and two

play07:58

together

play07:59

nine is produced by adding eight and one

play08:02

together and finally eight is produced

play08:05

by adding five and three to each other

play08:11

the next distinction we need to make is

play08:13

between rectangular arrays and jagged

play08:16

arrays

play08:17

now both rectangular and jagged arrays

play08:20

relate to two-dimensional array

play08:22

structures in other words matrices the

play08:26

concepts can be extended to higher

play08:28

dimensional array structures but for

play08:30

simplicity we will assume

play08:33

two-dimensional structures for this

play08:35

discussion

play08:37

so as the name suggests a rectangular

play08:39

array is a two-dimensional matrix

play08:43

structure

play08:44

in which all of the rows have the same

play08:47

number of elements and all of the

play08:48

columns have the same number of elements

play08:51

and rectangular arrays are supported in

play08:54

fortran and ada

play08:57

now in contrast a jagged array or a

play09:00

jagged matrix is a two-dimensional array

play09:03

structure in which rows can have a

play09:06

varying number of elements

play09:09

now behind the scenes a jagged array is

play09:12

actually represented as an array

play09:15

containing other arrays where each of

play09:18

the contained arrays will then represent

play09:21

one row in the matrix structure

play09:25

so languages that support jagged arrays

play09:29

are c c plus plus and java and you

play09:32

should be relatively familiar with how

play09:35

multi-dimensional array structures are

play09:37

dealt with in these programming

play09:38

languages

play09:40

now what's important to understand is

play09:42

that it is obviously possible to use a

play09:45

jagged array structure in order to

play09:48

represent a rectangular matrix the

play09:51

difference between a rectangular array

play09:54

and a jagged matrix is that a

play09:57

rectangular array is a single syntactic

play10:01

unit

play10:02

so in other words it is a single data

play10:05

structure that represents a

play10:08

two-dimensional

play10:09

matrix structure in memory it does not

play10:13

consist of an array containing other

play10:16

arrays which represent the rows

play10:20

in the grid structure

play10:23

now some programming languages such as c

play10:25

sharp and if shop support both jagged

play10:29

and rectangular arrays

play10:31

so these languages give you maximum

play10:33

flexibility in terms of how these grid

play10:36

structures can be represented

play10:40

related to the rectangular arrays we've

play10:43

just discussed

play10:44

we also then have the concept of array

play10:47

slices

play10:49

so a slice is then a substructure of an

play10:53

array so very simply an array slice is a

play10:58

referencing mechanism that retrieves

play11:00

part of an array as a single unit

play11:04

now array slices are only actually

play11:07

useful in languages that manipulate

play11:09

arrays as single units so in other words

play11:13

they're only really applicable to

play11:15

rectangular arrays and do not make sense

play11:18

in the context of jagged arrays

play11:22

for this reason the c programming

play11:24

language doesn't support slices so what

play11:27

i would like you to do at this point is

play11:29

to pause the video and try to explain

play11:33

for yourself

play11:34

why it doesn't make sense for erase

play11:36

slices to be supported in a programming

play11:39

language like c

play11:41

that supports only jagged arrays

play11:46

right c plus does then support slices

play11:50

however this is only in the context of

play11:52

the vowel array class and the vowel

play11:55

array class is used to simulate

play11:58

rectangular arrays so c plus doesn't

play12:00

directly support rectangular arrays

play12:03

but through a class that is provided

play12:07

known as the vowel array class it can

play12:09

simulate the operation of rectangular

play12:12

array structures

play12:13

slices are then supported for instances

play12:17

of this class

play12:21

in order to illustrate how array slices

play12:23

work here we have a few examples in

play12:26

fortran 95

play12:28

so our first two examples at the top

play12:31

over here

play12:32

illustrate two-dimensional array

play12:35

structures in other words simple

play12:37

matrices

play12:39

so over here we have an array slice we

play12:43

are assuming that the two-dimensional

play12:46

array structure is named matte

play12:49

and then we specify first of all the

play12:51

subsection of rows and then the

play12:55

subsection of columns that we want to

play12:57

extract from our matrix

play13:00

so here we are specifying that we want

play13:02

to extract rows one two three

play13:05

and then column 2

play13:07

so that will then be the shaded portion

play13:10

of this matrix

play13:12

the next example

play13:14

over here illustrates a similar array

play13:16

slice so here we are again generating a

play13:20

slice of our matrix mat

play13:23

and we are specifying that we want to

play13:26

retrieve rows two and three

play13:29

and then columns one two three so that

play13:32

will then be this shaded

play13:35

portion of our matrix structure

play13:39

we can also create array slices of

play13:42

three-dimensional array structures in

play13:44

other words cubes so here we're assuming

play13:46

that we have a three-dimensional array

play13:48

structure named cube

play13:51

so again we then need to specify rows

play13:54

and columns just as we did with the

play13:56

two-dimensional matrices but we

play13:58

additionally then need to specify a

play14:01

depth or a z-axis dimension

play14:06

so over here we are then accessing row 2

play14:10

which we can see

play14:11

in this face of our cube we are

play14:14

accessing row two

play14:17

and then columns one two three so that

play14:20

will then be these three columns over

play14:23

here and then as far as the depth goes

play14:26

we're looking at the z-axis

play14:28

one to 4 which then gives us this plane

play14:33

cut through the center of our cube

play14:36

our last example over here again

play14:38

performs a slicing operation on our

play14:41

three-dimensional array structure named

play14:44

cube

play14:45

here we are accessing rows one two three

play14:49

and columns one two three so this will

play14:52

then be an entire

play14:54

face of our grid structure but in terms

play14:57

of depth

play14:59

we then look at

play15:02

depth or z-axis two to three so that

play15:05

gives us in

play15:07

these two faces

play15:09

over here which will be accessed through

play15:12

the slicing operation on our cube

play15:17

the next concept that we'll look at is

play15:20

associative arrays

play15:22

so an associative array is in an

play15:24

unordered collection of data elements

play15:27

which are indexed by an equal number of

play15:30

values where these values are referred

play15:33

to as keys

play15:35

now it's important to understand that

play15:38

unordered in this context is a little

play15:40

bit of a misnomer there obviously must

play15:42

be some ordering to how the keys and

play15:46

their associated values are organized

play15:49

the point is that there isn't an

play15:51

intrinsic order you can't for example

play15:54

extract key and value pairs in the order

play15:56

that they were inserted and they also

play15:59

aren't indexes that are available to

play16:01

access a specific position within an

play16:04

associative array

play16:07

instead

play16:08

what happens is behind the scenes there

play16:10

is an organizational scheme

play16:13

but this organizational scheme is

play16:15

designed to allow for very efficient

play16:18

retrieval

play16:19

and

play16:20

accessing and manipulation of the data

play16:24

that is stored in the associative array

play16:26

so in general a more complex data

play16:29

structure will be used behind the scenes

play16:31

in order to handle the storage of keys

play16:35

and associated values within an

play16:37

associative array and a fairly commonly

play16:39

used approach is to use a hash table

play16:42

data structure

play16:44

now obviously an associative array must

play16:47

then store the keys as well as the data

play16:50

element values

play16:52

so this requires the additional storage

play16:55

to be allocated for the keys that will

play16:58

be associated with the values

play17:01

the

play17:02

indexes are then effectively the keys

play17:05

and there aren't then implicit indices

play17:08

the way that there are with regular

play17:11

arrays that we've spoken about

play17:12

previously

play17:14

so there are two main design issues that

play17:16

are associated with these associative

play17:19

arrays

play17:20

firstly what is the syntactic form of

play17:24

references to elements in other words

play17:26

how do you specify the key

play17:29

for the value that you want to retrieve

play17:32

and then the second design issue is do

play17:35

associative arrays have dynamic or

play17:38

static sizes

play17:41

again this relates then to a similar

play17:44

question that arises with regular array

play17:47

structures as to whether they will be

play17:48

static or dynamic in nature

play17:52

now associative arrays are very commonly

play17:55

supported in scripting languages so we

play17:57

see that there's built-in support for

play18:00

associative arrays by means of a

play18:02

specific type in perl python ruby and

play18:06

lua

play18:08

now in lua associative arrays are

play18:10

supported by means of the table data

play18:13

structure whereas in perl these are

play18:16

referred to as hashes

play18:20

on this slide we have a few examples of

play18:24

how associative arrays are handled in

play18:27

the perl programming language

play18:30

so in perl any name that begins with a

play18:33

percentage symbol

play18:36

is then considered to be a hash and in

play18:38

other words an associative array we can

play18:42

then perform an assignment to our hash

play18:45

so in this case we have a hash named

play18:47

high teams

play18:49

and we can then assign to that in

play18:52

parentheses a set of key value pairs so

play18:56

first we list the key then we have an

play18:58

arrow operator and then the value

play19:01

associated with that

play19:03

so in this associative array we then

play19:06

have three key value pairs

play19:08

the first key is the string man and

play19:11

associated with that is the value 77

play19:15

which is a numeric value the second key

play19:18

is 2 and associated with that we have

play19:22

the value 79 and then finally we have

play19:25

the key weight which again is a string

play19:28

and associated with that we have the

play19:30

value 65.

play19:33

now subscripting is then done by means

play19:36

of braces within which we list the key

play19:39

that we want to access

play19:41

so over here we are working with our

play19:44

high temps

play19:46

hash or associative array

play19:49

we use a dollar symbol to indicate that

play19:52

we are referring to a scalar value

play19:56

within

play19:57

our hash

play19:58

we then specify in braces the key that

play20:02

we want to access which in this case is

play20:04

the string width and then we can assign

play20:07

a value to that so in this case

play20:10

we are then replacing the initial value

play20:14

associated with the key weight which was

play20:17

65

play20:19

and we are replacing that with the value

play20:21

83

play20:23

we can also remove elements using the

play20:26

delete special word

play20:29

so this will then delete a key as well

play20:32

as its associated value so in this case

play20:36

we are accessing the high temps hash

play20:39

again we use a dollar symbol because we

play20:42

are referring to a scalar value within

play20:44

this hash

play20:46

we then use the delete special word and

play20:49

we specify then in braces the key that

play20:53

we want to delete so this will then

play20:55

delete the key 2 as well as the value 79

play21:00

associated with that key

play21:04

the next data type that we'll look at is

play21:07

the record type

play21:09

so a record is a possibly heterogeneous

play21:12

aggregate of data elements now what sets

play21:17

the support from arrays is that the data

play21:19

elements are referred to as fields and

play21:22

they are identified by means of names

play21:26

a record does not have the same kind of

play21:29

structure as an associative array which

play21:32

we've just discussed because associative

play21:34

arrays may have any number of key value

play21:37

pairs

play21:38

once a record has been defined to

play21:40

contain a certain number of fields with

play21:43

specific individual names for those

play21:46

fields then the record is fixed with

play21:49

that structure

play21:51

now there are two design issues that

play21:53

arise if we decide to implement records

play21:56

in a programming language

play21:58

firstly what is the syntactic form of a

play22:02

field reference so in other words what

play22:05

kind of syntactic notation is used in

play22:07

order to refer to a field within a

play22:11

record

play22:12

and then secondly our elliptical

play22:14

references allowed now we'll get to what

play22:17

exactly elliptical references are in a

play22:20

moment

play22:23

now kobold was the first high-level

play22:25

programming language to support records

play22:28

and in fact to support nested record

play22:30

structures

play22:32

so in kobold level numbers are used to

play22:35

show the hierarchical structure of

play22:37

record

play22:38

so in this example

play22:40

at level one we have our employee record

play22:45

the employee record consists of two

play22:48

fields and these are both at level two

play22:52

so firstly we have the employee name

play22:55

and then we have the hourly rate and the

play22:58

hourly rate then has a type associated

play23:00

with it which indicates that it is then

play23:04

a decimal value

play23:06

and this specifies the format of the

play23:09

decimal value

play23:11

the employee name then consists of three

play23:14

nested fields and each of these are then

play23:16

at level five

play23:18

so we have then the field first the

play23:21

field middle and the field last each of

play23:24

these also will then have a type

play23:27

associated with it so here we are

play23:29

specifying the length of the string in

play23:32

other words the number of characters

play23:34

and so first then has space for 20

play23:36

characters middle has space for 10 and

play23:40

last has space for 20 characters

play23:44

now what i would like you to do at this

play23:45

point is to pause the video and try to

play23:48

answer what effect on the language

play23:50

evaluation criteria does the use of

play23:54

level numbers in cobol have

play24:00

as an alternative to the nested record

play24:03

structure

play24:04

that we discussed in the context of

play24:06

cobol

play24:07

we have orthogonal records

play24:10

so these are supported by most languages

play24:14

that

play24:15

provide support for records

play24:18

other than kerbal

play24:20

and what we see here is that we use

play24:23

records that are contained within

play24:26

existing records so in other words we

play24:28

don't have an enforced hierarchical

play24:30

structure with level numbers

play24:33

so here we have an example of this in

play24:36

ada first of all we need to define the

play24:39

types that we'll be working with so the

play24:41

first type

play24:42

is referred to as employee name type and

play24:46

this is defined as a record and we can

play24:49

see that this consists of three fields

play24:52

namely first middle and last each of

play24:54

which is a string with a particular

play24:57

length associated with it

play24:59

we then end that record definition and

play25:02

then move on to our next type definition

play25:04

which specifies a record named employee

play25:08

record type

play25:10

so employee record type then has an

play25:13

hourly rate associated with it which is

play25:15

a floating point value but more

play25:18

importantly we have another field named

play25:22

employee name and the type of this field

play25:25

is employee name type

play25:28

so employee name type as we saw was

play25:31

defined up here and this means that we

play25:34

then have a nested record structure we

play25:37

have one entirely self-contained record

play25:41

namely the employee name type which is

play25:44

nested inside another record

play25:49

which is the employee record type

play25:52

so what we can then do is we can define

play25:54

a variable named employee record and we

play25:57

specify that its type is employee record

play26:00

type this will then allow us to set the

play26:04

fields as well as the nested records

play26:07

fields within the employee record

play26:10

variable

play26:14

now we'll move on to the two design

play26:16

questions for records

play26:18

so firstly we need to consider the form

play26:22

of record field references

play26:25

now cobol uses this kind of notation

play26:28

over here which relates to the previous

play26:31

example that we've just discussed

play26:33

and here the of special word is used to

play26:37

indicate

play26:39

records and how they relate to one

play26:41

another

play26:42

now in cobol we start with the innermost

play26:47

field and then move outwards so here we

play26:50

are specifying that we want to access

play26:52

the middle field which is contained

play26:55

within the employee name field which is

play26:58

contained inside the employee record

play27:03

now other programming languages other

play27:05

than kobold use a dot notation and this

play27:09

works in the opposite direction to

play27:12

cobol's field references

play27:14

so we start off with the containing

play27:17

record and then move inwards until we

play27:19

reach the field that we want to access

play27:23

so here we are accessing the employee

play27:27

record and then we use the dot notation

play27:30

over here and specify that we are trying

play27:33

to access the field named employee name

play27:36

within the employee record

play27:38

within the employee name

play27:41

which is in a field which references a

play27:45

contained record we then want to access

play27:48

the field middle

play27:51

now as far as support for elliptical

play27:54

references go we first need to discuss

play27:58

what the alternative is to elliptical

play28:00

references

play28:02

so a fully qualified reference is then a

play28:06

reference to a field where all of the

play28:09

record and field names

play28:12

must be listed explicitly so this is the

play28:16

case in most programming languages that

play28:18

support records for example in ada if we

play28:22

want to access the field middle then we

play28:26

would need to go through the employee

play28:29

record first and then the employee name

play28:32

there is no shortcut

play28:34

now kobold supports elliptical

play28:36

references and this is a shorthand

play28:38

notation and this allows a programmer to

play28:42

leave out record and field names if the

play28:45

reference is unambiguous

play28:49

so for example in cobol each of these

play28:52

three will be equivalent as long as

play28:55

first is unique and unambiguous so we

play28:59

can just directly access first as long

play29:02

as there is no conflicting

play29:04

occurrence of the field name first we

play29:08

can then just access it directly we

play29:10

don't need to qualify it in terms of

play29:14

further fields and record names

play29:18

and we can also then

play29:20

access first within employee name and

play29:24

thus leaving out employee record or we

play29:27

can access first within employee record

play29:31

thus leaving out employee name

play29:34

so what i would like you to do at this

play29:35

point is to pause the video and try to

play29:40

determine

play29:41

what language evaluation criteria are

play29:43

affected either positively or negatively

play29:46

by allowing support for elliptical

play29:49

references

play29:54

now of course there are a variety of

play29:56

operations that can be executed on

play29:59

records

play30:00

of these operations assignment is

play30:02

probably the most common

play30:04

and this will then copy corresponding

play30:07

fields from a source record to a

play30:10

destination record

play30:12

so the record on the left side of the

play30:14

assignment will receive the data from

play30:18

the

play30:18

record fields of the record on the right

play30:21

hand side of the assignment

play30:24

now in general the types on both sides

play30:26

of the assignment must be identical so

play30:29

in other words the record type on the

play30:31

left side of the assignment must match

play30:34

the record type on the right side of the

play30:36

assignment

play30:38

so what i would like you to do at this

play30:40

point is to pause the video and try to

play30:43

explain why it makes sense

play30:46

that the record types on both sides of

play30:48

the assignment should be equivalent to

play30:51

one another

play30:52

and then also try to

play30:56

explain

play30:57

how a programming language would

play31:00

implement

play31:01

a situation where records of different

play31:04

types are allowed on the two sides of

play31:07

the assignments in other words the

play31:08

record types on the left side and the

play31:10

right side of the assignment do not

play31:13

match

play31:14

the answer to this second question will

play31:17

be dealt with in more detail later on in

play31:20

our discussion on this chapter where we

play31:22

talk about type equivalence

play31:26

now the ada programming language allows

play31:28

for records to be compared to one

play31:30

another and again here the corresponding

play31:33

fields in the records are compared to

play31:36

one another one at a time

play31:38

if all of the fields match then the

play31:41

records are considered to be equivalent

play31:43

to one another and if not then the

play31:47

records are considered to not be

play31:48

equivalent to one another

play31:50

it also allows for record initialization

play31:53

with aggregate literals so essentially

play31:56

what this means

play31:57

is something similar to array

play31:59

initialization where in the declaration

play32:02

of the record

play32:03

an assignment can then

play32:06

be placed and this assignment will then

play32:09

allow a series of literals to then be

play32:12

assigned into the fields of the record

play32:15

in one go so this is in contrast to most

play32:20

other programming languages

play32:22

where

play32:23

we would have to explicitly set the

play32:25

values for each of the record fields by

play32:28

means of separate assignments until

play32:31

eventually we have then assigned to all

play32:34

of the fields within a record

play32:36

obviously this latter approach where we

play32:39

perform a series of assignments is much

play32:41

more verbose and requires more code than

play32:44

simply using an initialization

play32:47

where the values of all of the fields

play32:49

are set in one go

play32:52

now the global programming language

play32:54

provides a move corresponding operation

play32:58

and this is similar to an assignment it

play33:00

copies all of the fields of the source

play33:03

record to the corresponding fields in

play33:05

the target record however it is not

play33:08

necessary that the two records be of the

play33:12

same type

play33:14

so in other words what might happen is

play33:16

we might have a record that contains

play33:19

information related to a bank account

play33:22

and there may be a field in the record

play33:24

amongst other fields which is

play33:28

called name

play33:29

we might then also have an employee

play33:32

record and the employee record may also

play33:34

have a field called name

play33:37

so what would then happen with a move

play33:39

corresponding is that the name field

play33:41

would be then copied from the source

play33:43

record to the destination record in

play33:45

other words from the bank account record

play33:48

to the employee information record

play33:52

this filling takes place for all

play33:54

corresponding fields

play33:57

and fields that don't match between the

play34:00

two records will not be copied

play34:03

so in other words the then result in a

play34:06

partial copying of data

play34:08

where all of the relevant data that

play34:10

corresponds between two records will be

play34:12

copied across but the rest of the data

play34:15

will be left as is

play34:17

so what i would like you to do at this

play34:19

point is again pause the video

play34:21

and try to explain why the move

play34:24

corresponding operation makes sense

play34:27

for the cobol programming language in

play34:30

particular think about what the cobol

play34:33

programming language was intended for in

play34:35

terms of its original design and what it

play34:38

is still used for today

play34:44

to finish off our discussion on records

play34:47

let's compare them to arrays

play34:50

so in general one would use arrays when

play34:53

the values that one wants to store are

play34:55

homogeneous in other words of the same

play34:57

type and one would use records when the

play35:00

data values that one wants to store are

play35:03

heterogeneous

play35:05

now it's also important to note that

play35:07

array element access is a bit slower

play35:10

than accessing fields within a record

play35:14

the reason for this is that subscripts

play35:17

are dynamic and they can be for example

play35:21

variables

play35:22

where the values of the variables can

play35:24

change through the course of runtime and

play35:27

therefore computing the location in

play35:30

memory that a particular subscript

play35:32

refers to must be dynamic and must occur

play35:35

during runtime

play35:37

on the other hand field names are static

play35:40

in nature

play35:41

and this is because the fields within a

play35:44

record are fixed at compile time in

play35:48

other words prior to run time

play35:51

so what this means then is because

play35:54

dynamic operations are in general slower

play35:56

than static operations subscripting is

play36:00

slower than accessing fields directly

play36:04

now subscripts in an array can be used

play36:07

to simulate record fields dynamically

play36:11

and here then array subscripts need to

play36:14

refer to heterogeneous values that are

play36:17

stored within an array

play36:19

so what i would like you to do at this

play36:20

point is to pause the video and try to

play36:23

answer how you would go about achieving

play36:27

this kind of approach with an array

play36:30

where an array is effectively used to

play36:33

simulate a record

play36:37

right well quite simply we would either

play36:40

use a heterogeneous array structure if

play36:43

it is provided by the programming

play36:45

language alternatively if we have an

play36:48

object-oriented programming language

play36:50

then we can create an array that stores

play36:54

objects

play36:55

where our object class would then be the

play36:58

superclass that all other classes that

play37:01

we can use would inherit from

play37:04

so this would then mean that we can then

play37:06

store in the array any object that has a

play37:10

class which inherits from the object

play37:13

class

play37:15

now there are two main drawbacks

play37:17

associated with this kind of approach

play37:20

firstly it disallows type checking so

play37:23

what i would like you to do at this

play37:24

point is to pause the video

play37:26

and try to explain why using a

play37:31

heterogeneous array

play37:33

in order to simulate a record would

play37:36

disallow type checking

play37:40

now secondly of course as far as

play37:42

drawbacks go this approach would be much

play37:45

slower and the reason of course is that

play37:47

we are using an array rather than a

play37:50

record

play37:51

so this means that we are then accessing

play37:54

data values

play37:56

at runtime dynamically as opposed to

play38:00

statically and as i've previously

play38:02

explained dynamic operations are

play38:04

generally slower than static operations

play38:06

so therefore using a heterogeneous array

play38:10

in order to simulate a record will in

play38:13

general be somewhat slower in terms of

play38:16

execution time

play38:20

the next data type that we'll look at is

play38:23

the tuple type

play38:25

so tuples are fairly similar to records

play38:28

they in other words store a number of

play38:31

fields and these fields can have

play38:33

different types so they allow you to

play38:36

store heterogeneous data however the

play38:39

difference between a tuple and a record

play38:42

is that in a tuple the elements are not

play38:45

named in other words the fields don't

play38:47

have names associated with them

play38:49

so as a result of this tuples are

play38:52

generally used for temporary storage

play38:55

where a number of values need to simply

play38:57

be grouped together and handled as a

play39:00

single unit

play39:02

and one doesn't need to individually

play39:04

access the fields within the tuple

play39:08

now tuples are often used in scripting

play39:11

languages for instance they're supported

play39:14

in python

play39:15

but also in the ml functional

play39:18

programming language and the f-sharp

play39:20

functional programming language

play39:23

in all of these languages they are used

play39:27

by functions in order to return multiple

play39:30

values so again here what we see then is

play39:33

a number of values are grouped together

play39:35

as a single package and this package is

play39:38

then returned by a function which

play39:40

effectively allows them multiple values

play39:43

to be returned but once these values

play39:45

have been returned the tuple is no

play39:47

longer necessary and one can then just

play39:50

simply retrieve the data from the tuple

play39:52

and then use it as necessary

play39:55

so let's focus on python then for a

play39:58

moment

play39:59

and in python tuples very closely

play40:02

resemble lists however lists are mutable

play40:06

so in other words the values contained

play40:09

in a list can be changed whereas tuples

play40:12

in python are immutable in other words

play40:15

once the values have been set then they

play40:17

can no longer be changed

play40:19

so again this then highlights the fact

play40:22

that tuples 19 to justice temporary

play40:24

storage mechanisms

play40:27

now

play40:28

but we can create a tuple in python

play40:30

using a tuple literal

play40:33

in this example over here this is the

play40:35

tuple literal so we have a tuple that

play40:38

contains three values

play40:40

three which is an integer value 5.8

play40:43

which is a floating point value and then

play40:46

the string apple

play40:48

so once these values have now been set

play40:50

they cannot be changed and this is then

play40:54

assigned to a variable called my tuple

play40:57

which will then hold the tuple that has

play40:59

been created

play41:01

now referencing to the values contained

play41:04

in a tuple you use subscripts in a

play41:06

similar fashion to arrays

play41:09

so for instance if we access my tuple at

play41:12

index or subscript 1 then this refers to

play41:17

the first value contained in the tuple

play41:20

namely the value 3 which as we've seen

play41:23

is an integer value

play41:25

we can also concatenate tuples together

play41:28

using the plus operator

play41:31

and this allows us thing to add two

play41:33

tuples to one another a new tuple is

play41:36

then created and this tuple contains the

play41:39

elements from both of the tuples that

play41:41

appeared on the left and the right hand

play41:43

side of the addition operator

play41:47

now as i've previously mentioned tuples

play41:50

in python are immutable so it's not

play41:52

possible to remove individual items from

play41:55

tuples

play41:56

however there is a double operation

play41:59

which deletes a tuple completely

play42:04

the ml programming language is

play42:06

relatively similar to python in terms of

play42:10

its support for tuples

play42:12

so this is the notation that is used

play42:14

when a tuple is created you can see that

play42:16

it's relatively similar to python's

play42:19

approach

play42:20

again we have a literal that defines the

play42:23

values that are stored in the tuple once

play42:26

again we store the values 3 5.8 and the

play42:29

string apple

play42:30

and then we assign this to

play42:34

my tuple

play42:36

which is in a name that will refer to

play42:39

the tuple that has been created

play42:42

notice that ml is functional programming

play42:44

language so again we don't use the

play42:47

terminology variable

play42:50

we just simply refer to a name for a

play42:52

value

play42:54

now in order to access the first element

play42:56

in my tuple this is the notation that

play42:58

would be used so we use a hash symbol

play43:02

notation once again with the number

play43:05

referring to the specific

play43:08

value within the tuple that we want to

play43:11

access once again this will then access

play43:14

the first value in the tuple namely

play43:16

three

play43:18

now we can also define a tuple type

play43:22

and that's done using this kind of

play43:24

notation over here

play43:26

so here we are creating a new type that

play43:29

is called into real and we specify then

play43:32

that the interval type is a tuple and

play43:36

this tuple stores an integer value and a

play43:40

real value

play43:42

we can now use this interval type

play43:45

wherever a type can appear

play43:47

within ml so for example we can use

play43:50

interview as the type

play43:53

of a function parameter for instance

play43:59

f-sharp as we've previously mentioned

play44:01

also supports tuples

play44:03

and this is the notation that is used

play44:06

for creating a tuple you can see it's

play44:09

relatively similar to what we saw

play44:12

before in ml and in python

play44:16

so here we are associating the name type

play44:20

with a tuple that contains three values

play44:23

namely three five and seven

play44:26

now we can in f sharp perform an

play44:29

assignment and from a tuple to a tuple

play44:33

pattern and that's done in this example

play44:36

over here so here we're taking our

play44:39

existing tuple that contains the values

play44:41

three five and seven

play44:43

and we are then assigning it to

play44:46

this tuple pattern over here so we can

play44:49

see that there are three names in our

play44:51

tuple pattern a b and c

play44:54

the result of this is that the values

play44:56

contained in our tuple namely 3 5 and 7

play45:01

will then be assigned in order to each

play45:05

of the names in our tuple pattern so in

play45:08

other words a will receive the value 3

play45:12

b will receive the value 5 and c will

play45:16

receive the value 7.

play45:20

now we'll move on to the final data type

play45:24

that we will be discussing in this

play45:26

lecture namely the list type

play45:30

so a list is an ordered sequence of

play45:33

values where the values are oftentimes

play45:36

heterogeneous in nature in other words

play45:39

the values have different types

play45:42

and typically a list is represented as a

play45:46

linked list data structure behind the

play45:48

scenes

play45:49

now of course as we've previously

play45:51

mentioned lists are very central to the

play45:54

lisp and scheme programming languages

play45:57

and we've discussed how lists are

play45:59

represented and the operations that are

play46:02

legal for lists

play46:04

in our discussion on chapter 15. so i'm

play46:08

going to reiterate

play46:10

that information here

play46:12

in order to refresh your memory please

play46:14

refer to the lectures on chapter 15.

play46:19

the ml programming language is a

play46:21

functional programming language just

play46:24

like lisp and scheme and therefore also

play46:27

supports list types which are fairly

play46:30

central to the programming languages

play46:32

operation

play46:34

so lists are then written inside square

play46:38

brackets

play46:39

and the elements within the square

play46:41

brackets are then separated by means of

play46:44

commas

play46:45

however it's important to note that list

play46:48

elements

play46:49

are all have to be of exactly the same

play46:52

type

play46:54

so ml has an equivalent operation to

play46:58

schemes cons function

play47:00

and this is the binary double colon

play47:03

operator

play47:05

so this is the way that the operator

play47:07

would be used we can see on the left

play47:10

hand side there's numeric literal three

play47:13

and on the right hand side we have a

play47:15

list

play47:16

and this will then perform a cons like

play47:20

operation which will then insert the

play47:22

value 3 at the head of the list and the

play47:25

result will then be this list with the

play47:28

additional element in the first position

play47:31

in the list

play47:33

there are also equivalents for schemes

play47:37

car and cuda functions in ml

play47:40

these are named hd and tl respectively

play47:45

so this is an example of how the

play47:48

hd operation would be used in ml we can

play47:52

see that we apply hd

play47:55

to a list five seven and nine and this

play47:59

will then extract the first element in

play48:01

the list namely the value five

play48:04

which the entire application then of

play48:08

head would evaluate too

play48:10

tl is used in a fairly similar fashion

play48:13

so here we are applying tl

play48:15

to a list containing the values five

play48:17

seven and nine this will then extract

play48:20

the first element namely 5

play48:24

from our list and then as a result will

play48:28

then evaluate to the remaining values in

play48:31

the list so we get then as a final

play48:33

result the list containing the values

play48:35

seven and nine five is not included in

play48:39

that resulting list

play48:44

if sharp is also a functional

play48:46

programming language and as such also

play48:48

supports lists in much the same way as

play48:51

the previously discussed functional

play48:53

programming languages do

play48:56

now lists in f-sharp are fairly similar

play48:58

to those in ml so again square brackets

play49:02

are used to delimit the beginning and

play49:04

the end of a list

play49:07

however elements are separated by means

play49:10

of semicolons rather than commas

play49:13

now the binary double colon operator is

play49:16

also provided in if sharp and works

play49:18

exactly the same way as in ml

play49:23

now there is also an equivalent to the

play49:25

car

play49:26

function in scheme as well as the kuder

play49:29

function in scheme

play49:31

please note that the notation that's

play49:33

used here is correct for standard

play49:36

f-sharp

play49:38

and

play49:39

what is published in the textbook is

play49:42

incorrect so please take note of this

play49:44

when studying for

play49:46

tests or for the exam

play49:49

so the equivalent thing to the car

play49:51

function in scheme

play49:53

is list dot head and here we've applied

play49:56

that to a list containing the values one

play49:59

two and three so this will again extract

play50:02

then the first element in the list and

play50:05

the application of list dot head will

play50:07

then evaluate to this value namely one

play50:11

in this example

play50:13

the equivalent of the cuda function in

play50:15

scheme is similar to list dot head it's

play50:19

list dot tail here we have applied this

play50:22

to a list containing the values one two

play50:24

and 3. so this will evaluate to the

play50:27

remainder of the list with the head

play50:30

element

play50:31

removed so in other words only the

play50:33

values 2 and 3 will then be included in

play50:37

the resultant list that is produced by

play50:40

the application of list dot tail

play50:45

the python scripting language also

play50:48

supports lists and in python lists are

play50:51

the same thing as heterogeneous arrays

play50:54

now python's lists are mutables in other

play50:57

words the values that are contained

play51:00

within the list can be changed

play51:03

and this is unlike lists in the scheme

play51:06

common lisp ml and if sharp programming

play51:10

languages all of which have immutable

play51:13

lists in other words values cannot be

play51:15

changed within lists in these

play51:17

programming languages

play51:19

now elements in python lists can be of

play51:22

any type

play51:24

and one can also create a list by means

play51:27

of an assignment so that's done in this

play51:29

example over here here we are assigning

play51:32

a series of values notice that we use

play51:35

square brackets in order to denote the

play51:38

beginning and the end of the list

play51:40

and then my list as a variable will then

play51:44

store a list containing these three

play51:47

values

play51:48

notice that the values are all of

play51:50

different types so we have an integer

play51:53

value as the first element a floating

play51:56

point value is the second element and a

play51:58

string as the third element

play52:03

list elements in python lists are

play52:06

referenced by means of array-like

play52:09

subscripts so this explains why we said

play52:13

previously that lists in python are the

play52:16

same thing as heterogeneous arrays

play52:20

indices begin at zero much like regular

play52:23

arrays in most programming languages so

play52:26

for example if we want to set the

play52:28

variable x to contain the second value

play52:33

in the my list list

play52:36

then we would access this list at

play52:39

subscript one using the square brackets

play52:42

notation this would then retrieve the

play52:45

value 5.8 from the list and then assign

play52:49

that to the variable x

play52:52

list elements can also be deleted in

play52:55

python and here we use the dell special

play52:59

word this is an example over here so

play53:01

this would then delete the second

play53:05

element contained within our list namely

play53:09

5.8 once again

play53:14

now we mentioned in the previous lecture

play53:16

that array initialization in python is

play53:19

handled by means of list comprehensions

play53:23

so now we will actually discuss what a

play53:26

list comprehension is essentially a list

play53:29

comprehension allows us to perform an

play53:31

initialization of a list but do this in

play53:34

a fairly sophisticated fashion where we

play53:37

can attach for instance conditions to

play53:40

the values that will be placed into our

play53:43

list

play53:44

so over here we have an example of an

play53:47

assignment to a list comprehension the

play53:49

list comprehension is this latter part

play53:52

over here in square brackets and this

play53:55

list comprehension will then generate a

play53:57

list for us which we will then assign to

play54:00

the variable named list

play54:04

so how do we then evaluate this list

play54:06

comprehension well first of all we have

play54:09

a variable x

play54:11

and we consider then x values in a range

play54:15

defined by the value 12. so what this

play54:18

means is that x will take on the values

play54:21

0 to 12 inclusive of 12.

play54:26

now we have a condition which is

play54:28

optional and this is associated with the

play54:32

x values

play54:33

and so we only consider x values

play54:37

where x mod 3 is equivalent to zero so

play54:41

in other words we are only taking values

play54:44

in the range 0 to 12

play54:46

where the value is divisible by 3. so in

play54:50

other words x will then take on the

play54:53

values 0 3 6 9 and finally 12.

play54:59

now what we do is we can then

play55:03

perform an operation on these x values

play55:07

and that is the first part of the

play55:09

comprehension over here

play55:10

where we are computing x asterisk

play55:13

asterisk two so this operation in python

play55:17

is x raised to the power of 2.

play55:21

so what we then do is we take each of

play55:23

these values that x will take on 0 3 6 9

play55:28

and 12

play55:29

and we then raise those to the power of

play55:33

two

play55:33

these values are then placed into the

play55:36

list that is then assigned to the

play55:38

variable named list

play55:40

so in other words zero squared will give

play55:43

us a result of zero three squared will

play55:46

give us a result of 9 6 squared gives us

play55:49

36 9 squared gives us 81 and 12 squared

play55:54

gives us 144.

play55:56

so now each of these results the

play55:58

squaring operation will be placed into a

play56:02

new list which is then assigned to the

play56:04

variable

play56:05

list and therefore list will contain the

play56:08

values 0 9 36 81 and 144

play56:14

so we can see here then that list

play56:16

comprehensions allow for a very

play56:18

sophisticated initialization of the

play56:20

values contained in our list and this is

play56:23

much more complex than for instance

play56:26

regular array initialization would allow

play56:29

in the majority of programming languages

play56:35

list comprehensions are also supported

play56:37

in the haskell

play56:39

and if sharp programming languages

play56:42

haskell once again is a functional

play56:45

programming language so this is an

play56:47

example of a list comprehension in

play56:49

haskell

play56:51

and essentially what we are doing here

play56:53

is using in as our index variable and in

play56:57

takes on values ranging from 1 to 5

play57:00

inclusive of both of those values we

play57:03

then compute the square of each of those

play57:07

values and that will then be placed in a

play57:10

new list

play57:11

so in other words this list

play57:13

comprehension then defines a list

play57:15

containing these values over here the

play57:18

way we arrive at these values is that

play57:20

one squared gives us a result of one

play57:23

two squared gives us a result of 4

play57:25

3 squared is 9 4 squared is 16 and 5

play57:29

squared is 25.

play57:33

list comprehensions in if sharp can be

play57:35

used in order to create arrays and the

play57:38

notation is seen in this example over

play57:42

here

play57:43

so here we are associating the name my

play57:46

array with the result of this list

play57:49

comprehension over here

play57:51

and we

play57:52

then have values of i which will be our

play57:56

index variable

play57:57

and these then

play57:59

are generated in the range 1 to 5

play58:02

inclusive of both of those values and

play58:05

then we compute the square of i in each

play58:09

case so once again that will then result

play58:12

in a list containing the same values

play58:15

that we saw in our previous example

play58:18

where we were looking at haskell

play58:21

this will then

play58:23

associate the resultant list with the

play58:26

name

play58:26

my array

play58:30

finally both c-sharp and java's support

play58:34

lists

play58:35

both of these programming languages the

play58:37

lists are implemented as generic heap

play58:39

dynamic collection classes so they're

play58:42

implemented as linked lists which are

play58:44

generic in nature in other words they

play58:47

store a generic type t which can take on

play58:50

within any particular type that is

play58:53

stored in the linked list

play58:56

in c sharp the class is the list class

play59:01

and the arraylist class is used in java

play59:05

all right so that concludes then our

play59:08

discussion for this lecture in the next

play59:11

lecture we'll be finishing off the

play59:14

chapter and we'll discuss unions

play59:17

pointers and references

play59:18

the concepts underlying type checking

play59:22

strong versus weak typing type

play59:25

equivalence and then finally type theory

Rate This

5.0 / 5 (0 votes)

Related Tags
Data TypesArray OperationsAssociative ArraysRecord TypesTuple TypesList ComprehensionsHeterogeneous DataPolymorphismFunctional ProgrammingScripting Languages