Functional programming techniques

Similar documents
CS 842 Ben Cassell University of Waterloo

INF4820. Common Lisp: Closures and Macros

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

Common LISP Tutorial 1 (Basic)

Functional programming with Common Lisp

Common LISP-Introduction

Lisp Basic Example Test Questions

Announcement. Overview. LISP: A Quick Overview. Outline of Writing and Running Lisp.

Streams, Delayed Evaluation and a Normal Order Interpreter. CS 550 Programming Languages Jeremy Johnson

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

Functional Languages. CSE 307 Principles of Programming Languages Stony Brook University

Common Lisp. Blake McBride

A Brief Introduction to Common Lisp

Imperative languages

Modern Programming Languages. Lecture LISP Programming Language An Introduction

CIS4/681 { Articial Intelligence 2 > (insert-sort '( )) ( ) 2 More Complicated Recursion So far everything we have dened requires

Symbolic Computation and Common Lisp

Algorithms for AI and NLP (INF4820 Lisp & FSAs)

Robot Programming with Lisp

Functional Programming. Pure Functional Programming

Control in Sequential Languages

Putting the fun in functional programming

Functional Programming. Big Picture. Design of Programming Languages

Lambda Calculus and Lambda notation in Lisp II. Based on Prof. Gotshalks notes on Lambda Calculus and Chapter 9 in Wilensky.

UMBC CMSC 331 Final Exam

Lambda Calculus see notes on Lambda Calculus

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 4. LISP: PROMĚNNÉ, DALŠÍ VLASTNOSTI FUNKCÍ, BLOKY, MAPOVACÍ FUNKCIONÁLY, ITERAČNÍ CYKLY,

CSCI337 Organisation of Programming Languages LISP

Allegro CL Certification Program

A little bit of Lisp

Lecture 09: Data Abstraction ++ Parsing is the process of translating a sequence of characters (a string) into an abstract syntax tree.

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Introduction to Functional Programming

A Genetic Algorithm Implementation

Lisp: Lab Information. Donald F. Ross

Computer Science 21b (Spring Term, 2015) Structure and Interpretation of Computer Programs. Lexical addressing

Streams and Evalutation Strategies

Streams and Lazy Evaluation in Lisp

Functions, Conditionals & Predicates

A LISP Interpreter in ML

Scheme in Scheme: The Metacircular Evaluator Eval and Apply

4/19/2018. Chapter 11 :: Functional Languages

FP Foundations, Scheme

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

Recursion & Iteration

UMBC CMSC 331 Final Exam

Why do we need an interpreter? SICP Interpretation part 1. Role of each part of the interpreter. 1. Arithmetic calculator.

Symbolic Programming. Dr. Zoran Duric () Symbolic Programming 1/ 89 August 28, / 89

Organization of Programming Languages CS3200/5200N. Lecture 11

Functional Languages. Hwansoo Han

Functional Programming. Contents

CMSC 331 Final Exam Section 0201 December 18, 2000

Jatha. Common Lisp in Java. Ola Bini JRuby Core Developer ThoughtWorks Studios.

Documentation for LISP in BASIC

Chapter 15. Functional Programming Languages

INTRODUCTION TO SCHEME

ITERATORS AND STREAMS 9

CPS 506 Comparative Programming Languages. Programming Language Paradigm

LISP. Everything in a computer is a string of binary digits, ones and zeros, which everyone calls bits.

Associative Database Managment WIlensky Chapter 22

Functional Programming

Associative Database Managment

User-defined Functions. Conditional Expressions in Scheme

Deferred operations. Continuations Structure and Interpretation of Computer Programs. Tail recursion in action.

MIDTERM EXAMINATION - CS130 - Spring 2005

Notes on Higher Order Programming in Scheme. by Alexander Stepanov

Imperative, OO and Functional Languages A C program is

Announcements. Today s Menu

Normal Order (Lazy) Evaluation SICP. Applicative Order vs. Normal (Lazy) Order. Applicative vs. Normal? How can we implement lazy evaluation?

Fall 2018 Discussion 8: October 24, 2018 Solutions. 1 Introduction. 2 Primitives

Functional Programming

UMBC CMSC 331 Final Exam Section 0101 December 17, 2002

Lisp. Versions of LISP

Control in Sequential Languages

(defvar *state* nil "The current state: a list of conditions.")

Homework. Reading: Chapter 17 Homework: All exercises from Chapter 17 Due: 10/27 Correction: Chapter 16 homework is due 10/25

Chapter 15. Functional Programming Languages

Lecture #2 Kenneth W. Flynn RPI CS

Functional Programming

19 Machine Learning in Lisp

A Quick Introduction to Common Lisp

Functional Programming with Common Lisp

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

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 2. ÚVOD DO LISPU: ATOMY, SEZNAMY, FUNKCE,

FUNKCIONÁLNÍ A LOGICKÉ PROGRAMOVÁNÍ 3. LISP: ZÁKLADNÍ FUNKCE, POUŽÍVÁNÍ REKURZE,

LECTURE 16. Functional Programming

Programming Language Pragmatics

John McCarthy IBM 704

Programming Languages

Section 10: LISP to Scheme. Evolution of Software Languages

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

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

Reading: Chapter 17 Homework: All exercises from Chapter 17 Due: 10/27 Correction: Chapter 16 homework is due 10/25

CMSC 331 Final Exam Section 0201 December 18, 2000

History. Functional Programming. Based on Prof. Gotshalks notes on functionals. FP form. Meaningful Units of Work

Artificial Intelligence Programming

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

Department of Computer and information Science Norwegian University of Science and Technology

Object Oriented Programming (OOP)

CS A331 Programming Language Concepts

Transcription:

Functional programming techniques o Currying o Continuations o Streams. Lazy evaluation Currying o Haskell B. Curry. o Second-order programming: o Functions that return other functions. o Example: A two-arguments function is transformed in a oneargument function that returns a one-argument function. (defun adder (x) #'(lambda (y) (+ x y))) (adder 2) #'(lambda (y) (+ 2 y)) (funcall (adder 2) 3) 5 (setf f (adder 2)) (funcall f 3) 5 ML programming fun adder x y = x + y adder: int int int adder 2: int int

Examples (defun member (x l) (when l (or (equal (first l) x) (member x (rest l))))) (defun member-c (x) #'(lambda (list) (labels ((look (l) (when l (or (equal (first l) x) (look (rest l)))))) (look list)))) (defun new-member (a l) (funcall (member-c a) l)) Examples (defun map-c (fn) #'(lambda (args) (labels ((aplica (l) (when l (cons (funcall fn (first l)) (aplica (rest l)))))) (aplica args)))) (defun new-map (fn args) (funcall (map-c fn) args))

Currying o Generalization: Transform a function with n = m + k parameters into a function with m parameters that returns a function with k parameters. (defun swapper (x y ls) (cond ((null ls) nil) ((equal (first ls) x) (cons y (swapper x y (rest ls)))) ((equal (first ls) y) (cons x (swapper x y (rest ls)))) (t (cons (first ls) (swapper x y (rest ls)))))) (defun swapper-c (x y) #'(lambda (ls) (labels ((look-up (ls) (cond ((null ls) nil) ((equal (first ls) x) (cons y (look-up (rest ls)))) ((equal (first ls) y) (cons x (look-up (rest ls)))) (t (cons (first ls) (look-up (rest ls))))))) (look-up ls)))) (defun swapper-nou (x y ls) (funcall (swapper-c x y) ls)) (setf pp (swapper-c a b)) (funcall pp (c a d b e)) (c b d a e)

Currying o Useful when one (o more) of the arguments of a function remains constant o Efficiency in recursive programming: the stack of functional calls is shorter o Lambda functions of only one argument without losing of representation power o Related to the partial evaluation theorem by Kleene (1952): o Given a computable function f of n variables f(x 1,x 2,...,x n ) and k (k<=n) values a 1,..., a k. It is possible to compute a new function f such that: f (x k+1, x k+2,..., x n ) = f(x 1,x 2,...,x n ) Currying o AI interest: to model partial functions, needed for the management of incomplete reasoning o Partial deduction (logic programming) o Specialization: (A B) C A (B C) o Knowledge-base specialization (Milord II): (A, α), (A B C, ρ) (B C, f ( α, ρ)) a b z... KB... α β ζ b z... KB'... α β ζ z... KB''... α β ζ

Continuations o Idea: Given a n-argument function, we add a new continuation argument. The result of the original function is given to the continuation. o (defun f (x) x) o (defun f(x,continuation) (funcall continuation x)) o Program transformation technique based on secondorder functions. New programs are more efficiently represented. o Scheme o SML/NJ, Haskell o Actors model o Multiprocessing, search o Objects containing the state of the computation Example I (no recursive) Without continuations (defun length2 (x) (list x (length x))) (defun print-length2 (list) (format t The length is: ~A (length2 list))) With continuations (defun length2-c (x -c-) (funcall -c- (list x (length x)))) (defun print-length2 (list) (length2-c list # (lambda (val) (format t The length is: ~A (length2 val)))))

Continuations (recursive functions) o Program transformation technique based on secondorder functions. New programs are more efficiently represented. o Idea: Given a one-argument function, we find a new two-argument tail-recursive function. The first argument is of the same type that the original one and, the second is a function called continuation. o It is easy to define a new tail-recursive function. o Problem: second-order function representation is expensive. o Benefits when continuations can be represented as simple data structures, for instance, lists. Continuations (recursive functions) o Suppose the following function: f(x) = if p then q else E where x can appear in p, q and E o f appears only one time in E, applied over a sub expression of x, f(s(x)) o In the non trivial case a, where p[a/x] is false, the computation returns r = f(s(a)), γ = λw.ew where Ew = E[f(s(x))/w] o The function γ is applied over r, γ(r)

Continuations o Equivalent function for f: f(x) = f-tr(x,id) f-tr(x,γ) = γ(f(x)) = if p then γ(q) else f-tr(s(x),λw.γew) [Field i Harrison, 1988] o The function γ is called a continuation, the pending computation to perform after the calculation of the recursive call. Example II (recursive) o Optimization of tail-recursive calls No tail-recursive (defun fact (n) (if (= n 0) 1 (* n (fact (- n 1))))) (defun fact-c (n -c-) (if (= n 0) (funcall -c- 1) (fact-c (- n 1) # (lambda (val) (funcall -c- (* n val)))))) (defun fact (n) (fact-c n # (lambda (val) val)))

Memoize (defun memo (fn &key (key #'first) (test #'eql) name) "Return a memo-function of fn." (let ((table (make-hash-table :test test))) (setf (get name :memo) table) #'(lambda (&rest args) (let ((k (funcall key args))) (multiple-value-bind (val found-p) (gethash k table) (if found-p val (setf (gethash k table) (apply fn args)))))))) (defun clear-memoize (fn-name) "Clear the hash table from a memo function." (let ((table (get fn-name :memo))) (when table (clrhash table)))) (defun memoize (fn-name &key (key #'first) (test #'eql)) "Replace fn-name's global definition with a memoized version." (clear-memoize fn-name) (setf (symbol-function fn-name) (memo (symbol-function fn-name) :name fn-name :key key :test test))) Example III o Continuation in a local function Σ n x (defun sum-iter (n) (let ((sum 0)) (loop (if (= n 0) (return sum)) (setq sum (+ sum n)) (setq n (- n 1))))) (defun sum-clean (n) (labels ((sum-loop (n sum) (if (= n 0) sum (sum-loop (- n 1) (+ sum n))))) (sum-loop n 0))) (defun sum-cont (n -c-) (labels ((sum-loop (n sum) (if (= n 0) (funcall -c- sum) (sum-loop (- n 1) (+ sum n))))) (sum-loop n 0)))

Coroutines (make-array '(4 2 3) :initial-contents '(((a b c) (1 2 3)) ((d e f) (3 1 2)) ((g h i) (2 3 1)) ((j k l) (0 0 0)))) array-dimension aref (defun write-matrix (M) (let ((heigth (array-dimension M 0)) (width (array-dimension M 1))) (labels ((write-loop (i j corou) (cond ((= i heigth) nil) ((= j width) (write-loop (1+ i) 0 corou)) (t (funcall corou #'(lambda (item corou) (setf (aref M i j) item) (write-loop i (1+ j) corou))))))) (write-loop 0 0 corou))))) (defun read-matrix (M) (let ((heigth (array-dimension M 0)) (width (array-dimension M 1))) (labels ((read-loop (i j corou) (cond ((= i heigth) nil) ((= j width) (read-loop (1+ i) 0 corou)) (t (funcall corou (aref M i j) (read-loop i (1+ j) corou))))))) (read-loop 0 0 corou))))) (defun transfer-matrix (M1 M2) (let ((reader (read-matrix M1)) (writer (write-matrix M2))) (funcall writer reader))) Coroutines M1 = #2A((1 2 3)(4 5 6)) M2 = #2A((nil nil)(nil nil)) (funcall (write-matrix M2)(read-matrix M1)) M2 = #2A((1 2)(3 4)) (funcall (labels ((write-loop (i j corou) (cond ((= i 2) nil) ((= j 2) (write-loop (1+ i) 0 corou)) (t (funcall corou #'(lambda (item corou) (setf (aref M2 i j) item) (write-loop i (1+ j) corou))))))) (write-loop 0 0 corou))) (labels ((read-loop (i j corou) (cond ((= i 2) nil) ((= j 3) (read-loop (1+ i) 0 corou)) (t (funcall corou (aref M1 i j) (read-loop i (1+ j) corou))))))) (read-loop 0 0 corou)))) (funcall (labels ((read-loop (i j corou) (cond ((= i 2) nil) ((= j 3) (read-loop (1+ i) 0 corou)) (t (funcall corou (aref M1 i j) (read-loop i (1+ j) corou))))))) (read-loop 0 0 corou))) #'(lambda (item corou) (setf (aref M2 0 0) item) (write-loop 0 1 corou))) (funcall #'(lambda (item corou) (setf (aref M2 0 0) item) (write-loop 0 1 corou)) (aref M1 0 0) (read-loop 0 1 corou))) (setf (aref M2 0 0) (aref M1 0 0)) (write-loop 0 1 (read-loop 0 1 corou))))

Control Flow o Continuations are useful to define control strategies o Common Lisp uses continuations in: o BLOCK/RETURN_FROM lexical o CATCH/THROW dynamic (catch tag (...) (...)...) (if (...) (block then (setq...) (list... (return-from then...))) (...) (defun f (x) (catch 'hola (+ x 1) (+ 5 (g x)))) (throw tag (...)) (defun g (x) (if (< x 5) 567 (throw 'hola 10000))) Control Flow OnLisp: Chapter 20 o These mechanisms can be described with the function CALL-WITH-CURRENT-CONTINUATION (no Common Lisp) o Scheme (lisp dialect) o (+ 1 call/cc (lambda (cont) (+ 20 300))) 321 o (+ 1 call/cc (lambda (cont) (+ 20 (cont 300)))) 301 (defmacro block (name &rest forms) `(call-with-current-continuation #'(lambda (,name),@forms))) (defmacro return-from (name &optional value) `(funcall,name,value))

ATN (Augmented transition network) s::= np vp to-be np pred np::= proper-noun pronoun det noun vp::= to-be np to-be pred pred::= adj pp pp::= prep np adj::= nice small blue prep::= to in on out to-be ::= is are was were det::= the proper-noun::= maria carles antoni noun::= house car table pronoun::= mine yours ours theirs Maria is nice The house is blue The table is mine Two continuations: success or failure ATN (Augmented transition network) I (defun cont-atn (s) (parse-s s (cond ((null s) success) (T (funcall return)))) 'failure))) (defun parse-s (s success failure) (parse-np s (parse-vp s success return)) (categoria? 'to-be s (parse-np s (parse-pred s sucess return)) return)) failure)))) Success Failure (defun parse-np (s success failure) (categoria? 'proper-noun s sucess (categoria? 'pronoun s sucess (categoria? 'det s (categoria? 'noun s sucess return)) failure)))))) Syntax? (cont-atn (Maria is nice)) (parse-s (Maria is nice) success1 failure1) (parse-np (Maria is nice success2 failure2) (categoria? proper-noun (Maria is nice) success2 failure3)

ATN II (defun parse-pred (s success failure) (categoria? 'adj s success (parse-pp s success failure)))) (defun parse-pp (s success failure) (categoria? 'prep s (parse-np s success return)) failure)) (defun categoria? (caract s success failure) (if (or (null s) (not (categoriap (first s) caract))) (funcall failure) (funcall success (rest s) failure))) (defun categoriap (mot tipus) (case tipus (adj (member mot '(nice small blue))) (prep (member mot '(to in on out))) (to-be (member mot '(is are was were))) (det (member mot '(the))) (proper-noun (member mot '(maria carles antoni))) (noun (member mot '(house car table))) (pronoun (member mot '(mine yours ours theirs))))) (categoria? proper-noun (Maria is nice) success2 failure3) (funcall success2 (is nice) failure3) (funcall # (lambda(s return) (parse-vp s success1 return)) (is nice) failure3) (parse-vp (is nice) success1 failure3) (categoria? to-be (is nice) success1 failure3) (funcall # (lambda(s return) (parse-np s success1 return)) (nice) failure3) ATN III (defun parse-np (s success failure) (categoria? 'proper-noun s success (categoria? 'pronoun s success (categoria? 'det s (categoria? 'noun s success return)) failure)))))) (defun parse-vp (s success failure) (categoria? 'to-be s (parse-np s success return)) (categoria? 'to-be s (parse-pred s success return)) failure))))

ATN IV (categoria? proper-noun (The house is mine) success2 failure3) (funcall failure3) (funcall (categoria? 'pronoun (The house is mine) success2 (categoria? 'det s ) (funcall (categoria? 'det (The house is mine) (categoria? 'noun s success2 return)) failure2))))))) (categoria? to-be (is mine) success1 failure3) IA interests o Pros o Search and backtracking can be simplified. o Interesting control mechanisms. Necessary to define languages. o Modular and compact programming of ATNs o No backtracking o Continuation over failure states. o Cons o Read and write this kind of code is not easy. o Problematic program debugging with anonymous functions o Inspiration