CMSC330: OCAML BASICS

33 0 0
Tài liệu đã được kiểm tra trùng lặp
CMSC330: OCAML BASICS

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Công Nghệ Thông Tin, it, phầm mềm, website, web, mobile app, trí tuệ nhân tạo, blockchain, AI, machine learning - Công Nghệ Thông Tin, it, phầm mềm, website, web, mobile app, trí tuệ nhân tạo, blockchain, AI, machine learning - Lập trình CMSC330: OCaml Basics Chris Kauffman Last Updated: Thu Sep 28 09:09:59 AM EDT 2023 1 Logistics Assignments ▶ Project 3 Due Fri 06-Oct: Regex → NFA → DFA ▶ Quiz 2 on Fri 29-Sep in Discussion REMINDER: Past Semester Quizzes available under Resources on class web page ▶ Exam 1 on Thu 05-Oct, covers topics through Thu 28-Sep Reading: OCaml Docs https:ocaml.orgdocs ▶ Tutorial: Your First Day with OCaml ▶ Tutorial: OCaml Language Overview Goals: OCaml Overview ▶ Static Types Type Inference ▶ Pattern Matching ▶ Aggregate Data 2 A bit of History. . . ▶ 1930s: Alonzo Church invents the Lambda Calculus , a notation to succinctly describe computable functions. ▶ 1958: John McCarthy and others create Lisp , a programming language modeled after the Lambda Calculus. Lisp is the second oldest programming language still widely used. ▶ Descendants of Lisp include Common Lisp, Emacs Lisp, Scheme, Racket, etc. ▶ Lisp influenced almost every other language that followed it ▶ 1972: Robin Milner and others at EdinburghStanford develop the Logic For Computable Functions (LCF) Theorem Prover to do mathy stuff ▶ To tell LCF how to go about its proofs, they invent a Meta Language (ML) which is like Lisp with a type system (Hindley-Milner type system) ▶ Folks soon realize that ML is a damn fine general purpose programming language and start doing things with it besides programming theorem provers 3 Origins of OCaml Circa 1990, Xavier Leroy at France’s INRIA looks at the variety of ML implementations and declares “C’est nul” == “It’s crap” ▶ No command line compiler: only top level REPL ▶ Run only on Main Frames, not Personal Computers (a la Unix to Linux) ▶ Hard to experiment with adding new featuresC''''est nul Xavier Leroy in 2010 Leroy develops the ZINCa system for INRIA’s flavor of ML: Categorical Abstract Machine Language (CAML) to allow ▶ Separate compilation to bytecode and linking Later work introduces ▶ Object system: Objective Caml, shortened to OCaml ▶ Native code compiler ▶ Various other tools sweet tools like a time traveling debugger Question: Bytecode? Native Code? What are these? aXavier Leroy. The ZINC Experiment. Technical report 117, INRIA, 1990 4 Bytecode versus Native Code Compilation Native Code Compilation Convert source code to a form directly understandable by a CPU (an executable program) Bytecode Compilation Convert source code to an intermediate form (bytecode) that is must be further converted to native code by an interpreter. Source Code Interpreter Directly execute source code as it is read by doing on-the-fly conversions to native code. System CompilationExecution Model Java Compile to Bytecode: javac, Interpret to native: java C C++ Native Code Compilation: gcc clang Python Interpret Source Code with on-the-fly bytecode creation: python REPL: python OCaml Compile to Bytecode: ocamlc, Interpret to native: ocamlrun Native Code Compilation: ocamlopt REPL: ocaml 5 Bytecode versus Native-Code Compilation BYTECODE COMPILER : ocamlc > ocamlc speedtest.ml compile to bytecode > file a.out show file type a.out: a usrbinocamlrun script executable (binary data) > time .a.out time execution 33554432 real 0m0.277s about a quarter second passed user 0m0.276s full debug features available sys 0m0.000s NATIVE CODE COMPILER: ocamlopt > ocamlopt speedtest.ml compile to native code > file a.out show file type a.out: ELF 64-bit LSB pie executable x86-64 > time .a.out 33554432 real 0m0.022s about 110th the time: WAY FASTER user 0m0.022s BIG BUT: can'''' t use native code with sys 0m0.000s OCaml''''s debugger 6 Influence of Functional Programming and ML Why are we studying OCaml? No one uses it. . . – Every Student ever Tasked to Study OCaml You may never use OCaml for a job, but you will definitely feel its effects via the adoption of Functional Programming and ML-inspired static type systems ▶ Java 8 added lambdas, enabled MapReduce, uses a Generics system that is verbose substitute for ML’s polymorphic types ▶ C++ and C have added auto var types inferred by compiler ▶ F (Microsoft) : OCaml + .NET framework ▶ Swift (Apple) : ML + Objective-C library access ▶ Scala : JVM language with type inference, algebraic data types, functional features, OO features, every lang feature known and unknown ▶ Rust: C + Some OCaml syntax + Some Type Inference + Manage memory entirely at compile time Incidentally, the first Rust compiler was written in OCaml 7 Exercise: Collatz Computation An Introductory Example ▶ collatz.ml prompts for an integer and computes the Collatz Sequence starting there ▶ The current number is updated to the next in the sequence via if cur is EVEN cur=cur2; else cur=cur3+1 ▶ This process is repeated until it converges to 1 (mysteriously) or the maximum iteration count is reached ▶ The code demonstrates a variety of Python features and makes for a great crash course intro ▶ With a neighbor, study this code and identify the features you should look for in every programming language 8 Exercise: Collatz Computation An Introductory Example 1 ( collatz.ml: ) 2 open Printf;; ( use printf ) 3 let verbose = true;; ( module-level var ) 4 5 let collatz start maxsteps = ( func of 2 params ) 6 let cur = ref start in ( local variable ) 7 let step = ref 0 in ( refs for mutation ) 8 if verbose then 9 begin 10 printf "start: d maxsteps d\n" start maxsteps; 11 printf "Step Current\n"; 12 end; 13 while cur = 1 step < maxsteps do 14 if verbose then 15 printf "3d: 5d\n" step cur; 16 begin match cur mod 2 with ( pattern matching ) 17 0 -> cur := cur2; ( := is ref-assigment ) 18 -> cur := cur3+1; ( x is dereference ) 19 end; 20 step := step + 1; 21 done; 22 (cur,step) ( return value ) 23 ;; 24 let = ( main block ) 25 printstring "Collatz start val:\n"; 26 let start = readint () in 27 let (final,steps) = collatz start 500 in 28 printf "Reached d after d iters\n" final steps; 29 ;; Look for. . . Comments, StatementsExpressions, Variable Types, Assignment, Basic InputOutput, Function Declarations, Conditionals, Iteration, Aggregate Data, Library System >> ocamlc collatz.ml >> .a.out Collatz start val: 10 0: 10 1: 5 2: 16 3: 8 4: 4 5: 2 6: 1 9 Answers: Collatz Computation An Introductory Example ⊠ Comments: ( comment between ) ⊠ StatementsExpressions: expressions sort of normal like x+1 a b t < m printf "d" a; Variables introduced via let x = .. in ⊠ Variable Types: string, integer, boolean are obvious as values, no type names mentioned. . . isn’t OCaml statically typed? ⊠ Assignment: via let x = expr in or x := expr; ⊠ Basic InputOutput: printf() readint() ⊠ Function Declarations: let funcname param1 param2 = ⊠ Conditionals (if-else): if cond then ... else ... Multiple statements require beginend We’ll get to know this sexy matchwith character as soon. . . ⊠ Iteration (loops): clearly while cond do, others soon ⊟ Aggregate data (arrays, records, objects, etc): (ocaml,has,tuples) and others we’ll discuss soon ⊟ Library System: open Printf is like from Printf import 10 Type Inference ▶ All varsvalues are statically typed by compiler BUT. . . ▶ Compiler uses type inference to determine types so programs rarely states them explicitly; REPL shows this 1 >> ocaml ( start the REPL ) 2 OCaml version 5.0.0 3 Enter help;; for help. 4 ( TYPE INFERENCE ) 5 let x = 7;; ( bind x to 7 ) 6 val x : int = 7 ( x must be an integer ) 7 let doubler i = 2i;; ( bind doubler to a function ) 8 val doubler : int -> int = ( int argument, int returns ) 9 ( arg return ) 10 11 ( TYPE CHECKING ) 12 doubler 9;; ( call doubler on 9 ) 13 - : int = 18 ( result is an integer ) 14 doubler x;; ( call on x ) 15 - : int = 14 ( ok: x is an integer ) 16 doubler "hello";; ( call doubler "hello" ) 17 Line 1, characters 8-15: ( Type Checker says: ) 18 1 doubler "hello";; ( NO SOUP FOR YOU ) 19 ^^^^^^^ 20 Error: This expression has type string but an 21 expression was expected of type int 11 Type Inference During Compilation While explicit types don’t appear during normal compilation, they are always present and will appear in error messages >> cat typeinferenceerrors.ml 1 open Printf;; 2 3 let doubler i = 2i;; 4 5 let = 6 let four = doubler 2 in 7 let eight = doubler four in 8 let yesyes = doubler "yes" in ( Like in Python, right? ) 9 printf "d d d\n" four eight; 10 printf "d\n" yesyes; 11 ;; >> ocamlc typeinferenceerrors.ml Have a tall glass of NOPE File "typeinferenceerrors.ml", line 8, characters 23-28: 8 let yesyes = doubler "yes" in ^^^^^ Error: This expression has type string but an expression was expected of type int 12 Types and Type Notations Basic Types Expected basic types for high-level langs are present like int float bool string A few other special types like unit and ’a are common that will be discussed momentarily Aggregate Types OCaml has various built-in aggregate types as well let ia = 1; 2; 3;; val ia : int array = 1; 2; 3 let sl = "a"; "b";;; val sl : string list = "a"; "b" let tup = (true,4.56,"hi");; val tup : bool float string = (true, 4.56, "hi") Function Types Functions have types with each param separated by an arrow -> including the final return type let add a b = a+b;; val add : int -> int -> int = add;; - : int -> int -> int = let selfcat s = s^s;; val selfcat : string -> string = intofstring;; - : string -> int = let addpair (a,b) = a+b;; val addpair : int int -> int = let givemeaning () = 42;; val givemeaning : unit -> int = let polymeaning x = 42;; val polymeaning : ''''a -> int = 13 Type Annotations ▶ Types are inferred but one can annotate code with types ▶ Be aware that conflicts between annotations and inferred types will generate compiler errors ▶ May look at OCaml’s Module System which includes Interface Files that state the types of all functionsvariables, known as the module signature let a = 1;; val a : int = 1 let x : int = 5;; val x : int = 5 let y : int = "hi";; Line 1, characters 14-18: 1 let y : int = "hi";; ^^^^ Error: This expression has type string but an expression was expected of type int let add (a : int) (b : int) : int = a+b;; val add : int -> int -> int = let selfcat (s : string) : string = s+s;; Line 1, characters 36-37: 1 let selfcat (s : string) : string = s+s;; ^ Error: This expression has type string but an expression was expected of type int 14 Unit Type for Printing Side-Effects ▶ The notation () means unit and is the return value of functions that only perform side-effects ▶ Roughly equivalent to void in C Java etc. ▶ Often appears as return type for output functions ▶ Usually don’t about unit returns; don’t bind result and. . . ▶ Functions with no parameters are passed () to call them ▶ End statements returning unit with a semi-colon (;) except at the top level where ;; is used instead 1 printstring;; 2 - : string -> unit = 3 4 printstring "hi\n";; 5 hi 6 - : unit = () 7 8 printf "d\n" 42;; 9 42 10 - : unit = () 11 12 let meaning () = 42;; 13 val meaning : unit -> int = 14 15 meaning;; 16 - : unit -> int = 17 18 meaning ();; 19 - : int = 42 15 Exercise: Infer Those Types ▶ Determine the type of each of the following entities ▶ Tuples are created via (a,b) (parens optional) ▶ Lists are created via x;y;z ▶ Function types notated with type1 -> type2 -> type3 -> ... Each function is a one-li...

Trang 2

▶ Project 3 Due Fri 06-Oct: Regex→ NFA → DFA

Quiz 2 on Fri 29-Sep in Discussion

REMINDER: Past Semester Quizzes available under

Resources on class web page

▶ Exam 1 on Thu 05-Oct, covers topics through Thu 28-SepReading: OCaml Docshttps://ocaml.org/docs

▶ Tutorial: Your First Day with OCaml

▶ Tutorial: OCaml Language Overview

Goals: OCaml Overview

▶ Static Types / Type Inference▶ Pattern Matching

▶ Aggregate Data

Trang 3

A bit of History .

1930s: Alonzo Church invents the Lambda Calculus, a

notation to succinctly describe computable functions.

1958: John McCarthy and others create Lisp, a programming

language modeled after the Lambda Calculus Lisp is thesecond oldest programming language still widely used.

▶Descendants of Lisp include Common Lisp, Emacs Lisp,

Scheme, Racket, etc.

Lisp influenced almost every other language that followed it

▶ 1972: Robin Milner and others at Edinburgh/Stanford developthe Logic For Computable Functions (LCF) Theorem Proverto do mathy stuff

To tell LCF how to go about its proofs, they invent a Meta

Language (ML) which is like Lisp with a type system

(Hindley-Milner type system)

▶ Folks soon realize that ML is a damn fine general purposeprogramming languageand start doing things with it besidesprogramming theorem provers

Trang 4

Origins of OCaml

Circa 1990, Xavier Leroy at France’s INRIA looks atthe variety of ML implementations and declares

“C’est nul” == “It’s crap!”

▶No command line compiler: only top levelREPL▶Run only on Main Frames, not Personal

Computers (a la Unix to Linux)

▶Hard to experiment with adding new features

C'est nul!

Xavier Leroy in 2010

Leroy develops the ZINCasystem for INRIA’s flavor of ML: Categorical AbstractMachine Language (CAML) to allow

Separate compilation to bytecode and linking

Later work introduces

Object system: Objective Caml, shortened to OCaml

▶Native code compiler

Various other tools sweet tools like a time traveling debugger

Question:Bytecode? Native Code? What are these?

Xavier Leroy The ZINC Experiment Technical report 117, INRIA, 1990

Trang 5

Bytecode versus Native Code CompilationNative Code Compilation

Convert source code to a form directly understandable by a CPU(an executable program)

Bytecode Compilation

Convert source code to an intermediate form (bytecode) that ismust be further converted to native code by an interpreter.Source Code Interpreter

Directly execute source code as it is read by doing on-the-flyconversions to native code.

SystemCompilation/Execution Model

JavaCompile to Bytecode: javac, Interpret to native: javaC / C++Native Code Compilation: gcc / clang

PythonInterpret Source Code with on-the-fly bytecode creation: pythonREPL: python

OCamlCompile to Bytecode: ocamlc, Interpret to native: ocamlrunNative Code Compilation: ocamlopt

REPL: ocaml

Trang 6

Bytecode versus Native-Code Compilation

# BYTECODE COMPILER : ocamlc

> ocamlc speedtest.ml# compile to bytecode> file a.out# show file type

a.out: a /usr/bin/ocamlrun script executable(binary data)

>time./a.out# time execution

real0m0.277s# about a quarter second passeduser0m0.276s# full debug features availablesys0m0.000s

# NATIVE CODE COMPILER: ocamlopt

> ocamlopt speedtest.ml# compile to native code> file a.out# show file typea.out: ELF64-bit LSB pie executable x86-64>time./a.out

Trang 7

Influence of Functional Programming and ML

Why are we studying OCaml? No one uses it .– Every Student ever Tasked to Study OCaml

You may never use OCaml for a job, but you will definitely feel its

effects via the adoption of Functional Programming and

ML-inspired static type systems

▶ Java 8 added lambdas, enabled Map/Reduce, uses a Genericssystem that is verbose substitute for ML’s polymorphic types▶ C++ and C have added auto var types inferred by compiler▶ F# (Microsoft) : OCaml + NET framework

▶ Swift (Apple) : ML + Objective-C library access

▶ Scala : JVM language with type inference, algebraic datatypes, functional features, OO features, every lang featureknown and unknown

▶ Rust: C + Some OCaml syntax + Some Type Inference +Manage memory entirely at compile time

Incidentally, the first Rust compiler was written in OCaml

Trang 8

Exercise: Collatz Computation An Introductory Example

▶ collatz.ml prompts for an integer and computes the CollatzSequencestarting there

▶ The current number is updated to the next in the sequence viaif cur is EVEN cur=cur/2; else cur=cur*3+1▶ This process is repeated until it converges to 1 (mysteriously)

or the maximum iteration count is reached

▶ The code demonstrates a variety of Python features andmakes for a great crash course intro

▶ With a neighbor, study this codeand identify the features youshould look for in every programming language

Trang 9

Exercise: Collatz Computation An Introductory Example

1(* collatz.ml: *)

3 let verbose=true;;(* module-level var *)

5 let collatz start maxsteps=(* func of 2 params *)

6 let cur=ref start in (* local variable *)

7 let step=ref0in (* refs for mutation *)

8 ifverbose then

9 begin

10printf"start: %d maxsteps %d\n"start maxsteps;

12 end;

13 while !cur!= 1 && !step<maxsteps do

14 ifverbose then

15printf"%3d: %5d\n"!step!cur;

16 begin match !curmod 2with (* pattern matching *)

17| 0 ->cur:= !cur/2;(* := is ref-assigment *)

18| _ ->cur:= !cur*3+1;(* !x is dereference *)

24 let _ =(* main block *)

25print_string"Collatz start val:\n"

26 let start=read_int () in

27 let (final,steps) =collatz start500in

28printf"Reached %d after %d iters\n"final steps;

Look for Comments,Statements/Expressions,Variable Types,

Assignment, BasicInput/Output, FunctionDeclarations, Conditionals,Iteration, Aggregate Data,Library System

>> ocamlc collatz.ml>> /a.out

Collatz start val:

Trang 10

Answers: Collatz Computation An Introductory Example

⊠ Comments: (* comment between *)

⊠ Statements/Expressions: expressions sort of normal likex+1 a && b t < m printf "%d" a;Variables introduced via let x = in

⊠ Variable Types: string, integer, boolean are obvious as values,

no type names mentioned isn’t OCaml statically typed?

⊠ Assignment: via let x = expr in or x := expr;⊠ Basic Input/Output: printf() / read_int()

⊠ Function Declarations: let funcname param1 param2 =⊠ Conditionals (if-else): if cond then else

Multiple statements require begin/end

We’ll get to know this sexy match/with character as soon .

⊠ Iteration (loops): clearly while cond do, others soon⊟ Aggregate data (arrays, records, objects, etc):

(ocaml,has,tuples) and others we’ll discuss soon

⊟ Library System: open Printf is like from Printf import *

Trang 11

7# let doubler i= 2*i;;(* bind doubler to a function *)

8 val doubler: int -> int = <fun>(* int argument, int returns *)

16#doubler"hello";;(* call doubler "hello" *)

17 Line 1,characters8-15:(* Type Checker says: *)

181 |doubler"hello";;(* NO SOUP FOR YOU! *)

20 Error: This expression has typestring but an

21expression was expected of typeint

Trang 12

Type Inference During Compilation

While explicit types don’t appear during normal compilation, theyare always present and will appear in error messages

6 let four=doubler2 in

7 let eight=doubler four in

8 let yesyes=doubler"yes" in (* Like in Python, right? *)

9printf"%d %d %d\n"four eight;

Trang 13

Types and Type NotationsBasic Types

Expected basic types forhigh-level langs are present likeint float bool stringA few other special types likeunit and ’a are common thatwill be discussed momentarilyAggregate Types

OCaml has various built-inaggregate types as well

Trang 14

Type Annotations

▶ Types are inferred but

one can annotate code

with types

▶ Be aware that conflictsbetween annotations andinferred types willgenerate compiler errors▶ May look at OCaml’s

Module SystemwhichincludesInterface Files

that state the types of allfunctions/variables,known as the module

# let a= 1;;

val a: int = 1# let x: int = 5;;

val x: int = 5# let y: int ="hi";;

Line 1,characters14-18:1 | let y: int ="hi";;

Error: This expression has typestring but anexpression was expected of typeint

# let add(: int) (b: int) : int =ab;;

val add: int -> int -> int = <fun>

# let selfcat(: string) : string =ss;;

Trang 15

Unit Type for Printing / Side-Effects

▶ The notation () means unit andis the return value of functions thatonly perform side-effects

▶ Roughly equivalent to void in C /Java / etc.

▶ Often appears as return type foroutput functions

▶ Usually don’t about unit returns;don’t bind result and .

▶ Functions with no parameters arepassed () to call them

End statements returning unitwith a semi-colon (;) except at

the top level where ;; is usedinstead

10- : unit =()11

Trang 16

Exercise: Infer Those Types

Determine the type of each of the following entities

▶Tuples are created via (a,b) (parens optional)▶Lists are created via [x;y;z]

▶Function types notated with type1 -> type2 -> type3 ->

Each function is a one-liner with its return value on its sole line

Trang 17

Answers: Infer Those Types

Determine the type of each of the following entities

▶Tuples are created via (a,b) (parens optional)▶Lists are created via [x;y;z]

▶Function types notated with type1 -> type2 -> type3 ->

Each function is a one-liner with its return value on its sole line

14printf"%s - but Samy is my hero\n"str;;

15 val samy_print:string-> unit = <fun>

21printf"cur: %d\n"cur;;

22 val print_cur:unit ->unit = <fun>

Trang 18

Top-Level Statements

▶ Names bound to values are introduced with the let keyword▶ At the top level, separate these with double semi-colon ;;REPL

let pair_to_list(,) =[;b];;

(* Top-level ;; are optionalbut help clarity for newOCaml Coders *)

let inc_it x=x+1

let dec_it y=y-1

Trang 19

Syntax Note for ;; in Modules

When writing ml files, known as Modules, ending top-level

bindings with ;; is optional Lecture examples will include them tomake definition ends clear but your own code may omit them Thisis a matter of taste in source files but are required in the REPLwhich apes top-level declarations.

Trang 20

Exercise: Local Statements

▶ Statements in ocaml can be nested somewhat arbitrarily,particularly let bindings

▶ Commonly used to do actual computations▶ Local let statements are followed by keyword in

let first=(* first top level binding *)

let x= 1 in (* local binding *)

let y= 5 in (* local binding *)

y*2 +x(* * + : integer multiply and add *);;

let second=(* second top-level binding *)

let s="TAR" in (* local binding *)

let t="DIS" in (* local binding *)

What valuegets associated with names first and second?

Trang 21

Answers: Local Statements

let first=(* first top level binding *)

let x= 1 in (* local binding *)

let y= 5 in (* local binding *)

y*2 +x(* * + : integer multiply and add *);;

(* binds first toy*2 + x= 5*2 + 1= 11*)

let second=(* second top-level binding *)

let s="TAR" in (* local binding *)

let t="DIS" in (* local binding *)

Trang 22

(* A less clear way of writing the previous code *)

let first= let x= 1 in let y= 5 in y*2 +x;;

let second= let s="TAR" in let t="DIS" in st;;

▶ Compiler treats all whitespace the same so the code evaluatesidentically to the previous version

▶ Most readers will find this much harder to read▶ Favor clearly written code

▶Certainly at the expense of increased lines of code

▶In most cases clarity trumps execution speed

▶ Clarity is of course a matter of taste

Trang 23

Exercise: Explain the following Compile Error

▶ Below is a source file that fails to compile▶ Compiler error message is shown

▶ Why does the file fail to compile?

> cat -n local_is_local.ml

1(* local_is_local.ml : demo of local binding error *)2

4 let x="hello" in (* local binding *)5 let y=" " in (* local binding *)6 let z="world" in (* local binding *)

Trang 24

Answers: Local Bindings are Local

1(* local_is_local.ml : demo of local binding error *)2

4 let x="hello" in (* local binding *)5 let y=" " in (* local binding *)6 let z="world" in (* local binding *)

12print_endline x;;(* x is not defined *)

Scope: areas in source code where a name is well-defined and

its value is available

▶ a is bound at the top level: value available afterwards; has

module-level scope (module? Patience, grasshopper )

▶ The scope of x ends at Line 8: not available at the top-level▶ Compiler “forgets” x outside of its scope

Trang 25

Exercise: Fix Binding Problem

▶ Fixthe code below

Make changes so that it actually compiles and prints both a

and x

1(* local_is_local.ml : demo of local binding error *)2

4 let x="hello" in (* local binding *)5 let y=" " in (* local binding *)6 let z="world" in (* local binding *)

Trang 26

Answers: Fix Binding Problem

One obvious fix is below

> cat -n local_is_local_fixed.ml

1(* local_is_local_fixed.ml : fixeslocalbinding2error by making it a top-level binding3*

5letx="hello";;(* top-level binding *)6

8lety=" " in (localbinding *)9letz="world" in (localbinding *)

Trang 27

Mutable and Immutable Bindings

Q: How do I change thevalue bound to a name?A: You don’t.

▶ Each let/in bindingcreates a scope where aname is bound to a value▶ Most imperative languages

feature easily mutable

> pythonPython 3.6.5>>> x = 5>>> x += 7>>> x12

// C or Javaint main( ){

int x = 5;x += 5;

(* OCaml *)let x = 5 in???

print_int x;;

Trang 28

Approximate Mutability with Successive let/in

▶ Can approximate mutability by successively rebinding thesame name to a different value

1 let x= 5 in (* local: bind FIRST_x to 5 *)

2 let x=x+5 in (* local: SECOND_x is FIRST_x+5, FIRST_x gone *)3print_int x;;(* prints 10: most recent x, SECOND_x*)

▶arrays: cells are mutable by default

▶records: fields can be labelled mutable and then changed

We’ll examine these soon

Trang 29

Exercise: let/in Bindings

▶ Trace the following program

▶ Show what values are printed and whythey are as such1 let x= 7;;

11print_int x;;12print_endline"";;

Trang 30

Answers: let/in Bindings

▶ A later let/in supersedes an earlier one BUT .

▶ Ending a local scope reverts names to top-level definitions1 let x= 7;;(* top-level x < -+ *)

2 let y=(* top-level y < -+| *)3 let z=x+5 in (* z = 12 = 7+5|| *)4 let x=x+2 in (* x =9 = 7+2|| *)5 let z=z+2 in (* z = 14 = 12+2|| *)

8print_int y;;(* prints 23 -+| *)9print_endline"";;(*| *)

11print_int x;;(* prints 7 -+ *)12print_endline"";;(**)

OCaml is a lexically scoped language: can determine name/value

bindings purely from source code, not based on dynamic context.

Trang 31

Immediate Immutability ConcernsQ: What’s with the whole let/in thing?

Stems for Mathematics such as .

Pythagorean Thm: Let c be they length of the hypotenuse of a right

triangle and let a, b be the lengths of its other sides Then the relation

c2= a2+ b2holds.

Q: If I can’t change bindings, how do I get things done?

A: Turns out you can get lots done but it requires an adjustment of

thinking Often there is recursion involved.

Q: let/in seems bothersome Advantages over mutability?

A: Yes Roughly they are

▶It’s easier to formally / informally verify program correctness

▶Immutability opens up possibilities for parallelism

Q: Can I still write imperative code when it seems appropriate?

A: Definitely Some problems in CMSC330 will state constraints like“must not use mutation” to which you should adhere or risk deductions.

Ngày đăng: 08/06/2024, 14:33