Sunday, April 03, 2005

 

OCAML oddity

I kept getting this message from OCAML saying:
This expression has type map_path but is here used with type 'a
The type constructor map_path would escape its scope.


The error was occurring when I was trying to add a record to a Hashtbl. Here is a shorter piece of code that will generate the same error:

let ht=Hashtbl.create 100;;
type footype={foo1:int;foo2:int};;
Hashtbl.add ht "foo" {foo1=5;foo2=10};;

You'll get an error that the constructor footype would escape its scope. The thing that seems odd to me is that this error occurs because the hash table was created before the type was known, even though the hash table hasn't really been bound to a specific type yet. If you just reverse the order of the first two statements, everything works:

type footype={foo1:int;foo2:int};;
let ht=Hashtbl.create 100;;
Hashtbl.add ht "foo" {foo1=5;foo2=10};;

Although the error message is a bit confusing, the error itself makes sense when you think about it. The reason it is an error is that if you had to explicitly declare the type of the hash table when you created it, you wouldn't be able to because footype hasn't been declared yet. Once you realize that, even the error message makes sense. The type is declared after the hash table, so it was not "in scope" when the table was created. This makes more sense if you think of the statements as really being nested inside successive lets, although this isn't valid OCAML syntax:

let ht=Hashtbl.create 100 in
let type footype={foo1:int;foo2:int} in
Hashtbl.add ht "foo" {foo1=5; foo2=10};
ht;;

Written like this, you see that the scope of footype would really be within the scope of "let ht=".. and you shouldn't be able to see footype outside of the let. Since the let returns the table, though, you would be violating the scoping rules. Again, that's not exactly how OCAML does it, but it makes sense when you think of it this way.

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?