Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can non-shared structs have methods? Is an explicit constructor needed? #15

Open
eddyw opened this issue Apr 14, 2022 · 0 comments
Open

Comments

@eddyw
Copy link

eddyw commented Apr 14, 2022

Hi,

I'm failing to see how non-shared structs are different from, say something like this:

struct class Box {
  x; // Initialized to undefined
  
  #_ = void Object.seal(this); // Sealed

  constructor(x) {
    this.x = x;
  }
}
Object.freeze(Box);
Object.freeze(Box.prototype);

const box = new Box(123);
box.y = 123; // TypeError: Object is non-extensible
box.x = 123; // Ok

It's also not very clear to me why would non-shared structs be allowed to have methods. It wouldn't make them much different from classes besides from the internally "fixed layout" thing (sealed).

Personally, I think there are more use cases for structs that resemble factory functions/constructors for "fixed layout" "plain objects". Ideally with no need for an explicit constructor function:

struct class Box { x; y = 0; };     // No constructor (has non-overridable constructor)

const box1 = new Box();             // Box { x: undefined, y: 0 }
const box2 = new Box({x: 1, y: 2}); // Box { x: 1, y: 2 }
const box3 = new Box({x: 1, O: 9}); // Box { x: 1, y: 0 }
const box4 = new Box(box2);         // Box { x: 1, y: 2 }

Object.isSealed(box4); // true

Structs can only extends structs makes sense. To clarify, can a class extends a struct? Personally, that would make sense to me.

class CardBox extends Box {}

const box5 = new CardBox(); // CardBox { x: undefined, y: 0 }

Object.isSealed(box5); // false

Now shared struct could have the same semantics as non-shared with the only difference of only being allowed to contain primitives to other shared structs:

struct class Box { x = 0; y = 0; }
struct shared class Asd { x = 0; }

const box1 = new Box();             // Box { x: 0, y: 0 }
const box2 = new Box({x: () => 0}); // Box { x: function, y: 0 }
const asd1 = new Asd(box1);         // Asd { x: 0 } <- x is primitive
const asd2 = new Asd(box2);         // Error (x is not shared struct or primitive)

This would - imho - reduce the confusion around non-shared structs vs sealed classes vs shared structs. And the syntax is minimal.

I see structs as a way to define plain-object data structures with a fixed layout (for the engine) that can be passed around from method to method minimizing the changes for de-optimizations. In this proposal shared structs seem to go one step ahead to allow passing whole structs across threads.

I have written a separate proposal here Data Structures: struct (as a way to put my thoughts down). Maybe it's redundant and initially I thought my proposal had a separate goal from this one here but after trying to read and understand more about non-shared structs, maybe we're talking about the same things.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant