|
|
- A quick review for CSCI-344 (Programming Language Concepts)
-
-
- # Ch #1 What are Programming Languages
-
- ## Types
-
- ### Imperative
-
- Most common type of language
-
- - Von Neumann (Fortran, Basic, C)
- - Object-oriented (SmallTalk, java)
- - Scripting (perl, python, basic)
-
- ### Declarative
-
- - Functional (Scheme, ML)
- - Logical (Prolog)
-
- ## Compilation vs Interpretation
-
- Interpretation is more flexible and gives better diagnostics for debugging.
- Compilation provides better performance.
- Often there is no clear cut difference between compilation and interpretation because many languages like java and python do a mix of the both.
-
- ### Compilation
-
- ![](media/plcfinal/compilation.png)
-
- ### Interpretation
-
- ![](media/plcfinal/interpretation.png)
-
-
- ### Mixed
-
- ![](media/plcfinal/mixed.png)
-
-
- ### Compilation Overview
-
- ![](media/plcfinal/compOverview.png)
-
-
- # Ch #2 Parsing
-
- ## Context-Free Grammars
-
- We use CFGs to produce a parse tree from tokens.
-
- ![](media/plcfinal/cfgEx.png)
-
- ## LL Grammar
-
- LL(1) grammar means that it is left right left most derivation parsing with one token look ahead.
- In practice we would use a stack to keep track what we expect to see.
- In this approach we would build the tree top down.
- The LL parsing algorithm uses FIRST/FOLLOW/PREDICT tables.
-
- Ex grammar:
-
- ![](media/plcfinal/ll.png)
-
- ## LR Grammar
-
- LR (Left to right right most derivation) builds the tree bottom up and is almost always table driven.
-
-
- ## Scanning
-
- A scanner is responsible for tokenizing the source, removing comments, saving text of identifiers, and saving line locations for error messages.
- A scanner is most naturally represented as a DFA (Deterministic Finite Automaton).
-
- ![](media/plcfinal/scanner.png)
-
- # Ch #10 Object Oriented
-
- Three major OO Components:
-
- - Encapsulation
- - Inheritance
- - Dynamic method binding
-
- Strict terms for OO lang: everything is an object, inheritance, dynamic method binding.
- Since java has primitives, it is not a true OO language.
-
-
- ## Small Talk
-
- Started as a thesis project in the 1960's, has been noted as being one of the best OO language historically.
-
- Basic coding examples on class-inheritance and constructors may be on exam.
-
- ### Syntax
-
- Excessively uses parenthesis.
- Method calls are in the form: (function:: object parameter1 parameter 2).
- NOTICE: the colons in the function name represents how many parameters it has.
- Also, there are no commas between parameters.
-
-
-
- Basic example class.
-
- ```scheme
- (class Shape Object
- (perimeter area) ; class-level parameters
-
- ;constructor
- (class-method initalize::shape (per ar)
- (init::shape (new self) per ar)
- )
-
- (method init::shape (per ar)
- (setPerimeter: self per)
- (setArea: self ar)
- self
- )
-
- (method getPerimeter ()
- perimeter
- )
-
- (method getArea ()
- area
- )
-
- (method setArea: (a)
- (set area a)
- )
-
- (method setPerimeter: (p)
- (set perimeter p)
- )
- )
-
- (val shape1 (initalize::shape Shape 12 5))
-
- ; area
- (getArea shape1)
- (setArea: shape1 88)
- (getArea shape1)
- ```
-
-
- Example with inheritance:
-
- ```scheme
- (class Circle Shape
- (radius)
-
- (class-method initalize:circle (rad)
- (init:circle (new self) rad)
- )
-
- (method init:circle (rad)
- (setRadius: self rad)
- self
- )
-
- (method setRadius: (rad)
- (set radius rad)
- (setArea: self (computeArea self))
- (setPerimeter: self (computePerimeter self))
- )
-
- (method getRadius ()
- radius
- )
-
- (method computeArea ()
- (*
- (asFloat (/ 22 7))
- (asFloat (squared radius))
- )
- )
-
- (method computePerimeter ()
- (*
- (asFloat 2)
- (*
- (asFloat (/ 22 7))
- (asFloat radius)
- )
- )
- )
- )
-
-
- (val circle1 (initalize:circle Circle 5))
- (getRadius circle1)
- (getArea circle1)
- (getPerimeter circle1)
-
- (setRadius: circle1 6)
- (getRadius circle1)
- (getArea circle1)
- (getPerimeter circle1)
- ```
-
- # Ch #3: Name, Scope, and Binding
-
- A name is a identifier. A binding links a name to an item.
- Scope is simply when a binding is active.
-
-
- # Binding
-
- Binding typically happens at two times:
- - Static: before run time
- - Dynamic: at run time.
-
- The earlier the binding the greater efficiency you have. The later the binding the greater flexibility you have.
-
- Static scope rules use the structure of the program.
- Dynamic scope rules depends on the current state of the program so, the function call sequences can change which bindings are active.
-
- # Lifetime
-
- Key events:
-
- - creation of object
- - creation of binding
- - references to variables (uses binding)
- - deactivation of binding (leave function stack)
- - reactivation of bindings
- - destruction of bindings
- - destruction of object
-
- If object out lives its binding it's garbage.
- If binding out lives its object it's a dangling reference.
-
- # Ch #4 Semantic Analysis
-
- The role of semantic analysis is to enforce semantic rules and generate a syntax tree(decorate the parse tree).
- To do this we use a attribute grammar.
-
- ex attribute grammar:
-
- ![](media/plcfinal/attributeGrammar.png)
-
- ## S-Grammar:
-
- Only uses synthesized attributes: the grammar above.
-
- ![](media/plcfinal/sgrammar.png)
-
- ## L-Grammar:
-
- A l attribute depends on things above them or besides them in the parse tree.
-
- ![](media/plcfinal/lgrammar.png)
-
- ## Action Routines
-
- Functions used to interleave the parser.
-
-
- # Ch #11: Functional Programming
-
- Examples:
- - Lisp
- - Scheme
- - FP
- - ML
- - Haskell
-
- Key Ideas:
- - everything is done by composing functions
- - no mutable state
- - no side effects
- - just produces a answer/result
-
- Necessary Features:
- - first class and high-order functions (takes in/returns functions)
- - polymorphism
- - powerful list functionality
- - structured function returns
- - fully general aggregates
- - garbage collection
-
- Since there is no state, it heavily relies on recursion to replace iteration.
-
- ## Scheme
-
- Not purely functional because it has some imperative stuff like assignment, I/O, sequencing and IO
-
- Scheme scopes:
- - let: calculates all RHS and then assign, can't use prior ones
- - let*: evaluates and then assigns
- - letrec: evaluates and then assign, this will loop back to fill in missing pieces as they are declared
-
-
- ### Scheme Examples:
-
- Note: cdr is tail of list and car is the first element in the list.
-
- ```scheme
- ; Computes length of list
- (define (length lst)
- (if (null? lst)
- 0
- (+
- 1
- (length (cdr lst))
- )
- )
- )
-
-
- ; determines if something is in the list
- ; returns:
- ; 1 if true(in list)
- ; 0 if not in list
- (define (inList lst n)
- (if (null? lst)
- 0
- (if (= n (car lst))
- 1
- (inList (cdr lst) n)
- )
- )
- )
-
- ; finds the sum of the list
- (define (sumList lst)
- (if (null? lst)
- 0 ; empty list
- (+
- (car lst)
- (sumList (cdr lst))
- )
- )
- )
- ```
-
- # Ch #6: Control Flow
-
- Types of iteration:
- - Sequencing: specifies a linear ordering on statements
- - Selection: selects a section of code ie: if statements
- - Iteration: for loops, iterates over a well-defined set
- - Concurrency
- - Exception Handling
- - Non-determinacy
-
-
- Orthogonality: feature can be used in any combination and the meaning is consistent.
-
-
- # Ch #7: Data Types
-
-
- Data types are a collection of values from a "domain".
- Data types specify the structure of the data and a collection of well-defined operations you can perform on that type.
- Data types are useful for implicit context and so that we can avoid meaningless operations.
-
- Strong typing is when language prevents on data that is not appropriate.
-
- Static typing is strong typing that the compiler can do.
-
- Orthogonality: no restriction on how a collection of features can be combined: like python lists.
-
- ## Type Systems
-
- A type system has rules for the following:
- - type equivalence
- - type compatibility: can type A be used in context of type B
- - type inference: type of expression given its operands types
-
- ## Type Checking
-
- Two major types:
- - Structural Equivalence: based on memory layout to determine if same -- can result in unintended equivalencies
- - Name equivalence: based on declaration type -- most common
-
- ## Coercion
-
- When an expression of one type is used in the context of another. Implicit coercion is when the language does it.
- Explicit is when the programmer does it (Casting).
-
- # Ch #12: Logical Programming
-
- Logical programming is based on predicate calculus.
-
- Important concepts:
- - Axioms: facts assumed true in knowledge base
- - Theorems: things that are provably true
- - Hypotheses: things or queries we would like to prove
- - ATOM is a constant like a number
-
- Within logical languages, statements can be written many ways.
- Logical languages are good for people but bad for people.
- Prolog uses backwards chaining to prove things true mathematically.
-
-
- A horn clause contains a HEAD and a BODY, sll statements must be in this term. The head is a single term, but, the body can be a list of terms.
-
- ## Prolog Ex
-
- ```Prolog
- path(b, f, 6).
- path(g, f, 3).
- path(e, g, 2).
- path(h, g, 4).
-
-
- % makes paths bi-directional
- biPath(A, B, Y) :- path(A, B, Y).
- biPath(A, B, Y) :- path(B, A, Y).
-
- % X is starting point
- % Y is ending point
- % P is a list of the points on the final path if one exists
- % N is the distance between X and Y if one exists
-
- % rule for terminal
- solveV(X, X, [X], 0, V).
-
- % recursively build out path
- solveV(A, B, [A|P], N, V) :- biPath(A, C, CC),
- \+member(C, V),
- solveV(C, B, P, CCC, [C|V]),
- N is CC + CCC.
-
- % expand given definition to helper function
- solve(A, B, P, N) :- solveV(A, B, P, N, [A]).
-
- % ex test runs in interpreter
- solve(h, c, P, N).
- solve(a, e, P, N).
- solve(g, c, P, N).
- solve(a, a, P, N).
- solve(g, h, P, N).
- ```
-
- # Ch #8: Composite Types
-
- Types:
- - Records (Structures)
- - Arrays
- - Strings
- - Pointers
- - Lists
- - File I/O
-
- ## Garbage Collection
-
- Problem with reference counter for garbage collection:
-
- ![](media/plcfinal/counter.png)
-
- Mark and Sweep solution:
-
- - Garbage collector walks heap basically marks everything as useless
- - starts at outside pointers marking everything it can get to as useful
- -walks the heap again placing useless items in the free queue.
-
-
- ## Pointers
-
- ### Tombstones
-
- Costly way of dealing with pointers references.
- This will create an additional object to maintain the pointer.
-
- ![](media/plcfinal/rip.png)
-
-
- ### Lock and Keys
-
- Makes sure that pointers and pointe contains the same lock value before you dereference the object.
- Note: this does not prevent attempting to use memory outside of your block resulting in a seg fault.
-
- ![](media/plcfinal/lock.png)
-
-
- # Ch #13: Erlang
-
- Approaches to parallel programming:
- - Synchronized access to shared memory
- - Message passing between processes (slower)
-
- Race conditions are whe the result depends on the order of the thread actions.
- Usually due to bad synchronization but, not always bad.
-
- Synchronization ensures that events in different processes happen in a desired order.
- Mutual exclusion: only one can access at a time.
- Condition synchronization: wait until some condition is true.
-
- Spin lock - busy-wait mutual exclusion, they waste processing cycles. Semaphores: widely used and uses a scheduler-based methods.
- Monitors are used to note who is in a critical region.
-
- ## Erlang
-
- Syntax of erlang is very similar to prolog with its pattern matching.
- Erlang relies on message passing for concurrency.
- Each process contains a "mailbox" where it can receive messages from.
- You process by listening for a message of a specific format: ie you can choose to ignore certain messages for a period of time.
-
- ### Examples
-
- ![](media/plcfinal/erlang.png)
-
- ```Erlang
- %%%-------------------------------------------------------------------
- %%% @author Jeffery Russell
- %%% @doc
- %%% PLC assignment 4
- %%% @end
- %%% Created : 16. Nov 2019
- %%%-------------------------------------------------------------------
- -module(prog4).
- -author("jeff").
-
- %% API
- -export([start/0, bank/0, client/0]).
-
- % helper function to spawn a specific amount
- % of clients
- spawn_client(N) when N >= 1 ->
- io:fwrite("Spawning a client\n"),
- spawn(prog4, client, []),
- spawn_client(N -1);
-
- spawn_client(_) ->
- io:fwrite("Spawned all clients\n").
-
- % start with random account balance between 2k-3k
- % receives message {clientid, number}
- % negatives removes from bank, positives add
- % returns {<client_id>, balance}
- bank() ->
- Balance = rand:uniform(1000) + 1999,
- io:format("Bank balance starting at: ~w~n", [Balance]),
- Client_count = rand:uniform(7) + 2,
- Client_left = 1,
- spawn_client(Client_count),
- loop(Balance, Client_count, Client_left).
-
- % main bank loop which listens for messages and
- % processes them
- loop(Balance, Client_count, Client_left) ->
- receive
- %io:format("Bank now has ~w", [balance])
- {CLIENT_ID, balance} ->
- io:fwrite("~w Requested Balance from the bank\n", [CLIENT_ID]),
- CLIENT_ID ! {Balance},
- loop(Balance, Client_count, Client_left);
- {CLIENT_ID, NUMBER} ->
- if
- Balance + NUMBER >= 0 ->
- CLIENT_ID ! {NUMBER, Balance + NUMBER, successful},
- loop(Balance + NUMBER, Client_count, Client_left);
- true ->
- CLIENT_ID ! {NUMBER, Balance, failed},
- loop(Balance, Client_count, Client_left)
- end;
- goodbye ->
- if
- Client_left == Client_count ->
- io:format("Bank is closing with balance ~w`\n", [Balance]);
- true ->
- loop(Balance, Client_count, Client_left + 1)
- end
- end.
-
-
- % helper function to fetch and print balance of the bank
- client_fetch_balance() ->
- bank_pid ! {self(), balance},
- receive
- {Balance} ->
- io:format("~w recieved the balance of ~w from the bank~n", [self(), Balance])
- end.
-
-
- % client process loop
- % if loop is increment of 5, it requests balance of bank
- % withdraws a random amount of money from mank
- % and prints the bank's response
- % after each withdrawl, it will sleep
- client_loop(LoopUntil, CurrentIndex) ->
- if
- CurrentIndex rem 5 == 0 ->
- client_fetch_balance();
- true -> pass
- end,
-
- if
- LoopUntil == CurrentIndex ->
- bank_pid ! goodbye,
- io:format("~w Client Finished\n", [self()]);
- true ->
- bank_pid ! {self(), 100-rand:uniform(199) },
-
- receive
- {Amount, Balance, Suc} ->
- io:format("~w recieved the balance of ~w from the bank after a ~w transation request of ~w~n", [self(), Balance, Suc, Amount])
- end,
- timer:sleep(rand:uniform(1000) + 499),
- client_loop(LoopUntil, CurrentIndex + 1)
- end.
-
-
- % creates random amount of clients
- client() ->
- Nums = rand:uniform(10) + 9,
- client_loop(Nums, 0).
-
-
- % spawns the bank
- start() ->
- register(bank_pid, spawn(prog4, bank, [])).
- ```
-
- # Ch #14: Scripting Languages
-
-
- Common Characteristics:
- - both batch and interactive use
- - easy to write high level expressions
- - simple scoping rules
- - flexible dynamic typing
- - easy access to other programs
- - sophisticated pattern matching and string manipulation
- - high level data types
-
- Often used to glue together other programs.
-
- Need to know bash on the exam.
-
- ## Bash
-
- ### Shall Parameters
-
- - "$#" is the number of parameters passed
- - "$0" is name of the script and its location in filesystem
- - "$1" is the first command line parameter. Goes up till 9
- - "$*" single word of all the parameters
- - "$@" array of all the parameters
-
- ex:
-
- ```bash
- if [ $# -eq 3 ];
- then
- if [ -f $1 ]
- then
- if [ -f $2 ]
- then
- encode_message $1 $2 $3
- else
- echo "File $2 does not exist"
- fi
- else
- echo "File $1 does not exist"
- fi
- else
- echo "Usage:"
- echo " encoder.sh <plane_text_file> <secret_key_file> <encoded_file>"
- fi
- ```
-
- ### Files
-
- ```bash
- while read line || [ -n "$line" ];
- do
- for word in $line
- do
- echo "$word"
- done
- done < "$1"
- ```
-
- ### Comparisons
-
- Numbers:
-
- - "-eq" equal
- - "-ge" greater than or equal
- - "-le" less than or equal
- - "-ne" not equal
- - "-gt" greater
- - "-lt" less
-
- ex:
-
- ```bash
- [n1 -eq n2]
- ```
-
-
- Strings:
-
- - "=" equal
- - "!=" not equal
- - "-n" length is greater than zero
- - "-z" length is equal to zero
-
- ex:
-
- ```
- [ s1 - s2 ]
- [ -n s1 ]
- ```
-
- Files:
-
- - "-d" path is a directory
- - "-f" is a file
- - "-e" file name exists
- - "-r" check of read permission
- - "-s" file has length greater than 0
- - "-w" write permission
- - "-x" execution permission
-
- ex:
- ```bash
- [ -d fname ]
- ```
-
- ### Control Flow
-
- #### If Statements
-
- ```bash
- if [ expression ];
- then
- statements
- elif [ expression ];
- then
- statements
- else
- statements
- fi
- ```
-
-
- #### Switch Statements
-
- ```bash
- case $var in
- val1)
- statements
- ;;
- val2)
- statements
- ;;
- *)
- statements
- ;;
- esac
- ```
-
- ### Math
-
- To do math you math like this:
-
- ```bash
- echo "$((124+23))"
-
- # or like this:
-
- VALOR=$[124+23]
-
- # or with let
-
- let X=124+23
- ```
-
-
- ### Functions
-
- Functions exist in bash.
-
- ```bash
- #!/bin/bash
- hello()
- {
- echo "Woeie"
- }
- hello # no parenthesis needed when calling
-
- # you can also declare functions with the keyword
-
- function check()
- {
- return 42
- }
- ```
-
-
|