caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Modules and record fields
@ 2014-05-25 10:30 Ollie Frolovs
  2014-05-25 10:45 ` Gabriel Scherer
  2014-05-25 10:59 ` Gabriel Kerneis
  0 siblings, 2 replies; 8+ messages in thread
From: Ollie Frolovs @ 2014-05-25 10:30 UTC (permalink / raw)
  To: caml users

Hello

I was using some colours in my program and thought that it would be a good idea to put colour constants into a separate module. 

module Solarized = struct
  type colour = {r:int; g:int;  b:int}

  let base03 = {r=0x00; g=0x2b; b=0x36}
  let orange = {r=0xcb; g=0x4b; b=0x16}
  (* etc etc *)
end

I need three separate RGB components because I’m using an API which needs them separately, rather than in some pre-packed way.

I was planning to use the module like this

let module S = Solarized in
Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
(* etc etc *)

that is, to locally open the module and refer to the colours and their subcomponent.

But this does not work. It appears for some reason that I have to address the subcomponents as

Solarized.orange.Solarized.r

which defeats the purpose! Is there any other way to achieve my goal?

Best regards

Ollie 

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

* Re: [Caml-list] Modules and record fields
  2014-05-25 10:30 [Caml-list] Modules and record fields Ollie Frolovs
@ 2014-05-25 10:45 ` Gabriel Scherer
  2014-05-25 10:59 ` Gabriel Kerneis
  1 sibling, 0 replies; 8+ messages in thread
From: Gabriel Scherer @ 2014-05-25 10:45 UTC (permalink / raw)
  To: Ollie Frolovs; +Cc: caml users

let open Solarized in Sdl.set_render_draw_color ren orange.r orange.g
orange.b 0xff

Solarized.(Sdl.set_render_draw_color ren orange.r orange.g orange.b 0xff)

let module S = Solarized in Sdl.set_render_draw_color ren S.(orange.r)
S.(orange.g) S.(orange.b) 0xff

let apply f color = Solarized.(f color.r color.g color.b) in
apply (Sdl.set_render_draw_color ren) orange 0xff

On Sun, May 25, 2014 at 12:30 PM, Ollie Frolovs
<ollie.frolovs.2012@my.bristol.ac.uk> wrote:
> Hello
>
> I was using some colours in my program and thought that it would be a good idea to put colour constants into a separate module.
>
> module Solarized = struct
>   type colour = {r:int; g:int;  b:int}
>
>   let base03 = {r=0x00; g=0x2b; b=0x36}
>   let orange = {r=0xcb; g=0x4b; b=0x16}
>   (* etc etc *)
> end
>
> I need three separate RGB components because I’m using an API which needs them separately, rather than in some pre-packed way.
>
> I was planning to use the module like this
>
> let module S = Solarized in
> Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
> (* etc etc *)
>
> that is, to locally open the module and refer to the colours and their subcomponent.
>
> But this does not work. It appears for some reason that I have to address the subcomponents as
>
> Solarized.orange.Solarized.r
>
> which defeats the purpose! Is there any other way to achieve my goal?
>
> Best regards
>
> Ollie
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> 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] Modules and record fields
  2014-05-25 10:30 [Caml-list] Modules and record fields Ollie Frolovs
  2014-05-25 10:45 ` Gabriel Scherer
@ 2014-05-25 10:59 ` Gabriel Kerneis
  2014-05-25 12:46   ` Ollie Frolovs
  1 sibling, 1 reply; 8+ messages in thread
From: Gabriel Kerneis @ 2014-05-25 10:59 UTC (permalink / raw)
  To: Ollie Frolovs; +Cc: caml users

On Sun, May 25, 2014 at 11:30:20AM +0100, Ollie Frolovs wrote:
> let module S = Solarized in
> Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
> (* etc etc *)

Doesn't this work with the latest version of the compiler? (with a
warning "r is not visible in the current scope, and will not be
selected if the type becomes unknown")

-- 
Gabriel

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

* Re: [Caml-list] Modules and record fields
  2014-05-25 10:59 ` Gabriel Kerneis
@ 2014-05-25 12:46   ` Ollie Frolovs
  2014-05-25 13:57     ` Gabriel Scherer
  0 siblings, 1 reply; 8+ messages in thread
From: Ollie Frolovs @ 2014-05-25 12:46 UTC (permalink / raw)
  To: Gabriel Kerneis; +Cc: caml users

It does, but I am rather disturbed by the compiler warning. I usually aim not to have them, particularly when I am new to the language, assuming that they at least hint at unsafe programming techniques.

Update: I’ve put Solarized interface and definitions into separate files (rather than having both as module Solarized = … in the main file)  and there is no warning anymore for some reason. Unless there is something else I’m doing differently without realising it. 

I suppose that solves my problem. Thanks everybody!

solarize.mli:

type colour = {r:int; g:int;  b:int}
val base03 : colour
val orange : colour

(* END *)

solarize.ml:

type colour = {r:int; g:int;  b:int}
let base03 = {r=0x00; g=0x2b; b=0x36}
let orange = {r=0xcb; g=0x4b; b=0x16}

(* END *)

main.ml:

…
Solarized.(Sdl.set_render_draw_color ren orange.r orange.g orange.b 0xff)
… 
(* END *)


On 25 May 2014, at 11:59, Gabriel Kerneis <gabriel@kerneis.info> wrote:

> On Sun, May 25, 2014 at 11:30:20AM +0100, Ollie Frolovs wrote:
>> let module S = Solarized in
>> Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
>> (* etc etc *)
> 
> Doesn't this work with the latest version of the compiler? (with a
> warning "r is not visible in the current scope, and will not be
> selected if the type becomes unknown")
> 
> -- 
> Gabriel


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

* Re: [Caml-list] Modules and record fields
  2014-05-25 12:46   ` Ollie Frolovs
@ 2014-05-25 13:57     ` Gabriel Scherer
  2014-05-25 14:56       ` Ollie Frolovs
  0 siblings, 1 reply; 8+ messages in thread
From: Gabriel Scherer @ 2014-05-25 13:57 UTC (permalink / raw)
  To: Ollie Frolovs; +Cc: Gabriel Kerneis, caml users

The presence or absence of a warning is unrelated to whether it's a
local module or a separate file. Solarized.orange.r and
Solarized.(orange.r) are not equivalent. Solarized.orange.r means that
you access the field "r" (in the current scope) of the value
Solarized.orange. Solarized.(orange.r) opens Solarized locally for
both the resolution of the "orange" identifier and "r" field name.
Your new version is equivalent (Solarized's opening scope is even
wider).

The warning comes from the fact that since 4.01, OCaml can resolve a
field name not only by having its path given from the current scope
(eg. Solarized.r), but also by reasoning on the type of the record
value, even if the field name itself is not in scope. Accessing field
names that are not in scope is considered bad practice, hence the
warning (which is disabled by a few people that like this style).

On Sun, May 25, 2014 at 2:46 PM, Ollie Frolovs
<ollie.frolovs.2012@my.bristol.ac.uk> wrote:
> It does, but I am rather disturbed by the compiler warning. I usually aim not to have them, particularly when I am new to the language, assuming that they at least hint at unsafe programming techniques.
>
> Update: I’ve put Solarized interface and definitions into separate files (rather than having both as module Solarized = … in the main file)  and there is no warning anymore for some reason. Unless there is something else I’m doing differently without realising it.
>
> I suppose that solves my problem. Thanks everybody!
>
> solarize.mli:
>
> type colour = {r:int; g:int;  b:int}
> val base03 : colour
> val orange : colour
>
> (* END *)
>
> solarize.ml:
>
> type colour = {r:int; g:int;  b:int}
> let base03 = {r=0x00; g=0x2b; b=0x36}
> let orange = {r=0xcb; g=0x4b; b=0x16}
>
> (* END *)
>
> main.ml:
>
> …
> Solarized.(Sdl.set_render_draw_color ren orange.r orange.g orange.b 0xff)
> …
> (* END *)
>
>
> On 25 May 2014, at 11:59, Gabriel Kerneis <gabriel@kerneis.info> wrote:
>
>> On Sun, May 25, 2014 at 11:30:20AM +0100, Ollie Frolovs wrote:
>>> let module S = Solarized in
>>> Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
>>> (* etc etc *)
>>
>> Doesn't this work with the latest version of the compiler? (with a
>> warning "r is not visible in the current scope, and will not be
>> selected if the type becomes unknown")
>>
>> --
>> Gabriel
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> 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] Modules and record fields
  2014-05-25 13:57     ` Gabriel Scherer
@ 2014-05-25 14:56       ` Ollie Frolovs
  2014-05-25 15:02         ` Gabriel Scherer
  0 siblings, 1 reply; 8+ messages in thread
From: Ollie Frolovs @ 2014-05-25 14:56 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: Gabriel Kerneis, caml users

Aha. Now I understand what happens but I don’t understand why. Specifically, why would the compiler in Solarized.orange.r access the field “r" in the **current scope** of the value Solarized.orange, what use is this? In other words why Solarized.orange.r is not equivalent to Solarized.(orange.r) equivalent to Solarized.orange.(r), if that makes sense? There must be a good reason.

On 25 May 2014, at 14:57, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:

> The presence or absence of a warning is unrelated to whether it's a
> local module or a separate file. Solarized.orange.r and
> Solarized.(orange.r) are not equivalent. Solarized.orange.r means that
> you access the field "r" (in the current scope) of the value
> Solarized.orange. Solarized.(orange.r) opens Solarized locally for
> both the resolution of the "orange" identifier and "r" field name.
> Your new version is equivalent (Solarized's opening scope is even
> wider).
> 
> The warning comes from the fact that since 4.01, OCaml can resolve a
> field name not only by having its path given from the current scope
> (eg. Solarized.r), but also by reasoning on the type of the record
> value, even if the field name itself is not in scope. Accessing field
> names that are not in scope is considered bad practice, hence the
> warning (which is disabled by a few people that like this style).
> 
> On Sun, May 25, 2014 at 2:46 PM, Ollie Frolovs
> <ollie.frolovs.2012@my.bristol.ac.uk> wrote:
>> It does, but I am rather disturbed by the compiler warning. I usually aim not to have them, particularly when I am new to the language, assuming that they at least hint at unsafe programming techniques.
>> 
>> Update: I’ve put Solarized interface and definitions into separate files (rather than having both as module Solarized = … in the main file)  and there is no warning anymore for some reason. Unless there is something else I’m doing differently without realising it.
>> 
>> I suppose that solves my problem. Thanks everybody!
>> 
>> solarize.mli:
>> 
>> type colour = {r:int; g:int;  b:int}
>> val base03 : colour
>> val orange : colour
>> 
>> (* END *)
>> 
>> solarize.ml:
>> 
>> type colour = {r:int; g:int;  b:int}
>> let base03 = {r=0x00; g=0x2b; b=0x36}
>> let orange = {r=0xcb; g=0x4b; b=0x16}
>> 
>> (* END *)
>> 
>> main.ml:
>> 
>> …
>> Solarized.(Sdl.set_render_draw_color ren orange.r orange.g orange.b 0xff)
>> …
>> (* END *)
>> 
>> 
>> On 25 May 2014, at 11:59, Gabriel Kerneis <gabriel@kerneis.info> wrote:
>> 
>>> On Sun, May 25, 2014 at 11:30:20AM +0100, Ollie Frolovs wrote:
>>>> let module S = Solarized in
>>>> Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
>>>> (* etc etc *)
>>> 
>>> Doesn't this work with the latest version of the compiler? (with a
>>> warning "r is not visible in the current scope, and will not be
>>> selected if the type becomes unknown")
>>> 
>>> --
>>> Gabriel
>> 
>> 
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> 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] Modules and record fields
  2014-05-25 14:56       ` Ollie Frolovs
@ 2014-05-25 15:02         ` Gabriel Scherer
  2014-05-26  9:14           ` Goswin von Brederlow
  0 siblings, 1 reply; 8+ messages in thread
From: Gabriel Scherer @ 2014-05-25 15:02 UTC (permalink / raw)
  To: Ollie Frolovs; +Cc: Gabriel Kerneis, caml users

When I write M.v.f, it is not always the case that the field f is
exported by the module M. Consider for example:

module A = struct
  type t = { f: int }
end

module M = struct
  open A
  let v = { f = 1 }
  type u = { f : string }
end

print_int M.v.f

This rightly fails (with a warning) as one should write M.v.A.f to be
fully precise about the scope. Note that M.v.M.f or M.(v.f) would have
a completely different (and wrong) meaning.

On Sun, May 25, 2014 at 4:56 PM, Ollie Frolovs
<ollie.frolovs.2012@my.bristol.ac.uk> wrote:
> Aha. Now I understand what happens but I don’t understand why. Specifically, why would the compiler in Solarized.orange.r access the field “r" in the **current scope** of the value Solarized.orange, what use is this? In other words why Solarized.orange.r is not equivalent to Solarized.(orange.r) equivalent to Solarized.orange.(r), if that makes sense? There must be a good reason.
>
> On 25 May 2014, at 14:57, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:
>
>> The presence or absence of a warning is unrelated to whether it's a
>> local module or a separate file. Solarized.orange.r and
>> Solarized.(orange.r) are not equivalent. Solarized.orange.r means that
>> you access the field "r" (in the current scope) of the value
>> Solarized.orange. Solarized.(orange.r) opens Solarized locally for
>> both the resolution of the "orange" identifier and "r" field name.
>> Your new version is equivalent (Solarized's opening scope is even
>> wider).
>>
>> The warning comes from the fact that since 4.01, OCaml can resolve a
>> field name not only by having its path given from the current scope
>> (eg. Solarized.r), but also by reasoning on the type of the record
>> value, even if the field name itself is not in scope. Accessing field
>> names that are not in scope is considered bad practice, hence the
>> warning (which is disabled by a few people that like this style).
>>
>> On Sun, May 25, 2014 at 2:46 PM, Ollie Frolovs
>> <ollie.frolovs.2012@my.bristol.ac.uk> wrote:
>>> It does, but I am rather disturbed by the compiler warning. I usually aim not to have them, particularly when I am new to the language, assuming that they at least hint at unsafe programming techniques.
>>>
>>> Update: I’ve put Solarized interface and definitions into separate files (rather than having both as module Solarized = … in the main file)  and there is no warning anymore for some reason. Unless there is something else I’m doing differently without realising it.
>>>
>>> I suppose that solves my problem. Thanks everybody!
>>>
>>> solarize.mli:
>>>
>>> type colour = {r:int; g:int;  b:int}
>>> val base03 : colour
>>> val orange : colour
>>>
>>> (* END *)
>>>
>>> solarize.ml:
>>>
>>> type colour = {r:int; g:int;  b:int}
>>> let base03 = {r=0x00; g=0x2b; b=0x36}
>>> let orange = {r=0xcb; g=0x4b; b=0x16}
>>>
>>> (* END *)
>>>
>>> main.ml:
>>>
>>> …
>>> Solarized.(Sdl.set_render_draw_color ren orange.r orange.g orange.b 0xff)
>>> …
>>> (* END *)
>>>
>>>
>>> On 25 May 2014, at 11:59, Gabriel Kerneis <gabriel@kerneis.info> wrote:
>>>
>>>> On Sun, May 25, 2014 at 11:30:20AM +0100, Ollie Frolovs wrote:
>>>>> let module S = Solarized in
>>>>> Sdl.set_render_draw_color ren S.orange.r S.orange.g S.orange.b 0xff
>>>>> (* etc etc *)
>>>>
>>>> Doesn't this work with the latest version of the compiler? (with a
>>>> warning "r is not visible in the current scope, and will not be
>>>> selected if the type becomes unknown")
>>>>
>>>> --
>>>> Gabriel
>>>
>>>
>>> --
>>> Caml-list mailing list.  Subscription management and archives:
>>> https://sympa.inria.fr/sympa/arc/caml-list
>>> 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] Modules and record fields
  2014-05-25 15:02         ` Gabriel Scherer
@ 2014-05-26  9:14           ` Goswin von Brederlow
  0 siblings, 0 replies; 8+ messages in thread
From: Goswin von Brederlow @ 2014-05-26  9:14 UTC (permalink / raw)
  To: caml-list

On Sun, May 25, 2014 at 05:02:46PM +0200, Gabriel Scherer wrote:
> When I write M.v.f, it is not always the case that the field f is
> exported by the module M. Consider for example:
> 
> module A = struct
>   type t = { f: int }
> end
> 
> module M = struct
>   open A
>   let v = { f = 1 }
>   type u = { f : string }
> end
> 
> print_int M.v.f
> 
> This rightly fails (with a warning) as one should write M.v.A.f to be
> fully precise about the scope. Note that M.v.M.f or M.(v.f) would have
> a completely different (and wrong) meaning.

Here is another example:

module V2 = struct
  type t = { x:int; y:int; }
  let make x y =  { x; y; }
end

module V3 = struct
  type t = { x:int; y:int; z:int; }
  let make x y z =  { x; y; z; }
  let of_v2 v = { x = v.V2.x; y = v.V2.y; V3.z = 0; }
  let to_v2 v = { V2.x = v.x; V2.y = v.y; }
end

let v3_of_v2 v = { V3.x = v.V2.x; V3.y = v.V2.y; V3.z = 0; }

MfG
	Goswin

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

end of thread, other threads:[~2014-05-26  9:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-25 10:30 [Caml-list] Modules and record fields Ollie Frolovs
2014-05-25 10:45 ` Gabriel Scherer
2014-05-25 10:59 ` Gabriel Kerneis
2014-05-25 12:46   ` Ollie Frolovs
2014-05-25 13:57     ` Gabriel Scherer
2014-05-25 14:56       ` Ollie Frolovs
2014-05-25 15:02         ` Gabriel Scherer
2014-05-26  9:14           ` Goswin von Brederlow

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