C/CPS 506
Comparative Programming Languages Prof. Alex Ufkes
Topic 3: Out with Smalltalk, in with 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
Assignment description is posted!
If you liked Smalltalk, you could start working on the Smalltalk version.
Today
Alex Ufkes, 2020, 2021
4
Double dispatch
Smalltalk conclusion
Functional paradigm
Getting started with Elixir
Alex Ufkes, 2020, 2021
5
Method Overloading
Method Overloading
In Java, methods are overloaded through differing parameter lists:
In Java, method name and parameter list are independent.
In Smalltalk, they are fundamentally linked
Alex Ufkes, 2020, 2021 6
Method Overloading
Alex Ufkes, 2020, 2021
7
In Smalltalk, there is no overloading in this fashion.
We cannot have a single message that optionally
accepts differing numbers of arguments.
When we add another argument, the method name
changes.
Method Overloading
When we add another argument, the method/message name changes.
valueandvalue:are different names
value:andvalue:value: are different names
And so on
Alex Ufkes, 2020, 2021 8
Method Overloading
All well and good, but what about the same number of arguments with different types?
In Java, compiler sees these as different: public int add(int x, int y)
public double add(double x, double y)
In Smalltalk, argument types arent checked upon message pass.
Invoking a method (passing a message) only fails when receiving
object cant handle the message.
We get a runtime error in the body of the method if the
argument type is incompatible.
Alex Ufkes, 2020, 2021 9
Method Overloading
However! The following code succeeds!
Pass + message to SmallInteger 3 with SmallInteger argument 4
Pass + message to SmallInteger 3 with BoxedFloat64 argument 4.0
Same message, same receiving class, different kind of argument. How?
Alex Ufkes, 2020, 2021
10
Invoke superclass addition
Alex Ufkes, 2020, 2021 11
Alex Ufkes, 2020, 2021 12
Check if argument is integer.
If so, its an integer expression
and we can react accordingly
Check if operands have same sign
negative returns Boolean
Alex Ufkes, 2020, 2021 13
Alex Ufkes, 2020, 2021 14
If arg isFraction, we can still add precisely using numerator and denominator
If arg is neither fraction nor integer, we send it adaptToInteger:andSend: message
Alex Ufkes, 2020, 2021 15
adaptToInteger:andSend:
Convert original receiving integer to floating point
Perform addition between two BoxedFloat64
Its now a problem for the Float class implementation of +!
Alex Ufkes, 2020, 2021
16
Double Dispatch
Method overloading not possible in Smalltalk.
Uses the previous technique instead, called double dispatch
Double/multiple dispatch is not unique to Smalltalk.
Double Dispatch:
Broadly: Make additional method/function calls based on the types of the objects involved in the original call at runtime.
I.e., if arg is float, invoke method for floating point addition.
Overloading is done at compile time, double dispatch occurs
at runtime.
Alex Ufkes, 2020, 2021 17
Double Dispatch
Overloading is decided at compile time, double dispatch at runtime.
In Smalltalk (double dispatch), the same method gets invoked regardless of the argument type. Same message regardless!
Secondary method call(s) occur in the body of the first method, depending on argument type.
In Java, a different method gets invoked from the very start depending on the type of the argument.
Decided at compile time (early binding).
Explore this on your own for some of the other types and operators
Alex Ufkes, 2020, 2021 18
Late VS Early Binding
Dynamic/late binding VS static/early binding
Early binding
Method to be called is found at compile time
Method not found = compile error
More efficient at runtime
Late binding
Method is looked up at runtime
Often as simple is searching name
Symbol comparison in Smalltalk
Method not found = runtime error
Costlier at runtime
Alex Ufkes, 2020, 2021
19
Double dispatch happens at runtime, late binding
This concludes your Smalltalk crash course!
Lets finish with a high-level summary.
Alex Ufkes, 2020, 2021 20
Smalltalk Syntax
Extremely minimalist:
Only five reserved keywords: true, false, nil, self, super
Java has 50, C++ has 82, C has 32
There is an adage Smalltalk syntax fits on a postcard
Alex Ufkes, 2020, 2021 21
Smalltalk syntax fits on a postcard
Method with argument:
Unary messages
Binary messages
Temporary variable
Block
Heterogeneous array
Keyword message
Pass do: message with block argument to array
Alex Ufkes, 2020, 2021
22
Return result
Smalltalk Extensibility
We are free to modify core Smalltalk classes and methods:
Alex Ufkes, 2020, 2021 23
Amuse your friends! Confound your enemies!
We are free to modify core Smalltalk classes and methods:
Beware: You WILL cause havoc and be forced to create a new Pharo image.
The Pharo live environment is using these very methods in a JIT fashion.
Changing True to False means Pharo itself thinks True is False.
Alex Ufkes, 2020, 2021 24
Smalltalk Semantics
A compiler will complain about syntax, your coworkers will complain about semantics
Always remember:
Alex Ufkes, 2020, 2021
25
1. 2. 3.
Everything is an object
Computation is done by passing messages to objects. Message precedence: unary, binary, keyword.
Equal precedence evaluates left to right Everything else follows from these principles.
Smalltalk
Has garbage collection (like Java)
Best-in-class IDE (according to fans).
o Class browser, playground, debugger, transcript, etc.
Just-in-time compilation (JIT)
o Code executed in a live environment
Image-based development
Alex Ufkes, 2020, 2021 26
Smalltalk popularity? A dead language?
https://medium.com/smalltalk-talk/who-uses-smalltalk-c6fdaa6319a
JPMorgan Chase:
Around the time that Java was just being introduced to the world, the banking giant rolled out a new financial risk management and pricing system called Kapital, written entirely in Cincom Smalltalk.
JPMorgan estimates that developing and maintaining this system in any other language wouldve required at least three times the amount of resources.
Alex Ufkes, 2020, 2021 27
Smalltalk popularity? A dead language?
https://medium.com/smalltalk-talk/smalltalk-and-the-future-of-the- software-industry-3f69cac13e5a
One of the goals of Smalltalk was to make it very easy to teach programming to children.
I believe the best way to teach beginners how to program is with a good teaching language. Languages like Java, Python, JavaScript, C#, C/C++, PHP, Ruby are all industrial languages; they carry a lot of industrial baggage that can get in the way of a beginner.
Alex Ufkes, 2020, 2021 28
Smalltalk popularity? A dead language?
https://www.quora.com/Why-did-the-Smalltalk-programming-language- fail-to-become-a-popular-language
The popular story thats been around is that Sun killed Smalltalk with Java. That seems to be partly true
I think what prevented Smalltalk from increasing in popularity was the popularity of developing for the internet
The dominant idea in the Smalltalk community in the 90s was that it was a GUI desktop platform, and thats where it should stay.
Alex Ufkes, 2020, 2021 29
Loved: % of people currently using that want to keep using
Alex Ufkes, 2020, 2021
30
Alex Ufkes, 2020, 2021
31
Smalltalk disappears.
Not sure why, but I think they
didnt include it in the survey.
Rust still on top!
Dreaded: % of people currently using that no longer want to.
Alex Ufkes, 2020, 2021
32
Alex Ufkes, 2020, 2021
33
Wanted: % of people not using who want to use
Important!
This refers to what individual developers want to use.
It does not necessarily reflect what the market wants
https://spectrum.ieee.org/at-work/innovation/the-2018-top-programming-languages
Alex Ufkes, 2020, 2021 34
Leaving OOP Behind
Alex Ufkes, 2020, 2021
35
Object-oriented programming is an exceptionally bad idea which could only have originated in California.
Object-oriented programs are offered as alternatives to correct ones
Edsger Dijkstra
What OOP users claim:
Leaving OOP Behind
What actually happens:
Alex Ufkes, 2020, 2021 https://www.reddit.com/r/ProgrammerHumor/comments/41895/theory_vs_reality/ 36
Alex Ufkes, 2020, 2021 37
Alternatives to Imperative?
Two widely used paradigms:
Object Oriented Programming:
Pure OO languages treat even primitives and operators as objects
Java/C++ and others support OOP to greater or lesser degrees.
Functional Programming:
Avoid changing state, avoid mutable data
Declarative rather than imperative
Tell the program where to go, not
how to get there.
Alex Ufkes, 2020, 2021
38
Functional Programming
Alex Ufkes, 2020, 2021
39
Declarative VS Imperative
Declarative programming paradigm:
Style of building and structuring computer programs.
Functional programming languages are characterized by a declarative style.
Express the logic of a computation rather than explicit control flow. ?
The order in which individual statements, instructions or function calls of an imperative program are executed or evaluated.
Emphasis on explicit control flow is one thing that separates imperative languages from declarative languages.
Alex Ufkes, 2020, 2021
40
Control Flow
Determined using control structures in imperative languages.
Alex Ufkes, 2020, 2021
41
C/CPS 310/590 Example
At the machine instruction level, control flow typically works by altering the program counter.
Program counter tells the OS which instruction to fetch next.
Alex Ufkes, 2020, 2021
42
Declarative VS Imperative
Imperative languages implement algorithms as a sequence of explicit steps (statements, control flow)
Declarative language syntax describes the logic of an algorithm The declarative paradigm allows developers to worry about
the what, not the how.
The how is left up to the languages implementation (interpreter/compiler)
Alex Ufkes, 2020, 2021 43
Always Remember!
Alex Ufkes, 2020, 2021
44
Machine code is imperative.
Functional programs compile into machine code, just like
imperative ones.
The distinction is in what the programmer is required to think about, and what the language hides behind the scenes.
Declarative VS Imperative
The actual, practical difference between these two paradigms can be very hard to grasp.
How can we program without thinking about control flow?
What makes a language declarative? The fact that its not imperative.
Alex Ufkes, 2020, 2021
45
Faking it in C++
This C++ code is imperative
We use a control structure (for loop)
to tell the program to iterate.
Even specify how this iteration is done. Initialization,condition,update
Alex Ufkes, 2020, 2021
46
Faking it in C++
Simulatedeclarativeprogramming using preprocessor directives.
Directives here are basically a list of substitutions
Assume that this is done by the programming language behind the scenes.
Alex Ufkes, 2020, 2021
47
Faking it in C++
Directives here are basically a list of substitutions
ALoop(5, PrintWord(declarative));
Alex Ufkes, 2020, 2021
48
Faking it in C++
Directives here are basically a list of substitutions
action
cout << word << endl; ALoop(5, PrintWord(“declarative”));LOOP_5 (action)LOOP_5 (PrintWord(“declarative”))LOOP_5 (cout << word << endl;) Alex Ufkes, 2020, 202149Faking it in C++Directives here are basically a list of substitutions actioncout << word << endl; ALoop(5, PrintWord(“declarative”)); LOOP_5 (action)LOOP_4 (action) actionLOOP_3 (action) action actionLOOP_2 (action) action action actionLOOP_1 (action) action action action action action action action action action Alex Ufkes, 2020, 2021 50 Faking it in C++ Imagine this was all done behind the scenes by the implementation of the programming language Alex Ufkes, 2020, 202151 Declarative VS ImperativeImperative: Programmerspecifies control flow Each loop iteration explicitly definedDeclarative (C++ fakery): Programmersayswhatthey want Nevermind how its donefor (int i = 0; i < 5; i++){cout << “Imperative” << endl; } ALoop(5, PrintWord(“declarative”)); Alex Ufkes, 2020, 202152Functional Programming Depends what youre doing, depends who you ask… Alex Ufkes, 2020, 2021 53 Functional ProgrammingFunctional programming languages are characterized by a declarative style. Alex Ufkes, 2020, 202154Functional are not the only declarative languages: Always Remember! Alex Ufkes, 2020, 202155The line between imperative/OOP and functional programming is grey.Code can be written in a functional style using a language not specifically designed for functional programming.Some languages are designed to be functional, but still contain imperative elements. Functional Language CharacteristicsThings that are generally foreign to imperative programming: Avoids changing global state, no state to reason about. Avoid global variables, keep scope as tight/local as possible Alex Ufkes, 2020, 2021 56No side effects! Side Effects?Things that are generally foreign to imperative programming:A function can be said to have a side effect if it has an observable interaction with the outside world aside from returning a value. Alex Ufkes, 2020, 202157 Modify global variable Raise an exception Write data to display or file Side EffectsFunction/method output can depend on history (or current state): Call the same function, with the same argument, 5 times. Different result each time. Common in imperative languages. Rare in functional languages. Alex Ufkes, 2020, 2021 58 Side EffectsDeclarative/functional languages avoid side effects The output of a function depends solely on the input arguments o No side effects, no dependence on global or local state. This makes it much easier to predict the behavior of a program o Primary motivation for developing functional programming With no state to be concerned of, parallel processing becomes much easier. No race conditions!o Functions can be spawned as separate threads/processes Alex Ufkes, 2020, 2021 59 Functional Language CharacteristicsThings that are generally foreign to imperative programming:Pure functions are emphasized/enforced: Alex Ufkes, 2020, 202160 Pure function? A function without side effectsIf the return value of a pure function is not used, the function can be safely removed.Output depends solely on input (referential transparency). Pure functions without a data dependency can be executed in any order. Safe to parallelize (thread-safe). Quick Note Alex Ufkes, 2020, 202161 In practice its unreasonable to have a programming language containing only pure functions. This would preclude things like file I/O and user input. Common to have a pure function core surrounded byimpure functions that interact with the outside world This is true of Elixir, but depends on the language. Pure functions can be written in any language, butfunctional languages enforce them in various ways. Functional Language CharacteristicsFunctions and recursion are central:Flow control accomplished with functions calls. We already saw in Smalltalk how this is possible Much lower focus on loop/if-else/case constructs. Collections are operated upon using recursion. Specifically, tail recursion in Elixir. Tail recursion is recognized and optimized by the compiler into iterative machine code. Alex Ufkes, 2020, 202162 Recursionmult(3, 4)3+mult(3, 3) 3+(3+mult(3, 2)) 3+(3+(3+mult(3, 1))) 3+(3+(3+(3+mult(3, 0)))) 3+(3+(3+(3+0)))12 Alex Ufkes, 2020, 202163 Tail Recursion tail_mult(3, 4, 0) tail_mult(3, 3, 3) tail_mult(3, 2, 6) tail_mult(3, 1, 9) tail_mult(3, 0, 12) 12 Alex Ufkes, 2020, 202164 Tail Recursionmult(3, 4)3 + mult(3, 3)3 + (3 + mult(3, 2))3 + (3 + (3 + mult(3, 1)))3 + (3 + (3 + (3 + mult(3, 0)))) 3 + (3 + (3 + (3 + 0)))12 tail_mult(3, 4, 0)tail_mult(3, 3, 3)tail_mult(3, 2, 6)tail_mult(3, 1, 9)tail_mult(3, 0, 12)12Every recursive call must complete before we even begin adding valuesHere, total is updated each call. This version looks a lot more like iteration. Optimizable. Alex Ufkes, 2020, 202165 Functional Language CharacteristicsThings that are generally foreign to imperative programming:First class functions and higher order functions: Functions that return functions or accept them as argumentso I.e., differential operator. Derivative of function is a function. First class describes programming language entities that have no restriction on their use. I.e., first class functions can appear anywhere in the program that other first-class entities (such as numbers) can.o Functions as arguments, return values, etc. Alex Ufkes, 2020, 2021 66 Always Remember…The line between imperative and functional programming is grey.C supports passing functions as arguments via function pointers. Alex Ufkes, 2020, 202167 Functional Language CharacteristicsThings that are generally foreign to imperative programming:Strict (eager) VS. non-strict (lazy) evaluation: Strict: Always evaluate function arguments before invoking the function. Lazy: Evaluates arguments if their value is required to invoke the function.print length( [2+1, 3*2, 1/0, 5-4] );Fails under strict evaluation, cant divide by zero.Under lazy evaluation we get the correct value of 4. We dont need to know the actual values of the array elements to know how many there are. Alex Ufkes, 2020, 2021 68 Functional Programming: AdvantagesEasier to reason about pure functions: If the function is internally consistent, its always correct. No tracking down global variables, tracing pointers/references, etc. Alex Ufkes, 2020, 2021 69 Functional Programming: AdvantagesConcurrent programming is easier: No side effects, functions can be spawned as processes/threads. There is no state to be shared between different threads. No need for semaphores (or similar) if you dont have side effects!o Pure functions never access or modify things outside their scope o No such thing as a race condition when values are immutable. Alex Ufkes, 2020, 2021 70 Functional Programming: Advantages Programs are easier to understand: Allocate space for variable i Initializeito0 for (int i = 0; i < 5; i++) {cout << “Imperative” << endl;} Iterate as long as i is less than 5 Increment i after each iteration Dosomething5times ALoop(5, PrintWord(“declarative”)); Alex Ufkes, 2020, 202171 Functional Programming: Disadvantages Recursion can cause memory use to explode: Operating on a list with 10000 items requires 10000 recursive calls. Stack explodesTail recursion mitigates this as we saw, but using tail recursion can often require inelegant code gymnastics. Alex Ufkes, 2020, 202172 Functional Programming: DisadvantagesRecursion can cause memory use to explode: Operating on a list with 10000 items requires 10000 recursive calls. Stack explodes Tail recursion mitigates this as we saw, but using tail recursion can often require inelegant code gymnastics.No assignment statements, data is immutable: Alex Ufkes, 2020, 202173 Performing actions requires allocating new memory. Remember strings in Java Changing the value of a string actually creates a new string object with the new value. Garbage collection very important! Functional Programming: DisadvantagesPerformance: Functional languages will typically perform worse than imperative languages when: Computation is strictly sequential (CPU) Computation is uniformly parallel (GPU) Alex Ufkes, 2020, 202174 Alex Ufkes, 2020, 2021 75Only predated by FORTRAN Alex Ufkes, 2020, 2021 76 History: Erlang Proprietary language used at Ericsson, developed by Joe Armstrong Initially implemented in Prolog at Ericsson By 1988, it had been proven suitable forprototyping telephone exchanges but… Prolog interpreter was much too slow,needed to be 40x faster. In 1992 work began on BEAM VMo Compiles Erlang to Co Balance performance and disk space. Went from lab to real applications by 1995 In 1998, Ericsson banned internal use ofErlang, causing Armstrong to quit.o Rehired in 2004, after ban was lifted. Alex Ufkes, 2020, 202177History: Elixir Builds on Erlang, runs on BEAM VM Erlang was prolog-like, Elixir is moreconventional. First appeared in 2011 Developed by Jose Valim as an R&Dproject at Plataformatec (consulting firm) Used at Pinterest, and for webdevelopment by Discord. Alex Ufkes, 2020, 202178 Elixir: Overview Elixir is a functional programming languageo Mostly immutable, rich support for concurrency Everything is an expression.o Everything evaluates to something. Elixir compiles into Erlang bytecode.o Thus, Erlang functions can be called from Elixir Emphasizes recursion and higher-order functions o As opposed to side-effect-based looping Alex Ufkes, 2020, 202179 Elixir: Processes Alex Ufkes, 2020, 202180 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 Installing Elixirhttps://elixir-lang.org/ Alex Ufkes, 2020, 202181 Alex Ufkes, 2020, 2021 82 Alex Ufkes, 2020, 2021 83 Erlang ShellBetter than just a terminal window Alex Ufkes, 2020, 202184 Writing and Compiling ElixirPlay around in the interactive shell, or do things from the command line.IDEs exist, but youre on your own. I wont help troubleshoot IDE-related problems.This is the Erlang shell. We can: Type code into here line by line Copy and paste code into here large chunks at a time Define modules and functions though its tedious. Alex Ufkes, 2020, 2021 85 Elixir References https://media.pragprog.com/titles/elixir/ElixirCheat.pdfhttps://elixir-lang.org/getting-started/introduction.html https://hexdocs.pm/elixir/master/api-reference.html#content Alex Ufkes, 2020, 2021 86 Hello WorldIO.puts Hello, World! IO.puts prints to the shell When executing in the shell, return values get echoed. In this case, IO.puts returns the atom :ok Atoms in Elixir are similar in concept to symbols inSmalltalk. Alex Ufkes, 2020, 202187 Hello WorldIO.puts Hello, World! We will start in this shell for basic concepts. Later, we will see how to run scripts and compile code from the command line (Its not so bad) Alex Ufkes, 2020, 202188 Elixir Scripts Alex Ufkes, 2020, 202189 Elixir Syntax: Basic TypesTyping literals into the shell will echo them back, assuming they are valid. Decimal, binary, octal, and hexadecimal integers Alex Ufkes, 2020, 2021 90 Elixir Syntax: Basic TypesTyping literals into the shell will echo them back, assuming they are valid.More accurately: Alex Ufkes, 2020, 202191 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, 202192Floating point, Boolean, strings Floating PointFloating point numbers in Elixir are 64-bit, double precisionElixir supports scientific notationRounding and truncate functions Alex Ufkes, 2020, 202193 Floating PointFloating point numbers in Elixir are 64-bit, double precisionNotice: We can omit parentheses around function arguments. Multiple arguments are still separated by commas. Alex Ufkes, 2020, 2021 94 BooleanComparison operator works the way were used toWe can check if a value is Boolean using the is_boolean function Alex Ufkes, 2020, 202195 Types, Values, TruthinessIn 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 96Boolean:true, falseBoolean ExpressionsWith 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
97
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
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
98
Basic Arithmetic
Addition, multiplication
Division:
Notice 5.0, despite integer operands
/ operator returns floating point in Elixir
Alex Ufkes, 2020, 2021
99
Basic Arithmetic
div and rem functions
div:
Result of integer division
Like / in Java rem:
Remainderoperator
Same as % in C
Requiresintegerarguments
Alex Ufkes, 2020, 2021
100
Precedence?
Its fairly typical:
https://hexdocs.pm/elixir/master/operators.html
Alex Ufkes, 2020, 2021 101
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
102
Likewise for round and trunc and is_boolean
Summary
Alex Ufkes, 2020, 2021
103
Double dispatch
Smalltalk conclusion
Functional paradigm
Getting started with Elixir
Alex Ufkes, 2020, 2021 104
Reviews
There are no reviews yet.