* [Caml-list] Repacking modules gives unexpected results
@ 2015-05-12 21:47 peterfrey
2015-05-12 22:36 ` Jeremy Yallop
2015-05-15 22:28 ` peterfrey
0 siblings, 2 replies; 3+ messages in thread
From: peterfrey @ 2015-05-12 21:47 UTC (permalink / raw)
To: caml-list
(* I am running into a very strange problem with re-packed modules:
re-packed instances of variables take on their new values, but internal
functions that depend on those values are still tied to the initial
values.
module Make is initialized to buf = "foo" and len = (Bytes.length buf)
re_pack substitutes buf = "aBar" and len = 4
gives the result:
E.show():len:3 buf:foo E.buf:foo E.len:3
E.show():len:3 buf:foo E.buf:aBar E.len:4
i.e.: the data reported by show() is not changed.
E.buf and E.len reflect the results of re_pack
The second line above SHOULD be as follows:
E.show():len:4 buf:aBar E.buf:aBar E.len:4
In fact it is, IFF the line
let show() = sprintf"len:%i\tbuf:%s" len buf
is also included int the repacking.
Perhaps I am trying to do something that is not supported.
*)
open Printf
module type ELT = sig
val buf : bytes
val len : int
val show : unit -> string
end
module Make ( Data: sig val initial : string end) : ELT = struct
let buf = Data.initial
let len = (Bytes.length Data.initial)
let show() = sprintf"len:%i\tbuf:%s" len buf
end
module Reg = struct
let show (module E:ELT) =
sprintf"E.show():%s\tE.buf:%s\tE.len:%i\n" (E.show()) E.buf E.len
let re_pack env =
(module struct include (val env:ELT) let buf = "aBar"
let len = 4
(* let show() = sprintf"len:%i\tbuf:%s" len buf *)
(* with this it will 'work' ... *)
end : ELT )
end
let byte_source_of_string initial =
(module struct include Make(struct let initial = initial end) end :
ELT )
;;
open Reg;;
let s = byte_source_of_string "foo";;
print_endline (show s);;
let s' = re_pack s;;
print_endline (show s');;
(* show s' prints 0 - 2 demonstrating that ofs=2 and E.show() = 0 *)
Peter Frey
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] Repacking modules gives unexpected results
2015-05-12 21:47 [Caml-list] Repacking modules gives unexpected results peterfrey
@ 2015-05-12 22:36 ` Jeremy Yallop
2015-05-15 22:28 ` peterfrey
1 sibling, 0 replies; 3+ messages in thread
From: Jeremy Yallop @ 2015-05-12 22:36 UTC (permalink / raw)
To: peterfrey; +Cc: caml-list
On 12 May 2015 at 22:47, peterfrey <pjfrey@sympatico.ca> wrote:
> (* I am running into a very strange problem with re-packed modules:
> re-packed instances of variables take on their new values, but internal
> functions that depend on those values are still tied to the initial
> values.
I think you're thinking of modules as a way of defining something like
objects, where variables bound within the module behave like member
variables that can be overridden. In fact, modules are not very much
like objects, and variables bound in modules have the same lexical
scope as most of the rest of the language. In particular, in this
definition:
struct
let buf = Data.initial
let len = (Bytes.length Data.initial)
let show() = sprintf"len:%i\tbuf:%s" len buf
end
the names 'len' and 'buf' in the definition of 'show' will always
refer to the nearest bindings for those names in the scope *in which
show was defined*, no matter what you do elsewhere in the program.
OCaml programmers tend to think of this kind of lexical scope as a
feature, since it makes it quite straightforward to understand and
refactor code.
A little further down you have
include (val env:ELT) let buf = "aBar"
let len = 4
which, when you substitute in the value of 'env', and expand the
'include', gives you something equivalent to this:
let buf = Data.initial
let len = (Bytes.length Data.initial)
let show() = sprintf"len:%i\tbuf:%s" len buf
let buf = "aBar"
let len = 4
Although the names 'buf' and 'len' are rebound, the rebindings don't
have any effect on the uses of the previous bindings in the definition
of 'show'. Again, there's nothing module-specific going on here;
you'll see the same behaviour if you enter the definitions at the
top-level.
OCaml does have a system of objects and classes which behaves in
something like the way that you're expecting. For example, you can
write:
class make ~initial =
object
val buf = initial
val len = String.length initial
method show = Printf.sprintf "len:%i\tbuf:%s" len buf
method repack ~buf ~len = {< buf = buf; len = len >}
end
and then
# let s = new make ~initial:"foo";;
val s : make = <obj>
# s#show;;
- : string = "len:3\tbuf:foo"
# let s' = s#repack ~buf:"aBar" ~len:4;;
val s' : make = <obj>
# s'#show;;
- : string = "len:4\tbuf:aBar"
Jeremy.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Caml-list] Repacking modules gives unexpected results
2015-05-12 21:47 [Caml-list] Repacking modules gives unexpected results peterfrey
2015-05-12 22:36 ` Jeremy Yallop
@ 2015-05-15 22:28 ` peterfrey
1 sibling, 0 replies; 3+ messages in thread
From: peterfrey @ 2015-05-15 22:28 UTC (permalink / raw)
To: caml-list
On 15-05-12 05:47 PM, peterfrey wrote:
> For quite a while now I have been using first class modules as a sort of
replacement for objects. You are right, of course, I did not
notice that the variables were not
bound (not even after simplifying the code to almost nothing).
'Obvious' is not always obvious...
Thanks a lot, I don't know how much longer I would have stared at this.
>
> Peter Frey
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-05-15 22:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-12 21:47 [Caml-list] Repacking modules gives unexpected results peterfrey
2015-05-12 22:36 ` Jeremy Yallop
2015-05-15 22:28 ` peterfrey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox