Dr A Sahu Dept of Computer Science & Engeerg IIT Guwahati Admistrative thgs SML stallation and Book ML Motivation ML : Meta Language (Basic Concepts) Expression, Type Consistency, Variable & Environment Tuples and Lists Function: it s easy and it is fun Patterns Function Defitions, Local environment usg let Exception and I/O Course Structure : Functional Programmg (ML: Meta Lang.) 25% Logic Programmg (Prolog) 25% Concurrent/Parallel Programmg (Java/Cilk) 50% Lab hours : Mon 2PM 5PM (It is not mandatory to be present Lab) Tutorial hours Mon 5 6PM, 2001 (Mandatory) TAs : Debanjan, Pratik, Tarun and Rajendra Course website http://jatga.iitg.ernet./~asahu/cs431/ Assignments: One basic and one advanced from each part (Total 6 Assignments) ML Programmg: Basic (10%), Advanced (15%) Prolog programmg: Basic (10%), Advanced (15%) ParallelProgrammg: Programmg: Basic (20%), Advanced/Project (30%) Demos of Last Assignment/Project only Absolute Gradg Copy case any Assignment lead to F Grade ML Motivation : Why to Study? Functional Programmg Language: Entirely different paradigms Other than C Style for, while, do_while Thkg terms of Recursion Composite functions Functor (function on structures) Interactive type type expression, evaluate and get result Standard Meta language (SML) SML stallation http://www.smlnj.org/stall/dex.html Available for both Lux and Wdow ML Basic (Tutorial 1) ML Basic (Tutorial 1) ML Advanced (Tutorial 2 and 3) Jeffrey D. Ullman, Elements of ML Programmg, Prentice Hall, 1994 1
Expression Type Consistency Variable & Environment Tuples and Lists Function: it s easy and it is fun Patterns Function Defitions Local environment usg let Exception and I/O $ sml Standard ML of New Jersey v110.74 [built: Tue Jul 30 09:57:27 2013] - prt "hello world"; hello world val it = () : unit - $ sml Standard ML of New Jersey v110.74 [built: Tue Jul 30 09:57:27 2013] -1+2*3; val it =7 : t We typed the expr 1+2*3 and ML respond the value of variable it is 7. Constants : Integer, Real, Boolean, Strg Arithmetic Operations Arithmetic : +,, *, div and mod -3.0-4.5 +6.7; val it =5.2 : real val it 5.2 : real -43 div ( 8 mod 3 ) * 5 ; val it 105 : t Result type is also out put Unary operator mus is ~ - ~3+4; val it =1 : t Result type Strg operations - house ^ cat ; val it = housecat : strg - loleium ^ ; val it= loleium : strg Comparison Operations -2<1+3; val it =true : bool - abc <= ab ; val it false : bool Precedence of comparison is less as compared to arithmetic ops Logical Operators -1<2 orelase 3>4; val it=true: bool 1<2 andalso 3>4; val it=false: bool The If then else Operator -if 1<2 then 3+4 else 5+6; val it =7 : t 2
Almost strictly Typed Language -1+2; val it=3 : t -1.0+2.0; val it=3.0; real -1.0+2; 1 0 2 stdin:2.1-2.6 Error: operator and operand don't agree [literal] operator doma: real * real operand: real * t expression: 1.0 + 2 -if 1<2 then 3 else 4.0; stdin:1.2-2.2 Error: types of if branches do not agree [literal] then branch: t else branch: real expression: if 1 < 2 then 3 else 4.0 -if 2 then 3 else 4; stdin:1.2-1.20 Error: test expression if is not of type bool [literal] test t expression: t expression: if 2 then 3 else 4 Some time we have a reason to convert (coerce) from one type to another -real(4); val it=4.0 :real -5.3/real(4); val it=1.325 :real; -ceilg(3.5); val it=4 :t -floor(~3.5); val it=~4 :t -truncate(2.5); val it =2 : t -ord( a ); val it =97 : t -ord( a )-ord( A ); val it =32 :t -chr(97); val it = a : strg An Assignment like statement -val pi=3.14159; val pi=3.14159 :real -val radius=4.0; val radius=4.0:real -pi*radius*radius; val it=50.26544:real -val area= pi*radius*radius; val area=50.26544:real Tuple is kd of record -val t=(4,5.0, six ); val t=(4,5.0, six ):t*real*strg -val t1=(1,2,3); val t1=(1,2,3):t*t*t -vall t2=(1,(2,3.0)); (2 val t2==(1,(2,3.0)):t*(t*real) Accessg tuples -#1(t); val it=4:t -#3(t); val it= six :strg 3
List : element of same type -[1,2,3]; val it=[1,2,3]:t list -[ a ]; val it=[ a ] :strg list -[ a,3]; stdin:1.2-1.9 Error: operator and operand don't agree [literal] operator doma: strg * strg list operand: strg * t list expression: "a" :: 3 :: nil Operator head hd and tail tl Head of list is an element and tail of a list is a list -val L=[1,2,3]; val L=[1,2,3]:t list -hd(l); val it=1: t -tl(l); val it=[2,3]: t list -tl(tl(tl(l))); val it=[]:t list Cons operator (: : ) take an element and a list and produce a list -2::[3,4]; val it=[2,3,4]:t list -2.0::nil; val it=[2.0]: real list -1::2::3::4; Right associative: 1:: (2:: (3:: nil)) val it=[1,2,3,4]: t list Concatenation (@): concatenate two list of same type -[1,2]@[3,4]; val it=[1,2,3,4]: t list explode -expolde( abcd ); val it=[ a, b, c, d ]:strg list -expolde( ); val it=[]: strg list implode -implode([ a, bc, d ]); val it= abcd : strg -implode(nil); val it=[]: strg ML: Functional Programmg Language It s easy: It s fun Defe the function and use this function as argument seamlessly Use function place Where more traditional languages uses iterations (while, for, stmt loops) to defe Format fun <identifier> (<param list>) = expression; Examples -fun upper (c)= chr(ord (c) -32); val upper=fn: strg->strg Doma Range -upper( a ); val it= A : strg Parameter type -fun square(x:real)=x*x; val square=fn: real -> real -val area=3.142 * square 5.0; val area=70.55: real 4
Parameter type: Another example -fun square(x)=x*x; val square=fn: t -> t -val area=3.142 * square 5; stdin:3.5-3.22 Error: operator and operand don't agree [tycon mismatch] operator doma: real * real operand: real * t expression: pi * square 5 Function with three parameters -fun max3(a:t,b,c)= if a>b then if a>c then a else c else if b>c then b else c; val max3=fn: t*t*t->t Here ML deduce d b and c are teger type as if then else require same type parameters max3 works -max3(1,2,4); for val it=4:t -val t=(1,2,4); this type val t = (1,2,4):t*t*t also -max3(t); val it=4:t Recursive function A basis (base case) : for significantly small arguments we compute result without makg recursive call An ductive step: can t be handled by basic, we call function recursively one or more time with smaller argument -fun fact (n) = if n=0 then 1 else n*fact(n-1); val fact = fn : t -> t Other examples -fun reverse(l)= if L=nil then nil else reverse(tl(l))@ [hd(l)]; val reverse =fn: a list -> a list -reverse([1,2,3]; val it=[3,2,1]: a list fun reverse(l)= if L=nil then nil else reverse(tl(l))@ [hd(l)]; reverse([1,2,3]; Reverse.ml -use Reverse.ml ; (* Use file *) -open Math; (*Open library math *) -open Real; -open Int; -open List; Non Lear Recursion -fun(comb(n,m)=(*assume 0<=m<=n*) if m=0 orelse m=n then 1 else comb(n-1,m)+comb(n-1,m-1); val comb=fn:t*t ->t -comb(4,2); val it=6:t 5
Dependent recursive functions -fun odd (n) = if n=0 then false else even (n-1) and even (n) = if n=0 then true else odd (n-1); val odd = fn : t -> bool val even = fn : t -> bool -odd(4); val it=false : bool -even(4); val it=true : bool Dependent recursive functions -fun take (L) = if L=nil then nil else if hd(l)::skip(tl(l)) and skip(l) = if L=nil then nil else take(tl(l)); val take = fn : a list -> a list val skip = fn : a list -> a list -take([1,2,3,4,5); val it=[1,3,5]: t list -skip([ a, b, c, d, e ]); val it=[ b, d ] : strg list Matchg declaration - val (fst, snd) = (4, 4.45); val fst = 4 : t val snd = 4.45 : real -val abscissa=x, ordate=y = abscissa=1.2, ordate=3.2; val x = 1.2 : real val y = 3.2 : real -val b=x,...=a=2,b="s,c=3.4,d=[1]; val x = "s" : strg - val 2=x,... = (1,2,3); val x = 2 : t -val (x,x) = (2,3); stdin:22.1-22.18 Error: duplicate variable pattern(s): x -val (x,_,y,_) = (1,2,3,4); val x = 1 : t val y = 3 : t -val head :: _ = [1, 2, 3]; stdin:25.1-25.26 Warng: bdg not exhaustive head :: _ =... val head = 1 : t -fun reverse(nil)=nil reverse(x::xs)=reverse(xs)@[x]; val reverse =fn: a list -> a list -fun comb(n,0)=1 comb(n,n)=1 comb(n,m)=comb(n-1,m)+comb(n-1,m-1); Error: duplicate variable pattern(s):n fun comb(_,0)=1 if m=n then 1 else comb(n,m)=comb(n-1,m)+comb(n-1,m-1); val comb=fn:t*t -> t -fun sumpairs(nil)=0 SumPair((x,y)::zs)=x+y+sumPair(zs); val reverse =fn: (t*t)list -> t -sumpairs([(1,2),(1,5),(~3,6)]); val it= 12: t -fun sumll(nil)=0 sumll(nil::ys)=sumll(ys) sumll(x::xs)::ys)=x+sumlist(xs::ys); val sumll=fn: t list list->t -sumll([[1,2],nil,[3,4,5],[6])); val it=21:t 6
#clude<stdio.h> char A='E'; t ma() char A='M'; char A='B'; prtf("inside Block %c\n",a); extern char A; prtf("inside Ext Block %c\n",a); prtf("inside Ma %c\n",a); #clude<stdio.h> char A='E'; t ma() char A='M'; char *p=&a; //Save before decl. char A='B'; prtf("inside Block %c\n",a); prtf( Saved Value=%c\n",*p); extern char A; prtf("inside Ext Block %c\n",a); prtf("inside Ma %c\n",a); #clude<stdio.h> /* In C++, this feature has been removed, encourage to use :: */ void Resolve() prtf("external\n"); t ma() void Resolve()prtf("Ma\n"); void Resolve()prtf("Block\n"); Resolve(); extern void Resolve(); Resolve(); Resolve(); let val=<first variable>=<first expr>; val= <second variable>=<second expr>; val= <last variable>=<last expr> expression Expression can be combation expression and functions -fun hudreadthpower(x:real)= let val four=x*x*x*x; val twenty=four*four*four*four*four twenty*twenty*twenty*twenty*twenty val hundreadthpower: fn : real->real -hundreadthpower(2.0); val it=1.267050e30 :real -fun split(nil)=nil split([a])=([a],nil); split(a::b::cs)= let val (M,N)=split(cs) (a::m,b::n) It divide the list to two equal parts with alternative element val split: fn : a list-> a list* a list -split([1,2,3,4,5]); val it=(1,3,5],[2,4]): t list * t list 7
-fun merge(nil,m)=m merge(n,nil)=n; merge(x:;xs,y::ys)= if (x<y) then x::merge(xs,y::ys) else y::merge(x::xs,ys); ys); val merge=fn: a list* a list-> a list -fun mergesort(nil)=nil mergesort([a])=([a]); mergesort(l)= let val (M,N)=split(L); val M=mergeSort(M); val N=mergeSort(N) Split(L): divide the list to two equal parts with alternative elements merge(m,n) val mergesort: fn : a list-> a list -5 div 0; uncaught exception Div 5.0/0.0 uncaught exception Div hd(nil); uncaught exception Hd chr(500); uncaught exception Chr -exception BadN; exception badn - fun fact (n) = if n<0 raise BadN else if n=0 then 1 else n*fact(n-1); val fact=fn:t->t -exception BadM; exception badm fun comb(n,m) = if n<0 then raise BadN else if m<0 orelse m>n then raise BadM else if m=0 orelse m=1 then 1 else comb(n-1,m)+comb(n-1,m-1) val comb = fn : t*t->t fun comb(n,m) = let exception BadN; exception BadM; if n<0 then raise BadN else if m<0 orelse m>n then raise BadM else if m=0 orelse m=1 then 1 else comb(n-1,m)+comb(n-1,m-1) val comb = fn : t*t->t - fun id x = x; val id = fn : 'a -> 'a - (id 1, id "two"); val it = (1,"two") : t * strg - fun fst (x,y) = x; val fst = fn : 'a * 'b -> 'a - fun snd (x,y) = y; val snd = fn : 'a * 'b -> 'b - fst (1,"two"); val it = 1 : t - fst ([true, false], 3.14159); val it = [true,false] : bool list - fst (1,"two") + snd ((1,2), hd [1,2,3]); val it = 2 : t 8
- fun switch (x,y) = (y,x); val switch = fn : 'a * 'b -> 'b * 'a - switch (2, "abc"); val it = ("abc",2) : strg * t - switch (2,3.14159); val it = (3.14159,2) : real * t - #2 (switch ([6,9], (fn x =>x))); val it = [6,9] : t list - fun null (nil) = true null (_::_) = false; val null = fn : 'a list -> bool - fun length (x) = if null x then 0 else length (tl x) + 1; val length = fn : 'a list -> t Op: convertg fix operators to function names -2+3; val it 5: t -op + (2,3); val it 5: t -fun map = map (f,nil) = nil map (f,h::t) = f(h) :: map (f,t); val map = fn : ('a->'b)*'a list -> 'b list -fun square(x:t)=x*x; val sqaure= fn:t->t -map(square,[1,2,3]); val it=[1,4,9]; -map (fn x=>x+1, [1,2,3,4,5]); val it = [2,3,4,5,6] : t list -map(~,[1,2,3]); val it = [~1,~2,~3]: t list Defe function onle -fun comp(f,g)= let fun C(x)=G(F(x)) C val map = fn : ('a->'b)* ( b-> c)-> ('a-> c) -fun F(x)=x+3; val F=fn:t->t -fun G(y)=y*y+2*y; val G = fn: t->t -val H=comp(F,G);; val H= fn:t->t -H(10); val it=195; - val f = comp (Math.s, Math.cos); val f = fn : real -> real - val g = Math.s o Math.cos; (* Composition "o" is predefed *) val g = fn : real -> real - f(0.25); val it = 0.824270418114 : real - g(0.25); val it = 0.824270418114 : real Dividg a to b to n equal parts of some n Let h=(b a)/n; Area of i th trapezoid has width δ runs from a+(i 1)h to a+ih is = Area= h( f ( a + ( i 1) h) + f ( a + ih) )/ 2 Total Area 9
Recursive defition of this Will be Total Area=Area of first trapezoid + rest area h(f(a)+f(a+h))/2 + Trap(a+h,b,n 1,F) -fun sqaure:real)=x+x; val square :fn :real->real; -fun trap(a,b,n,f) = if n<=0 orelse b-a<=0.0 then 0.0 else let val h=(b-a)/real(n) h*(f(a)+f(a+h))/2.0+trap(a+h,b,n-1,f) val trap=fn:real8real*t*(real->real)->real; -trap(0.0,1.0,8, square); Val it =.3359375 :real -exception Emptylist; exception EmptyList; -fun reduce(f,nil) =raise EmptyList reduce(f,[a]) = a; reduce(f,x::xs)=f(x,reduce(f,xs); val reduce:fn: ( a* a-> a)* alist-> a -reduce(+,[1,4,8]); val it=13:t -fun plus(x:real)=x+y; val plus:fn :real*real->real n n 2 2 Var = ( ai ) / n (( ai ) / n) i= 1 i= 1 -fun variance(l)= let val n=length(l) reduce(plus,map(sqaure(l))/n - square(reduce(plus,l)/n) val variance = fn: real list->real -variance ([1.0,2.0,5.0,8.0]); val it =7.5:real 10