CPL 2016, week 10. Clojure functional core. Oleg Batrashev. April 11, Institute of Computer Science, Tartu, Estonia

Similar documents
Declarative concurrency. March 3, 2014

Clojure is. A dynamic, LISP-based. programming language. running on the JVM

.consulting.solutions.partnership. Clojure by Example. A practical introduction to Clojure on the JVM

Introduction Basics Concurrency Conclusion. Clojure. Marcel Klinzing. December 13, M. Klinzing Clojure 1/18

POETRY OF PROGRAMMING CODE READING EXERCISES IN CLOJURE V

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Clojure. A (not-so-pure) functional approach to concurrency. Paolo Baldan Linguaggi per il Global Computing AA 2016/2017

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

Common LISP Tutorial 1 (Basic)

Functional Programming. Pure Functional Programming

An introduction introduction to functional functional programming programming using usin Haskell

CSCC24 Functional Programming Scheme Part 2

The Curious Clojureist

G Programming Languages - Fall 2012

Seminar on Languages for Scientific Computing Aachen, 6 Feb Navid Abbaszadeh.

Functional Programming Lecture 1: Introduction

n n Try tutorial on front page to get started! n spring13/ n Stack Overflow!

Introducing Wybe a language for everyone

LECTURE 16. Functional Programming

Functional Programming. Pure Functional Languages

Scala : an LLVM-targeted Scala compiler

CS 11 Haskell track: lecture 1

Introduction to Functional Programming

Lecture 8: Summary of Haskell course + Type Level Programming

Symbolic Computation and Common Lisp

Introduction to Concepts in Functional Programming. CS16: Introduction to Data Structures & Algorithms Spring 2017

COP4020 Programming Assignment 1 - Spring 2011

Functional Programming and Haskell

Functional Programming. Pure Functional Languages

This tutorial is designed for all those software professionals who are keen on learning the basics of Clojure and how to put it into practice.

Scheme as implemented by Racket

CSCI-GA Scripting Languages

Functional Programming. Big Picture. Design of Programming Languages

G Programming Languages - Fall 2012

Programming Systems in Artificial Intelligence Functional Programming

Refactoring to Functional. Hadi Hariri

Classical Themes of Computer Science

INTRODUCTION TO SCHEME

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

Functional programming with Common Lisp

Clojure Concurrency Constructs. CSCI 5828: Foundations of Software Engineering Lecture 12 10/02/2014

CS 360: Programming Languages Lecture 10: Introduction to Haskell

List Functions, and Higher-Order Functions

Functional Programming - 2. Higher Order Functions

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

Programming with Math and Logic

Scheme: Expressions & Procedures

INF4820: Algorithms for Artificial Intelligence and Natural Language Processing. Common Lisp Fundamentals

(Func&onal (Programming (in (Scheme)))) Jianguo Lu

4. Functional Programming Language-Oriented Programming

Summer 2017 Discussion 10: July 25, Introduction. 2 Primitives and Define

Introduction to Haskell

A Second Look At ML. Chapter Seven Modern Programming Languages, 2nd ed. 1

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Processadors de Llenguatge II. Functional Paradigm. Pratt A.7 Robert Harper s SML tutorial (Sec II)

Symbols. abstractions, implementing, 270 through indirection, 77 with macros, 183 abstract syntax tree (AST), 149

Functional Languages. Hwansoo Han

Principles of Programming Languages 2017W, Functional Programming

Week 2: The Clojure Language. Background Basic structure A few of the most useful facilities. A modernized Lisp. An insider's opinion

CS 2340 Objects and Design - Scala

CSCE 314 Programming Languages

Principles of Programming Languages Topic: Functional Programming Professor L. Thorne McCarty Spring 2003

Higher Order Functions in Haskell

Scheme: Data. CS F331 Programming Languages CSCE A331 Programming Language Concepts Lecture Slides Monday, April 3, Glenn G.

Racket. CSE341: Programming Languages Lecture 14 Introduction to Racket. Getting started. Racket vs. Scheme. Example.

Shell CSCE 314 TAMU. Higher Order Functions

INTRODUCTION TO HASKELL

Using Scala in CS241

CSci 4223 Principles of Programming Languages

CS457/557 Functional Languages

Concepts of programming languages

Notes from a Short Introductory Lecture on Scala (Based on Programming in Scala, 2nd Ed.)

CSCI337 Organisation of Programming Languages LISP

Overloading, Type Classes, and Algebraic Datatypes

Lazy Functional Programming in Haskell

A general introduction to Functional Programming using Haskell

Scheme Tutorial. Introduction. The Structure of Scheme Programs. Syntax

A LISP Interpreter in ML

JVM ByteCode Interpreter

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

Programming Languages and Techniques (CIS120)

Tuples. CMSC 330: Organization of Programming Languages. Examples With Tuples. Another Example

Scheme. Functional Programming. Lambda Calculus. CSC 4101: Programming Languages 1. Textbook, Sections , 13.7

Chapter 15. Functional Programming Languages

Defining Functions. CSc 372. Comparative Programming Languages. 5 : Haskell Function Definitions. Department of Computer Science University of Arizona

Quote of the Day. CS Functional Programming. Introductory Notes on Lisp/Clojure. Another Quote. What is Clojure? 1-4

CS 61A Interpreters, Tail Calls, Macros, Streams, Iterators. Spring 2019 Guerrilla Section 5: April 20, Interpreters.

Plan (next 4 weeks) 1. Fast forward. 2. Rewind. 3. Slow motion. Rapid introduction to what s in OCaml. Go over the pieces individually

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

Chapter 1. Fundamentals of Higher Order Programming

Shell CSCE 314 TAMU. Haskell Functions

Fundamentals of Artificial Intelligence COMP221: Functional Programming in Scheme (and LISP)

FOFL and FOBS: First-Order Functions

CSE413: Programming Languages and Implementation Racket structs Implementing languages with interpreters Implementing closures

SCHEME 7. 1 Introduction. 2 Primitives COMPUTER SCIENCE 61A. October 29, 2015

CS 320: Concepts of Programming Languages

Functional Programming. Pure Functional Programming

Introduction to Functional Programming in Racket. CS 550 Programming Languages Jeremy Johnson

CS 321 Programming Languages

Exercise 1: Graph coloring (10 points)

Transcription:

CPL 2016, week 10 Clojure functional core Oleg Batrashev Institute of Computer Science, Tartu, Estonia April 11, 2016

Overview Today Clojure language core Next weeks Immutable data structures Clojure simple state and design Software transactional memory Agents in Clojure

Functional core 3/32 - Overview Declarative programming (DP) what is declarativeness Immutable data structures lists, trees DP basics iterative comutation recursive computation Declarative concurrency (DC) DP and DC in Haskell and other languages

Functional core 4/32 Declarative programming - Outline Functional core Declarative programming Clojure immutable code-data Basics of declarative programming

Functional core 5/32 Declarative programming - Some quotes Recent Effective Scala from Twitter developers http://twitter.github.com/effectivescala/ Use Futures to manage concurrency. Futures allow the programmer to express concurrent computation in a declarative style If an immutable collection will do, use it... reasoning about them in a concurrent context is simple. The Java memory model is a subtle beast, but luckily we can avoid all of these pitfalls by using the declarative style What is declarative style, future and immutable collection and how are they special?

Functional core 6/32 Declarative programming - What is declarativeness An operation with input and output is declarative Same input always gives the same output independent (of outside state) stateless (no inside state) deterministic ( fixed control-flow) no side effects (no writing to IO or outside state) Examples typical algebraic operations (+,-,*,/) if-then-else pure functions

Functional core 7/32 Declarative programming - Declarativeness is important Compositional plug declarative component Declarative operation arguments results Rest of computation Reasoning is simple understand component behaviour alone no need to consider external/internal state

Functional core 8/32 Declarative programming - In Clojure (and other FP) variables are immutable function arguments, loop variables, local (let) variables except def, defn creates global mutable variables standard data structures are immutable (persistent) list, vector, map, set pure functions no side effects: i.e. no IO/shared state read or write

Functional core 9/32 Clojure immutable code-data - Outline Functional core Declarative programming Clojure immutable code-data Basics of declarative programming

Functional core 10/32 Clojure immutable code-data - Running code REPL (read-eval-print loop) $ clojure Clojure 1.6.0 user => (+ 4 5) 9 user => ( println " Hello ") Hello Create file with extension clj and run it with clojure use def to define global variables ( def x 5) ( println " Hello " x) avoid them for now, because they are not part of declarative model

Functional core 11/32 Clojure immutable code-data - Lisp syntax parentheses () play an important role almost always call a function ( fnname arg1 arg2 arg3 ) no infix operators, so even adding 2 values (+ 2 3) try to read this (+ (/ (* 2 5) 3) (- 1 2)) quoting do not execute the function '(+ 2 3) returns linked list of 3 values: + function, integers 2 and 3 + is function value (reference to the value) code is data, in the form of linked lists!

Functional core 12/32 Clojure immutable code-data - Basic types booleans, integers, rationals, floats ( println true false 5 (/ 1 4) 0.25) characters, strings ( println \H " ello ") keywords are symbolic constants (like in Erlang) ( println : keyw1 ( type : keyw2 )) ; -> : keyw1 clojure. lang. Keyword symbols are names for variables, functions, etc difficult to catch compiler tries to substitute for their values ( println sym1 ) ; -> CompilerException... Unable to resolve symbol : sym1 but they are real ( println 'sym1 ( class 'sym1 )) ; -> sym1 clojure. lang. Symbol

Functional core 13/32 Clojure immutable code-data - Immutable linked lists (list 3 4 7) or with quoting '(3 4 7) actual representation (cons 3 (cons 4 (cons 7 ()))) empty list () ends the list cons pair (cons H T) consists of head H references one list value tail T references the rest of the list first/rest accessing head and tail destructuring: extract head and tail (let [[H & T] '(3 4 7)] (println T) ) prints (4 7) changing an element in the list is impossible adding head (cons 11 lst), also (conj lst 11)

Functional core 14/32 Clojure immutable code-data - Appending lists Appending a=(1 2 3) b=(6 7) must result in copying the first list (cons 1 (cons 2 (cons 3 b))) 1 2 3 6 7 1 2 3 Append one list to another by just reassigning the tail? No! the first list must stay immutable whoever has reference to it should not see changes the second list may be appended to any other whoever has reference to it sees no changes

Functional core 15/32 Clojure immutable code-data - Variables single-assignment variables you can only assign value once let construct, x and y are not re-assignable ( let [x 5 y 10] ( println (- x y ))) function arguments (x,y) are not re-assignable (fn [x y] (* x y)) def assigns to things called vars, return to them in 2 weeks ( def f (fn [x y] (* x y ))) ( println (f 5 10)) they are re-assignable

Functional core 16/32 Clojure immutable code-data - Static scoping Variables/parameters are only seen within scope let define local symbols and execute statements clojure. core / let ( let [ bindings *] exprs *) fn parameter symbols seen within function scope clojure. core /fn (fn name? [ params *] exprs *) (fn name? ([ params *] exprs *) +) for local symbols seen with for scope ( for [x ( range 10) y ( range 5) : let [z (+ x y)] : when (< z 10)] ( list x y z))

Functional core 17/32 Clojure immutable code-data - Defining functions don t panic fn defines anonymous function ( fn [ arg1 arg2 arg3 ] stm1 stm2 stm3 ) def assigns value to global variable ( def sym val ) the rest is just syntactic sugar ( defn f1 [ arg1 arg2 ] stm1 stm2 stm3 ) ; assigns function to global variable ' f1 ' letfn for local functions ( letfn [( f2 [x y] ( println :we) (- x y ))] ( println (f2 2 3)))

Functional core 18/32 Basics of declarative programming - Outline Functional core Declarative programming Clojure immutable code-data Basics of declarative programming

Functional core 19/32 Basics of declarative programming - Iterative computation (1) How to iterate over values with single-assignment variable? with recursion each (recursive) call creates new variables for the arguments ( defn iteration [ X Sum ] (if ( >= X 10) Sum ; stop and return result (do ; else ( println X) ( iteration ( inc X) (+ Sum X ))))) ( println ( iteration 0 0))

Functional core 20/32 Basics of declarative programming - Iterative computation (2) On the third iteration "Result" "X" "Sum" x 1 0 s 1 0 x 2 1 s 2 0 x 3 2 s 3 1 current call new values are created on the stack in each call recursion stops at x 10 old x i and s i can safely be used by external code/threads (unlike in imperative PLs) Java final keyword for closures

Functional core 21/32 Basics of declarative programming - Clojure recur avoid stack grow with recur must be in tail position calls current function with tail call optimization (TCO) JVM does not allow TCO, Clojure has to generate iterative code instead of recursive calls ( defn iteration [ i s] (if ( >= i 10) s (do ; else ( println i) ( recur ( inc i) (+ s i)) ))) ( println ( iteration 0 0))

Functional core 22/32 Basics of declarative programming - Recursive computation (1) Naive implementations are often wasteful stack grows because of append is not in tail position ( defn append [ Ls Ms] (if (= Ls ()) Ms ( cons ( first Ls) ( append ( rest Ls) Ms )))) ( println ( append '(1 5 3) '(3 2 3))) Naive definitions are often slow ( defn reverse [ Xs] (if (= Xs ()) '() ( append ( reverse ( rest Xs )) ( list ( first Xs )) ))) ( println ( reverse '(1 2 3 4)))

Functional core 23/32 Basics of declarative programming - Recursive computation (2) Use accumulators and tail recursion ( defn - reverse2_iter [ Rs Ys] (if (= Ys '()) Rs ; return accumulated result ( recur ( cons ( first Ys) Rs) ( rest Ys )))) ( defn reverse2 [ Xs] ( reverse2_iter '() Xs )) ; empty accumulator ( println ( reverse2 '(1 4 3 2))) Rs is an accumulator for the new list Recursive call is in tail position same with reduce ( def P (fn [ acc val ] ( cons val acc ))) ( reduce P [] [1 2 7])

Functional core 24/32 Basics of declarative programming - Recursion example ( d e f l e t t e r T y p e s #{C h a r a c t e r /LOWERCASE_LETTER C h a r a c t e r /UPPERCASE_LETTER}) ( d e f n l e t t e r? [ ch ] ( l e t t e r T y p e s ( C h a r a c t e r / gettype ch ) ) ) ( defn scan word [ r e a d e r word ] "Read s i n g l e word from t h e r e a d e r. " ( l e t [ ch (. r e a d r e a d e r ) ] ( i f ( l e t t e r? ch ) ( r e c u r r e a d e r ( cons ch word ) ) ( a p p l y s t r (map c h a r ( r e v e r s e word ) ) ) ) ) ) ( defn scan words i m p l [ r e a d e r words ] ( l e t [ ch (. r e a d r e a d e r ) ] ; r e a d n e x t symbol ( i f (= ch 1) ; i s end o f r e a d e r? words ; f i n i s h and r e t u r n words ( i f ( l e t t e r? ch ) ; ; scan t h e word ( r e c u r r e a d e r ( c o n j words ( scan word r e a d e r ( l i s t ch ) ) ) ) ; ; s k i p c h a r a c t e r ( r e c u r r e a d e r words ) ) ) ) ) ( d e f n scan words [ r e a d e r ] ( scan words i m p l r e a d e r [ ] )

Functional core 25/32 Basics of declarative programming - Higher-order programming (1) Reverse the list (1 2 7) 1 2 7 () (1) (2 1) (7 2 1) (P.) (P.) (P.) accumulator values from R0=() to R3=(7 2 1) can be also viewed as state transform from S0 to S 3 tansformation takes In and X and returns Out Out (P In X) In X (P.) Out

Functional core 26/32 Basics of declarative programming - Higher-order programming (2) Define the generic function ( defn forallacc [ Lst P Acc ] (if ( empty? Lst ) Acc ( let [[ X & Tail ] Lst ; split the list NewAcc ( P Acc X)] ; update accum ( recur Tail P NewAcc )))) ; proceed with the rest ; use sum as the transform function ( println ( forallacc [1 2 3] + 0)) ; use prepend as the transform function ( let [ prepend (fn [a x] ( cons x a ))] ( println ( forallacc [1 2 3] prepend ()))) forallacc is actually foldl state transform view: X may be incoming message

Functional core 27/32 Basics of declarative programming - Idiomatic functional operations filter filter each element of the list according to the predicate list + predicate = list map transform each element of the list list + transform function = list fold (reduce) reduce all elements of the list using given function list + reduction function = scalar [X Y Z] and * as the reduction function (notation is not Clojure) (X*Y)*Z for left folding X*(Y*Z) for right folding

Functional core 28/32 Basics of declarative programming - Clojure collections vectors: [1 2 3], (vector 1 2 3), (vec (1 2 3)) maps: {:key1 "val", :key2 42, 99 "ok"} ( class {: key1 " val "}) ; -> clojure. lang. PersistentArrayMap with constructor: (hash-map :key1 "val") sorted map (sorted-map :key1 2) sets: #{:val1 "str" 12} sorted set... seq interface: seq, first, rest, next

Functional core 29/32 Basics of declarative programming - Sequence library in Clojure conj, into range, repeat, repeatedly, iterate take, cycle interleave, interpose (join) constructors (list, vector, hash-set, hash-map) compare to vec filter, take-while, drop-while, split-at, split-with every?, some map, reduce, sort, sort-by for does map + filter