Principles of Programming Languagesppl182/wiki.files/class/presentations/... · functional...

49
Collaboration and Management Dana Fisman 1 Principles of Programming Languages www.cs.bgu.ac.il/~ppl172 Lesson 3 - Processing Complex Data Types with TypeScript and JSON

Transcript of Principles of Programming Languagesppl182/wiki.files/class/presentations/... · functional...

Collaboration and ManagementDana Fisman

1

Principles of Programming Languages

www.cs.bgu.ac.il/~ppl172

Lesson 3 - Processing Complex Data Typeswith

TypeScript and JSON

2

How are values defined? Recall: there are primitive values and compound values

Atomic values are defined literally, using a string that represents them in all programming languages

Value Literal The number 17 17

The Boolean Value True True / tt / true

The string abcdef “abcdef”

Semantic

Element Syntactic

Element

requires

evaluation

is the

result of

evaluation

3

What about compound values?Value Literal

An array of 3 elements, first is “avi”

second is “bob”third is “john”

[“avi”, “bob”, “john”]

Languages like C++, Java provide no or very limited ways to specify compound values literally.

Java for the above semantic value :

ArrayList<String> names =

new ArrayList<String>(

Arrays.asList("avi", "bob", "John"));

Javascrip

t

Written

directly

Invocation of

constructor

methods

4

Complex Data Values in Javascript

By combining arrays and maps, one can construct expressive data structures in Javascript.

let person1 = {name:"avi", age:25}, person2 = {name:"beate", age:23}, csDept = { name:"CS", faculty:"Natural Sciences"}, course = { name:"PPL", dept: csDept, students:[person1, person2]} course

==> { name: 'PPL', dept: { name: 'CS', faculty: 'Natural Sciences' }, students: [ { name: 'avi', age: 25 }, { name: 'beate', age: 23 } ] }

5

Complex Data Values in Javascript

We can define the same compound-value directly

let ppl = { name: 'PPL', dept: { name: 'CS', faculty: 'Natural Sciences' }, students: [ { name: 'avi', age: 25 }, { name: 'beate', age: 23 } ]};

ppl.students[0].name;

{ name: 'PPL', dept: { name: 'CS', faculty: 'Natural Sciences' }, students: [ { name: 'avi', age: 25 }, { name: 'beate', age: 23 } ] }

==>'avi'

6

To create it in Java…

o We need to invoke new on every sub-component o We have to built it bottom up o We need to define classed for each sub-expression

class Person { private String name; private int age; ...}class Dept { private String name; private String faculty; ...}class Course { private String name; private Dept dept; private ArrayList<Person> students; ... public void addStudent(Person p) { students.add(p); }

public static void main(String[] args) { Person person1 = new Person("avi", 25); Person person2 = new Person("beate", 23); Dept csDept = new Dept("cs", "Natural Sciences"); Course ppl = new Course("ppl", csDept); ppl.addStudent(person1); ppl.addStudent(person2); }

}

7

Literal Representation - Pros and Cons

Representations by literals is much more concise much more flexible compound-values are easily manipulated as we will shortly see) encourages programmers to use the facility

Representations by literals does not carry with it a mechanism to check type compatibility

Cons

Pros

8

JSON - Java Script Object Notation

A concrete way to define compound-values using string (stricter subset of general Javascript compound-vales)

Used for data exchange in client-server communication, and serialization of values in databases (data is read/send in files)

The key parts of JSON are the stringify() and parse() methods which form the JSON interface.

There are JSON libraries in Java, C++, Python etc. (JSON plays a role similar to XML in enabling data exchange across heterogeneous processes).

9

JSON interface Defines two methods

JSON.stringify(o) maps a

value to a string

maps a string (in JSON syntax)

to a value.

JSON.parse(o)

10

JSON example

parse()

stringify()

11

JSON Syntax Restricts the general literals of Javascript by requiring that all keys in maps are written with double quotes

{ “a": 1 }

OK in JSON not OK in JSON

{ a : 1 }

JSON supports the following data types:

stringnumber booleannull

arraysmaps

atomic

compound

12

JSON Example

Having a unique way to represent the same

compound type makes comparison really easy

13

JSON Example

14

JSON nesting containers Compound data types in JSON are obtained using the containers map and array.

These two containers can be nested one within another (simply by applying the recursive definition).

15

Accessing sub-values

16

heterogeneous arrays Javascript and JSON arrays can be heterogeneous

17

Map and Array Mutators In Javascript, compound values are mutable.

This means that (in addition to accessing parts of a compound value) Javascript allows us:

to change the value of sub-components of a larger compound value and to remove sub-components

This makes real functional

programming difficult

In real functional

programming values are immutable

18

Deleting a sub-component

19

Changing a sub-component

20

Array Methods

In Javascript, some of the array methods are mutators, and some are not.

Sometimes it is hard to keep track which is which :-(

21

Array Mutators

reverse()

sort()

22

Array Mutators

push()

pop()

23

Array Mutators

unshift()

shift()

24

Array Method

concat() not a

mutator

25

Useful Array Methods length: returns the number of elements in the array

join(delimiter): returns a string with all the items of the array serialized with delimiter between them.

26

Useful Array Methods includes(x):

returns true if x is an element in the array, false otherwise

indexOf(x):

returns the index of x within the array, -1 if x is not in the array

27

Useful Array Methods slice(start, end): returns the corresponding sub-sequence of the array.

splice(index): splits the array at the index position, and returns the suffix of the array after index.

not a

mutator mutat

or

28

Higher Order Methods on Arrays and JSON

The Array interface includes higher order methods - methods which receive a function as an argument.

a.sort((a,b) => a > b) a.map(x => x*x) a.filter(pred) a.find(pred) a.findIndex(pred) a.every(pred) a.some(pred) a.forEach(f) a.reduce((acc, item) => transformer, init)

29

Higher Order Function - Example Sort

mutator

30

Higher Order Function - Example Sort

Sort by

name

Sort by

age

31

Higher Order Methods on Arrays and JSON

The Array interface includes higher order methods - methods which receive a function as an argument.

a.sort((a,b) => a > b) a.map(x => x*x) a.filter(pred) a.find(pred) a.findIndex(pred) a.every(pred) a.some(pred) a.forEach(f) a.reduce((acc, item) => transformer, init)

How do we iterate over array elements?

Using a counter variable i

Can we also iterate backwards?

Does it matter? 32

Declarative vs. Procedural

function cubes(numbers) { for (let i = 0; i < numbers.length; i++) { numbers[i] = cube(numbers[i]); }}

In FP we prefer to abstract away the way the array is traversed

We want a simple way to prescribe: “apply a certain operation on all elements of an array”.

This abstract operation is called map.

33

Declarative vs. Procedural

function cubes3(numbers) { return numbers.map(cube);}

cubes3([0,1,2]);

==> [ 0, 1, 8 ]

f(x1) f(x2) f(x3) f(x4) f(x5)

f f f f f

x1 x2 x3 x4 x5

array.map(f)

An higher order function to implement the useful pattern of iterating over an array and keeping only elements that satisfy a certain condition.

34

Filter

x1 x2 x4

x1 x2 x3 x4 x5

p?(x1) p?(x2) p?(x3) p?(x4) p?(x5)Yes Yes YesNo No

filter(p? , a)

==> [ 2, 4 ]

[1, 2, 3, 4].filter(isEven)

filter(isEven, [1,2,3,4])

==> [ 2, 4 ]

35

Reduce

acc1 x2 x3 x4 x5

array.reduce(f, init)

f: (acc, item) => transformer

acc0 x1 x2 x3 x4 x5

acc2 x3 x4 x5

acc3 x4 x5

acc4 x5

acc5

acc1 = f(acc0, x1)

acc0 = init

acc2 = f(acc1, x2)

acc3 = f(acc2, x3)

acc4 = f(acc3, x4)

acc5 = f(acc4, x5)returned

value

36

Sum using reduce

10 20 30 40 50

array.reduce(f, 0)

f: (acc, item) => acc + item

0 10 20 30 40 50

30 30 40 50

150

acc1 = f(0, 10)

acc0 = 0

acc2 = f(10, 20)

acc3 = f(30, 30)

acc5 = f(100, 50)returned

value

acc3 = f(60, 40)

60 40 50

100 50

37

Product

Define a product of an array using reduce

38

Factorial

Define the factorial function using reduce, and range

import * as R from 'ramda';

R.range(1,5)

[ 1,2,3,4 ]

39

Min

Define a min of an array using reduce

40

Max

Define a max of an array using reduce

41

Boolean OR

Define a boolean OR of a bit array using reduce

42

Boolean AND

Define a boolean AND of a bit array using reduce

43

Map

Define a map using reduce

44

Filter

Define a filter using reduce

45

Some

Define a some using reduce

46

Every

Define a every using reduce

47

Summary - Literals and Complex Values

Programming languages define as part of their syntax ways to describe literal expressions which are evaluated to values.

Javascript (and most dynamic programming languages which do not require type declarations for all variables) allows programmers to write literal compound expressions which encode compound values.

Compound values can be embedded recursively to yield complex data structures.

Javascript variables and data structures are mutable.

48

Summary - JSON JSON is a string serialization of Javascript values (atomic and compound).

The JSON interface includes 2 functions: JSON.stringify() and JSON.parse()

JSON values can include embedded arrays and maps in a recursive manner

JSON compound values can be taken apart

mutated

removed

a[1] m.k a[1].k

a[1].k = “foo”

delete a[1].k

49

Summary - Array Methods

Arrays include primitive methods to access and mutate them.

Arrays include higher-order methods which receive functions as parameters.

In particular, map(), filter() and reduce() are extremely useful.

length, join(delimiter), includes(x), indexOf(x),

slice(start, end), splice(index)