Closed yunxing closed 2 months ago
{mutable field: int} and {field: int ref} are significantly different. Consider what {field: int ref} looks like after expanding the definition of ref
:
type 'a ref = {mutable contents: 'a}
{field: {mutable contents: int}}
So there is an additional reference/pointer in the ref case: a value of type {mutable field: int} is a pointer to an block of memory that contains an int, where the int may change, a value of type {field: {mutable contents: int}} is a pointer to a block of memory that contains a constant pointer to another block of memory that contains an int, where the int may change.
If the existence of both forms is confusing, I would say to just remove ref, or hide it somewhere beginners are not likely to find.
If the existence of both forms is confusing, I would say to just remove ref, or hide it somewhere beginners are not likely to find.
This is exactly the approach we've taken in the docs. :D
In fact, I've eliminated ref
in my own code. I always just use a record with field contents
.
I think if there were a second syntax for mutation that we encouraged, it could still be a {contents}
behind the scenes, but one that is more intuitive. @jberdine, does the following seem easy to implement?
let x = "hey I'm a regular let binding";
var y = "I'm a faux mutable binding";
if (someCondition) {
y = "new Value";
};
callOutToSomeFunction y;
Which would be converted to:
let x = "hey I'm a regular let binding";
let y = {contents: "I'm a faux mutable binding"};
if (someCondition) {
y.contents = "new Value";
};
callOutToSomeFunction y.contents;
oh, I guess I missed one thing: When you write callOutToSomeFunction y
Our parser would need to be smart enough to tell we are reading from a reference and automatically convert it to callOutToSomeFunction y.contents
.
Yes, that is correct - it should be trivially lexical though (not involving any type system work, or dependencies between two files).
The hard thing for me, as a newbie, is how the ref
type is the first introduction to mutability in beginner texts like Real World OCaml. There it tells you to use !
and :=
to read and write refs
. That doesn't really fit with Reason's more C-like syntax. So it'll probably be hard to hide it from beginners.
It feels sloppy to access foo.contents
for ref
s in Reason. I like the idea of using var
as sugar around a single-field record. I think the simple rule of "if foo
was declared as a var
, then replace all occurrences of foo
with foo.contents
" will achieve what you want?
From a beginner's perspective, I find the "mutable" keyword and "ref" keyword are pretty confusing: What's the difference between using
{mutable field: int}
and{field: int ref}
? It looks like they are expressing the same intention to have a mutable field.I'm thinking if we can unify these two by the following proposal:
{mutable field: int}
mutable a = 1
obj.field = 1
(we already have this today) andmutable a = 1; a = 2
(It is written aslet a = ref 1; a := 2
today )