CS代考程序代写 Erlang Elixir Java python C/CPS 506

C/CPS 506
Comparative Programming Languages Prof. Alex Ufkes
Topic 4: Functions & control flow in Elixir

Notice!
Obligatory copyright notice in the age of digital delivery and online classrooms:
The copyright to this original work is held by Alex Ufkes. Students registered in course C/CPS 506 can use this material for the purposes of this course but no other use is permitted, and there can be no sale or transfer or use of the work for any other purpose without explicit permission of Alex Ufkes.
© Alex Ufkes, 2020, 2021 2

Course Administration
© Alex Ufkes, 2020, 2021
3
• • •
Lab 3 description is posted
Assignment description and tester for Smalltalk is posted If you liked Smalltalk, you can start working on the Smalltalk version.

Today
© Alex Ufkes, 2020, 2021
4
Continuing Elixir:
• Basic types, lists and tuples
• Function and module basics
• Named and anonymous functions

Elixir Syntax: Basic Types
Typing literals into the shell will echo them back, assuming they are valid.
Decimal, binary, octal, and hexadecimal integers
© Alex Ufkes, 2020, 2021 5

Elixir Syntax: Basic Types
Typing literals into the shell will echo them back, assuming they are valid.
More accurately:
© Alex Ufkes, 2020, 2021
6
• • • •
Everything in Elixir is an expression, even single literals. Evaluating a literal simply results in that value.
In the interactive shell, the return value is printed for us. :ok is the return value of IO.puts. The actual printing to the screen is a side effect!

Elixir Syntax: Basic Types
© Alex Ufkes, 2020, 2021
7
Floating point, Boolean, strings

Floating Point
Floating point numbers in Elixir are 64-bit, double precision
Elixir supports scientific notation
Rounding and truncate functions
© Alex Ufkes, 2020, 2021
8

Floating Point
Floating point numbers in Elixir are 64-bit, double precision
Notice:
• We can omit parentheses around function arguments.
• Multiple arguments are still separated by commas.
© Alex Ufkes, 2020, 2021 9

Boolean
Comparison operator works the way we’re used to
We can check if a value is Boolean using the is_boolean function
© Alex Ufkes, 2020, 2021
10

Types, Values, Truthiness
In Elixir we have Boolean values true and false. Not all languages have a Boolean type.
C does not have a Boolean type. It still supports Boolean expressions, of course. • In C, numeric 0 is considered False, and everything else is considered True.
In Java, we have Boolean. Logical operators are only valid with Boolean operands.
Elixir complicates things by combining both approaches:
• We have Boolean True and False, but values of every other type are considered either true or false.
© Alex Ufkes, 2020, 2021 11

Boolean:
true, false
Boolean Expressions
With these operators:
• non-false and non-nil are true.
• nil and false are false.
• 0 is considered true!
iex> “gh” && false Except…
© Alex Ufkes, 2020, 2021
12
false
iex> “gh” || false
• •
The result isn’t true or false It’s the value that decided the result of true or false
“gh”
&&, ||, !
What we get is the value that determined the truthiness of the expression

Test Type
Elixir is dynamically typed!
• Type errors occur at run-time, not at compile time.
• I.e., attempting some operation on incompatible types
results in a run-time error.
• A static type system catches type errors at compile time
© Alex Ufkes, 2020, 2021
13

Basic Arithmetic
Addition, multiplication
Division:
• Notice 5.0, despite integer operands
• / operator returns floating point in Elixir
© Alex Ufkes, 2020, 2021
14

Basic Arithmetic
div and rem functions
div:
• Result of integer division
• Like / in Java
rem:
• Remainderoperator
• Requiresintegerarguments
© Alex Ufkes, 2020, 2021
15

Precedence?
It’s fairly typical:
https://hexdocs.pm/elixir/master/operators.html
© Alex Ufkes, 2020, 2021 16

div and rem are functions:
• Elixir allows us to drop the brackets
• Even with multiple arguments.
• Can make precedence hard to decipher.
© Alex Ufkes, 2020, 2021
17
Likewise for round and trunc and is_boolean

Function Arity
Elixir functions are described in terms of their name and arity? Arity refers to the number of arguments a function takes
Elixir functions are commonly described by the following notation: name/arity
© Alex Ufkes, 2020, 2021
18
round/1
rem/2
trunc/1
div/2
is_boolean/1
This is not language syntax, just a documentation style.

© Alex Ufkes, 2020, 2021 19

More Types: Atoms
Atoms:
A constant whose name is its value:
iex> :hello
:hello
iex> :world
:world
iex> :hello == :world
false
Boolean literals are Atoms:
iex> :true == true
true
iex> :false == false
true
iex> is_boolean(:false)
true
© Alex Ufkes, 2020, 2021
20
Elixir atoms are the equivalent of Smalltalk symbols. Atoms with same value exist only once in memory.

More Types: Strings
Can have line breaks in them:
iex> “Hello,
…> World!”
“Hello,\nWorld!”
iex> “Hello,\nWorld”
“Hello,\nWorld”
We can use IO.puts/1 to print a string:
iex> IO.puts “Hello\nWorld!”
Hello
World! :ok
IO.puts/1 returns the atom :ok after printing
© Alex Ufkes, 2020, 2021
21
Newline is evaluated when we use the puts function.

Strings in Elixir are represented by sequences of bytes.
However. Unicode characters beyond 255 require two bytes to represent:
iex> byte_size “Hello” 5
iex> byte_size “Hellö” 6
iex> String.length “Hellö” 5
More Types: Strings Unicode: length VS number of bytes
Use String.length/1 to find the number of characters.
© Alex Ufkes, 2020, 2021
22

More Types: Strings Interpolation, concatenation
iex> name = “Alex”
“Alex”
iex> “Hello, #{name}!” “Hello, Alex!”
iex> name = “Alex”
“Alex”
iex> “Hello, ” <> name “Hello, Alex”
© Alex Ufkes, 2020, 2021
23
Interpolation
Concatenation

Type Summary
Integer:
+, -, *, /
div/2, rem/2
>, >=, <, <=, ==, != 2, -7, 0x1F, 0o777, 0b10101 Float: 2.0, 1.1e-3, 3.14e7 Boolean: true, false Atom: :Hello, :world, :false, :true String: “Hello, World!”, “123”, “tr\nue” © Alex Ufkes, 2020, 2021 24 Concatenation <>, interpolation #{}

Collections: Lists
• Use [ ] to define a list of values.
• Like Smalltalk, values can be anything (heterogeneous).
• Operating on lists is central in functional languages
iex> [1, 2, true, 3, false]
[1, 2, true, 3, false]
iex> length [1, 2, 3] 3
Lists are implemented in Elixir as linked lists.
Use length/1 to print the number of items in the list.
© Alex Ufkes, 2020, 2021
25

Lists are implemented in Elixir as linked lists. Heads Tails
iex> list = [1, 3.14, true, “Hello”, :World]
[1, 3.14, true, “Hello”, :World]
iex> hd list 1
iex> tl list
[3.14, true, “Hello”, :World]
Return first element of list
Return all but first element of a list
© Alex Ufkes, 2020, 2021 26

Lists are implemented in Elixir as linked lists. Heads Tails
iex(30)> hd [1] 1
iex(31)> tl [1] []
© Alex Ufkes, 2020, 2021
27

List Concatenation & Subtraction
iex> list = [1, 2, true, :Hello, “World”, false, 5] [1, 2, true, :Hello, “World”, false, 5]
iex> list — [true, false]
[1, 2, :Hello, “World”, 5]
iex> list ++ [6]
[1, 2, true, :Hello, “World”, false, 5, 6]
iex> list — [:Hello, “abcd”]
[1, 2, true, “World”, false, 5]
Safe to attempt removal of an item not in the list!
© Alex Ufkes, 2020, 2021 28

Huh?
© Alex Ufkes, 2020, 2021
29
iex> [104, 101, 108, 108, 111] ‘hello’
When the Erlang shell sees a list of printable Unicode values, it displays them as a list of characters.

Collections: Tuples
A sequence of values whose elements are stored contiguously in memory
iex> tup = {1, “2”, :three} {1, “2”, :three}
iex> elem tup, 0
1
iex> elem tup, 1
“2”
iex> elem tup, 2
:three
iex> elem tup, 3
** (ArgumentError) argument error
:erlang.element(4, {1, “2”, :three})
This means we can directly access individual elements using elem/2:
© Alex Ufkes, 2020, 2021 30

Lists & Tuples are Immutable Operations result in new lists/tuples:
iex> tup
{1, “2”, :three}
iex> put_elem(tup, 1, 55)
{1, 55, :three}
iex> tup
{1, “2”, :three}
Bind a new label (or re-bind tuple) to save the result.
tup = put_elem(tuple, 1, 55)
put_elem/3 returned a different tuple. The original hasn’t changed.
© Alex Ufkes, 2020, 2021
31
put_elem/3 to change an element

Elixir Variables are Immutable
When we say: x=1
• The value 1 is created in memory • xis a label for the value 1
If we then say: x=2
• We are NOT changing the value 1 in memory.
• We are creating the value 2 at a different place in memory
• xis now a label for the value 2
• This is called re-binding.
• We change the label, not the value.
© Alex Ufkes, 2020, 2021
32

Elixir Variables are Immutable x=1
x=2
1×2
© Alex Ufkes, 2020, 2021
33

Elixir Variables are Immutable x=1
x=2
1×2
Garbage:
© Alex Ufkes, 2020, 2021
34

Elixir Variables are Immutable
• In imperative languages, variables can be thought of as containers.
• We can put whatever we want into the container (if the type
system allows it, of course)
• Reassigning a variable means mutating the value in the container
• In Elixir and other functional languages, variables are labels.
• We can change the value that we apply the label to, but we can’t
change the value itself.
© Alex Ufkes, 2020, 2021 35

Lists or Tuples?
Lists in Elixir are linked lists:
• Linear time to access and append, constant time to pre-pend
• Use to store a collection of values
Tuples are contiguous:
• Constant time to access, linear time to update
• Use when size and contents are fixed at compile time.
• Not meant to be iterated over, direct element access only.
Both are immutable, updating creates new list/tuple. However:
• If we change one element in a 10-element tuple, we don’t
actually duplicate values for the 9 unchanged elements.
• Behind the scenes, elements can be shared.
© Alex Ufkes, 2020, 2021 36

Lists or Tuples?
© Alex Ufkes, 2020, 2021
37
Just like Python:
• Fixed, small number of elements, need fast random access? Use a tuple.
• Large number of elements, changing in size over time, don’t need random access? Use a list.
• Always keep in mind the cost of operations on arrays VS linked lists (C/CPS305)

Functions
© Alex Ufkes, 2020, 2021
38

© Alex Ufkes, 2020, 2021
39
Recall: First Class VS Higher Order
Higher Order functions
• Can accept a first-class functions as an arguments
• Can return a first-class function
First Class functions
• •
Can be passed to higher order functions as arguments Can be returned from higher order functions

Named Functions Defined within a module
© Alex Ufkes, 2020, 2021
40
• •
• •
Modules can contain multiple functions
Modules can be compiled independently, making functions available for later use.
Named functions are not first class!
o Cannot be passed as arguments, cannot be returned Named functions of same name can have different arity, unlike anonymous functions (coming up)

Modules and Named Functions
Module name:
defmodule Greeter do def hello(name) do
“Hello, ” <> name
end
end
© Alex Ufkes, 2020, 2021 41
Function name and argument list
Function expressions

Erlang bytecode
© Alex Ufkes, 2020, 2021 42

In a script file (.exs)
© Alex Ufkes, 2020, 2021 43

Named Functions
Named functions (and modules) can be defined in a script, but then we can’t use them later (without including their source code)
© Alex Ufkes, 2020, 2021
44

Named functions (and modules) can be defined in a script, but then we can’t use them later (without including their source code)
• Define Greeter module in the file “Greeter.ex”
• Compile it with elixirc:
© Alex Ufkes, 2020, 2021 45

As long as the script is in the same folder, we can invoke functions from Greeter:
© Alex Ufkes, 2020, 2021 46

Private Functions, Default Arguments
Private function:
Can only be invoked inside Greeter module
defmodule Greeter do
defp hello(), do: “Hello ”
def greet(name \\ “Bill”), do: hello() <> name
end
Default argument:
If no argument is provided, name will be “Bill”
© Alex Ufkes, 2020, 2021 47

© Alex Ufkes, 2020, 2021 48

Return Values
• We don’t have an imperative-style return statement in Elixir
• The result of the final expression is returned.
Four expressions
defmodule Silly do def print() do
“Hello” “,”
“” “World!”
end end
IO.puts Silly.print() World!
© Alex Ufkes, 2020, 2021
49

Overloading
© Alex Ufkes, 2020, 2021 50

Multiple Modules
© Alex Ufkes, 2020, 2021
51

Anonymous Functions
Can be created live, inline:
iex> add = fn a, b -> a + b end
• “Anonymous” functions can still be named.
• They are first class
• Can be passed to another
function and invoked there.
Function parameters
© Alex Ufkes, 2020, 2021 52
Function behavior

Anonymous Functions
Invoke using the dot operator:
iex> add = fn (a, b) -> a + b end #Function<12.99386804/2 in :erl_eval.expr/5>
iex> add.(1, 2) 3
iex> add.(8, 9)
17
Arguments are passed in the usual manner
Can’t use this syntax with anonymous functions:
iex> add 8, 9
** (CompileError) iex:8: undefined function add/2
© Alex Ufkes, 2020, 2021 53

Shorthand
© Alex Ufkes, 2020, 2021
54
iex> add = &(&1 + &2) &:erlang.+/2
iex> add.(3, 4) 7
iex> add.(8, -4)
4

Function Composition
(Maybe) not the most readable
© Alex Ufkes, 2020, 2021
55

Function Composition
The pipe operator:
x = inc.(inc.(inc.(inc.(0))))
Can be written as:
x = 0 |> inc.() |> inc.() |> inc.() |> inc.()
Result becomes first argument of next function call
Very useful with Enums and Streams (next class)
© Alex Ufkes, 2020, 2021
56

Higher Order & First Class Functions
Higher order functions:
• Functions that return functions or accept them as arguments
• Named functions are higher order in Elixir
First class functions:
• First class functions can be passed as arguments into other functions
• Anonymous functions are first class in Elixir
© Alex Ufkes, 2020, 2021 57

Higher Order & First Class Functions
A function accepting a function as an argument?
defmodule UserMath do
def hof(val, func) do
func.(val)
end end
Two arguments:
• A numeric value and a function
• (Or so our function assumes)
Invoke func with val as argument
• If func is not actually a function?
• We will get a run-time type error
if/when we try to use it as such.
© Alex Ufkes, 2020, 2021
58

Higher Order & First Class Functions
A function accepting a function as an argument?
defmodule UserMath do
def hof(val, func) do
func.(val)
end end
• Anonymous function to do some operation
• Recall – only anonymous functions can be args
© Alex Ufkes, 2020, 2021 59
• Pass value 8 and function sq to hof

Same Thing?
No! the result of pow() is passed as an argument, not the function itself.
Are we not passing a function to another function here?
© Alex Ufkes, 2020, 2021 60

In Summary:
© Alex Ufkes, 2020, 2021
61
Continuing Elixir:
• Lists and tuples
• Function and module basics
• Named and anonymous functions

© Alex Ufkes, 2020, 2021 62