06 input and output functional programming. streams two kinds of streams character streams binary...

36
06 INPUT AND OUTPUT Functional Programming

Upload: deborah-fitzgerald

Post on 02-Jan-2016

240 views

Category:

Documents


2 download

TRANSCRIPT

06 INPUT AND OUTPUT

Functional Programming

Streams

Two kinds of streams Character streams Binary streams

Character streams are Lisp objects representing sources and/or destinations of characters

To read from or write to a file, you open it as a stream, but streams are not identical with files

When you read or print at the toplevel, you also use a stream

Streams

Default input is read from the stream *standard-input*

Default output is write to *standard-output*

Initially *standard-input* and *standard-output* will be the same place: a stream presenting the toplevel

Streams

Make the file > (setf path (make-pathname :name “myfile”))

#P”myfile”

Open the file > (setf str (open path :direction :output

:if-exists :supersede))#<BUFFERED FILE-STREAM CHARACTER #P”myifle” @1>

Write to the stream > (format str “Something~%”)

NIL

Close the stream > (close str)

NIL

Streams

Read the file Open a stream with :direction :input > (setf str (open path :direction :input))

#<BUFFERED FILE-STREAM CHARACTER #P”myifle” @1> > (read-line str)

“Something”

with-open-file macro > (with-open-file (str path :direction :output

:if-exists :supersede) (format str “Something~%”))

The stream is automatically closed

Input

Most popular input functions read-line read

> (progn (format t “Please enter your name: “) (read-line))Please enter your name: Rodrigo de Bivar“Rodrigo de Bivar”NIL → is true only if read-line ran out of input before encountering a newline

Input

(defun pseudo-cat (file) (with-open-file (str file :direction :input) (do ((line (read-line str nil ‘eof) (read-line str nil ‘eof))) ((eql line ‘eof)) (format t “~A~%” line))))

If you want input parsed into Lisp objects, use read > (read)

(abc)(A B C)

Output

Three simplest output functions prin1

Generates output for programs > (prin1 “Hello”)

“Hello”“Hello”

princ Generates output for people > (princ “Hello”)

Hello“Hello”

terpri Prints a new line

Output

format > (format nil “Dear ~A, ~% Our records indicate…”

“Mr. Malatesta”)“Dear Mr. Malatesta, Our records indicate…”

> (format t “~S ~A” “z” “z”)“z” zNIL

Output

> (format nil “~10,2,0,’*, ‘ F” 26.21875)“ 26.22”Rounded to 2 decimal placesWith the decimal point shifted right 0 placesRight-justified in a field of 10 charactersPadded on the left by blanksIf it is too long to fit in the space allowed by the first argument, the

character * is printed > (format nil “~,2,,,F” 26.21875)

“26.22”> (format nil “~,2F” 26.21875)

“26.22”

Review – Function pointer in C

1#include <iostream> 2 3using namespace std; 4 5void printArrayOdd(int* beg, int* end) { 6  while(beg != end) { 7    if ((*beg)%2) 8      cout << *beg << endl; 9      10    beg++;11  }12}1314void printArrayEven(int* beg, int* end) {15  while(beg != end) {16    if (!((*beg)%2))17      cout << *beg << endl;18      19    beg++;20  }21}22

Review – Function pointer in C

23void printArrayGreaterThan2(int* beg, int* end) {24  while(beg != end) {25    if ((*beg)>2)26      cout << *beg << endl;27      28    beg++;29  }30}3132int main() {33  int ia[] = {1, 2, 3};34  35  cout << "Odd" << endl;36  printArrayOdd(ia, ia + 3);3738  39  cout << "Even" << endl;40  printArrayEven(ia, ia + 3);41  42  cout << "Greater than 2" << endl;43  printArrayGreaterThan2(ia, ia + 3);44}

Execution results

Odd13Even2Greater than 23

Review – Function pointer in C

1/**//* 2  (C) OOMusou 2007 http://oomusou.cnblogs.com 3 4Filename    : FuntionPointer.cpp 5Compiler    : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++ 6Description : Demo how to use function pointer 7Release     : 05/01/2007 1.0 8*/ 9#include <iostream>1011using namespace std;1213typedef bool (*predicate)(int);1415bool isOdd(int i) {16  return i%2? true : false;17}1819bool isEven(int i) {20  return i%2? false : true;21}22

Review – Function pointer in C

23bool greaterThan2(int i) {24  return i > 2;25}2627void printArray(int* beg, int* end, predicate  fn) {28  while(beg != end) {29    if ((*fn)(*beg))30      cout << *beg << endl;31      32    beg++;33  }34}3536int main() {37  int ia[] = {1, 2, 3};38  39  cout << "Odd" << endl;40  printArray(ia, ia + 3, isOdd);41  42  cout << "Even" << endl;43  printArray(ia, ia + 3, isEven);44  45  cout << "Greater than 2" << endl;46  printArray(ia, ia + 3, greaterThan2);47}

Execution results

Odd13Even2Greater than 23

Review – Function pointer in C

By using function pointer, C can pass a function as an argument to another function

C++ and C# also provide similar idea C++: Function object (Functor) C# (pronounced as C sharp): Delegate

But…., how to return a function? C also could return a function pointer

http://www.newty.de/fpt/fpt.html However, it needs more complex consideration to write such a

function with higher feasibility

Review – Closure

Functional programming languages use “closures” to provide feasibility of functions, so that returning a function becomes easier and more practical

(defun make-adder (n) #’(lambda (x) (+ x n))) → returns a function (setf add3 (make-adder 3))

#<CLOSURE: LAMBDA (X) (+ X N)> > (funcall add3 2)

5

Review

> (list ‘my (+ 2 1) “Sons”)(MY 3 “Sons”)

> (list ‘(+ 2 1) (+ 2 1))((+ 2 1) 3)

> (cons ‘a ‘(b c d))(A B C D)

> (cons ‘a (cons ‘b nil))(A B)

> (car ‘(a b c))A

> (cdr ‘(a b c))(B C)

Review

> (setf x (list ‘a ‘b ‘c))(A B C)

> (setf (car x ) ‘n)N> x(N B C)

Review

> (apply #’+ ‘(1 2 3))6

> (mapcar #’(lambda (x) (+ x 10)) ‘(1 2 3))(11 12 13)

> (mapcar #’list ‘(a b c) ‘(1 2 3 4))((A 1) (B 2) (C 3))

> (maplist #’(lambda (x) x) ‘(a b c))((A B C) (B C) (C))

Review

> (member ‘b ‘(a b c))(B C)

> (member ‘(b) ‘((a) (b) (c)))NIL Why?

Equal: the same expression?Eql: the same symbol or number?member compares objects using eql> (member ‘(a) ‘((a) (z)) :test #’equal) ;:test-> keyword argument

((A) (Z))> (member ‘a ‘((a b) (c d)) :key #’car)

((A B) (C D)) Ask if there is an element whose car is a

Review

> (subseq ‘(a b c d) 1 2)(B)

> (every #’oddp ‘(1 3 5)) ;everyone is …T

> (some #’evenp ‘(1 2 3)) ;someone is …T

> (every #’> ‘(1 3 5) ‘(0 2 4))T

Review

Dotted list:is an n-part data structure (A . B) (setf pair (cons ‘a ‘b))

(A . B)

> ‘(a . (b . (c . nil)))(A B C)

> (cons ‘a (cons ‘b (cons ‘c ‘d)))(A B C . D)

Review

make-array > (setf arr (make-array ‘(2 3) :initial-element nil))

#<Array T (2 3)> Maximum:

7 dimensions Each dimension can have 1023 elements

Initial-element Optional Whole array will be initialized to this value

> (aref arr 0 0)NIL

> (setf (aref arr 0 0) ‘b)B

> (aref arr 0 0) ; access the arrayB

Review

One-dimensional array > (setf vec (make-array 4 :initial-element nil))

#(NIL NIL NIL NIL) > (vector “a” ‘b 5 “c”)

#(“a” B 5 “c”) > (setf vec (vector “a” ‘b 5 “c”))

> (svref vec 1) ;access the vector (sv: simple vector)B

String: a vector of characters> (sort “elbow” #’char<)

“below”Retrieve an element of a string

> (aref “abc” 1)#\b

> (char “abc” 1)#\b

Review

Replace elements of a stirng > (let ((str (copy-seq “Merlin”)))

(setf (char str 3) #\k) str)“Merkin”

Compare two strings > (equal “fred” “fred”)

T > (equal “fred” “Fred”)

NIL > (string-equal “fred” “Fred”)

T

Building strings > (format nil “~A or ~A” “truth” “dare”)

“truth or dare” > (concatenate ‘string “not “ “to worry”)

“not to worry”

Review

> (progn (format t “a”) (format t “b”) (+ 11 12) )ab23 -> only the value of the last expression is returned

> (block head (format t “Here we go.”) (return-from head ‘idea) (format t “We’ll never see this.”))Here we go.

Review

> (let ((x 7) (y 2)) (format t “Number”) (+ x y))Number9

> ((lambda (x) (+ x 1)) 3)4

(let ((x 2) (y (+ x 1))) (+ x y))

((lambda (x y) (+ x y)) 2 (+ x 1))

Review

(if <test> <then form> <else form>)(if <test> <then form>)

(when <test> <then form>)

(if <test> nil <else form>) (unless <test> <else form>)

Review

cond (cond (<test 1> <consequent 1-1> …)

(<test 2> <consequent 2-1> …) … (<test m> <consequent m-1> …));cond

case (case <key form>

(<key 1> <consequent 1-1> …) (<key 2> <consequent 2-1> …) ... (<key m> <consequent m-1> …)) ;case

Review

do (do ((<parameter 1> <initial value 1> <update form 1>)

(<parameter 2> <initial value 2> <update form 2>) … (<parameter n> <initial value n> <update form n>)) (<termination test> <intermediate forms, if any> <result form>) <body> ) ;do

> (let ((x ‘a)) (do ((x 1 (+ x 1)) (y x x)) ((> x 5)) (format t “(~A ~A) “ x y)))(1 A) (2 1) (3 2) (4 3) (5 4) ;on each iteration, x gets its previousNIL ;value plus 1; y also gets the previous ;value

Review

do* Has the same relation to do as let* does to let > (do* ((x 1 (+ x 1))

(y x x)) ((> x 5)) (format t “(~A ~A) “ x y))(1 1) (2 2) (3 3) (4 4) (5 5)NIL

Review

dolist > (dolist (x ‘(a b c d) ‘done)

(format t “~A “ x))A B C DDONE

dotimes > (dotimes (x 5 x) ; for x = 0 to 5-1, return x

(format t “~A “ x))0 1 2 3 4 5

Review

Multiple values> (values ‘a nil (+ 2 4))

ANIL6

(labels ((add10 (x) (+ x 10)) (consa (x) (cons ‘a x))) (consa (add10 3)))(A . 13)

> (labels ((len (lst) (if (null lst) 0 (+ (len (cdr lst)) 1)))) (len ‘(a b c)))3

Review

(defun our-funcall (fn &rest args) (apply fn args))

> (defun keylist (a &key x y z) (list a x y z))

Review

(defun disjoin (fn &rest fns)

(if (null fns)

fn

(let ((disj (apply #’disjoin fns)))

#’(lambda (&rest args)

(or (apply fn args) (apply disj args))))))> (mapcar (disjoin #’integerp #’symbolp)

‘(a “a” 2 3))(T NIL T T)

Midterm exam Time: April 21 Classroom: 資工所 (應用科學大樓 )/B1演講廳