pl categories: functional pls introduction to haskell ... · 2/22/2017  · a functional...

34
PL Categories: Functional PLs Introduction to Haskell Haskell: Functions CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Wednesday, February 22, 2017 Glenn G. Chappell Department of Computer Science University of Alaska Fairbanks [email protected] © 2017 Glenn G. Chappell

Upload: others

Post on 14-Jul-2020

9 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

PL Categories: Functional PLsIntroduction to HaskellHaskell: Functions

CS F331 Programming LanguagesCSCE A331 Programming Language ConceptsLecture SlidesWednesday, February 22, 2017

Glenn G. ChappellDepartment of Computer ScienceUniversity of Alaska [email protected]

© 2017 Glenn G. Chappell

Page 2: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

ReviewShift-Reduce Parsing [1/2]

Shift-Reduce is a bottom-up, LR parsing algorithm.§ It is table-driven.§ Shift-Reduce is no longer used. However, a number of similar—but

more complicated—algorithms are heavily used.

A Shift-Reduce parser is a state machine with an associated stack.§ A stack item holds a symbol—terminal or nonterminal—and a state.§ The current state is the state in the top-of-stack item.§ The table has two parts: action table (rows are states, columns

are terminals) and goto table (rows are states, columns are nonterminals).

Operation§ Begin by pushing an item holding the start state (and any symbol).§ At each step, do a lookup in the action table, using the current state

and the current input symbol. Do what the action table entry says.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 2

Page 3: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

ReviewShift-Reduce Parsing [2/2]

We constructed the following Shift-Reduce parsing table in class.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017

STATE ACTION TABLE GOTO TABLE

Note Number ID ( ) $ all item

start: — 1 S2 S3 G8 G4

ID 2 R3( 3 S2 S3 G5

—item 4 S6

(item 5 S7

—item$ 6 R1

(item) 7 R2

—all 8 ACCEPT

3

Page 4: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

ReviewParsing Wrap-Up — Efficiency of Parsing

Practical parsing algorithms:§ Cannot handle all CFLs.§ Run in linear time.

This includes Recursive Descent and Shift-Reduce.

There are parsing algorithms that can handle all CFLs. These are much slower and are mostly theoretical curiosities.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 4

Page 5: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

PL Categories: Functional PLsBackground [1/3]

Functional programming (FP) is a programming style that generally has the following characteristics.§ Computation is considered primarily in terms of the evaluation of

functions (as opposed to execution of code).§ Thus, functions are a primary concern. Rather than considered as

repositories for code, functions are values to be constructed and manipulated.

§ Side effects & mutable data are avoided. The only job of a function is to return a value.§ A side effect occurs when a function alters data, and this alteration is

visible outside the function.§ Mutable data is data that can be altered.

In PLs like C++, Java, and Lua, we mostly do imperative programming: tell the computer what to do. An alternative is declarative programming: tell the computer what is true. FP is one kind of declarative programming. (We will look at another kind later in the semester.)

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 5

Page 6: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

PL Categories: Functional PLsBackground [2/3]

One can do FP, in some sense, in just about any PL. However, some PLs support it better than others.

A functional programming language is a PL designed to support FP well. This is thus a somewhat vague term.§ No one calls C a functional PL.§ Opinions vary about JavaScript.§ Everyone agrees that Haskell is a functional PL.

PLs generally agreed to be functional include Haskell, the ML family (ML, OCaml, F#), R, and Miranda.

In addition, the Lisp family (Common Lisp, Emacs Lisp, Scheme, Clojure, Racket, Logo) generally offers excellent support for FP, but is usually considered as a separate category.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 6

Page 7: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

PL Categories: Functional PLsBackground [3/3]

FP and functional PLs have been around for many decades, but they remained largely the province of academia until two things happened.§ In the 1990s the problem of how to do interactive I/O in a purely

functional context was solved.§ In the years around 2000, serious attention was first given to the

practical issues of algorithmic efficiency and resource usage in a purely functional context.

Today, FP and functional PLs are becoming increasingly mainstream. Constructs inspired by FP are being introduced into a number of PLs.§ For example, lambda functions became part of C++ in the 2011

Standard.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 7

Page 8: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

PL Categories: Functional PLsTypical Characteristics [1/2]

Recall that a type is first-class if its values can be tossed around with the same ease and facility as types like int in C++.

More formally, a type is first-class if its values can be used in each of the following ways.§ New values can be created from existing values at runtime.§ Values can be passed as arguments to functions and returned from

functions.§ Values can be stored in containers.

We are particularly interested in the idea of first-class functions.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 8

Page 9: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

PL Categories: Functional PLsTypical Characteristics [2/2]

A typical functional programming language has the following features/characteristics.§ It has first-class functions.§ It offers good support for higher-order functions.

§ A higher-order function is a function that acts on functions.§ It offers good support for recursion.§ It has a preference for immutable data.

A pure functional PL goes further, and does not support mutable data at all. There are no side effects in a pure functional PL.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 9

Page 10: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellHistory [1/2]

The next programming language we will look at is Haskell, named for Logician Haskell Curry (1900–1982).

Haskell was created as the result of a meeting in 1987. Some members of the FP community felt that their efforts were too fragmented. They decided to create a single PL intended to support research or development by large numbers of people.

The initial version of Haskell was released in 1990.In the 1990s, the problem of how to do interactive I/O without side

effects was solved, allowing Haskell and FP to enter the mainstream.

Various language definitions in the 1990s culminated in a long-term standard in 1998 (Haskell 98). This was implemented in Hugs, a simple interactive environment supported on all major platforms. There was also a full-featured compiler: the Glorious Glasgow Haskell Compiler (GHC). Hugs has since been folded into GHC; the interactive environment is now called GHCi.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 10

Page 11: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellHistory [2/2]

2009 saw the release of the Haskell Platform, a collection of libraries and tools with the goal of creating a high-quality, “batteries-included” collection of packages that all Haskell developers could have in common. A new release of the Haskell Platform comes once or twice each year.

A second Haskell standard was published in 2010 (Haskell 2010, or Haskell Prime). The is currently the most recent standard. A plan for yearly standards was announced, but it has not become a reality. A third Haskell standard is currently in the works.

Haskell is now a robust, well supported PL, suitable for large commercial projects. However, its unusual nature has led to a fair amount of resistance from traditionally minded programmers. The most recent TIOBE index—February 2017—lists Haskell as the 38th most popular PL (up from 40th a year ago and 46th two years ago).

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 11

Page 12: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Type System [1/4]

Haskell is a pure functional PL. It has first-class functions and good support for higher-order functions.

Haskell has a sound static type system with sophisticated type inference. So typing is largely inferred, and thus implicit; however, we are allowed to use manifest typing, if we wish.

Haskell’s type-checking standards are difficult to place on the nominal-structural axis.

Haskell has few implicit type conversions. New implicit type conversions cannot be defined.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 12

Page 13: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Type System [2/4]

Like C++ and Java, Haskell does static typing of both variables and values. Unlike C++ and Java, Haskell includes excellent support for type inference (based on the Hindley-Milner type-inference algorithm). Thus, types usually do not need to be specified.

In C++:

int n = 3;

In Haskell:

n = 3

Of course, in Lua we can say that, too. But in contrast to Lua, the variable n has a type in Haskell (Integer in this case); the compiler is able to figure this out for us.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 13

Page 14: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Type System [3/4]

Haskell still allows type annotations, if desired. We can say:

n :: Integern = 3

This lets us communicate our intentions to be compiler. For example, the following is legal.

s = "abc"

But this will not compile:

s :: Integers = "abc" -- Type error: "abc" is not of type Integer

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 14

Page 15: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Type System [4/4]

We can also use Haskell type annotations to restrict which types are allowed. Below is a function with its natural type annotation. Omitting this annotation would have the same result.

blug :: (Eq t, Num t) => t -> t -> Boolblug a b = (a == b+1)

The above says that blug is a function that takes two values of type t, where t is a numeric type with equality operations defined, and it returns a boolean.

But if we only want blug to take integers, then we can do this:

blug :: Integer -> Integer -> Boolblug a b = (a == b+1)

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 15

Page 16: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Flow of Control

Haskell implementations are required to do tail call optimization(TCO). This means that the last operation in a function is not implemented via a function call, but rather as the equivalent of a goto, never returning to the original function.

Iteration is difficult without mutable data. And, indeed, Haskell has no iterative flow-of-control constructs. It uses recursion instead, with tail recursion preferred. The latter will generally be optimized using TCO.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 16

Page 17: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Syntax [1/2]

Haskell has a simple syntax, with less punctuation than C++—and even less than Lua. Here are function calls in C++ and Lua.

foo(a, b, c); // C++foo(a, b, c) -- Lua

Here is a more or less equivalent function call in Haskell.

foo a b c -- Haskell

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 17

Page 18: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Syntax [2/2]

Haskell has significant indentation. Indenting is the usual way to indicate the start & end of a block. Here is Lua.

function bar(a)local b = 42 // Indented, but only forlocal c = 30 * b + 1 // readability; the compilerreturn foo(a, b, c) // ignores indentation.

end

And here is the more or less equivalent Haskell.

bar a = foo a b c whereb = 42c = 30 * b + 1 -- We MUST indent this line.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 18

Page 19: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Evaluation [1/2]

By default Haskell does lazy evaluation: expressions are not evaluated until they need to be. C++, Java, and Lua do the opposite, evaluating as soon as an expression is encountered; this is eager evaluation (or strict evaluation).

For example, here is a function in Lua, and then in Haskell.

function f(x, y)return x+1 -- y is not used

end

f x y = x+1 -- y is not used

We look at what eager evaluation vs. lazy evaluation means for these.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 19

Page 20: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellCharacteristics — Evaluation [2/2]

function f(x, y)return x+1 -- y is not used

end

Lua (eager). Do “f(g(1), g(2))”. Function g is called with 1. Then g is called with 2. The return values are passed to f.

f x y = x+1 -- y is not used

Haskell (lazy). Do “f (g 1) (g 2)”. Function f is called; this uses its first parameter (x), so g is called with argument 1, and its return value becomes x. Then f adds 1 to this and returns the result. The second call to g is never made.

If the return value of f is not used, then no calls to g are made!Lazy evaluation has other interesting consequences, as we will see.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 20

Page 21: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellBuild & Execution [1/3]

The standard filename suffix for Haskell source files is “.hs”.

GHC is a Haskell compiler that usually generates native machine code. On the command line, GHC is used much like g++, clang, or any other command-line compiler.

ghc myprog.hs –o myprog

If there are no errors, then an executable named “myprog” will be generated. Running that file will execute function main in module Main (a module in Haskell is much like a module in Lua).

Of course, if you are using an IDE, then things are handled differently. GHC is supported by various IDEs, including Eclipse.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 21

Page 22: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellBuild & Execution [2/3]

GHCi is an interactive environment that interprets Haskell code. Such an environment is often called a Read-Eval-Print Loop(REPL), a term originating with Lisp.

GHCi can load source files or evaluate entered Haskell expressions. Haskell is compiled to a bytecode, which is interpreted.

After running GHCi, you are presented with a prompt. GHCicommands begin with colon (:). Some important commands:

:l FILENAME.hsLoad & compile the given source file. Afterward, calls to functions in the file may be typed in at the prompt.

:r

Reload the last file loaded. Useful if you change a file.

Continued …

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 22

Page 23: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellBuild & Execution [3/3]

Continuing with GHCi commands:

:t EXPRESSIONGet the type of a Haskell expression. The expression can involve variables and functions defined in a file that has been loaded.

:i IDENTIFIERGet information about the identifier: its type; precedence and associativity if it is an operator; perhaps the file it is defined in.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 23

Page 24: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Introduction to HaskellSome Programming

I have written a simple example Haskell program that computes Fibonacci numbers.

22 Feb 2017 CS F331 / CSCE A331 Spring 2017

See fibo.hs.

24

Page 25: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsBasic Syntax [1/3]

The material for this topic is also covered in a Haskell source file, which is extensively commented.

Haskell expression: stream of words separated by blanks where necessary. Optional parentheses for grouping.§ Each line below is a single Haskell expression. Type it at the GHCi

prompt and press <Enter> to see its value.

2+3(2+3)*5reverse "abcde"map (\ x -> x*x) [1,2,3,4]

22 Feb 2017 CS F331 / CSCE A331 Spring 2017

See func.hs.

25

Page 26: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsBasic Syntax [2/3]

Comments§ Single line, two dashes to end of line: -- …§ Multi-line, begin with brace-dash, end with dash-brace: {- … -}

Identifiers begin with letter or underscore, and contain only letters, underscores, digits, and single quotes (').§ Normal identifiers begin with lower-case letter or underscore. These

are used to name variables and functions.

myVariablemy_Function'_33

§ Special identifiers begin with UPPER-CASE letter. These are used to name types, modules, and constructors.

MyModule

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 26

Page 27: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsBasic Syntax [3/3]

Define a variable by giving its name, and equals sign (=) and an expression for the value.

ab'c = 7 * (3 + 2)

A variable definition is not an expression in Haskell.The above is legal in a Haskell source file. At the GHCi prompt it

must be preceded by let.

let ab'c = 7 * (3 + 2)

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 27

Page 28: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsDefining Functions & Operators [1/3]

To define a Haskell function, write what looks like a call to the function, an equals sign, and then an expression for what the function returns.

addem a b = a+b

We can also define new operators. Infix binary operators have names consisting of special characters. They are defined similarly.

a +$+ b = 2*a + b

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 28

Page 29: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsDefining Functions & Operators [2/3]

Function definitions use pattern matching. Define a function differently for different patterns. The first matching pattern is the one used.

Here is a factorial function.

factorial 0 = 1factorial n = n * factorial (n-1)

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 29

Page 30: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsDefining Functions & Operators [3/3]

We can use a regular function as an infix operator by surrounding its name with backquotes (`). Having defined function addem, try the following at the GHCi prompt.

2 `addem` 3

And we can use an operator as a regular function by surrounding its name with parentheses. Having defined +$+, try the following at the GHCi prompt.

(+$+) 5 7

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 30

Page 31: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsLocal Definitions

Use where to introduce a block (indent!) of local definitions.

plus_minus times a b c d = a_plus_b * c_minus_d wherea_plus_b = a + bc_minus_d = c - d

Local-definiton blocks can be nested.

twiceFactorial n = twice (factorial n) wheretwice k = two*k where

two = 2factorial 0 = 1factorial curr = curr * factorial prev where

prev = curr-1

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 31

Page 32: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsFunction Application & Currying

Currying mean simulating a multiparameter function using a single parameter function that returns a function.

For example, our function addem really takes one parameter. It returns a function that adds that parameter to something. The following are the same:

addem 2 3 -- Returns 5(addem 2) 3 -- Returns 5

We can give the intermediate function a name.

add2 = addem 2add2 3 -- Returns 5

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 32

Page 33: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsHigher-Order Functions

A higher-order function is a function that acts on functions.

rev f a b = f b a

sub a b = a - brsub = rev sub

sub 5 2 -- Returns 3rsub 5 2 -- Returns -3

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 33

Page 34: PL Categories: Functional PLs Introduction to Haskell ... · 2/22/2017  · A functional programming languageis a PL designed to support FP well. This is thus a somewhat vague term

Haskell: FunctionsLambda Functions

A lambda function (or lambda expression) is a kind of expression whose value is a function.§ The name comes from the lambda calculus, a mathematical

system in which everything is a function. In this system, an unnamed function is introduced using the Greek letter lambda (λ).

§ Haskell uses a backslash (\) since it looks a bit like a lambda.

square x = x*xsquare’ = \ x -> x*x -- Using lambda function;

-- same as above

-- Alternate definitions for addemaddem’ = \ x y -> x+yaddem’’ a = \ y -> a+yaddem’’’ = \ x -> (\ y -> x+y)

22 Feb 2017 CS F331 / CSCE A331 Spring 2017 34