Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 1: Class overview & Introduction to Functional Programming

Similar presentations


Presentation on theme: "Lecture 1: Class overview & Introduction to Functional Programming"— Presentation transcript:

1 Lecture 1: Class overview & Introduction to Functional Programming
MPCS 51400: Functional Programming

2 Lamont Samuels, PhD Office Hours: TBD

3 Course Overview All course information is located on the course website: 2017/fall/ /

4 What is functional programming?
Functional programming is a programming paradigm that relies on functions modeled on mathematical functions Programs are built from expressions: Concrete values (2, 3.45, False, “Hello!”) Variables (x, y, z) Functions ( C/Java: void foo(), void bar(int b) ) Thus, a functional program consists of a combination of expressions

5 Functions Functions are expressions that are applied to an argument or input, and once applied can be reduced or evaluated. Generally functions in functional languages are first-class: Functions can be represented as values, arguments and inputs to other functions.

6 Why Study functional programming?
Functional concepts are being adopted by more popular languages: First-class functions added to C++ (C++11), Java, Objective C, Visual Basic Found in scripting languages: Perl, Python, Ruby?(closures) MapReduce at Google, Twitter, etc. Use of ML and Haskell in financial industry Applications in graphics programming and web (REACT, Elm) Combination of Object-Oriented Programming and Functional Programming (OCaml, Moby, Scala) Real reason: power with simplicity (doing things the easy way)

7 Haskell Haskell is a lazy pure functional language (more on lazy evaluation later…) “Pure” in functional programming sometimes also used to mean what is more properly called referential transparency: Same function, given the same values to evaluate will always return the same output. Similar to functions described in mathematics: f(x) = x + 2, g(x) = x^2

8 Why Haskell? High-level of abstraction and comparability due to it being a purely functional language. Abstraction allows you to write shorter and concise programs by factoring out repeated structures into more generic code that be reused. Haskell programs are built from independent functions kind of like LEGOs: Functions are bricks that can be assembled and reassembled

9 Course Software

10 Course Software Stack (Haskell Project building tool): E/ Haskell platform: Git: IDE or Text Editor. I’m using Visual Studio Code:

11 Git Modern version control system.
Is an example of a DVCS (Distributed Version Control System). As Atlassian states, “Rather than have only one single place for the full version history of the software as is common in once-popular version control systems like CVS or Subversion (also known as SVN), in Git, every developer's working copy of the code is also a repository that can contain the full history of all changes"

12 GIT architecture

13 Git Setup Download Git from here: git-scm.com/downloads
After installing Git and placing it in your PATH environment variable then you want to configure your and name git config --global user.name “Lamont Samuels" git config --global user. Normally, you’ll want to clone a repository. Cloning copies an existing Git repository. For example : git clone

14 Git Commands Add and Commit Files
Add files from your working-dir to stage-dir git add . git add src/. git add src/MyFile.java Moving files back from stage-directory to working directory. git reset head src/. git reset head src/MyFile.java

15 Git Commands Once you add a file/directory you need to commit them to HEAD, but not in your remote repository yet. git commit -m "Commit message” Once your changes are in HEAD then you send those changes to your remote repository.: git push origin master To fetch changes from your remote directory use fetch: git fetch --all

16 Introduction to Haskell

17 Interacting with Haskell
Haskell provides three ways of code interaction: GHCi (aka the REPL): allows you to enter in simple expressions for an immediate answer. File loading: loading files that were modified in an editor/IDE into GHCi for evaluation. Project Building: Large projects can be built and executed using the stack build tool. (Later in the course)

18 REPL The REPL (Read-Eval-Print Loop) originated in the Lisp language and allows for easily and quickly evaluating code and seeing the result. To run the REPL enter one of the following into a terminal window: ghci stack ghci It will initially load the Prelude, which is a library of standard functions (e.g., arithmetic operations, list operations, etc..) If you used stack ghci2 there was probably a lot more startup text, If you have installed GHC outside of Stack, then you should be able to open it with just the ghci command, but if your only GHC installation is what Stack installed, then you will need stack ghci.

19 Demo: Using the REPL

20 Working with Source Files
REPL is great for quickly learning about features of Haskell and evaluating simple expressions. For all nontrivial programming you’ll want to use an editor or IDE and load those files into GHCi. Save files with the .hs extension and you can load them using the following command GHCi commands: :load test.hs loads a file called test.hs :reload reloads the last loaded file (in this case test.hs) :module reloads the Prelude.

21 Demo: Loading from files

22 Expression Evaluation
Everything in Haskell is an expression or declaration. An expressions are values, combinations of values, and/or functions applied to values that produce a result. Evaluation in Haskell is driven by substitution, (aka term rewriting): A process whereby subexpressions of a given expression are replaced by with other expressions. For example (==> represents a simplification of an expression via one substitution step): 4 ** 3 + (4 * 5) ==> 64 + ( 4 * 5) ==> ==> 84

23 Expression Evaluation (Cont’d)
Normal form: expressions are in normal form when there are no evaluation steps (i.e. they are irreducible). Reducible expressions (aka redexes): expressions that can be further reduced. For example on the prior slide: 84 is the normal form of the reducible expression: 4 ** 3 + (4 * 5)

24 Variables We can also introduce particular names for values in the GHCi (aka variables in many other languages) by using the following notation: let <var> = <expr> For example: We can calculate the distance by defining three variables: > let rate = 10 > let time = 20 > let distance = rate * time > distance 200 This is great if we only want to evaluate distance traveled for a single rate and time but what if we want to calculate multiple distances? Functions

25 Functions Functions in Haskell are a specific type of expressions that are related to functions in mathematics: f (x) = x + y g (x) = g^2 Functions are expressions that are applied to an argument that always produce a output. Functions allow use to factor out redundant code into something we can reuse with different inputs Functions have the following syntax in the GHCi: let <function name> <parameters separated by spaces> = <expr> Examples: > let distance rate time = rate * time > distance 10 20 200 > distance 20 30 600 Let's take this apart. The let distance part tells the interpreter that we're going to be defining (or binding) the name distance. The rate time which follow indicate that distance will denote a function that takes two arguments, which we're going to give the names rate and time respectively, the = separates the binding's template from the body of the function we're defining, and then finally rate * time specifies that body. Evaluation: In the first step, we substitute the first argument 10 in for rate, and the second argument 20 in for time in the body of the distance function, and then continue as before.

26 Functions Think of function evaluation as a sequence of substitutions:
> distance 10 20 ==> 10 * 20 ==> 200 Haskel when it seems as though we are passing multiple arguments to a function. We are actually applying a series of nested functions, each to one argument, which is called currying Remember Haskell functions only take one argument. Can we make calling/declaring functions look similar to ones in other imperative languages? Yes! In the first step, we substitute the first argument 10 in for rate, and the second argument 20 in for time in the body of the distance function, and then continue as before.

27 Demo: Functions

28 Prefix & Infix Operations
Functions use prefix syntax were the function is applied at the beginning of the expression  Arithmetic operations (+, -, *) use infix syntax were the operator is between its operands  You can sometimes use infix syntax on functions by using single tick around the function: 100 `div` 10  Similarly some infix operations can be converted to prefix notation by surrounding the operator with ( ): (+) 10 20 

29 Associativity & precedence
Arithmetic operations (+,-,/*) follow the order of operations in mathematics with left associativity  Although some operations may have right associativity such (^)  Functions are right associative and have higher precedence arithmetic operations: Prelude>  distance  10 (2 + 2) 40  Prelude>  distance 2 + 2  22

30 Operator Information You can check the associatively and precedence of operations by using the :info ( or :i) command: > :info (*)  class Num a where ... (*) :: a -> a -> a -- Defined in ‘GHC.Num’ infixl 7 * infixl : means it’s an infix operator, left  associative.  7 : is the precedence: higher is applied first, on a scale of 0-9.  * : Infix function name: in this case, multiplication.

31 Functions & Variables IN FILES
Functions and variables have a slightly different syntax in Haskell source files (.hs)  Variables and functions do not require the “let” keyword before beginning their declaration: distance rate time = rate * time  pi =  

32 Naming Conventions  All variables and functions, parameters should begin with a lower-case letter and use camelCase: The first letter is still lowercase, but we use an uppercase to delineate a word boundary.  All Haskell files and modules should begin with a upper-case letter.  

33 Common Mistakes One of the most important aspects about Haskell source code is that indentation matters.  Incorrect indentation can break your code  ALWAYS use spaces and NOT tabs  Ensure that variables are lined up with each other and there are not spaces at the beginning of new function or variable declarations in the file. 

34 ($) Operator  Very commonly used in Haskell as a convenience to limit the number of parentheses in an expression:  (2^) (2 + 2) ==> 16  -- can replace those parentheses  (2^) $ ==> 16 -- without either parentheses or $  (2^) ==> 6 -- can also stack up the $ in an expression  (2^) $ (+2) $ 3*2 ==> 256

35 Sectioning Allows for passing around partially applied functions.
-- normal infix operation for addition operator  1 + 2  ==> 3 -- prefix notation for the addition operator (+) 1 2 ==>   -- sectioning notation for addition operator  -- adds plus one to any additional argument applied to (+1)  let addOne = (+1) addOne 2 ==> 3 addOne 4 ==> 5 

36 Sectioning (Cont’d.) Commutative functions (e.g. addition) no difference between (+) or (3+) because the order won’t change the result. Non-commutative operations order matters   Prelude> (1/) 2  0.5  Prelude> (/1) 2  2.0

37 Sectioning: Subtraction
Subtraction (-), is a special case because the (-) operator could also mean negation.   - - work just fine  Prelude> 2 - 1 Prelude> (-) 2 1 doesn’t not work. Prelude> (-2) 1

38 Sectioning: Subtraction
Still can use subtraction but it either must be the first argument or use the (subtract x) function :  Prelude> let x = 5  Prelude> let y = (1 -)  Prelude> y x -4  -- or use the (subtract x) function: Prelude> (subtract 2) 3 1

39 Let & Where Syntax Both allow for the binding of variables in a function or nested expression.   Similar in functionality but are fundamentally different: where expression introduces a declaration and is bound to the surrounding syntactic construct:  printInc n = print plusTwo where  plusTwo = n + 2 let expression introduces a bound expression that only scopes over the expression which it encloses printInc2 n = let plusTwo = n + 2  in print plusTwo What’s the difference? We will talk about that more next week.

40 Top-level & local definitions
When the compiler reads a file, we all see top-level declarations (i.e.,declarations that accessible anywhere within the file no matter their order.  In contrast, local-definitions are nested inside another expression and not accessible throughout the file. printInc2 n = let plusTwo = n + 2  in print plusTwo printInc2 ==> top-level declaration. plusTwo ==> local-definition and is only accessible within the definition of printInc2

41 Types Haskell has a strict and expressive typing system.
Every value has a type and types are how we group a set of related values together.  Haskell has many atomic types (e.g. Integer, Double, Char, etc.) that are the building blocks of the type system. You find out the type of an expression easily by typing in :type into the interpreter  Prelude> :type 1.0  1.0 :: Fractional  The “::” symbol is read as “has the type”. The “::” represents a type signature/annotation: A line of  code that defines the types for a value, expression, or function.  A standard programming discipline in Haskell is to provide a type annotation for every top-level definition. This will be our practice henceforth, and you will be expected to do likewise. One of Haskell's greatest strengths is its powerful and robust type system, by which a static analysis of your programs code ensures that the values and expressions you build are used consistently. This said, perhaps the biggest challenge of learning to Haskell is the interaction between the language of function definition and the language of type. Haskell provides considerable support through automatic type inference, but this does not exempt the programmer from the need to understand Haskell's type system, nor from having to annotate some expressions.

42 Integral Types Integral numbers are whole numbers that are positive and negative.  Haskell contains a number of integral types, but the two most important are Int and Integer Int type: Fixed-precision integer with a maximum and minimum range. Use only if performance is important (e.g., computer graphics) Int types: Int8, Int16, Int32, etc. Integer type: Supports arbitrarily large and small numbers. In most cases you’ll want to use Integer type 

43 Real Types Haskell has two main real types: Float and Double
Float : corresponds to IEEE single-precision floating point arithmetic Double : corresponds to IEEE double-precisions floating point arithmetic. Higher precision for a number. Unless there is a very good reason for doing otherwise (e.g., as in computer graphics, where space usage is an issue), programmers will usually use Double to represent real numbers.

44 Char Type Represents unicode characters, which are typically represented via character literals. letter :: Char letter = ‘a’ Documented in Data.Char Contains a lot of useful functions for working with characters such as chr and ord to convert been Char and Int

45 Bool Type Allows for representing truth values: True, and False
Similar to other languages Haskell also has comparison operators Equality operations (Eq): (==) equal to operator  (/=) is not equal to operator  and (not) operator is the negation operator for a boolean expression  Ordering Operations (Ord) : (<) “greater than” , (>) “less than” (>=) “greater than equal to”, (<=) “less than equal to” Conjunction operator (&&) : “true and true” Disjunction operator (||) : “false or true” 

46 If-then Expression Similar to if-statements in other imperative languages. Structure:  if <COND> then <EXPRA> else <EXPRB>  Prelude> let x = 0  Prelude> if (x + 1 == 1) then "AWESOME" else “wut” "AWESOME"

47 Tuples Allows you pass around multiple values as a single value.
Tuples are also immutable and are created within parentheses “ ( … ) “ Must have at least two values. The empty or single tuple is called a unit “()”   Can have a infinite number of values inside the tuple and all values can have different types:  Prelude> let person = (“Mary”, 19)  The two-tuple also has functions for retrieving its first and second components:  fst :: (a, b) ->a AND snd :: (a, b) -> b Prelude> fst person "Mary" Prelude> snd person 19

48 Tuple Constructor You can also use the tuple constructor operator "(,)” to make a tuple but remember it requires at least 2 values: Prelude> (,) 8 10  (8,10)  Prelude> (,) 8 “Julie" (8,"Julie”)  Prelude> (,) True 'c’  (True,’c’)

49 Accessing nth-Tuples You can deconstruct a nth-tuple parameter inside an expression by using the “()” and binding its components to variables. total (a1, b1, c1) (a2, b2, c2) = a1 + b1 + c1 + a2 + b2 + c2 > total (1,2,3) (4,5,6) 21 You can also deconstruct them using let and where expressions: total2 tup1 tup2 = >let (a1,b1,b2) = tup1 (a2,b2,b3) = tup2 in a1 + b1 + c1 + a2 + b2 + c2 > total2 (1,2,3) (4,5,6)

50 Accessing nth-Tuples This notation also works with nested nth-tuples.
nestedTotal ((a, b), (a1, b1, c1)) = a + b + a1 + b1 + c1 >nestedTotal ((3,4),(1,2,3)) 13 You are not required to bind each component to a variable. You can ignore components by using a “_” (wild card). We will talk more about this next week. nestedTotal2 ((a, b), (_, _, c1)) = a + b + c1 > nestedTotal2 ((3,4),(1,2,3)) 10

51 Lists Also allow you to pass around multiple values as a single value but with three differences from tuples: All values must be of the same type  They have their own distinct syntax “[ ]”  The are mutable  Example:  Prelude> let numbers = [1,2,3,4]  Prelude> :t numbers  numbers :: Num t => [t]

52 Constructing Lists Explicit enumerations of its elements (syntactic sugar) using [ … ] Provides a clear concise notation for constructing lists: [1,2,3,4,5] In reality, there are only two types of lists: Empty list, which contains no elements. Constructed using ( [ ] ), Cons list, which is a list that contains at least one element. Constructed using (:) Eg. 1:2:3:4:5:[] Note that ( : ) associates to the right so really it looks like : 1 : (2 : (3 : (4 : (5 : []))))

53 New “Types” The type keyword is used to introduce a new name (a synonym) for an existing type, it does not create a new type. type String = [Char]

54 New “Types” EXAMPLE word1:: String word1 = “Hello" word2 :: [Char]
word2 = “World!" word3 :: String word3 = [‘H’,'e','l','l','o'] Prelude> word1== word3 True

55 Function Types A function f from type A to B has type “A -> B”. For example: square :: Int -> Int square intNum = intNum ^ 2 The arrow “->” associates to the right: (+) :: Int -> Int -> Int Which is shorthand for: — Remember functions only take in one argument (+) :: Int -> (Int -> Int)

56 Function Type Examples
So an expression like this: (+) 3 4 Could have the various subexpression types: (+) :: Int -> Int -> Int {- also equivalent to ==> Int -> (Int -> Int) -} :: Int (+) 3 :: Int -> Int :: Int (+) 3 4 :: Int


Download ppt "Lecture 1: Class overview & Introduction to Functional Programming"

Similar presentations


Ads by Google