[SOLVED] CS Elixir algorithm concurrency python C/CPS 506

$25

File Name: CS_Elixir_algorithm_concurrency_python_C/CPS_506.zip
File Size: 452.16 KB

5/5 - (1 vote)

C/CPS 506
Comparative Programming Languages Prof. Alex Ufkes
Topic 5: Finishing up 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 CCPS 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
Midterm next week!

Takes place on D2L during the 2h lecture period. Test is ONLY available during these two hours.

This Week
Alex Ufkes, 2020, 2021
4
Finish up Elixir
Pattern Matching
Control flow, keyword lists
Enum VS Stream
List comprehensions
Elixir processes

Alex Ufkes, 2020, 2021
5
Lets Get Started!

Any Questions?
Alex Ufkes, 2020, 2021
6

Pattern Matching
Alex Ufkes, 2020, 2021 7

Alex Ufkes, 2020, 2021
8
=
This is not the assignment operator. It is the match operator. Pattern matching is a fundamental part of Elixir
x= 1
When a name is on the left-hand side of the match operator, we bind or rebind the name.

Alex Ufkes, 2020, 2021
9
iex> x = 2 2
iex> 2 = x 2
This is a valid expression!
(Variable) Name on the Right?
iex> 3 = x
** (MatchError) no match of right hand side value: 2
iex> 3 = x + 1 3
If a match is successful, it returns the value of the right-hand side of the expression. If not, a MatchError.

(Variable) Name on the Right?
iex> x = 2 2
iex> 2 = x 2
This is a valid expression!
iex> 3 = x
** (MatchError) no match of right hand side value: 2
iex> 3 = x + 1 3
Names on the left? Bind or rebind to value on the right. Names on the right? Pattern match with value on the left.
Alex Ufkes, 2020, 2021 10

Matching Lists Lets see matching with lists:
iex> list = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> [1, 2, 3, 4, 5] = list [1, 2, 3, 4, 5]
Alex Ufkes, 2020, 2021
11

Matching Lists
iex> list = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> [1 | tail] = list
[1, 2, 3, 4, 5]
iex> tail
[2, 3, 4, 5]
iex> [2 | tail] = list
** (MatchError) no match of right hand side
value: [1, 2, 3, 4, 5]
A pattern match will error if the sides cant be matched
Separates list into head and tail.
In this case, the head must be 1!
Alex Ufkes, 2020, 2021 12

Not equating the tail (of tail) with anything
_ can never be read from. Value discarded.
iex> tail
[2, 3, 4, 5]
iex> [2 | _] = tail [2, 3, 4, 5]
iex> [2, 3 | test ] = tail
[2, 3, 4, 5]
iex> test
[4, 5]
iex> [_ | test ] = tail
[2, 3, 4, 5]
Match first two values
Match test with tail of tail
Alex Ufkes, 2020, 2021 13

iex> tup = {:OK, Hello} {:OK, Hello}
iex> {:OK, value} = tup
{:OK, Hello}
iex> value
Hello
Matching Tuples
When matching tuples, the comma is used as a separator.
Tuples dont deal in head/tail
They arent linked lists.
Comma for tuples, | for lists.
Alex Ufkes, 2020, 2021 14

iex> {a | b} = {1, 2, 3, 4, 5}
** (CompileError) iex: misplaced operator |/2
The | operator is typically used between brackets as the cons operator: [head | tail]
where head is a single element and the tail is the remaining of a list. It is also used to update maps and structs, via the %{map | key: value} notation, and in typespecs, such as @type and @spec, to express the union of two types
Alex Ufkes, 2020, 2021 15

Matching Tuples
iex> {a, b, c} = {:hello, World, 42}
{:hello, World, 42}
iex> {a, b} = {:hello, World, 42}
** (MatchError) no match of right hand side
value: {:hello, World, 42}
This is called destructuring. a, b, c are now bound to individual elements of the tuple.
Alex Ufkes, 2020, 2021 16

Pin Operator
If we use the match operator with a variable on the left side of the expression, that variable is simply re-bound to that value. For example:
iex> x = 3 3
iex> x = 2 2
iex> x = 3 3
iex> ^x = 2
** (MatchError) no match of right hand side value: 2
This is often undesirable!
Alex Ufkes, 2020, 2021
17
Use ^ operator to force x to hold its binding

iex> x = 2 2
Pin Operator: Lists & Tuples
iex> [^x, y] = [1, 3]
** (MatchError) no match of right hand side value: [1, 3]
iex> y
** (CompileError) iex:2: undefined function y/0
iex> [^x, y] = [2, 3] [2, 3]
iex> y 3
Alex Ufkes, 2020, 2021 18

Functions & Patterns
Alex Ufkes, 2020, 2021 19

Pattern Matching: Function Signatures Function overloading is just pattern matching on the signature
Alex Ufkes, 2020, 2021 20

Ideas? What can we do?
Alex Ufkes, 2020, 2021 21

Alex Ufkes, 2020, 2021 22

What about
?
Alex Ufkes, 2020, 2021
23
Single argument, a tuple

Alex Ufkes, 2020, 2021 24

Alex Ufkes, 2020, 2021 25

Alex Ufkes, 2020, 2021 26

Recursion in Elixir
Who needs looping anyway?
defmodule Length do
def of([]), do: 0
def of([_ | t]), do: 1 + of(t)
end
When theres one value left in the list, t will be [ ]
Alex Ufkes, 2020, 2021 27

Argument pattern matching makes recursion straightforward:
Base cases
Recursive case
Alex Ufkes, 2020, 2021
28

Tail Recursion?
Consider UserMath.fac()
defmodule UserMath do
def fac(0), do: 1
def fac(n), do: n*fac(n-1)
end
defmodule UserMath do
do: fac(num, 1)
def fac(0, prod), do: prod
def fac(num, prod), do: fac(num-1, num*prod) end
Wrapper function so user can invoke without initializing the running product
def fac(num),
Pass running product as argument
Alex Ufkes, 2020, 2021 29

Private Functions, Default Arguments
defmodule UserMath do
def fac(num), do: fac(num, 1)
defp fac(0, prod), do: prod
defp fac(num, prod), do: fac(num-1, num*prod)
end
Hide the tail helper functions from the outside world
Alex Ufkes, 2020, 2021 30

Control Structures
Implemented using function calls and pattern matching
Alex Ufkes, 2020, 2021 31

Selection: if/else
Alex Ufkes, 2020, 2021
32

Alex Ufkes, 2020, 2021 33

As long as this expressions evaluates to true or false
Why?
Alex Ufkes, 2020, 2021 34

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
35
false
iex> gh || false
gh

The result isnt true or false Its the value that decided the result of true or false
&&, ||, !
What we actually get is the value that determined the truthiness of the expression

No loop/if-else/case constructs
In Elixir, we have several control structures that are implemented as macros. They are not actually constructs of the programming language.
Their implementation exists in the Elixir Kernel module.
They allow us to write if/else-style constructs in a familiar way. However, these are function calls behind the scenes.
Alex Ufkes, 2020, 2021
36

?
Alex Ufkes, 2020, 2021
37

if 1 < 2 do HelloendIs the same as: Is the same as:if 1 < 2, do: Helloif(1 < 2, do: Hello)do/end VS Keyword List This form is a syntactic convenience allowed by Elixir to make the language more accessible. Alex Ufkes, 2020, 202138 if 1 < 2 do Helloelse Worldenddo/end VS Keyword List Is the same as:if 1 < 2, do: Hello, else: WorldIs the same as:if(1 < 2, do: Hello, else: World)iex> if 1 < 2, do: “Hello”, else: “World” “Hello”iex> if(1 < 2, do: “Hello”, else: “World”) “Hello” Alex Ufkes, 2020, 2021 39 if 1 < 2 do Helloelse Worldenddo/end VS Keyword List Is the same as: if(1 < 2, do: Hello, else: World)Is the same as: if(1<2, [{:do, “Hello”}, {:else, “World”}]) Alex Ufkes, 2020, 202140 if(1<2, [{:do, “Hello”}, {:else, “World”}]) Alex Ufkes, 2020, 2021 41 if 1 < 2 do Helloelse Worldenddo/end VS Keyword List Is the same as: if 1 < 2, do: Hello, else: WorldIs the same as: if(1<2, [{:do, “Hello”}, {:else, “World”}]) Alex Ufkes, 2020, 202142iex> if 1 < 2, do: “Hello”, else: “World” “Hello”iex> if(1 < 2, [{:do, “Hello}, {:else, “World”}]) “Hello”Can be any expression! iex> if(1 < 2, [{:do, IO.puts “Hello”}, {:else, “World”}]) Hello:okiex>
Alex Ufkes, 2020, 2021 43

unless
unless is_integer(hello) do
Not an Int
end
iex> unless(is_integer(hello), do: Not an Int) Not an Int
iex> unless(is_integer(hello), [{:do, Not an Int}]) Not an Int
Alex Ufkes, 2020, 2021 44

unless: With an else
unless is_integer(0b10101) do Not an Int
else
An Int
end
Alex Ufkes, 2020, 2021
45
An Int

case
if and unless cant handle pattern matching gracefully:
We can never get here!
Matching returns the right-hand side
UNLESS no match is found, then it yields
a MatchError.
If a match is found wed be OK [1, 2, 3]
is true (non-nil, non-false)
Alex Ufkes, 2020, 2021 46

case
Match this tuple successively
with each case:
tup = {:ok, Hello World} case tup do
{:ok, result} -> result {:error} -> Uh oh!
_ -> Catch all
end
Pattern match!
{:ok, result} = {:ok, Hello World}
{:error} = {:ok, Hello World}
_ = {:ok, Hello World}
Without a catch-all, wed get an error if no match was found.
Alex Ufkes, 2020, 2021
47

Alex Ufkes, 2020, 2021 48

Alex Ufkes, 2020, 2021 49

Alex Ufkes, 2020, 2021 50

Comment out catch all case
Alex Ufkes, 2020, 2021 51

case: Matching Variables pi = 3.14
IO.puts pi What prints?
case do
pi -> IO.puts Tasty <> pi
_ -> IO.puts #{pi} is not tasty
end
Attempts to match: pi = apple pie
Whats the problem here?
Alex Ufkes, 2020, 2021
52
apple pie

Pin pi using ^
Alex Ufkes, 2020, 2021 53

Guard Clauses
Guard reference: https://hexdocs.pm/elixir/master/guards.html
Alex Ufkes, 2020, 2021 54
Place a condition on the match:
In this case, match is only successful if x < 0 Guard ClausesGuard reference: https://hexdocs.pm/elixir/master/guards.html Alex Ufkes, 2020, 2021 55condcase is for pattern matching, cond is for conditions: Evaluating cond: We say y=cond … Cond evaluates to the final expressionunder the first true condition. Similar to a block in Smalltalk Alex Ufkes, 2020, 202156 Alex Ufkes, 2020, 2021 57 cond: Always have a catch-all Alex Ufkes, 2020, 202158 Alex Ufkes, 2020, 202159Enum EnumA set of algorithms for enumeration over enumerables! (lists, tuples, and more) Enum applies functions to lists in various ways. We will see a few:Enum.all?# Entire collection must evaluate to true for a given condition Enum.any?# Any value in the collection must evaluate true Enum.map# Apply a function to every element in the collectionMore: https://elixirschool.com/en/lessons/basics/enum/ Alex Ufkes, 2020, 2021 60 Enum.all?Entire collection must evaluate to true for a given condition Pass list as first argAnon function as second arg Alex Ufkes, 2020, 2021 61 Enum.all? We can do it! and the function result with the running Boolean result. If we hit an element for which f.(h) is false, the entire running Boolean becomes false. Alex Ufkes, 2020, 202162Tail recursive! Enum.all? We can do it! Alex Ufkes, 2020, 202163 Enum.any?Any value in collection must evaluate to true for a given condition Alex Ufkes, 2020, 2021 64 Enum.any? We can do it!Very similar to MyEnum.all Initialize res to false Any true value from function fwill turn result true. We are ORing instead of ANDing Alex Ufkes, 2020, 202165 Enum.any? We can do it! Alex Ufkes, 2020, 202166 Enum.mapVery useful! Apply a function to every element Alex Ufkes, 2020, 202167 Enum.map: We can do it! Result initialized as an empty list Concatenate [f.(h)] to therunning result list Alex Ufkes, 2020, 202168 Enum.map: We can do it! Alex Ufkes, 2020, 202169 Enum.map: We can do it! Alex Ufkes, 2020, 2021Huh?70 Interlude: IO.puts VS IO.inspect IO.puts cant handle arbitrary lists:iex> x = [1, 2.0, Hello, :world] [1, 2.0, Hello, :world]
iex> IO.puts x
** (ArgumentError) argument error
(stdlib) :io.put_chars(:standard_io, :unicode,
[[1, 2.0, Hello, :world], 10])
IO.puts wants a list containing things it can convert to Unicode.
Alex Ufkes, 2020, 2021 71

Interlude: IO.puts VS IO.inspect We can use IO.inspect:
iex> x = [1, 2.0, Hello, :world] [1, 2.0, Hello, :world]
iex> IO.inspect x
[1, 2.0, Hello, :world]
[1, 2.0, Hello, :world]
Alex Ufkes, 2020, 2021 72
IO.inspect prints and returns the list.

Interlude: IO.puts VS IO.inspect We can use IO.inspect:
iex> x = [104, 101, 108, 108, 111] hello
iex> IO.inspect x
hello
hello
IO.inspect still prints as Unicode!
Alex Ufkes, 2020, 2021 73

Interlude: IO.puts VS IO.inspect We can use IO.inspect:
iex> x = [104, 101, 108, 108, 111] hello
iex> IO.inspect x
hello
hello
iex> IO.inspect x, charlists: :as_lists
[104, 101, 108, 108, 111] hello
Prints list as a list, rather than converting to Unicode.
Alex Ufkes, 2020, 2021 74
Invoke IO.inspect thusly:

Interlude: IO.puts VS IO.inspect IO.inspect x, charlists: :as_lists
Recall keyword list form:
IO.inspect(x, [{:charlists, :as_lists}])
Alex Ufkes, 2020, 2021 75

Enum.reduce
Distill collection to single value based on some function
acc is the running value
By default, initialized to first element in list
Alex Ufkes, 2020, 2021
76

Enum.reduce
Distill collection to single value based on some function
(9 (8 (7 (6 (5 (4 (3 (2 (1 (0 acc))
VS
((acc 1) 2) 3) 4) 5) 6) 7) 8) 9)
Alex Ufkes, 2020, 2021 77

Enum.reduce: We can do it!
Result initialized as head of list
Pass head of list and current
result into f
Alex Ufkes, 2020, 2021
78

Enum.reduce: We can do it!
Alex Ufkes, 2020, 2021
79

acc is the running value
By default, initialized to first element in list
We can add an optional 3rd argument to initialize acc:
iex> Enum.reduce([1, 2, 3], 10, fn(x, acc) -> x+acc end) 16
iex> Enum.reduce([1, 2, 3], fn(x, acc) -> x+acc end)
6
10 + 1 + 2 + 3
VS
1+ 2 + 3
Alex Ufkes, 2020, 2021 80

Stream
Alex Ufkes, 2020, 2021 81

Streams
Like Enum, but Streams are lazy! Enum functions are strict/eager.
The result of an Enum is the list that results from applying it:
iex> list = [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
iex> Enum.map(list, &(&1 + 1)) [2, 3, 4, 5, 6]
Alex Ufkes, 2020, 2021
82

Streams
Like Enum, but Streams are lazy!
Stream and Enum share many functions.
What is the result of evaluating Stream.map?
iex> list = [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
iex> Stream.map(list, &(&1 + 1)) #Stream<[enum: [1, 2, 3, 4, 5],funs: [#Function<48.103564624/1 in Stream.map/2>] ]>
Alex Ufkes, 2020, 2021 83

iex> list = [1, 2, 3, 4, 5] [1, 2, 3, 4, 5]
iex> Stream.map(list, &(&1 + 1)) #Stream<[enum: [1, 2, 3, 4, 5],funs: [#Function<48.103564624/1 in Stream.map/2>] ]>
Thats not a list! Stream is its own type.
Think of a stream as a recipe for producing the transformed list.
Here, our stream is a recipe for adding 1 to every element.
We havent actually done the cooking!
Why is this useful?
Alex Ufkes, 2020, 2021 84

Streams
Consider the following script:
list = [1, 2, 3, 4, 5]
r1 = Enum.map(list, &(&1 + 1)) |>
Enum.map(&(&1 * 3)) |> Enum.map(&(&1 / 2))
An aside: Pipe is useful here!
Output list from Enum piped
into next call as 1st arg.
Thus, subsequent Enum calls
only have 1 arg.
Alex Ufkes, 2020, 2021
85
How many new lists are created when we evaluate this? One for each Enum call! Very inefficient.

Streams
list = [1, 2, 3, 4, 5]
r1 = Stream.map(list, &(&1 + 1)) |>
Stream.map(&(&1 * 3)) |> Stream.map(&(&1 / 2))
list = [1, 2, 3, 4, 5]
r1 = Stream.map(list, &(&1 + 1)) |>
Stream.map(&(&1 * 3)) |> Enum.map(&(&1 / 2))
r1is a recipe for a new list
At this point, no new list(s)
have been created!
If we finish with an Enum call, the stream is applied.
Only one new list created
Alex Ufkes, 2020, 2021
86

Alex Ufkes, 2020, 2021 87

Apply the Stream?
Can also use Enum.to_list
list = [1, 2, 3, 4, 5]
r1 = Stream.map(list, &(&1 + 1)) |>
Stream.map(&(&1 * 3)) |>
Stream.map(&(&1 / 2))
Enum.to_list(r1)
Alex Ufkes, 2020, 2021
88

Lots more: https://hexdocs.pm/elixir/Stream.html
Alex Ufkes, 2020, 2021 89

List Comprehensions
for:
Generating Filtering
Operating
Produces a list when its done!
Not the same as an imperative-style for loop! Not for general purpose iteration.
Alex Ufkes, 2020, 2021
90

List Comprehensions
Very much like comprehensions in Python:
Three parts:
Generator Filter
Collector
Comprehensions are syntactic sugar for things we could otherwise do with Enum or recursive functions
Alex Ufkes, 2020, 2021
91

List Comprehensions
iex> Enum.map([1, 2, 3, 4], &(&1*&1)) [1, 4, 9, 16]
iex> for n <- [1, 2, 3, 4], do: n*n [1, 4, 9, 16] Generator: Any enumerable In this case, a plain old list Alex Ufkes, 2020, 202192 List Comprehensionsiex> Enum.map([1, 2, 3, 4], &(&1*&1)) [1, 4, 9, 16]
iex> for n <- [1, 2, 3, 4], do: n*n [1, 4, 9, 16]iex> for n <- do: n*n [1, 4, 9, 16]1..4, Used to produce list [1, 2, 3, 4] Can generate large lists this way Note: 1..4 is NOT itself a list! It is a Range Alex Ufkes, 2020, 202193 Alex Ufkes, 2020, 2021 94 List Comprehensionsiex> for n <- 1..4, do: n*n [1, 4, 9, 16] List comprehensions produce lists Generators like the above are lazy (Range) Operate on elements one at a time,discarding previous. That is, at no point do we produce thecomplete list [1, 2, 3, 4] in memory. https://hexdocs.pm/elixir/Range.html Alex Ufkes, 2020, 202195 List Comprehensions: Pattern Matching iex> vals = [good: 1, good: 2, bad: 3, good: 4]
Keyword list!
iex> vals = [{:good, 1}, {:good, 2}, {:bad, 3}, {:good, 4}] [good: 1, good: 2, bad: 3, good: 4]
Alex Ufkes, 2020, 2021 96

List Comprehensions: Pattern Matching iex> vals = [good: 1, good: 2, bad: 3, good: 4]
[good: 1, good: 2, bad: 3, good: 4]
iex> for {:good, n} <- vals, do: n*n [1, 4, 16] Alex Ufkes, 2020, 202197 Pattern matching is powerfulWe can also filter in a Boolean fashion List Comprehensions: Filtering iex> fun = &(rem(&1, 3) == 0) #Function<6.99386804/1 in :erl_eval.expr/5>
iex> for n <- 1..20, do: n [3, 6, 9, 12, 15, 18]fun.(n), Filter is optional Include it after generator if desired Only elements that evaluate to true whenfiltered will make it to the do: block Alex Ufkes, 2020, 202198 List Comprehensions: Filtering & Matching iex> list = [a: 1, b: 2, a: 3.0, a: 4.0, b: {5}, a: [6.0]]
[a: 1, b: 2, a: 3.0, a: 4.0, b: {5}, a: [6.0]]
iex> for {:a, n} <- list, is_number(n), do: n [1, 3.0]Nothing semantically new here Anything we can do with comprehensions we can do with Enum or our own functions. It might require more syntax, but we can do it. Comprehensions can be used to create concise code Alex Ufkes, 2020, 202199 List Comprehensions: In 2D?iex> for i <- [:a, :b, :c], j <- [1, 2], do: {i, j}[a: 1, a: 2, b: 1, b: 2, c: 1, c: 2]We get a keyword list containing combinations of all elements from both generators Alex Ufkes, 2020, 2021100 Alex Ufkes, 2020, 2021101 Elixir Processes (In Brief):Elixir is built on a process model. Recall:Elixir code runs inside lightweight threads of execution. o Isolated, exchange information via message passing.Not uncommon to have hundreds of thousands of processes running concurrently in same VM.o Note: These are NOT operating system processes! o Extremely lightweight in terms of CPU and memory o A process need not be an expensive resource Elixir Processes Playing with processes: self() Returns PID of current process.o In this case, its the PID of our interactive shell session Process.alive?() tests if a process is currently active. We can spawn functions as processes! Alex Ufkes, 2020, 2021102 Elixir Processes spawn takes a function as an argument and returns its PID once spawned. Function executes when spawned Process is not active, the function is not currently executing Alex Ufkes, 2020, 2021103 Elixir Processes: Send & Receive iex> send(self(), {:Hello, World})
{:Hello, World}
send/2 can be used to send a message (!!!) to a process (by PID)
This message goes into a mailbox and can be received using the
receive/1 function
When invoking receive, it will go through the messages in the mailbox
and attempt to match the messages with the provided patterns
Alex Ufkes, 2020, 2021 104

Elixir Processes: Send & Receive
iex> send(self(), {:Hello, World}) {:Hello, World}
iex> receive do
> {:Hello, msg} -> msg
> {:World, msg} -> wont match
> end
World
iex>
Once the message is received, it is consumed!
We cant receive the same message twice.
Subsequent receive calls will be blocking
Alex Ufkes, 2020, 2021
105

Elixir Processes: Send & Receive
Alex Ufkes, 2020, 2021
106

Elixir Processes: Send & Receive
Receive is blocking!
We sent one message, and received it.
We then try and receive again, but the
mailbox is empty.
Process sits and waits.
Alex Ufkes, 2020, 2021
107

Elixir Processes: Send & Receive
Alex Ufkes, 2020, 2021
108

Elixir Processes: Send & Receive
Spawning a function as a process executes that function.
A blocking receive can be used to wait for messages.
Once the function receives a message, it will pattern match.
Receive only blocks once! We have to spawn the function three times.
Different order?
Execution is interleaved.
Up to scheduler.
Alex Ufkes, 2020, 2021
109

Elixir Processes: Send & Receive
Spawn all three, send each a message.
Which child process gets chosen to
execute is up to the scheduler.
Alex Ufkes, 2020, 2021
110

Elixir Processes
This has been a taste. Theres lots more.
Elixir is famous for powerful concurrent processing.
Processes can be used to emulate the object message
passing model in languages like Smalltalk.
If you understand a bit about concurrency from 209 or
590, check it out.
https://elixir-lang.org/getting-started/processes.html
Alex Ufkes, 2020, 2021 111

Alex Ufkes, 2020, 2021 112

Functional Programming & Elixir
We saw:
Functionsasfirst-classentities
o How to create and pass anonymous functions as arguments o How to return anonymous functions

Immutable data variables (names) are bound and matched using = o Collections are not modified.
o Enum.map returns a new collection
Recursion Loops are tail-recursive (ideally) functions calls. o Enum functions work this way behind the scenes
Elixir provides many syntax conveniences that make code more familiar to programmers accustomed to the imperative style.
Alex Ufkes, 2020, 2021 113

Functional Programming & Elixir
Flow control is not built into the language as syntax constructs
This suggests theres no iteration in the typical sense of the word.
Looping is accomplished with control structures in imperative languages.
If control structures are functions, that means looping is always recursive.
However
This refers to the high level implementation only.
Machine instructions are optimized into iteration via tail recursion.
Alex Ufkes, 2020, 2021 114

Elixir Syntax
Dynamically typed
o Type inferred at run-time
o Need not explicitly specify type upon declaration
Provides syntax conveniences to make it more intuitive to programmers accustomed to imperative languages
Interactive shell provides help/search functionality
https://media.pragprog.com/titles/elixir/ElixirCheat.pdf
Alex Ufkes, 2020, 2021 115

Elixir Syntax
Reserved words
true,false,nil o Used as atoms
when,and,or,not,in o Used as operators
fn
o Used for anonymous function definitions
do,end,catch,rescue,after,else o Used in do/end blocks
https://github.com/elixir-lang/elixir/blob/master/lib/elixir/pages/Syntax%20Reference.md
Alex Ufkes, 2020, 2021 116

Further Reading
https://elixir-lang.org/getting-started/introduction.html https://elixirschool.com/en/lessons/basics/basics/
Alex Ufkes, 2020, 2021 117

Elixir Popularity
Alex Ufkes, 2020, 2021
118

Elixir Popularity
https://techbeacon.com/5-emerging-programming-languages-bright-future
This list also includes Rust!
Alex Ufkes, 2020, 2021
119

Alex Ufkes, 2020, 2021 120

Alex Ufkes, 2020, 2021 121

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] CS Elixir algorithm concurrency python C/CPS 506
$25