From: Ville-Pertti Keinonen <will@exomi.com>
To: Richard Jones <rich@annexia.org>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Why doesn't ocamlopt detect a missing ; after failwith statement?
Date: Fri, 26 Nov 2004 15:32:26 +0200 [thread overview]
Message-ID: <41A7306A.2020103@exomi.com> (raw)
In-Reply-To: <20041126090120.GA19749@annexia.org>
Richard Jones wrote:
>I'd just like to add that this error bit me in a real program, and it
>would be nice if OCaml detected this common case and warned about it:
>
> if cond then (
> ...
> raise Exn
> )
> next_stmt <-- catastrophic failure, because this statement
> is silently ignored
>
>
It may help to realize that as a (mostly) functional language, OCaml
doesn't have statements, only expressions (although expressions of the
type 'unit' could be considered equivalent of statements).
The question to ask isn't "why isn't the missing semicolon detected?"
Instead, you should think about what the entire expression looks like in
the absence of the semicolon - it looks like a function application
(i.e. that you're applying the result of "raise Exn" to whatever follows).
There is no reasonable way to detect such "special cases" (in this case,
functions that don't return) without a way for the type system to
express them (you don't e.g. want to special-case "raise" explicitly by
making it a keyword, as it wouldn't help in the case of "failwith" in
your original example).
Currently, the type of functions that don't return is expressed as a
type variable (e.g. 'a) that is not present in the function arguments,
meaning that it's compatible with any type. This ensures that when you
write e.g. "if x then raise Exn else y", the types of "raise Exn" and
"y" are compatible and can be unified. It's also compatible with a
function taking as an argument any expression that may follow it.
Such functions could, instead, return a special type in order to avoid
cases such as this. I haven't thought about it in detail, nor have I
tried to fully understand the suggestions of others, but intuitively,
I'd think it would have to be unifiable with other types but not capable
of being used as a value (only valid as a return type of a function)
until it was unified with (in effect, changed to) some other type on a
different branch of control flow. As type inference doesn't have a
concept of control flow, this could be pretty messy, but it might be
possible to make it work.
BTW: Hindley-Milner type inference is extremely straightforward, and
understanding it helps better understand OCaml and other similar languages.
The rules for type inference should pretty much be self-evident if you
just think about it, but it may help to know the actual basic algorithm,
described informally as:
We have two namespaces; one binding variables to types (globals to
actual types, lexically bound variables to type variables), which I'll
express using '::', and another linking type variables to types (which
can be other type variables), which I'll express using '=>'.
To infer the type of an expression:
- Variable x: If there exists x :: t, the type is t (otherwise the
variable is not visible at this point, which is an error)
- Literal: The type is immediately known
- Function abstraction (fun x -> e): Create a new type variable 'a.
Infer the type of e (call it E) with x :: 'a. The type of the expression
is 'a -> E
- Function application (f x): Infer the types of f (F) and x (X).
Create a new type variable 'a. Unify (X -> 'a) and F. The type of the
expression is 'a
(Most other things can basically be expressed equivalently to functions)
Unification of t1 and t2:
With t1 and t2 normalized, do one of:
- If t1 and t2 are equal, do nothing
- If t1 is a type variable, link t1 => t2
- If t2 is a type variable, link t2 => t1
- If t1 and t2 are both functions (a1 -> b1, a2 -> b2), unify a1 and
a2, unify b1 and b2
- Otherwise fail with a type mismatch
To normalize t:
- If there exists t => t', repeat with t'
- Otherwise just return t
prev parent reply other threads:[~2004-11-26 13:32 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-11-25 20:46 Richard Jones
2004-11-25 21:14 ` [Caml-list] " Nicolas Cannasse
2004-11-26 0:11 ` skaller
2004-11-26 0:44 ` Jacques Garrigue
2004-11-26 3:08 ` skaller
2004-11-26 5:25 ` Jacques Garrigue
2004-11-26 7:08 ` Nicolas Cannasse
2004-11-26 14:42 ` Jacques Garrigue
2004-11-26 17:01 ` Alain Frisch
2004-11-26 19:36 ` Michal Moskal
2004-11-26 17:01 ` Damien Doligez
2004-11-29 0:40 ` Jacques Garrigue
2004-11-29 11:07 ` [Caml-list] Why doesn't ocamlopt detect a missing ; afterfailwith statement? Frederic van der Plancke
2004-11-29 11:43 ` Jacques Garrigue
2004-11-29 11:27 ` Frederic van der Plancke
2004-11-26 22:24 ` [Caml-list] Why doesn't ocamlopt detect a missing ; after failwith statement? Hendrik Tews
2004-11-27 3:47 ` skaller
2004-11-29 0:01 ` Jacques Garrigue
2004-11-29 7:52 ` Marcin 'Qrczak' Kowalczyk
2004-11-26 3:58 ` skaller
2004-11-26 19:16 ` Brian Hurt
2004-11-26 9:01 ` Richard Jones
2004-11-26 9:56 ` skaller
2004-11-26 13:32 ` Ville-Pertti Keinonen [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41A7306A.2020103@exomi.com \
--to=will@exomi.com \
--cc=caml-list@inria.fr \
--cc=rich@annexia.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox