The reader is referred to the Objective Caml reference manual for a more detailed description of these features.

Similar documents
CS558 Programming Languages

CSCI-GA Scripting Languages

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

RSL Reference Manual

COSE212: Programming Languages. Lecture 3 Functional Programming in OCaml

egrapher Language Reference Manual

Type Checking and Type Inference

CS558 Programming Languages

Lecture: Functional Programming

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

Object oriented programming. Instructor: Masoud Asghari Web page: Ch: 3

CMSC 330: Organization of Programming Languages. OCaml Imperative Programming

L3 Programming September 19, OCaml Cheatsheet

CIS 120 Midterm I February 16, 2015 SOLUTIONS

Recap: Functions as first-class values

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

Part I. Language Core

List Functions, and Higher-Order Functions

Appendix. Grammar. A.1 Introduction. A.2 Keywords. There is no worse danger for a teacher than to teach words instead of things.

Control Flow. COMS W1007 Introduction to Computer Science. Christopher Conway 3 June 2003

Chapter 3 Function Overloading

The Typed Racket Guide

Inductive Data Types

The Substitution Model. Nate Foster Spring 2018

Some Advanced ML Features

IPCoreL. Phillip Duane Douglas, Jr. 11/3/2010

Typed Racket: Racket with Static Types

Mini-ML. CS 502 Lecture 2 8/28/08

The Substitution Model

CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Dan Grossman Spring 2011

Chapter 10 Introduction to Classes

CS4215 Programming Language Implementation. Martin Henz

Basic concepts. Chapter Toplevel loop

CS1622. Semantic Analysis. The Compiler So Far. Lecture 15 Semantic Analysis. How to build symbol tables How to use them to find

Why OCaml? Introduction to Objective Caml. Features of OCaml. Applications written in OCaml. Stefan Wehr

Introduction to Objective Caml

CS558 Programming Languages

F28PL1 Programming Languages. Lecture 12: Standard ML 2

Objectives. Chapter 2: Basic Elements of C++ Introduction. Objectives (cont d.) A C++ Program (cont d.) A C++ Program

GBIL: Generic Binary Instrumentation Language. Language Reference Manual. By: Andrew Calvano. COMS W4115 Fall 2015 CVN

OCaml Data CMSC 330: Organization of Programming Languages. User Defined Types. Variation: Shapes in Java

Chapter 2: Basic Elements of C++

Chapter 2: Basic Elements of C++ Objectives. Objectives (cont d.) A C++ Program. Introduction

CS201 Latest Solved MCQs

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

02157 Functional Programming. Michael R. Ha. Lecture 3: Programming as a model-based activity. Michael R. Hansen

Sprite an animation manipulation language Language Reference Manual

OCaml Style Guide Fall 2017

CSCI 2041: Functions, Mutation, and Arrays

SPARK-PL: Introduction

Typed Scheme: Scheme with Static Types

Introduction to OCaml

Formal Semantics. Prof. Clarkson Fall Today s music: Down to Earth by Peter Gabriel from the WALL-E soundtrack

02157 Functional Programming Tagged values and Higher-order list functions

An introduction introduction to functional functional programming programming using usin Haskell

Metaprogramming assignment 3

CMSC330 Fall 2016 Midterm #1 2:00pm/3:30pm

Chapter 2 Basic Elements of C++

Short Notes of CS201

CHAPTER 4 FUNCTIONS. 4.1 Introduction

1. true / false By a compiler we mean a program that translates to code that will run natively on some machine.

Tokens, Expressions and Control Structures

CS201 - Introduction to Programming Glossary By

Instantiation of Template class

Quiz Start Time: 09:34 PM Time Left 82 sec(s)

PIC 10A Objects/Classes

Review. CS152: Programming Languages. Lecture 11 STLC Extensions and Related Topics. Let bindings (CBV) Adding Stuff. Booleans and Conditionals

The Typed Racket Reference

CE221 Programming in C++ Part 1 Introduction

Java Bytecode (binary file)

Lecture 18 Tao Wang 1

Lecture 19: Functions, Types and Data Structures in Haskell

Java: introduction to object-oriented features

Haskell Types, Classes, and Functions, Currying, and Polymorphism

CSI33 Data Structures

Introduction to OCaml

02157 Functional Programming. Michael R. Ha. Tagged values and Higher-order list functions. Michael R. Hansen

Haskell 98 in short! CPSC 449 Principles of Programming Languages

Contents. Figures. Tables. Examples. Foreword. Preface. 1 Basics of Java Programming 1. xix. xxi. xxiii. xxvii. xxix

Programming Languages Lecture 15: Recursive Types & Subtyping

CIS 120 Midterm II November 8, 2013 SOLUTIONS

COMPUTER APPLICATION

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

GOBLAN Language Reference Manual

G Programming Languages - Fall 2012

OCaml. ML Flow. Complex types: Lists. Complex types: Lists. The PL for the discerning hacker. All elements must have same type.

A First Look at ML. Chapter Five Modern Programming Languages, 2nd ed. 1

CSE341: Programming Languages Lecture 7 First-Class Functions. Dan Grossman Winter 2013

Static Vulnerability Analysis

Harvard School of Engineering and Applied Sciences Computer Science 152

CSE 3302 Programming Languages Lecture 8: Functional Programming

11. Arrays. For example, an array containing 5 integer values of type int called foo could be represented as:

Mutable Data Types. Prof. Clarkson Fall A New Despair Mutability Strikes Back Return of Imperative Programming

A Brief Haskell and GHC Refresher

Programming refresher and intro to C programming

CIS24 Project #3. Student Name: Chun Chung Cheung Course Section: SA Date: 4/28/2003 Professor: Kopec. Subject: Functional Programming Language (ML)

Introduction to Programming Using Java (98-388)

A Functional Evaluation Model

D7020E. Robust and Energy-Efficient Real-Time Systems D7020E. Lecture 2: Components & the Timber language

Transcription:

B Objective Caml 3.04 Independently of the development of Objective Caml, several extensions of the language appeared. One of these, named Olabl, was integrated with Objective Caml, starting with version 3.00. This appendix describes briefly the new features offered in the current version of Objective Caml at the time of this writing, that is. Objective Caml 3.04. This version can be found on the CD-ROM accompanying this book. The new features include: labels; optional arguments; polymorphic constructors; the ocamlbrowser IDE; the LablTk library. The reader is referred to the Objective Caml reference manual for a more detailed description of these features. Language Extensions Objective Caml 3.04 brings three language extensions to Objective Caml: labels, optional arguments, and polymorphic constructors. These extensions preserve backward compatibility with the original language: a program written for version 2.04 keeps the same semantics in version 3.04.

704 Objective Caml 3.04 Labels A label is an annotation for the arguments of a function in its declaration and its application. It is presented as a separate identifier of the function parameter (formal or actual), enclosed between an initial symbol ~ and a final symbol :. Labels can appear in the declarations of functions: Syntax : let f ~label:p = exp in the anonymous declarations with the keyword fun : Syntax : fun ~label:p -> exp and in the actual parameter of a function: Syntax : ( f ~label:exp ) Labels in types The labels given to arguments of a functional expression appear in its type and annotate the types of the arguments to which they refer. (The ~ symbol in front of the label is omitted in types.) # let add ~op1:x ~op2:y = x + y ; ; val add : op1:int -> op2:int -> int = <fun> # let mk triplet ~arg1:x ~arg2:y ~arg3:z = (x,y,z) ; ; val mk_triplet : arg1: a -> arg2: b -> arg3: c -> a * b * c = <fun> If one wishes to give the same identifier to the label and the variable, as in ~x:x, it is unnecessary to repeat the identifier; the shorter syntax ~x can be used instead. Syntax : fun ~p > exp # let mk triplet ~arg1 ~arg2 ~arg3 = (arg1,arg2,arg3) ; ; val mk_triplet : arg1: a -> arg2: b -> arg3: c -> a * b * c = <fun> It is not possible to define labels in a declaration of a function by pattern matching; consequently the keyword function cannot be used for a function with a label. # let f = function ~arg:x x ; ; Toplevel input: # let f = function ~arg:x -> x ;; ^^^^^ Syntax error # let f = fun ~arg:x x ; ; val f : arg: a -> a = <fun>

Objective Caml 3.04 705 Labels in function applications When a function is defined with labeled parameters, applications of this function require that matching labels are provided on the function arguments. # mk triplet ~arg1: 1 ~arg2:2 ~arg3:3.0 ; ; - : char * int * float = 1, 2, 3 # mk triplet 1 2 3.0 ; ; - : char * int * float = 1, 2, 3 A consequence of this requirement is that the order of arguments having a label does not matter, since one can identify them by their label. Thus, labeled arguments to a function can be commuted, that is, passed in an order different from the function definition. # mk triplet ~arg2:2 ~arg1: 1 ~arg3:3.0 ; ; - : char * int * float = 1, 2, 3 This feature is particularly useful for making a partial application on an argument that is not the first in the declaration. # let triplet 0 0 = mk triplet ~arg2:0 ~arg3:0 ; ; val triplet_0_0 : arg1: a -> a * int * int = <fun> # triplet 0 0 ~arg1:2 ; ; - : int * int * int = 2, 0, 0 Arguments that have no label, or that have the same label as another argument, do not commute. In such a case, the application uses the first argument that has the given label. # let test ~arg1:_ ~arg2: ~arg2: = () ; ; val test : arg1: a -> arg2: b -> c -> arg2: d -> e -> unit = <fun> # test ~arg2: () ; ; (* the first arg2: in the declaration *) - : arg1: a -> b -> arg2: c -> d -> unit = <fun> # test () ; ; (* the first unlabeled argument in the declaration *) - : arg1: a -> arg2: b -> arg2: c -> d -> unit = <fun> Legibility of code Besides allowing re-ordering of function arguments, labels are also very useful to make the function interface more explicit. Consider for instance the String.sub standard library function. # String.sub ; ; - : string -> int -> int -> string = <fun> In the type of this function, nothing indicates that the first integer argument is a character position, while the second is the length of the string to be extracted. Objective Caml 3.04 provides a labelized version of this function, where the purpose of the different function arguments have been made explicit using labels.

706 Objective Caml 3.04 # StringLabels.sub ; ; - : string -> pos:int -> len:int -> string = <fun> Clearly, the function StringLabels.sub takes as arguments a string, the position of the first character, and the length of the string to be extracted. Objective Caml 3.04 provides labelized versions of many standard library functions in the modules ArrayLabels, ListLabels, StringLabels, UnixLabels, and MoreLabels. Table B.1 gives the labeling conventions that were used. label pos: len: buf: src: dst: init: cmp: mode: significance a position in a string or array a length a string used as buffer the source of an operation the destination of an operation the initial value for an iterator a comparison function an operation mode or a flag list Figure B.1: Conventions for labels Optional arguments Objective Caml 3.04 allows the definition of functions with labeled optional arguments. Such arguments are defined with a default value (the value given to the parameter if the application does not give any other explicitly). Syntax : fun?name: ( p = exp 1 ) > exp 2 As in the case of regular labels, the argument label can be omitted if it is identical to the argument identifier: Syntax : fun?( name = exp 1 ) > exp 2 Optional arguments appear in the function type prefixed with the? symbol. # let sp incr?inc:(x=1) y = y :=!y + x ; ; val sp_incr :?inc:int -> int ref -> unit = <fun> The function sp incr behaves like the function incr from the Pervasives module. # let v = ref 4 in sp incr v ; v ; ; - : int ref = {contents = 5} However, one can specify a different increment from the default. # let v = ref 4 in sp incr ~inc:3 v ; v ; ; - : int ref = {contents = 7}

Objective Caml 3.04 707 A function is applied by giving the default value to all the optional parameters until the actual parameter is passed by the application. If the argument of the call is given without a label, it is considered as being the first non-optional argument of the function. # let f?(x1=0)?(x2=0) x3 x4 = 1000*x1+100*x2+10*x3+x4 ; ; val f :?x1:int ->?x2:int -> int -> int -> int = <fun> # f 3 ; ; - : int -> int = <fun> # f 3 4 ; ; - : int = 34 # f ~x1:1 3 4 ; ; - : int = 1034 # f ~x2:2 3 4 ; ; - : int = 234 An optional argument can be given without a default value, in this case it is considered in the body of the function as being of the type a option; None is its default value. Syntax : fun?name:p > exp # let print integer?file:opt f n = match opt f with None print int n Some f let fic = open out f in output string fic (string of int n) ; output string fic "\n" ; close out fic ; ; val print_integer :?file:string -> int -> unit = <fun> By default, the function print integer displays its argument on standard output. If it receives a file name with the label file, it outputs its integer argument to that file instead. Note If the last parameter of a function is optional, it will have to be applied explicitly. # let test?x?y n?a?b = n ; ; val test :?x: a ->?y: b -> c ->?a: d ->?b: e -> c = <fun> # test 1 ; ; - :?a: _a ->?b: _b -> int = <fun> # test 1 ~b: x ; ; - :?a: _a -> int = <fun> # test 1 ~a: () ~b: x ; ; - : int = 1

708 Objective Caml 3.04 Labels and objects Labels can be used for the parameters of a method or an object s constructor. # class point?(x=0)?(y=0) (col : Graphics.color) = object val pos = (x,y) val color = col method print?dest:(file=stdout) () = output string file "point (" ; output string file (string of int (fst pos)) ; output string file "," ; output string file (string of int (snd pos)) ; output string file ")\n" end ; ; class point :?x:int ->?y:int -> Graphics.color -> object method print :?dest:out_channel -> unit -> unit val color : Graphics.color val pos : int * int end # let obj1 = new point ~x:1 ~y:2 Graphics.white in obj1#print () ; ; point (1,2) - : unit = () # let obj2 = new point Graphics.black in obj2#print () ; ; point (0,0) - : unit = () Labels and optional arguments provide an alternative to method and constructor overloading often found in object-oriented languages, but missing from Objective Caml. This emulation of overloading has some limitations. In particular, it is necessary that at least one of the arguments is not optional. A dummy argument of type unit can always be used. # class number?integer?real () = object val mutable value = 0.0 method print = print float value initializer match (integer,real) with (None,None) (Some _,Some _) failwith "incorrect number" (None,Some f) value <- f

Objective Caml 3.04 709 (Some n,none) value <- float of int n end ; ; class number :?integer:int ->?real:float -> unit -> object method print : unit val mutable value : float end # let n1 = new number ~integer:1 () ; ; val n1 : number = <obj> # let n2 = new number ~real:1.0 () ; ; val n2 : number = <obj> Polymorphic variants The variant types of Objective Caml have two principal limitations. First, it is not possible to extend a variant type with a new constructor. Also, a constructor can belong to only one type. Objective Caml 3.04 features an alternate kind of variant types, called polymorphic variants that do not have these two constraints. Constructors for polymorphic variants are prefixed with a (backquote) character, to distinguish them from regular constructors. Apart from this, the syntactic constraints on polymorphic constructors are the same as for other constructors. In particular, the identifier used to build the constructor must begin with a capital letter. Syntax : Name ou Syntax : Name type A group of polymorphic variant constructors forms a type, but this type does not need to be declared before using the constructors. # let x = Integer 3 ; ; val x : [> Integer of int] = Integer 3 The type of x with the symbol [> indicates that the type contains at least the constructor Integer int. # let int of = function Integer n n Real r int of float r ; ; val int_of : [< Integer of int Real of float] -> int = <fun> Conversely, the symbol [< indicates that the argument of int of belongs to the type that contains at most the constructors Integer int and Real float.

710 Objective Caml 3.04 It is also possible to define a polymorphic variant type by enumerating its constructors: Syntax : type t = [ Name 1 Name 2... Name n ] or for parameterized types: Syntax : type ( a, b,...) t = [ Name 1 Name 2... Name n ] # type value = [ Integer of int Real of float ] ; ; type value = [ Integer of int Real of float] Constructors of polymorphic variants can take arguments of different types. # let v1 = Number 2 and v2 = Number 2.0 ; ; val v1 : [> Number of int] = Number 2 val v2 : [> Number of float] = Number 2 However, v1 and v2 have different types. # v1=v2 ; ; Toplevel input: # v1=v2 ;; ^^ This expression has type [> Number of float] but is here used with type [> Number of int] More generally, the constraints on the type of arguments for polymorphic variant constructors are accumulated in their type by the annotation &. # let test nul integer = function Number n n=0 and test nul real = function Number r r=0.0 ; ; val test_nul_integer : [< Number of int] -> bool = <fun> val test_nul_real : [< Number of float] -> bool = <fun> # let test nul x = (test nul integer x) (test nul real x) ; ; val test_nul : [< Number of float & int] -> bool = <fun> The type of test nul indicates that the only values accepted by this function are those with the constructor Number and an argument which is at the same time of type int and of float. That is, the only acceptable values are of type a! # let f () = test nul (failwith "returns a value of type a") ; ; val f : unit -> bool = <fun> The types of the polymorphic variant constructor are themselves likely to be polymorphic. # let id = function Ctor Ctor ; ; val id : [< Ctor] -> [> Ctor] = <fun> The type of the value returned from id is the group of constructors that contains at least Ctor therefore it is a polymorphic type which can instantiate to a more precise type. In the same way, the argument of id is the group of constructors that contains

Objective Caml 3.04 711 no more than Ctor which is also likely to be specified. Consequently, they follow the general polymorphic type mechanism of Objective Caml knowing that they are likely to be weakened. # let v = id Ctor ; ; val v : _[> Ctor] = Ctor v, the result of the application is not polymorphic (as denoted by the character in the name of the type variable). # id v ; ; - : _[> Ctor] = Ctor v is monomorphic and its type is a sub-type of contains at least the constructor Ctor. Applying it with id will force its type to be a sub-type of contains no more than the constructor Ctor. Logically, it must now have the type contains exactly Ctor. Let us check. # v ; ; - : [ Ctor] = Ctor As with object types, the types of polymorphic variant constructors can be open. # let is integer = function Integer (n : int) true _ false ; ; val is_integer : [> Integer of int] -> bool = <fun> # is integer ( Integer 3) ; ; - : bool = true # is integer Other ; ; - : bool = false All the constructors are accepted, but the constructor Integer must have an integer argument. # is integer ( Integer 3.0) ; ; Toplevel input: # is_integer ( Integer 3.0) ;; ^^^^^^^^^^^^ This expression has type [> Integer of float] but is here used with type [> Integer of int] As with object types, the type of a constructor can be cyclic. # let rec long = function Rec x 1 + (long x) ; ; val long : ([< Rec of a] as a) -> int = <fun> Finally, let us note that the type can be at the same time a sub-group and one of a group of constructors. Starting with a a simple example: # let ex1 = function C1 C2 ; ; val ex1 : [< C1] -> [> C2] = <fun> Now we identify the input and output types of the example by a second pattern. # let ex2 = function C1 C2 x x ; ; val ex2 : ([> C2 C1] as a) -> a = <fun> We thus obtain the open type which contains at least C2 since the return type contains at least C2. # ex2 ( C1 : [> C1 ] ) ; ; (* is a subtype of [< C2 C1.. > C2] *)

712 Objective Caml 3.04 - : _[> C2 C1] = C2 # ex2 ( C1 : [ C1 ] ) ; ; (* is not a subtype of [< C2 C1.. > C2] *) Toplevel input: # ex2 ( C1 : [ C1 ] ) ;; (* is not a subtype of [< C2 C1.. > C2] *) ^^^ This expression has type [ C1] but is here used with type [> C2 C1] LablTk Library The interface to Tcl/Tk was integrated in the distribution of Objective Caml 3.04, and is available for Unix and Windows. The installation provides one new command: labltk, which launches a toplevel interactive loop integrating the LablTk library. The LablTk library defines a large number of modules, and heavily uses the language extensions of Objective Caml 3.04. A detailed presentation of this module falls outside the scope of this appendix, and we invite the interested reader to refer to the documentation of Objective Caml 3.04. There is also an interface with Gtk, written in class-based style, but it is not yet part of the Objective Caml distribution. It should be compatible with Unix and Windows. OCamlBrowser OcamlBrowser is a code browser for Objective Caml, providing a LablTk-based graphical user interface. It integrates a navigator allowing to browse various modules, to look at their contents (names of values and types), and to edit them. When launching OCamlBrowser by the command ocamlbrowser, the list of all the compiled modules available (see figure B.2) is displayed. One can add more modules by specifying a path to find them. From the menu File, one can launch a toplevel interactive loop or an editor in a new window. When one of the modules is clicked on, a new window opens to display its contents (see figure B.3). By selecting a value, its type appears in bottom of the window. In the main window, one can search on the name of a function. The result appears in a new window. The figure B.4 shows the result of a search on the word create. There are other possibilities that we let the user discover.

Objective Caml 3.04 713 Figure B.2: OCamlBrowser : the main window Figure B.3: OCamlBrowser : module contents Figure B.4: OCamlBrowser : search for create

714 Objective Caml 3.04