Getting Functional.

Slides:



Advertisements
Similar presentations
JavaScript I. JavaScript is an object oriented programming language used to add interactivity to web pages. Different from Java, even though bears some.
Advertisements

7-Jun-14 Lists. Arrays and Lists Arrays are a fixed length and occupy sequential locations in memory This makes random access (for example, getting the.
A Third Look At ML 1. Outline More pattern matching Function values and anonymous functions Higher-order functions and currying Predefined higher-order.
Type Checking, Inference, & Elaboration CS153: Compilers Greg Morrisett.
ML Lists.1 Standard ML Lists. ML Lists.2 Lists  A list is a finite sequence of elements. [3,5,9] ["a", "list" ] []  ML lists are immutable.  Elements.
More about functions Plus a few random things. 2 Tail recursion A function is said to be tail recursive if the recursive call is the very last thing it.
Lambda Calculus and Lisp PZ03J. Lambda Calculus The lambda calculus is a model for functional programming like Turing machines are models for imperative.
©2004 Brooks/Cole Chapter 7 Strings and Characters.
Introduction to ML - Part 2 Kenny Zhu. What is next? ML has a rich set of structured values Tuples: (17, true, “stuff”) Records: {name = “george”, age.
1 Chapter 2 Introductory Programs. 2 Getting started To create and run a Java program –Create a text file with a.java extension for the source code. For.
1 Data types, operations, and expressions Overview l Format of a Java Application l Primitive Data Types l Variable Declaration l Arithmetic Operations.
Getting Functional. 2 What is Functional Programming (FP)? In FP, Functions are first-class objects. That is, they are values, just like other objects.
A Brief Intro to Scala Tim Underwood. About Me Tim Underwood Co-Founder of Frugal Mechanic Software Developer Perl, PHP, C, C++, C#, Java, Ruby and now.
Pattern matching. The if expression The else part of an if expression is optional if ( condition ) expression1 else expression2 If the condition evaluates.
Haskell. 2 GHC and HUGS Haskell 98 is the current version of Haskell GHC (Glasgow Haskell Compiler, version 7.4.1) is the version of Haskell I am using.
Introduction to Java Applications Part II. In this chapter you will learn:  Different data types( Primitive data types).  How to declare variables?
Functions and Methods. Definitions and types A function is a piece of code that takes arguments and returns a result A pure function is a function whose.
A Third Look At ML Chapter NineModern Programming Languages, 2nd ed.1.
Cases and Classes and Case Classes And Other Miscellany 16-Dec-15.
Error Example - 65/4; ! Toplevel input: ! 65/4; ! ^^ ! Type clash: expression of type ! int ! cannot have type ! real.
Classes and Objects and Traits And Other Miscellany 25-Jan-16.
Methods Awesomeness!!!. Methods Methods give a name to a section of code Methods give a name to a section of code Methods have a number of important uses.
Getting Functional. Object-Oriented Programming in Scala Scala is object-oriented, and is based on Java’s model An object is a singleton object (there.
23-Feb-16 Lists. Arrays and Lists Arrays are a fixed length and occupy sequential locations in memory This makes random access (for example, getting the.
4-Mar-16 Getting Started with Scala. Getting Scala Download ScalaIDE: / This is a customized version of Eclipse I'm.
Java Programming: From Problem Analysis to Program Design, Second Edition 1 Lecture 1 Objectives  Become familiar with the basic components of a Java.
21-Mar-16 Getting Started with Scala. Hello World /** Everybody’s first program */ object HelloWorld { def main(args: Array[String]) { println("Hello,
Sequences and for loops. Simple for loops A for loop is used to do something with every element of a sequence scala> for (i
CS 106A, Lecture 4 Introduction to Java
String is a synonym for the type [Char].
Types CSCE 314 Spring 2016.
ML: a quasi-functional language with strong typing
Building Java Programs
Functions and patterns
ML Again ( Chapter 7) Patterns Local variable definitions
Classes and Objects and Traits
Haskell.
Exceptions and other things
Programming Language Concepts (CIS 635)
Java Programming: From Problem Analysis to Program Design, 4e
Lists 20-Sep-18.
Methods The real power of an object-oriented programming language takes place when you start to manipulate objects. A method defines an action that allows.
PROGRAMMING IN HASKELL
PROGRAMMING IN HASKELL
Functions As Objects.
Building Java Programs
PROGRAMMING IN HASKELL
Getting Started with Scala
Cases and Classes and Case Classes
Getting Functional.
PROGRAMMING IN HASKELL
CSCE 314: Programming Languages Dr. Dylan Shell
Building Java Programs Chapter 2
Getting Started with Scala
Plus a few random things
CSE-321 Programming Languages Introduction to Functional Programming
The Scala API.
Building Java Programs
Getting Started with Scala
Functions and patterns
Classes and Objects and Traits
Building Java Programs Chapter 2
Scala Apologia 27-Apr-19.
Programming Languages and Paradigms
Just Enough Java 17-May-19.
PROGRAMMING IN HASKELL
Monads.
CSE 3302 Programming Languages
Review Previously in: Lots of language features: functions, lists, records, tuples, variants, pattern matching Today: No new language features New idioms.
Presentation transcript:

Getting Functional

Object-Oriented Programming in Scala Scala is object-oriented, and is based on Java’s model An object is a singleton object (there is only one of it) Variables and methods in an object are somewhat similar to Java’s static variables and methods Reference to an object’s variables and methods have the syntax ObjectName.methodOrVariableName The name of an object should be capitalized A class may take parameters, and may describe any number of objects The class body is the constructor, but you can have additional constructors With correct use of val and var, Scala provides getters and setters for class parameters

Functional Programming (FP) in Scala In FP, Functions are first-class objects. That is, they are values, just like other objects are values, and can be treated as such Functions can be assigned to variables, passed as parameters to higher-order functions, returned as results of functions There is some way to write function literals Functions should only transform their inputs into their outputs A function should have no side effects It should not do any input/output It should not change any state (any external data) Given the same inputs, a function should produce the same outputs, every time--it is deterministic If a function is side-effect free and deterministic, it has referential transparency—all calls to the function could be replaced in the program text by the result of the function But we need random numbers, date and time, etc. 3

Creating Lists scala> List('a', 'b', 'c') res0: List[Char] = List(a, b, c) scala> "abc" toList res1: List[Char] = List(a, b, c) scala> "Welcome to Scala" split(" ") res2: Array[java.lang.String] = Array(Welcome, to, Scala) scala> val scala = "Scala" toList scala: List[Char] = List(S, c, a, l, a) scala> "Hello" :: scala res3: List[Any] = List(Hello, S, c, a, l, a) 4

Nil and :: scala> List() res4: List[Nothing] = List() scala> Nil res5: scala.collection.immutable.Nil.type = List() scala> List() == Nil res6: Boolean = true scala> List[String]() res7: List[String] = List() scala> "xyz" :: Nil res8: List[java.lang.String] = List(xyz) scala> "abc" :: "xyz" :: Nil res9: List[java.lang.String] = List(abc, xyz) 5

head, tail, and isEmpty scala> val penn = "Pennsylvania" toList penn: List[Char] = List(P, e, n, n, s, y, l, v, a, n, i, a) scala> penn head res10: Char = P scala> penn tail res11: List[Char] = List(e, n, n, s, y, l, v, a, n, i, a) scala> penn isEmpty res12: Boolean = false scala> Nil isEmpty res13: Boolean = true scala> Nil head java.util.NoSuchElementException: head of empty list (plus many more lines!) 6

take, drop, and splitAt scala> penn res16: List[Char] = List(P, e, n, n, s, y, l, v, a, n, i, a) scala> penn take 4 res17: List[Char] = List(P, e, n, n) scala> penn drop 4 res18: List[Char] = List(s, y, l, v, a, n, i, a) scala> penn splitAt 4 res19: (List[Char], List[Char]) = (List(P, e, n, n),List(s, y, l, v, a, n, i, a)) scala> penn.splitAt(4) res20: (List[Char], List[Char]) = (List(P, e, n, n),List(s, y, l, v, a, n, i, a)) 7

toString and mkString scala> List(1, 2, 3).toString res25: String = List(1, 2, 3) scala> List(1, 2, 3).toString == "List(1, 2, 3)" res26: Boolean = true scala> List(1, 2, 3) mkString(" is less than ") res27: String = 1 is less than 2 is less than 3 scala> List(1, 2, 3) mkString("*") res28: String = 1*2*3 scala> List(1, 2, 3) mkString("<: ", "--", " :>") res29: String = <: 1--2--3 :> scala> List(1, 2, 3) mkString("(", ", ", ")") res30: String = (1, 2, 3) 8

zip and unzip scala> val words = "one two three" split " " words: Array[java.lang.String] = Array(one, two, three) scala> val numbers = List(1, 2, 3, 4, 5) numbers: List[Int] = List(1, 2, 3, 4, 5) scala> val z = words zip numbers z: Array[(java.lang.String, Int)] = Array((one,1), (two,2), (three,3)) scala> val zz = numbers zip words zz: List[(Int, java.lang.String)] = List((1,one), (2,two), (3,three)) scala> z toMap res31: scala.collection.immutable.Map[java.lang.String,Int] = Map((one,1), (two,2), (three,3)) scala> zz unzip res32: (List[Int], List[java.lang.String]) = (List(1, 2, 3),List(one, two, three)) 9

Higher-order functions The basic syntax of a function literal is parameter_list => function_body A higher-order function is one that takes a function as a parameter, or returns a function as a result scala> val brag = "Scala is great!" toList brag: List[Char] = List(S, c, a, l, a, , i, s, , g, r, e, a, t, !) scala> brag count((ch: Char) => ch == 'a') res34: Int = 3 scala> brag count((ch: Char) => !(ch isLetter)) res35: Int = 3 scala> "Scala is great!".toList.count((ch: Char) => ch < 'f') res36: Int = 9 scala> "aeiou" contains 'e' res37: Boolean = true scala> "Scala is great!".toList.count((ch: Char) => "aeiou" contains ch) res38: Int = 5 10

Abbreviations In a literal function, you can usually omit the type (and, if there’s only one parameter, the parentheses) scala> brag res40: List[Char] = List(S, c, a, l, a, , i, s, , g, r, e, a, t, !) scala> brag count((ch: Char) => ch == 'a') res41: Int = 3 scala> brag count (ch => ch == 'a') res42: Int = 3 In fact, if there is only one parameter, used once, you can omit the parameter and the => and just use _ to stand in for the parameter scala> brag count (_ == 'a') res44: Int = 3 You can use underscores to stand for multiple parameters, provided each is used once, and they are used in order scala> (1 to 10).foldLeft(0)(_ + _) res27: Int = 55 11

sortWith scala> brag sortWith((x, y) => x < y) res49: List[Char] = List( , , !, S, a, a, a, c, e, g, i, l, r, s, t) Since there are two parameters, we can use two underscores scala> brag sortWith (_ < _) res50: List[Char] = List( , , !, S, a, a, a, c, e, g, i, l, r, s, t) Order matters! scala> brag sortWith (_ > _) res52: List[Char] = List(t, s, r, l, i, g, e, c, a, a, a, S, !, , ) 12

forall and exists Whereas count returns an Int, forall and exists return a Boolean scala> val n = List(3, 1, 4, 1, 6) n: List[Int] = List(3, 1, 4, 1, 6) scala> n forall(x => x < 8) res53: Boolean = true scala> n forall(x => x < 5) res54: Boolean = false scala> n exists(_ < 5) res55: Boolean = true scala> n exists(_ > 8) res56: Boolean = false 13

foreach foreach returns the (uninteresting) Unit value scala> val brag = List("Scala", "is", "great!") brag: List[java.lang.String] = List(Scala, is, great!) scala> brag foreach (println(_)) Scala is great! scala> brag foreach(println) scala> List(3, 1, 4, 1, 6) foreach (x => if (x > 1) println(x)) 3 4 6 14

Least upper bound The following list contains only integers: scala> val list = List(1, 2, 3) list: List[Int] = List(1, 2, 3) Now let’s add a non-integer to it scala> "hello" :: list res0: List[Any] = List(hello, 1, 2, 3) The type of this new list is the lowest class in the hierarchy that is a superclass of all the elements of the list

Closures scala> var c = 5 c: Int = 5 scala> val mult = (x: Int) => c * x mult: (Int) => Int = <function1> scala> mult(3) res63: Int = 15 scala> c = 7 c: Int = 7 scala> mult(10) res64: Int = 70 What will happen if we pass the mult function into another function in another context? It continues to “link to” (enclose?) the original variable c, not it’s value 16

map map produces a new list by applying the given function to each element of the given list scala> val n = List(1, 2, 3, 4, 5) n: List[Int] = List(1, 2, 3, 4, 5) scala> n map(x => x * x) res65: List[Int] = List(1, 4, 9, 16, 25) scala> n map (_ >= 3) res66: List[Boolean] = List(false, false, true, true, true) 17

flatMap flatMap produces a new list by applying the given function to each element of the given list, and “flattening” the result scala> n res70: List[Int] = List(1, 2, 3, 4, 5) scala> n map (x => List(x, x*x)) res72: List[List[Int]] = List(List(1, 1), List(2, 4), List(3, 9), List(4, 16), List(5, 25)) scala> n flatMap(x => List(x, x*x)) res73: List[Int] = List(1, 1, 2, 4, 3, 9, 4, 16, 5, 25) 18

filter filter produces a new list consisting of the values that pass the given test scala> n res67: List[Int] = List(1, 2, 3, 4, 5) scala> n filter (_ < 4) res68: List[Int] = List(1, 2, 3) scala> n filter (_ % 2 == 1) res69: List[Int] = List(1, 3, 5) 19

foldl, foldr The “fold” functions apply a binary operator to the values in a list, pairwise, starting from the left or starting from the right scala> val list = List(10, 1, 2, 3) list: List[Int] = List(10, 1, 2, 3) scala> list.foldLeft(0)(_ - _) res3: Int = -16 scala> list.foldRight(0)(_ - _) res4: Int = 8 scala> ((((0 - 10) - 1) - 2) - 3) res6: Int = -16 scala> (10 - (1 - (2 - (3 - 0)))) res8: Int = 8

Some Map methods These methods have little to do with “being functional,” so think of them as a bonus :-) We’re going to use a map that takes small numbers (1..5) to their squares: scala> val m = Map(1 -> 1, 2 -> 4, 3 -> 9, 4 -> 16, 5 -> 25) m: scala.collection.immutable.Map[Int,Int] = Map((5,25), (1,1), (2,4), (3,9), (4,16)) scala> m(4) res1: Int = 16 scala> m(10) java.util.NoSuchElementException: key not found: 10 ...and many more lines of error message scala> m.get(4) res3: Option[Int] = Some(16) scala> m.get(10) res4: Option[Int] = None scala> m.get(4) match { | case Some(x) => x | case None => -999 | } res5: Int = 16 21

Another Map method scala> m res6: scala.collection.immutable.Map[Int,Int] = Map((5,25), (1,1), (2,4), (3,9), (4,16)) scala> m.getOrElse(4, -999) res7: Int = 16 scala> m.getOrElse(10, -999) res8: Int = -999

“Houston, we have a problem.” scala> val x = m.getOrElse(4, "Hello") x: Any = 16 That’s pretty scary--but it gets worse: scala> x + 1 <console>:8: error: type mismatch; found : Int(1) required: String x + 1 ^

The End If I were to pick a language to use today other than Java, it would be Scala. --James Gosling, creator of Java 24