power_output
power_output

Reputation: 421

Ocaml - global vs local variable

I wanted to create a global variable called result that uses 5 string concatenations to create a string containing 9 times the string start, separated by commas. I have two pieces of code, only the second one declares a global variable. For some reason it's not registering easily in my brain... Is it just that i used a let in so result in the first piece of code is a local variable? Is there a more detailed explanation for this?

let start = "ab";;

let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result;;
- : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"

let result = 
  let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result;;
val result : string = "ab,ab,ab,ab,ab,ab,ab,ab,ab"

Upvotes: 3

Views: 3794

Answers (3)

ivg
ivg

Reputation: 35210

Let me to be a little bit boring person. There are no local and global variables in OCaml. This concept came from languages with different scoping rules. Also, the word "variable" itself should be taken with care. Its meaning was perverted by C-like languages. The original, mathematical, meaning of this word corresponds to a name of some mathematical object, that is used inside a formula, that represent a range of such values. In C-like languages, a variable is confused with the memory cell, that can change in time. So, to avoid the confusion let's use a more accurate terminology. Let's use word name instead of variable. Since, variables... sorry names are not memory cells, there is nothing to create. When you're using one of the let syntaxes, you're actually creating a binding, i.e., an association between a name and a value. The let <name> = <expr-1> in <expr-2> binds a value of the in the scope of the <expr-2> expression. The let <name> = <expr-1> in <expr-2> is by itself is also an expression, so, for example <expr-2> can also contain let ... in ... constructs inside, e.g.,

 let a = 1 in
   let b = a + 1 in
     let c = b + 1 in 
       a + b + c

I especially, indented the code in non-idiomatic way to highlight the syntactic structure of the expression. OCaml also allows to use a name, that is already bound in the scope. The new binding will hide the existing one (that is not allowed in C, for example), e.g.,

  let a = a + 1 in
    let a = a + 1 in
      let a = a + 1 in
          a + a + a

Finally, the top-level (aka module level) let-binding (called definition in OCaml parlance), has the syntax: let <name> = <expr>, note that there is no in here. The definition binds the <name> to a result of the evaluation of <expr> in the lexical scope that extends form the point of definition to the end of the enclosing module. When you're implementing a module, you must use let <name> = <expr> to bind your code to names (you may omit name by using _). It is a little bit different from the interactive toplevel (interactive ocaml program), that actually accepts an expression, and evaluates it. For example,

let result = start ^ "," in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ result in
  let result = result ^ start in 
  result

Is not a valid OCaml program (something that can be put into an ml file and compiled). Because it is an expression, not a module definition.

Upvotes: 6

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66808

When you have let ... in, you're declaring a local variable. When you have just let by itself (at the top level of a module), you're declaring a global name of the module. (That is, a name that can be exported from the module.)

Your first example consists entirely of let ... in. So there is no top-level name declared.

Your second example has one let by itself, followed by several occurrences of let ... in. So it declares a top-level name result.

Upvotes: 0

sepp2k
sepp2k

Reputation: 370082

Is it just that i used a let in so result in the first piece of code is a local variable?

Pretty much. The syntax to define a global variable is let variable = expression without an in. The syntax to define a local variable is let variable = expression in expression which will define variable local to the expression after the in.

Upvotes: 1

Related Questions