OCaml program structure

Source: Internet
Author: User
Tags ocaml
Document directory
  • Let-bind
  • Reference: real variables
  • Nested Functions

From: http://www.nirvanastudio.org/ocaml/the-structure-of-ocaml-programs.html

Original article address:Http://www.ocaml-tutorial.org/the_structure_of_ocaml_programsTranslation: ShiningRay

Now we will spend some time looking at the actual OCaml program at a higher level. I want to teach you how to use local and global definitions.;;When is it;And modules, nested functions, and references. In this way, we need to look at these OCaml concepts that we have never seen before, but now we don't have to worry about details. First, pay attention to the overall structure of the program and some features I have pointed out.

Local "variable "( ActuallyLocal expressions)

Let's take it firstaverageTake a look at the function and add a local variable in the C language (you can compare it with our first definition ).

double
average (double a, double b)
{
  double sum = a + b;
  return sum / 2;
}

Now we are doing the same thing in OCaml:

let average a b =
  let sum = a +. b in
   sum /. 2.0;;
# Let average a B = (a +. B)/. 2.0; pay attention to priority.
Val pjz: float-> float = <fun>
# Pjz 10.5 21.5 ;;
-: Float = 16.
#

Standard phraselet name = expression inCan be used to define a local expression, and thennameIt can be used in subsequent functions to replaceexpressionUntil the end of the code block;;. Note thatinWe didn't indent it later. Just putlet...inAs a statement.

Now, compare the local variables of C with those named local expressions, as if they were similar. They are actually two different things. C variablesumThere is a slot assigned to it on the stack. If necessary, you can givesumAssign value or even obtainsum. However, this is not true for the OCaml version. In the OCaml version,sumOnly expressionsa +. b. Not possiblesumAssign a value or change its value. (I will show you how to create real variables later ).

The following is another example to make things clearer. The following two code snippets return the same value (that is, (a + B) + (a + B) 2 ):

let f a b =
  (a +. b) +. (a +. b) ** 2.
   ;;
let f a b =
  let x = a +. b in
   x +. x ** 2.
   ;;

The second version may be faster (but now most compilers should be able to "remove duplicate subexpressions" for you) and easier to read. In the second examplexOnlya +. b.

Global "variable "( ActuallyGlobal expression)

You can also define global names for some things at the top level. Like the local "variables" we mentioned above, these are not real variables, but just aliases of some things. The following is an example of a practical application (for deletion ):

Let html =
Let content = read_whole_file file in
GHtml.html _ from_string content
;;

Let menu_bold () =
Match bold_button # active
True-> html # set_font_style ~ Enable: ['bold] ()
| False-> html # set_font_style ~ Disable: ['bold] ()
;;

Let main () =
(* Code omitted *)
Factory # add_item "Cut "~ Key: _ X ~ Callback: html # cut
;;

In this actual code,htmlIs an HTML editorial component (an object from the lablgtk Library), which is composed of the first line of statementslet html=It is created at the beginning of the program. Then it is referenced multiple times in subsequent functions.

Note thathtmlThe name cannot be regarded as an actual global variable in C or other imperative languages. There is nohtmlPointer "allocates any space for" Storage ". OrhtmlAssign any value, for example, re-assign it to another different part. In the following section, we will discuss references, which are the real variables.

Let-bind

Anylet ...Is calledLet-bind.

Reference: real variables

What if you need to assign values to a real variable that can be used and changed in the program? In this case, we need to useReference(Reference ). References are very similar to pointers in C/C ++. In Java, all the variables for saving objects are actually object references (pointers ). In Perl, references are references-the same thing as in OCaml.

The following describes how to createintWorth referencing:

ref 0;;

In fact, this statement has no major purpose. We only created a reference, but because we didn't name it, the garbage collector will immediately recycle it! (In fact, it may also be thrown away during compilation ). Let's name this reference:

let my_ref = ref 0;;
# let myvar= ref "hello";;
val myvar : string ref = {contents = "hello"}
#

This reference currently stores an integer zero. Next we will put some other things in (assign values ):

my_ref := 100;;

At the same time, let's see what this reference contains:

# !my_ref;;
- : int = 100
Show variable value
# !myvar
   ;;
- : string = "hello"
#

So,:=The operator is used to assign values to the reference.!The operator can unreference and obtain the actual content. The following is a rough comparison with C/C ++:

OCaml                   C/C++

let my_ref = ref 0;;    int a = 0; int *my_ptr = &a;
my_ref := 100;;         *my_ptr = 100;
!my_ref                 *my_ptr

References have their purposes, but you may find that references are not often used. More often, you will uselet name = expression inTo name a local expression.

Nested Functions

C does not actually have the concept of nested functions. GCC supports nested functions of C Programs, but I still don't know what programs will actually use this extension. Anyway, let's first look at how the gcc info page explains nested functions:

A "nested function" refers to a function defined in another function. (Gnu c ++ does not support nested functions .) The name of a nested function is limited to the code block defined by it. For example, we define a nested function called square and call it twice:

foo (double a, double b)
{
  double square (double z) { return z * z; }

  return square (a) + square (b);
}

Nested functions can access any variables that can be seen when the functions that contain them are defined. This is called lexical scoping ). For example, the following shows how to use a nested function with inherited variables called 'offset:

bar (int *array, int offset, int size)
{
  int access (int *array, int index)
    { return array[index + offset]; }
  int i;
  /* ... */
  for (i = 0; i < size; i++)
    /* ... */ access (array, i) /* ... */
}

You should understand. However, nested functions are very useful and commonly used in OCaml. The following is an example of nested functions captured from some practical application code:

let read_whole_channel chan =
  let buf = Buffer.create 4096 in
  let rec loop () =
    let newline = input_line chan in
    Buffer.add_string buf newline;
    Buffer.add_char buf '\n';
     loop ()
  in
  try
     loop ()
  with
     End_of_file -> Buffer.contents buf;;

You don't need to worry about what this code has done-it also contains many concepts that have not been discussed in this tutorial. The first thing that follows is"loop"Nested function, which has only one unit parameter. You can callread_whole_channelCallingloop ()But it is not defined outside the function. Nested functions can access the variables defined in the main function (hereloopAccessible local namebuf).

The form of nested functions is the same as that of local naming expressions:Let nameParameters=Function DefinitionIn.

In general, you need to indent the function definition on the new line, as shown in the above example, and remember that if the function is recursive, you need to uselet recRatherlet(As shown in the preceding example ).

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.