Balthasar
Balthasar

Reputation: 323

Does an equivalent function in OCaml exist that works the same way as "set!" in Scheme?

I'm trying to make a function that defines a vector that varies based on the function's input, and set! works great for this in Scheme. Is there a functional equivalent for this in OCaml?

Upvotes: 0

Views: 366

Answers (2)

newacct
newacct

Reputation: 122439

set! in Scheme assigns to a variable. You cannot assign to a variable in OCaml, at all. (So "variables" are not really "variable".) So there is no equivalent.

But OCaml is not a pure functional language. It has mutable data structures. The following things can be assigned to:

  • Array elements
  • String elements
  • Mutable fields of records
  • Mutable fields of objects

In these situations, the <- syntax is used for assignment.

The ref type mentioned by @jrouquie is a simple, built-in mutable record type that acts as a mutable container of one thing. OCaml also provides ! and := operators for working with refs.

Upvotes: 0

jrouquie
jrouquie

Reputation: 4405

I agree with sepp2k that you should expand your question, and give more detailed examples.

Maybe what you need are references.

As a rough approximation, you can see them as variables to which you can assign:

let a = ref 5;;
!a;; (* This evaluates to 5 *)
a := 42;;
!a;; (* This evaluates to 42 *)

Here is a more detailed explanation from http://caml.inria.fr/pub/docs/u3-ocaml/ocaml-core.html:

The language we have described so far is purely functional. That is, several evaluations of the same expression will always produce the same answer. This prevents, for instance, the implementation of a counter whose interface is a single function next : unit -> int that increments the counter and returns its new value. Repeated invocation of this function should return a sequence of consecutive integers — a different answer each time.

Indeed, the counter needs to memorize its state in some particular location, with read/write accesses, but before all, some information must be shared between two calls to next. The solution is to use mutable storage and interact with the store by so-called side effects.

In OCaml, the counter could be defined as follows:

let new_count =
  let r = ref 0 in
  let next () = r := !r+1; !r in
  next;;

Another, maybe more concrete, example of mutable storage is a bank account. In OCaml, record fields can be declared mutable, so that new values can be assigned to them later. Hence, a bank account could be a two-field record, its number, and its balance, where the balance is mutable.

type account = { number : int; mutable balance : float }
let retrieve account requested =
  let s = min account.balance requested in
  account.balance <- account.balance -. s; s;;

In fact, in OCaml, references are not primitive: they are special cases of mutable records. For instance, one could define:

type 'a ref = { mutable content : 'a }
let ref x = { content = x }
let deref r = r.content
let assign r x = r.content <- x; x

Upvotes: 4

Related Questions