caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] passing object to a function fails to compile (lablgtk2 involved)
@ 2012-07-16  6:49 Ivan
  2012-07-16 15:29 ` Anthony Tavener
  0 siblings, 1 reply; 4+ messages in thread
From: Ivan @ 2012-07-16  6:49 UTC (permalink / raw)
  To: caml-list

Excuse me for the topic formulation, but I cannot state it better.

I have two simple functions:

let fill_model model name_col value_col =
  let pars = P.from_file "parallax.cfg" in
  let add_record (name, value) =
    let iter = model#append () in
    model#set ~row:iter ~column:name_col  name;
    model#set ~row:iter ~column:value_col   value
  in List.iter add_record pars

(where P.from_file some function generating an assoc list -> (string * string) list )

and 

let create_model () =
  let cols   = new GTree.column_list in
  let name_col  = cols#add Gobject.Data.string
  and value_col = cols#add Gobject.Data.string in
  let model  = GTree.list_store cols in
  (model, name_col, value_col)

When I try to pass values returned by function `create_model' to function `fill_model' with the following expression:

  let model, name_col, value_col = create_model () in
  fill_model model name_col value_col

compiler refuses with:

Error: This expression has type GTree.list_store
       but an expression was expected of type
         < append : unit -> Gtk.tree_iter;
           set : row:Gtk.tree_iter -> column:'a -> Types.id -> unit; .. >
       The universal variable 'b would escape its scope

If I write the two functions in one, like this:
let fill_and_create_model () =
  let cols   = new GTree.column_list in
  let name_col  = cols#add Gobject.Data.string
  and value_col = cols#add Gobject.Data.string in
  let model  = GTree.list_store cols in
  let pars = P.resolve_links (P.from_file "parallax.cfg") in
  let add_record (name, value) =
    let iter = model#append () in
    model#set ~row:iter ~column:name_col  name;
    model#set ~row:iter ~column:value_col "shit"
  in List.iter add_record pars

everything compiles without a notice.

Please, can somebody explain me what I am doing wrong, and what is  "universal variable 'b" that escapes from its scope.

Big thanks, in advance for any help!


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] passing object to a function fails to compile (lablgtk2 involved)
  2012-07-16  6:49 [Caml-list] passing object to a function fails to compile (lablgtk2 involved) Ivan
@ 2012-07-16 15:29 ` Anthony Tavener
  2012-07-17  8:32   ` Ivan
  0 siblings, 1 reply; 4+ messages in thread
From: Anthony Tavener @ 2012-07-16 15:29 UTC (permalink / raw)
  To: Ivan; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 3240 bytes --]

Hi Ivan, I'm not an OCaml wizard, but I'll hazard a guess...

Are your lines calling create_model and fill_model in a different module
than where the functions are defined? (or called from the toplevel?) If so,
it might be that the types at the module boundary are not constrained
enough to be compatible? (apologies if my terminology is incorrect)

If these functions are in a different module than the calls to them, you
might need to define the module signature, using a consistent type for a
"model". Sometimes two types are not equal, even though they *would* amount
to the same underlying representation in a particular scenario. So, check
the inferred types of your functions... you might need to add another hint
to express what you want.

When you roll everything into one function, the compiler has more
information about how the values are used. ie., Usage provides another
constraint for typing.

 -Tony

On Mon, Jul 16, 2012 at 12:49 AM, Ivan <ivg@ieee.org> wrote:

> Excuse me for the topic formulation, but I cannot state it better.
>
> I have two simple functions:
>
> let fill_model model name_col value_col =
>   let pars = P.from_file "parallax.cfg" in
>   let add_record (name, value) =
>     let iter = model#append () in
>     model#set ~row:iter ~column:name_col  name;
>     model#set ~row:iter ~column:value_col   value
>   in List.iter add_record pars
>
> (where P.from_file some function generating an assoc list -> (string *
> string) list )
>
> and
>
> let create_model () =
>   let cols   = new GTree.column_list in
>   let name_col  = cols#add Gobject.Data.string
>   and value_col = cols#add Gobject.Data.string in
>   let model  = GTree.list_store cols in
>   (model, name_col, value_col)
>
> When I try to pass values returned by function `create_model' to function
> `fill_model' with the following expression:
>
>   let model, name_col, value_col = create_model () in
>   fill_model model name_col value_col
>
> compiler refuses with:
>
> Error: This expression has type GTree.list_store
>        but an expression was expected of type
>          < append : unit -> Gtk.tree_iter;
>            set : row:Gtk.tree_iter -> column:'a -> Types.id -> unit; .. >
>        The universal variable 'b would escape its scope
>
> If I write the two functions in one, like this:
> let fill_and_create_model () =
>   let cols   = new GTree.column_list in
>   let name_col  = cols#add Gobject.Data.string
>   and value_col = cols#add Gobject.Data.string in
>   let model  = GTree.list_store cols in
>   let pars = P.resolve_links (P.from_file "parallax.cfg") in
>   let add_record (name, value) =
>     let iter = model#append () in
>     model#set ~row:iter ~column:name_col  name;
>     model#set ~row:iter ~column:value_col "shit"
>   in List.iter add_record pars
>
> everything compiles without a notice.
>
> Please, can somebody explain me what I am doing wrong, and what is
>  "universal variable 'b" that escapes from its scope.
>
> Big thanks, in advance for any help!
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa-roc.inria.fr/wws/info/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>

[-- Attachment #2: Type: text/html, Size: 4161 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] passing object to a function fails to compile (lablgtk2 involved)
  2012-07-16 15:29 ` Anthony Tavener
@ 2012-07-17  8:32   ` Ivan
  2012-07-18 16:53     ` Olivier Andrieu
  0 siblings, 1 reply; 4+ messages in thread
From: Ivan @ 2012-07-17  8:32 UTC (permalink / raw)
  To: Anthony Tavener; +Cc: caml-list

Thanks, Anthony!

16.07.2012, 19:29, "Anthony Tavener" <anthony.tavener@gmail.com>:

>  Are your lines calling create_model and fill_model in a different module than where the functions are defined?
>  (or called from the toplevel?) If so, it might be that the types at the module boundary are not constrained enough
>  to be compatible? (apologies if my terminology is incorrect)

Everything happens in the same file/module. It seems to me, just by some insight, that a compiler do not know about columns, stored at the model, so, when he infers his method, they remain polymorphic. I think that some constraint should help, but I'm in doubt how to spell it right. Method set (which I'm suspecting as a cause of a failure) has type, that contains type quantifier: "'a. row:Gtk.tree_iter -> column:'a column -> 'a -> unit". Right now, type quantifiers are out of my ocaml's active vocabulary. In other words I do not know, how to handle them properly. 
Moreover, I still have no insight on the variable 'b. Why do the compiler refers to some 'b, without even mentioning it in the types it inferred? It's very strange for me. 

> If these functions are in a different module than the calls to them, 
> you might need to define the module signature, using a consistent type for a "model". 
> Sometimes two types are not equal, even though they *would* 
> amount to the same underlying representation in a particular scenario. 
> So, check the inferred types of your functions... you might need to add another hint to express what you want.

Yes, It seems that refactoring this functions in a separate modules will bring additional benefits in addition to solving the problem. I'll consider looking in that direction, though the problem of constraining unusual (for me) type still remains.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Caml-list] passing object to a function fails to compile (lablgtk2 involved)
  2012-07-17  8:32   ` Ivan
@ 2012-07-18 16:53     ` Olivier Andrieu
  0 siblings, 0 replies; 4+ messages in thread
From: Olivier Andrieu @ 2012-07-18 16:53 UTC (permalink / raw)
  To: Ivan; +Cc: caml-list

On Tue, Jul 17, 2012 at 10:32 AM, Ivan <ivg@ieee.org> wrote:
> Method set (which I'm suspecting as a cause of a failure) has type, that contains type quantifier:
> "'a. row:Gtk.tree_iter -> column:'a column -> 'a -> unit". Right now, type quantifiers are out of my ocaml's
> active vocabulary. In other words I do not know, how to handle them properly.

Yes, the GTree.list_store has a polymorphic method #set. Such methods
usually need a type annotation otherwise
the type inference will give you a regular non-polymorphic type for the method.

In your case the simple solution would be to constrain your model argument :
    let fill_model (model : GTree.list_store) name_col value_col =

(not tested :)

> Moreover, I still have no insight on the variable 'b. Why do the compiler refers to some 'b, without even mentioning it in the types it inferred? It's very strange for me.

This 'b variable is hidden in GTree.list_store I think.
A class name such as GTree.list_store acts like an alias for the
corresponding object type, here something like < ... set : 'b.
row:Gtk.tree_iter -> column:'b  GTree.column-> 'b -> unit ... >.

-- 
  Olivier

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-07-18 16:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-16  6:49 [Caml-list] passing object to a function fails to compile (lablgtk2 involved) Ivan
2012-07-16 15:29 ` Anthony Tavener
2012-07-17  8:32   ` Ivan
2012-07-18 16:53     ` Olivier Andrieu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).