principles of programming languagesppl182/wiki.files/class/presentations/... · functional...
TRANSCRIPT
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)
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
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).
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
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 :-(
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)
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
38
Factorial
Define the factorial function using reduce, and range
import * as R from 'ramda';
R.range(1,5)
[ 1,2,3,4 ]
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)