06 INPUT AND OUTPUT Functional Programming. Streams Two kinds of streams Character streams Binary...

36
06 INPUT AND OUTPUT Functional Programming

Transcript of 06 INPUT AND OUTPUT Functional Programming. Streams Two kinds of streams Character streams Binary...

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演講廳