
I recall someone (@mflatt?) said that at the time, they thought “private” fields by default make sense, but it becomes clear later that this is a mistake, and Rhombus should/will fix this issue.

pretty much what @sorawee said, yeah

I’m not really sure transparent / opaque is the right thing to think about in rhombus though

the encapsulation of non-transparent structs is a good thing. the bad part is the lack of structural equal+hash and default printing behavior.

in my experience, a good default is opaque structs, but with structural equal+hash and a printed representation that prints each field

Another thing I’m slightly annoyed is unreadable values, like #<void>
or #<procedure>
, cause it screws up read
o write
= id
. Making it readable, but represented by a special struct that says “you can’t rely on the content of this struct” makes much more sense to me.

I think read
and write
are just not good ways to serialize data

I thought structure is a good way to compose and carry data, not a good way to encapsulate.

They’re both. That’s kind of what makes them awkward at times. They have a ton of features that don’t matter of you just want to carry data, and the features for encapsulation are a bit awkward because they’re also trying to work for data carriers.

I think read and write are awesome for serialization, and that encapsulation with transparent printing doesn’t make much sense

I don’t think read and write are good because they don’t support user-defined types. I can’t make multisets read
-able.

prefab?

I mean: you don’t need the multiset thing to be a prefab, just that you can serialize its values via a prefab

but that wouldn’t that satisfy @sorawee’s read
o write
= id
condition

it would, in the prefab. The rest is translation from/to prefab

yes, you can round-trip the prefab, but not the actual struct you want to use, right?

yes. Though it shouldn’t be hard to make translators

Oh, actually I didn’t really mean read
o write
= id
.

I mean, read
o write
shouldn’t error

:smile:

well, that’s not hard to satisfy

It makes sense that when #<void>
and #<procedure>
are there, you are not gonna get id
back

read
o write
= id
is a good id
though

Shouldn’t #<void> just not be printed at all?

void should not be printed, but it should be writable

(for serialization)

Like, I have (list (void))
. If I write
this value, what do you expect to happen?

It becomes (list)
? That looks weird to me.

Why on earth would you have (list (void))
? :smile:

Should (list (error "yummy"))
be readable after being written?

I’m happy with "#<void> is not readable and breaks everything if you try to read it. Don’t write it anyway.".

Though instead of breaking, it could read the value within a struct unreadable
so that #<something>
is read as (unreadable 'something)
for example.

Yes, that’s exactly what I am proposing

(or opaque
rather than unreadable
)

Took me a while to come around!

My use case is the following:
When you do some heavy computation, you would want to write the result to a file so that you can subsequently analyze (and not having to run the whole thing again). A part of the result could be these #<void>
. But once it’s written, I can’t read them back!
Granted, perhaps it’s a problem with writing. That is, I should be more careful not to write any #<void>
, but that’s kinda difficult to control. Perhaps it’s embedded in a data structure that someone else produces, etc.

I was playing the devil’s advocate, I think it makes more sense to be able to read these, as well as opaque struct instances.

Extending the reader to produce an instance of the struct opaque
would be nice indeed

Wait: > (write (list (void)))
(#<void>)

I think the reason #<void> is unreadable is due to Scheme implementations returned void, where the standard said “the result of the expression is unspecified.”.

What I mean is that if I have a list or a hash I can just read
and write
it, but if I have a set, a multiset, or a multidict I can’t without converting it to something else first. And the only reason for that is because the reader knows about lists and hashes and treats them specially.

how automatic do you expect it to be? Racket’s reader can be extended, right?

I expect it to work more like serialize
and deserialize
, which give user defined types the ability to implement support for it

I’d like to be able to write some code in the definition of the multiset
type that makes all multisets readable and writable.

prefab, cough

I have to give up too much to use prefabs

• no pretty printing • no invariant guarantees (anyone can shove anything into any field) • can’t implement any struct type properties • can’t control the hash function used for hashing

It make no sense to me that I can’t just print/display the content of a structure while I can access all fields in it with accessor.

Well, perhaps if you don’t provide an accessor to users, then they won’t have accessors to use?

You can if you have the accessors. If the module that defines the structure type doesn’t export its accessors (or its descriptor), then it’s harder to get at that content.

So maybe it should be a property in the module contract? Not structure itself.

Or just let the user decide whether or not to provide the default print function for that structure.