I am new to OCaml. I saw code like
let main_t = Term.(pure main $ address $ port $ pid_file $ log_file $ dbConf)
what does '$' symbol mean?
There's no predefined meaning in OCaml for $. It can be defined as an infix operator; the meaning must come from a library that you're using.
If I had to guess, I'd say that $ has been defined as a low precedence function application operator. It is used for this in Haskell, and it is often quite handy.
In OCaml it is possible to define your own infix and prefix operators. In cmdliner library the operator $ is defined as:
val ( $ ) : ('a -> 'b) t -> 'a t -> 'b t
(** [f $ v] is a term that evaluates to the result of applying
the evaluation of [v] to the one of [f]. *)
And is actually an infix form of the apply function (named app in Cmdliner). It is used to accumulate the arguments. Basically, a construct of the form pure f $a $b $c $d accepts a function f that takes four arguments of type a, b, c and d, given, that a is a value of type a Term.t, b is a value of type b Term.t, etc. In general this is a pattern for building typesafe variadic functions. For more information, about the pattern read the Applicative Programming with Effects paper.
there is no special meaning of $ in standard ocaml. In your case, this is coming from Term module where specific syntax may be defined. (BTW, which module is it ? - I mean how did you install it)
Related
I'm taking a look to this programming language "Ocaml" and I have some troubles because I read the official ocaml documentation but I don't uderstand how to use :
";" and ";;" and "in" specially inside the definition of functions.
This is my code :
let abs_val value : int -> int =
let abs_ret = ref 0 ;
if value >= 0
then abs_ret := value
else abs_ret := -value ;
let return : int = abs_ret
;;
print_int abs_val -12
Compiled with "ocamlc" it said :
File "first_program.ml", line 7, characters 2-4:
7 | ;;
^^
Error: Syntax error
And it sounds so weird for me because official ocaml's doc says that when function definition ends I must use ";;".
I noticed that after the definition of abs_val VisualStudio Code ,when I go on a newline, put automatically the cursor to 2 spaces on the right, not at the beginning of the line.
I'm new in ocaml so I don't know if this is common or not but for me sounds like if something is missing, and probably it is :)
P.S. : I know that an abs function already exists but I'm doing this to learn.
Update :
let abs_val value =
let abs_ret = ref 0 in
if value >= 0
then abs_ret := value
else abs_ret := -value in
let return : int = abs_ret;
;;
print_int abs_val -12
Am I closer right?
Sometimes it happens the syntax error is not here but above. Did you closed your previous function with ;; ? Also, what is this return ? Use the functional paradigm of the language. You use variables and references and force the type checking. I'm not sure how do you want to use this code but in a general way, try to let OCaml determine the type of your functions rather than telling the compiler what is the signature. Plus, your code shouldn't be using that much references. For instance the following :
let abs_val value =
if value < 0 then
-value
else
value
Will work perfectly and not mess up things with reference. If you wish to use references, I suggest you learn more about the functional paradigm of OCaml before going deeper into its imperative possibilities.
Your syntax error is a result of having let with no matching in.
This is a very common error when learning OCaml syntax. There are two separate uses of let in OCaml. At the top level of a module, you use let to define a symbol (a function or a value) that is one of the elements of the module. So in the following:
module M = struct
let f x = x * 2
end
The let defines a function named M.f.
Similarly your code uses let this way to define abs_val.
In other cases (not at the top level of a module), let is used only as part of the let ... in expression that looks like this:
let v = exp1 in exp2
This essentially defines a local variable v with the value exp1 that can be used in the body of exp2.
All your other uses of let (except the initial definition of abs_val) are of this second kind. However, none of them have in, so they are all syntactically incorrect.
You need to fix up these problems before you can make progress with this function. You can fix the first one, for example, by changing the first semicolon (;) to in.
As #SDAChess points out, you have a second problem with the return value of your function. There is no special return keyword in OCaml that's used to return the value of a function. A function in OCaml is just a set of nested function calls, and the value of the function is the value returned by the outermost call.
I use vscode, with extensions of "OCaml and Reason IDE"
Here is my result in utop:
utop # 1. = 1. ;;
Line 1, characters 0-2:
Error: This expression has type float but an expression was expected of type
int
And also for String:
utop # "Me" = "Me";;
Line 1, characters 0-4:
Error: This expression has type string but an expression was expected of type
int
Same for anything but int:
utop # 2 = 2 ;;
- : bool = true
">" "<" also have the same symptom. I don't know what actually happens. Can anyone help me out ? Thanks a lot!
You are probably using JaneStreet Base library. Maybe you imported it like that:
open Base;;
Base tries to limit exceptions to functions that have explicit _exn suffix, so it shadows the built-in polymorphic equality (=) which can raise an exception on some inputs (for example, if you compare structures containing functions).
You can get polymorphic equality back as follows:
let (=) = Poly.(=);;
Or you can use it with a local import: Poly.(x = y).
There are pros and cons to polymorphic comparison.
The consensus seems to be that using monomorphic comparison (for example, String.equal, etc) is a more robust choice, even though it is less convenient.
This is my simple OCaml code to print out a merged list.
let rec merge cmp x y = match x, y with
| [], l -> l
| l, [] -> l
| hx::tx, hy::ty ->
if cmp hx hy
then hx :: merge cmp tx (hy :: ty)
else hy :: merge cmp (hx :: tx) ty
let rec print_list = function
| [] -> ()
| e::l -> print_int e ; print_string " " ; print_list l
;;
print_list (merge ( <= ) [1;2;3] [4;5;6]) ;;
I copied the print_list function from Print a List in OCaml, but I had to add ';;' after the function's implementation in order to avoid this error message.
File "merge.ml", line 11, characters 47-57:
Error: This function has type int list -> unit
It is applied to too many arguments; maybe you forgot a `;'.
My question is why ';;' is needed for print_list while merge is not?
The ;; is, in essence, a way of marking the end of an expression. It's not necessary in source code (though you can use it if you like). It is useful in the toplevel (the OCaml REPL) to cause the evaluation of what you've typed so far. Without such a symbol, the toplevel has no way to know whether you're going to type more of the expression later.
In your case, it marks the end of the expression representing the body of the function print_list. Without this marker, the following symbols look like they're part of the same expression, which leads to a type error.
For top-level expressions in OCaml files, I prefer to write something like the following:
let () = print_list (merge ( <= ) [1;2;3] [4;5;6])
If you code this way you don't need to use the ;; token in your source files.
This is an expansion of Jeffrey's answer.
As you know, when doing language parsing, a program has to break the flow in manageable lexical elements, and expect these so called lexemes (or tokens) to follow certain syntactic rules, allowing to regroup lexemes in larger units of meaning.
In many languages, the largest syntactic element is the statement, which diversifies in instructions and definitions. In these same languages, the structure of the grammar requires a special lexeme to indicate the end of some of these units, usually either instructions or statements. Others use instead a lexeme to separate instructions (rather than end each of them), but it's basically the same idea.
In OCaml, the grammar follows patterns which, within the algorithm used to parse the language, permits to elide such instruction terminator (or separator) in various circumstances. The keyword let for instance, is always necessary to introduce a new definition. This can be used to detect the end of the preceding statement at the outermost level of program statements (the top level).
However, you can easily see the problem it induces: the interactive version of Ocaml always need the beginning of a new statement to be able to figure out the previous one, and a user would never be able to provide statements one by one! The ;; special token was thus defined(*) to indicate the end of a top level statement.
(*): I actually seem to recall that the token was originally in OCaml ancestors, but then made optional when OCaml was devised; however, don't quote me on that.
I just start learning haskell and pattern matching. I just don't understand how it implemented, is the [] and (x:_) evaluates to the different type and the function implementations for this pattern recognized because of polymorphism, or I just wrong and there is another technique used.
head' :: [a] -> a
head' [] = error "Can't call head on an empty list, dummy!"
head' (x:_) = x
Or lets consider this pattern matching function:
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
tell (x:y:_) = "This list is long. The first two elements are: " ++ show x ++ " and " ++ show y
I think I wrong because each list with different number of elements can't have deferent type. Can you explain me how haskell knows which pattern is correct for some function implementation? I understand how it works logically but not deep. Explain it to me please.
There's a bit of a level of indirection between the syntax in Haskell and the implementation at runtime. The list syntax that you see in most source is actually a bit of sugar for what is actually a fairly regular data type. The following two lines are equivalent:
data List a = Nil | Cons a (List a)
data [a] = [] | a : [a] -- pseudocode
So when you type in [a,b,c] this translates into the internal representation as (a : (b : (c : []))).
The pattern matching you'll see at the top level bindings in are also a bit of syntactic sugar ( sans some minor details ) for case statements which deconstruct the data types onto the right hand side of the case of the pattern match. The _ symbol is a builtin for the wildcard pattern which matches any expression ( so long as the pattern is well-typed ) but does add a variable to the RHS scope.
head :: [a] -> a
head x = case x of
(a : _) -> a
I think I wrong because each list with different number of elements can't have deferent type. Can you explain me how haskell knows which pattern is correct for some function implementation?
So to answer your question [] and (x:_) are both of the same type (namely [a] or List a in our example above). The list datatype is also recursive so all recursive combinations of Cons'ing values of type a have the same type, namely [a].
When the compiler typechecks the case statement it runs along each of the LHS columns and ensures that all the types are equivalent or can be made equivalent using a process called unification. The same is done on the right hand side of the cases.
Haskell "knows" which pattern is correct by trying each branch sequentially and unpacking the matched value to see if it has the same number of cons elements as the pattern and then proceeding to the branch which does, or failing with a pattern match error if none match. The same process is done for any pattern matching on data types, not just lists.
There are two separate sets of checks:
in compile time (before the program is run) the compiler simply checks that the types of the cases conform to the function's signature and that the calls to the function conform to the function's signature.
In runtime, when we have access to the actual input, a similar, but different, set of checks is executed: these checks take the * actual* input (not its type) at hand and determine which of the cases matches it.
So, to answer your question: the decision is made in compile time where we have not only the type but also the actual value.
Can someone give a concise description of when the relaxed value restriction kicks in? I've had trouble finding a concise and clear description of the rules. There's Garrigue's paper:
http://caml.inria.fr/pub/papers/garrigue-value_restriction-fiwflp04.pdf
but it's a little dense. Anyone know of a pithier source?
An Addendum
Some good explanations were added below, but I was unable to find an explanation there for the following behavior:
# let _x = 3 in (fun () -> ref None);;
- : unit -> 'a option ref = <fun>
# let _x = ref 3 in (fun () -> ref None);;
- : unit -> '_a option ref = <fun>
Can anyone clarify the above? Why does the stray definition of a ref within the RHS of the enclosing let affect the heuristic.
I am not a type theorist, but here is my interpretation of Garrigue's explanation. You have a value V. Start with the type that would be assigned to V (in OCaml) under the usual value restriction. There will be some number (maybe 0) monomorphic type variables in the type. For each such variable that appears only in covariant position in the type (on the right sides of function arrows), you can replace it with a fully polymorphic type variable.
The argument goes as follows. Since your monomorphic variable is a variable, you can imagine replacing it with any single type. So you choose an uninhabited type U. Now since it is in covariant position only, U can in turn be replaced by any supertype. But every type is a supertype of an uninhabited type, hence it's safe to replace with a fully polymorphic variable.
So, the relaxed value restriction kicks in when you have (what would be) monomorphic variables that appear only in covariant positions.
(I hope I have this right. Certainly #gasche would do better, as octref suggests.)
Jeffrey provided the intuitive explanation of why the relaxation is correct. As to when it is useful, I think we can first reproduce the answer octref helpfully linked to:
You may safely ignore those subtleties until, someday, you hit a problem with an abstract type of yours that is not as polymorphic as you would like, and then you should remember than a covariance annotation in the signature may help.
We discussed this on reddit/ocaml a few months ago:
Consider the following code example:
module type S = sig
type 'a collection
val empty : unit -> 'a collection
end
module C : S = struct
type 'a collection =
| Nil
| Cons of 'a * 'a collection
let empty () = Nil
end
let test = C.empty ()
The type you get for test is '_a C.collection, instead of the 'a C.collection that you would expect. It is not a polymorphic type ('_a is a monomorphic inference variable that is not yet fully determined), and you won't be happy with it in most cases.
This is because C.empty () is not a value, so its type is not generalized (~ made polymorphic). To benefit from the relaxed value restriction, you have to mark the abstract type 'a collection covariant:
module type S = sig
type +'a collection
val empty : unit -> 'a collection
end
Of course this only happens because the module C is sealed with the signature S : module C : S = .... If the module C was not given an explicit signature, the type-system would infer the most general variance (here covariance) and one wouldn't notice that.
Programming against an abstract interface is often useful (when defining a functor, or enforcing a phantom type discipline, or writing modular programs) so this sort of situation definitely happens and it is then useful to know about the relaxed value restriction.
That's an example of when you need to be aware of it to get more polymorphism, because you set up an abstraction boundary (a module signature with an abstract type) and it doesn't work automatically, you have explicitly to say that the abstract type is covariant.
In most cases it happens without your notice, when you manipulate polymorphic data structures. [] # [] only has the polymorphic type 'a list thanks to the relaxation.
A concrete but more advanced example is Oleg's Ber-MetaOCaml, which uses a type ('cl, 'ty) code to represent quoted expressions which are built piecewise. 'ty represents the type of the result of the quoted code, and 'cl is a kind of phantom region variable that guarantees that, when it remains polymorphic, the scoping of variable in quoted code is correct. As this relies on polymorphism in situations where quoted expressions are built by composing other quoted expressions (so are generally not values), it basically would not work at all without the relaxed value restriction (it's a side remark in his excellent yet technical document on type inference).
The question why the two examples given in the addendum are typed differently has puzzled me for a couple of days. Here is what I found by digging into the OCaml compiler's code (disclaimer: I'm neither an expert on OCaml nor on the ML type system).
Recap
# let _x = 3 in (fun () -> ref None);; (* (1) *)
- : unit -> 'a option ref = <fun>
is given a polymorphic type (think ∀ α. unit → α option ref) while
# let _x = ref 3 in (fun () -> ref None);; (* (2) *)
- : unit -> '_a option ref = <fun>
is given a monomorphic type (think unit → α option ref, that is, the type variable α is not universally quantified).
Intuition
For the purposes of type checking, the OCaml compiler sees no difference between example (2) and
# let r = ref None in (fun () -> r);; (* (3) *)
- : unit -> '_a option ref = <fun>
since it doesn't look into the body of the let to see if the bound variable is actually used (as one might expect). But (3) clearly must be given a monomorphic type, otherwise a polymorphically typed reference cell could escape, potentially leading to unsound behaviour like memory corruption.
Expansiveness
To understand why (1) and (2) are typed the way they are, let's have a look at how the OCaml compiler actually checks whether a let expression is a value (i.e. "nonexpansive") or not (see is_nonexpansive):
let rec is_nonexpansive exp =
match exp.exp_desc with
(* ... *)
| Texp_let(rec_flag, pat_exp_list, body) ->
List.for_all (fun vb -> is_nonexpansive vb.vb_expr) pat_exp_list &&
is_nonexpansive body
| (* ... *)
So a let-expression is a value if both its body and all the bound variables are values.
In both examples given in the addendum, the body is fun () -> ref None, which is a function and hence a value. The difference between the two pieces of code is that 3 is a value while ref 3 is not. Therefore OCaml considers the first let a value but not the second.
Typing
Again looking at the code of the OCaml compiler, we can see that whether an expression is considered expansive determines how the type of the let-expressions is generalised (see type_expression):
(* Typing of toplevel expressions *)
let type_expression env sexp =
(* ... *)
let exp = type_exp env sexp in
(* ... *)
if is_nonexpansive exp then generalize exp.exp_type
else generalize_expansive env exp.exp_type;
(* ... *)
Since let _x = 3 in (fun () -> ref None) is nonexpansive, it is typed using generalize which gives it a polymorphic type. let _x = ref 3 in (fun () -> ref None), on the other hand, is typed via generalize_expansive, giving it a monomorphic type.
That's as far as I got. If you want to dig even deeper, reading Oleg Kiselyov's Efficient and Insightful Generalization alongside generalize and generalize_expansive may be a good start.
Many thanks to Leo White from OCaml Labs Cambridge for encouraging me to start digging!
Although I'm not very familiar with this theory, I have asked a question about it.
gasche provided me with a concise explanation. The example is just a part of OCaml's map module. Check it out!
Maybe he will be able to provide you with a better answer. #gasche