CS 11 Ocaml track: lecture 3Equality/inequality operatorsUnit typeOption typesString accessing/mutating (1)String accessing/mutating (2)printf and friends (1)printf and friends (2)printf and friends (3)printf and friends (4)File I/O (1)File I/O (2)File I/O (3)File I/O (4)begin/end and sequencing (1)begin/end and sequencing (2)begin/end and sequencing (3)begin/end and sequencing (4)assertOn to...Imperative programmingReferences (1)References (2)while loopExampleRecords with mutable fields (1)Records with mutable fields (2)Records with mutable fields (3)Records with mutable fields (4)Arraysfor loopsBreaking out of loopsNext timeCS 11 Ocaml track: lecture 3Today:A (large) variety of odds and endsImperative programming in ocamlEquality/inequality operatorsTwo inequality operators: <> and !=Two equality operators: = and ==Usually want to use = and <>= means "structurally equal"<> means "structurally unequal"== means "the same exact object"!= means "not the same exact object"Unit typeThe unit type is a type with only one member: ()not a tuple with only one element!tuples must have at least two elementsSeems useless, butall ocaml functions must return a valuereturn () when value is irrelevanti.e. when function called for side effectsOption typestype 'a option = | None | Some of 'aBuilt in to ocamlUsed for functions that can return a value but can also "fail" (return None)Alternative to raising exception on failureString accessing/mutating (1)Strings are not immutableCan treat as an array of charsTo access a particular char:s.[i]To mutate a particular char:s.[i] <- 'a'String accessing/mutating (2)# let s = "some string" ;;val s : string = "some string"# s.[0] ;; (* note weird syntax *)- : char = 's'# s.[0] <- 't' ;;- : unit = ()# s ;;- : string = "tome string"printf and friends (1)# Printf.printf "hello, world!\n" ;;hello, world!- : unit = ()# open Printf ;;# printf "hello, world!\n" ;;hello, world!- : unit = ()printf and friends (2)# printf "s = %s\tf = %f\ti = %d\n" "foo" 3.2 1 ;;s = foo f = 3.200000 i = 1- : unit = ()printf has a weird typenot really well-typedcompiler "knows" about it and makes it workprintf and friends (3)# fprintf stderr "Oops! An error occurred!\n" ;;- : unit = ()# stderr ;;- : out_channel = <abstr>Predefined I/O "channels":stdin : in_channelstdout : out_channelstderr : out_channelprintf and friends (4)# sprintf "%d + %d = %d\n" 2 2 4 ;;- : string = "2 + 2 = 4\n"sprintf is "printing to a string"Very useful!File I/O (1)Files come in two flavors: input and output# open_in ;;- : string -> in_channel = <fun># open_out ;;- : string -> out_channel = <fun># close_in ;;- : in_channel -> unit = <fun># close_out ;;- : out_channel -> unit = <fun>File I/O (2)Files come in two flavors: input and outputlet infile = open_in "foo"tries to open file named "foo" for input onlybinds file object to infileclose_in infilecloses the input fileFile I/O (3)Files come in two flavors: input and outputlet outfile = open_out "bar"tries to open file named "bar" for output onlybinds file object to outfileclose_out outfilecloses the output fileFile I/O (4)flush stdoutforces an output file (here, stdout) to write its buffers to the diskinput_line stdingets a line of input from an input file (here, stdin) and returns a stringbegin/end and sequencing (1)With side effects, often want multiple statements inside a function:let print_and_square x = Printf.printf "%d\n" x ; x * xSingle semicolon used to separate statements that execute one after anotherbegin/end and sequencing (2)Sometimes want to say "these sequences should be treated as a single expression"Use begin/end for this:begin Printf.printf "%d\n" x; x * xendCan often leave out begin/endbegin/end and sequencing (3)Sometimes can just use parentheses:(Printf.printf "%d\n" x ; x * x)I advise against thisCan make code hard to readbegin/end and sequencing (4)Very often, when you get weird error messages it's because you should have put in a begin/end somewhereCommonly found in nested match expressions (ocaml grammar is highly ambiguous!)When in doubt, add explicit begin/end statements everywhere you use sequencingassertOcaml has an assert statement like most imperative languagesNot a function!Takes one "argument", a booleanIf it's false, raises Assert_failure exceptionTurn off assertions with -noassert compiler optionOn to...Imperative programming!We've already done imperative programmingprintf is a function called for side-effects onlybegin/end and sequencing only useful for side effecting operationsNow want to cover the "core" of imperative programmingImperative programmingImperative data types:referencesrecords with mutable fieldsmutable arraysImperative statements:for loopwhile loopBreaking out of loopsReferences (1)A reference type is like a regular type in C/C++/Java/Python/whateverCan also think of as a box that holds a single value# let x = ref 0 ;;val x : int ref = {contents = 0}# !x ;;- : int = 0References (2)The ! operator fetches the value from the reference "box"The := operator assigns a new value to the reference# x := 10 ;;- : unit = ()# x ;;- : int ref = {contents = 10}LHS of := must be a reference, not a value!while loopwhile loop is basically like C/C++/Java while loop:while <condition> do <stmt1>; <stmt2>; ... <stmtn>doneExamplelet factorial n = let result = ref 1 in let i = ref n in while !i > 1 do result := !result * !i; i := !i - 1 done; !resultVery easy to accidentally omit ! operatorsRecords with mutable fields (1)References are just a special case of records with mutable fieldsRecall record type declaration:type point = { x: int; y: int }This declares point as an i mmutable typex and y fields can't change after point creatednot always what you wantRecords with mutable fields (2)To get mutable fields:type point = { mutable x: int; mutable y: int }Now can change x, y fields:let p = { x = 10; y = 20 } ;;val p : point = {x = 10; y = 20}# p.x <- 1000 ;;- : unit = ()# p ;;- : point = {x = 1000; y = 20}Records with mutable fields (3)To get only some mutable fields:type point = { x: int; mutable y: int }Now can change only change y field:# let p = { x = 10; y = 20 } ;;val p : point =
View Full Document