caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* "opening" record types
@ 2007-08-21 13:18 Yitzhak Mandelbaum
  2007-08-21 13:34 ` [Caml-list] " Olivier Andrieu
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Yitzhak Mandelbaum @ 2007-08-21 13:18 UTC (permalink / raw)
  To: caml-list

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

Hi,

I'm generally averse to opening modules, as I find it can make it  
hard to figure out where definitions are coming from. Instead, I  
prefer to bind only those pieces of the module that I need, and to do  
so explicitly.  However, there is one instance in which I find myself  
with little choice: record types.  In order to bind the field- 
constructors for a record, you need to copy the entire type from the  
module in which its declared. For example,

module Foo =
struct
   type t = {a: int; b:int}
end

without copying the type:

let y = {Foo.a=3; Foo.b=4}

with copying:

type t = Foo.t =  {a: int; b:int}

let x = {a=3; b=4}

While this is a nuisance to begin with, its even worse if the record  
type is subject to change -- each time it changes, you need to update  
every place where you copied the definition.

Is there any way around this?  That is, is there any way to use the  
field names of a record defined in another module without opening the  
whole module or copying the whole definition of the record.

Cheers,
Yitzhak

--------------------------------------------------
Yitzhak Mandelbaum
AT&T Labs - Research

http://www.research.att.com/~yitzhak



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

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

* Re: [Caml-list] "opening" record types
  2007-08-21 13:18 "opening" record types Yitzhak Mandelbaum
@ 2007-08-21 13:34 ` Olivier Andrieu
  2007-08-21 22:19   ` Yaron Minsky
  2007-08-21 13:42 ` Christophe TROESTLER
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Olivier Andrieu @ 2007-08-21 13:34 UTC (permalink / raw)
  To: Yitzhak Mandelbaum; +Cc: caml-list

On 8/21/07, Yitzhak Mandelbaum <yitzhak@research.att.com> wrote:
> module Foo =
> struct
>   type t = {a: int; b:int}
> end
>
> without copying the type:
>
> let y = {Foo.a=3; Foo.b=4}

actually, you can write
  let y = {Foo.a=3; b=4}

i.e. you only need the module name on one field of the record, not all

-- 
  Olivier


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

* Re: [Caml-list] "opening" record types
  2007-08-21 13:18 "opening" record types Yitzhak Mandelbaum
  2007-08-21 13:34 ` [Caml-list] " Olivier Andrieu
@ 2007-08-21 13:42 ` Christophe TROESTLER
  2007-08-21 13:55   ` Daniel de Rauglaudre
  2007-08-21 13:47 ` Virgile Prevosto
  2007-08-22 16:32 ` Philippe Wang
  3 siblings, 1 reply; 8+ messages in thread
From: Christophe TROESTLER @ 2007-08-21 13:42 UTC (permalink / raw)
  To: yitzhak; +Cc: caml-list

On Tue, 21 Aug 2007 09:18:02 -0400, Yitzhak Mandelbaum wrote:
> 
> let y = {Foo.a=3; Foo.b=4}
> 
> Is there any way around this?  That is, is there any way to use the  
> field names of a record defined in another module without opening the  
> whole module or copying the whole definition of the record.

No because the record {a,b} may also be defined in another module and
you need to tell which one to use.  However, you can put the
qualification only once :

let y = {Foo.a=3; b=4}

Of course, if [Foo] name is long, you can alias it at the beginning of
your code :

module F = Very.Long.Module.Name

Cheers,
ChriS


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

* Re: [Caml-list] "opening" record types
  2007-08-21 13:18 "opening" record types Yitzhak Mandelbaum
  2007-08-21 13:34 ` [Caml-list] " Olivier Andrieu
  2007-08-21 13:42 ` Christophe TROESTLER
@ 2007-08-21 13:47 ` Virgile Prevosto
  2007-08-22 16:32 ` Philippe Wang
  3 siblings, 0 replies; 8+ messages in thread
From: Virgile Prevosto @ 2007-08-21 13:47 UTC (permalink / raw)
  To: caml-list

Hello,

Le mar 21 aoû 2007 09:18:02 CEST,
Yitzhak Mandelbaum <yitzhak@research.att.com> a écrit :

> Is there any way around this?  That is, is there any way to use the  
> field names of a record defined in another module without opening
> the whole module or copying the whole definition of the record.

Olivier Andrieu has written a camlp4 extension (which won't compile
with camlp4 3.10, I'm afraid) that does more or less this:
http://oandrieu.nerim.net/ocaml/index.html#pa_records

It should allow you to write (not tested)

let x = Foo.{a=3; b=4}

-- 
E tutto per oggi, a la prossima volta.
Virgile


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

* Re: [Caml-list] "opening" record types
  2007-08-21 13:42 ` Christophe TROESTLER
@ 2007-08-21 13:55   ` Daniel de Rauglaudre
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel de Rauglaudre @ 2007-08-21 13:55 UTC (permalink / raw)
  To: caml-list

Hi,

> Is there any way around this?  That is, is there any way to use the  
> field names of a record defined in another module without opening the  
> whole module or copying the whole definition of the record.

Yes, instead of doing "open Foo", do:

  type t = Foo.t = {a: int; b:int}

-- 
Daniel de Rauglaudre
http://pauillac.inria.fr/~ddr/


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

* Re: [Caml-list] "opening" record types
  2007-08-21 13:34 ` [Caml-list] " Olivier Andrieu
@ 2007-08-21 22:19   ` Yaron Minsky
  0 siblings, 0 replies; 8+ messages in thread
From: Yaron Minsky @ 2007-08-21 22:19 UTC (permalink / raw)
  To: Olivier Andrieu; +Cc: Yitzhak Mandelbaum, caml-list

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

On 8/21/07, Olivier Andrieu <oandrieu@gmail.com> wrote:

> actually, you can write
>   let y = {Foo.a=3; b=4}
>
> i.e. you only need the module name on one field of the record, not all


Indeed, at Jane Street, we've come to favor the following idiom:

   let y  = { Module_name.
              field1 = val1;
              field2 = val2;
              ...
            }

The module name then works almost like a constructor, so you hardly need the
syntax extension discussed elsewhere in this thread.

y

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

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

* Re: [Caml-list] "opening" record types
  2007-08-21 13:18 "opening" record types Yitzhak Mandelbaum
                   ` (2 preceding siblings ...)
  2007-08-21 13:47 ` Virgile Prevosto
@ 2007-08-22 16:32 ` Philippe Wang
  2007-08-22 19:24   ` Jeremy Yallop
  3 siblings, 1 reply; 8+ messages in thread
From: Philippe Wang @ 2007-08-22 16:32 UTC (permalink / raw)
  To: Yitzhak Mandelbaum; +Cc: caml-list

Yet another suggestion :

Instead of :
#  module M = struct type t = { a : int ; b : int } end ;;
module M : sig type t = { a : int; b : int; } end

Write :
#  module M = struct type t = { a : int ; b : int } module N = struct 
type t = M.t = { a : int ; b : int } end end ;;
module M :
  sig
    type t = { a : int; b : int; }
    module N : sig type t = M.t = { a : int; b : int; } end
  end

Then :

# include M.N;;
type t = M.t = { a : int; b : int; }

So that you can do :
# { a = 42 ; b = 23 } ;;
- : t = {a = 42; b = 23}

That way, when you change or add definitions, it's easy to spread 
changes, and you export only what you want to export...
:-)

Cheers,

--
Philippe Wang
  mail[at]philippewang.info


Yitzhak Mandelbaum wrote:
> Hi,
>
> I'm generally averse to opening modules, as I find it can make it hard 
> to figure out where definitions are coming from. Instead, I prefer to 
> bind only those pieces of the module that I need, and to do so 
> explicitly.  However, there is one instance in which I find myself 
> with little choice: record types.  In order to bind the 
> field-constructors for a record, you need to copy the entire type from 
> the module in which its declared. For example,
>
> module Foo = 
> struct
>   type t = {a: int; b:int}
> end
>
> without copying the type:
>
> let y = {Foo.a=3; Foo.b=4}
>
> with copying: 
>
> type t = Foo.t =  {a: int; b:int}
>
> let x = {a=3; b=4}
>
> While this is a nuisance to begin with, its even worse if the record 
> type is subject to change -- each time it changes, you need to update 
> every place where you copied the definition.
>
> Is there any way around this?  That is, is there any way to use the 
> field names of a record defined in another module without opening the 
> whole module or copying the whole definition of the record.
>
> Cheers,
> Yitzhak
>
> --------------------------------------------------
> Yitzhak Mandelbaum
> AT&T Labs - Research
>
> http://www.research.att.com/~yitzhak 
> <http://www.research.att.com/%7Eyitzhak>
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>   


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

* Re: [Caml-list] "opening" record types
  2007-08-22 16:32 ` Philippe Wang
@ 2007-08-22 19:24   ` Jeremy Yallop
  0 siblings, 0 replies; 8+ messages in thread
From: Jeremy Yallop @ 2007-08-22 19:24 UTC (permalink / raw)
  To: Philippe Wang; +Cc: Yitzhak Mandelbaum, caml-list

Philippe Wang wrote:
> Instead of :
> #  module M = struct type t = { a : int ; b : int } end ;;
> module M : sig type t = { a : int; b : int; } end
> 
> Write :
> #  module M = struct type t = { a : int ; b : int } module N = struct 
> type t = M.t = { a : int ; b : int } end end ;;

I don't think this code is quite what you intended.

   # ({a = 0 ; b = 0 } : M.t );;
   Characters 1-17:
      ({a = 0 ; b = 0 } : M.t );;
      ^^^^^^^^^^^^^^^^
   This expression has type t = M.t but is here used with type M.t

I like the idea, though.  You can avoid duplicating the type definition 
by writing the inner module first.

   module M =
   struct
     module N = struct type t = { a : int; b : int } end
     include N
   end

Then, as before:

    open M.N

    { a = 0; b = 0 }

> That way, when you change or add definitions, it's easy to spread 
> changes, and you export only what you want to export...

Yes.  Unforunately, the technique is only useful if you have control of 
the module that you want to import.

Jeremy.


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

end of thread, other threads:[~2007-08-22 19:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-21 13:18 "opening" record types Yitzhak Mandelbaum
2007-08-21 13:34 ` [Caml-list] " Olivier Andrieu
2007-08-21 22:19   ` Yaron Minsky
2007-08-21 13:42 ` Christophe TROESTLER
2007-08-21 13:55   ` Daniel de Rauglaudre
2007-08-21 13:47 ` Virgile Prevosto
2007-08-22 16:32 ` Philippe Wang
2007-08-22 19:24   ` Jeremy Yallop

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).