360 likes | 527 Vues
Functional Programming. 06 Input and Output. Streams. Two kinds of streams Character streams Binary streams Character streams are Lisp objects representing sources and/or destinations of characters
E N D
Functional Programming 06 Input and Output
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 • > (setfstr (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 • > (setfstr (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 places • With the decimal point shifted right 0 places • Right-justified in a field of 10 characters • Padded on the left by blanks • If 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>23using namespace std; 45void printArrayOdd(int* beg, int* end) {6 while(beg != end) { 7 if ((*beg)%2) 8 cout << *beg << endl; 910 beg++;11 }12}1314void printArrayEven(int* beg, int* end) {15 while(beg != end) {16 if (!((*beg)%2))17 cout << *beg << endl;1819 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() {33intia[] = {1, 2, 3};3435cout << "Odd" << endl;36printArrayOdd(ia, ia + 3);3738 39cout << "Even" << endl;40printArrayEven(ia, ia + 3);4142cout << "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.com34Filename : FuntionPointer.cpp5Compiler : Visual C++ 8.0 / BCB 6.0 / gcc 3.4.2 / ISO C++6Description : Demo how to use function pointer7Release : 05/01/2007 1.08*/9#include <iostream>1011using namespace std;1213typedef bool (*predicate)(int);1415bool isOdd(inti) {16 return i%2? true : false;17}1819boolisEven(inti) {20 return i%2? false : true;21}22
Review – Function pointer in C 23bool greaterThan2(inti) {24 return i > 2;25}2627void printArray(int* beg, int* end, predicate fn) {28 while(beg != end) {29 if ((*fn)(*beg))30cout << *beg << endl;3132 beg++;33 }34}3536int main() {37intia[] = {1, 2, 3};3839cout << "Odd" << endl;40printArray(ia, ia + 3, isOdd);4142cout << "Even" << endl;43printArray(ia, ia + 3, isEven);4445cout << "Greater than 2" << endl;46printArray(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 • > (setfarr (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 • > (arefarr 0 0)NIL • > (setf(arefarr 0 0) ‘b)B • > (arefarr 0 0) ; access the arrayB
Review • One-dimensional array • > (setfvec (make-array 4 :initial-element nil))#(NIL NILNILNIL) • > (vector “a” ‘b 5 “c”)#(“a” B 5 “c”) • > (setfvec (vector “a” ‘b 5 “c”)) > (svrefvec 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 (cdrlst)) 1)))) (len ‘(a b c)))3
Review • (defun our-funcall (fn &restargs) (apply fn args)) • > (defunkeylist (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 disjargs)))))) > (mapcar (disjoin #’integerp #’symbolp) ‘(a “a” 2 3))(T NIL T T)
Midterm exam • Time: April 21 • Classroom: 資工所(應用科學大樓)/B1演講廳