TC39 Roundup Drama Edition Part I: Shared Structs

In this episode, Surma talks about the Stage 2 proposal "JavaScript Struct", which introduces fixed-layout objects and the ability to share them between realms.

Notes & Corrections from Shu:

Surma was slightly wrong about why private fields were originally considered problematic for sharability. The problem occurs when a class can be evaluated multiple times:

function makeClass() {
  return class MyClass { 
    #priv; 
    getPrivateField(instance) { 
      return instance.#priv; 
    } 
  };
}
const C1 = makeClass();
const C2 = makeClass();
const i1 = new C1();
const i2 = new C2();
// this throws!
i1.getPrivateField(i2);

This behavior makes it hard to compile private fields just as "slots" on an object, as clearly additional behavior is required. This is somewhat at odds with the goal of achieving a fixed layout.

Also, launching is mid-2025 is very optimistic.

Resources:

Transcript
  1. Surma:What did we learn from our last recording, Jake?
  2. Surma:We learned that I'm not wearing the bone-conducing headphones this time.
  3. Jake:Oh, excellent, yes. Shall we get the show on the road? Are you
  4. Surma:Because apparently they can still be heard
  5. Surma:when you stand as close to a microphone as I'm doing right now.
  6. Jake:ready to… Oh, alright. Hello! What, you spoiled my big moment! Look, there was going
  7. Surma:Yeah.
  8. Surma:The fucking low energy!
  9. Jake:to be a little sad sigh at the start, while I tried to build up my energy, and then…
  10. Surma:We sigh our sorrows away and then put the happy face on.
  11. Jake:No one was going to notice! Yeah, I was going to switch into just big podcast mode, and
  12. Jake:it was all going to be fine. No one was going to know how tired I am.
  13. Surma:Okay, big podcast mode engaged!
  14. Jake:Hello and welcome to another episode of OTMT, with me, Jake. Yeah, thanks to Shopify for…
  15. Surma:And me, Surma!
  16. Surma:You know what? I don't get more comfortable.
  17. Jake:Oh, look, and you've spoiled the sponsor bit! This is going to be a real mess, isn't
  18. Surma:Oh, okay. Thank you, Shopify.
  19. Jake:it? Yeah, for letting us do this. Cheers. Yeah, no, it's weird.
  20. Surma:Thank you.
  21. Surma:I guess I just noticed, like, this is episode 13, I want to say, maybe?
  22. Surma:I still haven't gotten more comfortable with saying my own name.
  23. Surma:I don't know why.
  24. Surma:It's a thing that I never liked doing, you know, giving presentations at conferences.
  25. Jake:No, I agree with you! No, I feel like there's a lot of talks I see, you know, they start
  26. Surma:And at some point it just stopped.
  27. Surma:I was kind of like, I'm gonna put my name on the slide.
  28. Surma:At the time when Twitter was still cool,
  29. Surma:I put my Twitter handle on the slide and just never said my own name
  30. Surma:because I felt weird about it.
  31. Jake:with the person, like, you know, telling me why they're an expert in the topic they're
  32. Jake:about to talk about. And it's kind of, well, cool. And I guess, like, especially maybe
  33. Jake:if you're early in your career, you want to kind of tell people your name and to remember,
  34. Jake:but a lot of the time when people are sort of telling you how smart they are, or how
  35. Jake:qualified they are, and it's like, I'll be the judge of that. It sets me against them
  36. Surma:Yeah, maybe we're just being privileged white people.
  37. Jake:instantly, you know? It's like, right, well, we'll see if your content lives up to that
  38. Jake:intro of yourself. So, same as you, I just kind of go, hi, it's me. Anyway, here's some
  39. Jake:stuff, like it or don't, you know? Oh, definitely. Oh, tell me more.
  40. Surma:I'm not sure, but while things are a podcast, I can put my name on a slide.
  41. Surma:Well, I guess my name is kind on the subtitle of the podcast itself.
  42. Surma:I don't know, man.
  43. Surma:Let's just move on from the awkward.
  44. Surma:Although that reminds me, I did have an I feel old experience just a couple of days ago.
  45. Surma:I was just like, so I live in Bristol, student-y city, lots of students around,
  46. Surma:which means lots of people around who are significantly younger than me
  47. Surma:or rather they stay the same age.
  48. Surma:I just keep getting older and it just makes me aware of how things have evolved.
  49. Surma:And a couple days ago, it was, I think it was a Friday night in the evening,
  50. Surma:you know, people going to the pub from the pub.
  51. Surma:And there were these two guys and a girl and the guy was like,
  52. Surma:dude, look at this fresh tarmac.
  53. Surma:And he was correct because our street had been previously freshly tar-macked.
  54. Jake:Yeah, okay. I don't know why it made you feel old. I like, I am happy that the youth
  55. Surma:And the girl responds with, that's lit.
  56. Surma:And the second guy says, man, that is really fresh tarmac.
  57. Surma:And that conversation has stayed with me for a couple of days now.
  58. Jake:of today gets excited by road surfaces. Like, in today's society, where we have so many
  59. Jake:potholes, I'm glad that proper council work is being appreciated by the youth. Well, see,
  60. Surma:Yeah.
  61. Surma:But also just, I thought, have we gone full circle on lit?
  62. Jake:that's the thing. I was expecting you to say that the guy replied, oh, lit. Wow. What decade
  63. Jake:are you from? You know? Because I feel like, yeah, I think lit has been and gone. Like,
  64. Jake:the phrase, not the, maybe it's, oh, it's retro. Oh. Do you know what? And their tagline
  65. Surma:Or maybe it's back now.
  66. Surma:It's going full circle.
  67. Surma:Maybe, I don't know, I'm not the authority,
  68. Surma:but maybe this is then the moment for lit HTML to make a comeback
  69. Surma:and people going like, oh my God, it's so lit.
  70. Jake:would be, lit HTML, it's fresh tarmac. Because that could be a new, are you sure they were
  71. Jake:actually talking about fresh tarmac? Are you sure it's not just a new? That's such fresh
  72. Surma:Or maybe just talking about weed and that's the new word for it.
  73. Jake:tarmac, man. That's such fresh tarmac. Shall we talk about the web?
  74. Surma:That's lit.
  75. Surma:Yes, you just lit it.
  76. Surma:That's why it's lit.
  77. Jake:Ooh, a drama edition. Excellent. Again, put that in the title. That's good. Right. Okay. I'm ready
  78. Surma:Probably better.
  79. Surma:I thought it is my turn to do the TC39 Roundup Drama Edition.
  80. Jake:for drama. Do you know what? That's, that's really, I don't know what you've been talking
  81. Surma:I want to talk about two proposals specifically.
  82. Surma:And choosing these two proposals because I'm interested in them.
  83. Surma:There's your reason.
  84. Surma:Deal with it.
  85. Jake:about in previous episodes, but I find that's a really good way to run a presentation or a podcast.
  86. Surma:It's mostly that there's more proposals, I think,
  87. Surma:that have evolved or been started since you did the last roundup.
  88. Surma:And here's my reason why none of them are included except these two.
  89. Jake:That's fine.
  90. Surma:It's because I'm interested in them.
  91. Surma:Yeah, one of them I'm interested in because it is about multi-threading and shared data.
  92. Surma:It's called Shared Strux.
  93. Surma:And the other one I'm interested in because that is the one that sparked some drama
  94. Surma:and we love some popcorn-y drama.
  95. Surma:And that is the JS0 slash JS Sugar quote-unquote proposal.
  96. Surma:I'm not sure if it's actually officially a proposal yet,
  97. Jake:Yeah. Yes. And I like, when that whole drama happened, I think you said at the time, oh,
  98. Surma:but it was talked about at TC39.
  99. Surma:So I want to dive into those and see what you think
  100. Surma:because I think you may also have opinions.
  101. Jake:I'd love to do an episode on that. So I kept myself mostly like, not reading up about it.
  102. Jake:I mean, obviously, some of it, you just can't avoid. But I'm kind of like, I'm fresh tarmac.
  103. Jake:So, yeah, I'm ready for the data and my reaction will be genuine and roughly like.
  104. Surma:So then let's start with where I'm sure that it is in fact an official proposal.
  105. Surma:Both of these are actually by Shu, a former colleague of ours
  106. Surma:who is one of the three JavaScript spec editors and works at Chrome at Google.
  107. Surma:And I worked with him at the time quite a bit
  108. Surma:because he was basically my ally in crime in bringing multi-threading to JavaScript,
  109. Surma:which was one of my passion things to work on.
  110. Surma:And so he's been kind of working in that realm for a long time
  111. Surma:and specifically has been working towards this Shared Strux proposal
  112. Surma:for, I want to say, the last three or four years.
  113. Surma:He was already working on it before we both moved away from Google.
  114. Surma:So it's been a long, long time.
  115. Surma:And that kind of says a bit about how much underlying complexity is to something
  116. Jake:Multi-threading in JavaScript is a long and rocky road. Like I remember even like 10,
  117. Surma:that actually at the surface doesn't look like that big of a deal.
  118. Jake:maybe even 15 years ago, like Intel looked at it for, you know, doing things like array mapping,
  119. Jake:multi-threaded, and it just sort of didn't work essentially due to
  120. Jake:how JavaScript works with like variable scoping and that sort of thing.
  121. Surma:Yes. Let me try and give you the high-level summary of what this does.
  122. Jake:We got shared array buffer, which is genuine, like memory access across workers,
  123. Jake:which is the thread primitive, I suppose. But yes, like this is a new bit. This is something,
  124. Jake:a new bit. It's more structured, right? It's more structured than just an array of bytes.
  125. Surma:And actually, there's a couple of levels to it.
  126. Surma:And I think I'm not even going to dive into the last level
  127. Surma:because it's probably going to be more of a distraction than anything else.
  128. Surma:But the basic premise is this proposal introduces structs to JavaScript.
  129. Jake:So, yeah, I'm ready for the data and my reaction will be genuine and roughly like 10,
  130. Jake:maybe even 15 years ago, like Intel looked at it for, you know, doing things like array mapping,
  131. Surma:It's a new keyword, struct, like class, literally interchangeable.
  132. Jake:multi-threaded, and it just sort of didn't work essentially due to how JavaScript works with like
  133. Jake:variable scoping and that sort of thing. But yes, like this is a new bit. This is something,
  134. Surma:The difference is that a struct has a fixed layout.
  135. Surma:So you have to define all the properties.
  136. Jake:a new bit. It's more structured, right? It's more structured than just an array of bytes.
  137. Surma:And not like with an object or a class in JavaScript,
  138. Surma:you can't just add new properties onto it.
  139. Jake:We got shared array buffer, which is genuine, like memory access across workers,
  140. Surma:It's all frozen. There is a fixed layout.
  141. Jake:which is the thread primitive, and it just sort of didn't work essentially due to how JavaScript works.
  142. Surma:And that is mostly because for shared memory,
  143. Jake:So, yeah, I'm ready for the data and my reaction will be genuine and roughly like 10,
  144. Surma:you need to know where these certain properties are stored in memory
  145. Jake:maybe even 15 years ago, like Intel looked at it for, you know, doing things like array mapping,
  146. Surma:to allow it to have efficient access.
  147. Surma:And actually, I think that's kind of interesting
  148. Jake:multi-threaded, and it just sort of didn't work essentially due to how JavaScript works with like
  149. Surma:because I'm assuming there's also performance benefits to just local code,
  150. Jake:variable scoping and that sort of thing. But yes, like this is a new bit. This is something,
  151. Surma:like normal JavaScript code, I think, might get to an optimized version faster
  152. Jake:a new bit. It's more structured, right? It's more structured than just an array of bytes.
  153. Jake:So, yeah, I'm ready for the data and my reaction will be genuine and roughly like 10,
  154. Surma:if you use structs rather than classes or objects.
  155. Jake:maybe even 15 years ago, like Intel looked at it for, you know, doing things like array mapping,
  156. Surma:That's a hunch. I don't know.
  157. Surma:But I could assume or I could see how having a fixed layout for an object
  158. Jake:multi-threaded, and it just sort of didn't work essentially due to how JavaScript works with,
  159. Surma:allows the JIT compiler to more earlier actually output optimized machine code
  160. Jake:you know, variable scoping and that sort of thing.
  161. Surma:because it doesn't need to observe to detect the shape of an object.
  162. Surma:In this case, it would already know.
  163. Surma:And actually, most of the time, I think, when we use objects or classes,
  164. Surma:they are de facto fixed shape.
  165. Surma:It's where we go off the rails,
  166. Surma:especially since TypeScript and add random things onto it, right?
  167. Surma:Most of the time, you kind of know which properties will exist
  168. Surma:and even what kind of type they will have.
  169. Jake:So can I ask a dumb question?
  170. Surma:Strings are special.
  171. Jake:Like, so the idea of having a...
  172. Jake:because you're more experienced with lower level programming languages than me.
  173. Jake:So having a fixed bit of memory for an object,
  174. Jake:how does that work for things like, you know,
  175. Jake:if a property is a string, you don't know how long that string is.
  176. Jake:So how are you reserving a fixed bit of memory for that object?
  177. Jake:Or does it just point off for those things?
  178. Surma:So I should say that the thing we're going to introduce next in this proposal
  179. Surma:are shared structs.
  180. Surma:So structs themselves are not shareable, multithreaded yet.
  181. Surma:So they only introduce the fixed layout.
  182. Surma:And so the properties on structs can hold any value
  183. Surma:because it's like, for example, a string is not embedded into the struct.
  184. Surma:It's a pointer to a string somewhere else in memory.
  185. Surma:But let's hold on to that question
  186. Surma:because we have to address it once we are in shared struct land.
  187. Jake:So you're saying like a struct, I can have a property,
  188. Jake:which points to like an HTML element, which I know is not shareable.
  189. Surma:Yes.
  190. Jake:But you're saying like a normal struct is fine.
  191. Jake:And then the shareable thing comes across,
  192. Surma:Right.
  193. Jake:which is like your difference between an array and a shared array buffer, right?
  194. Jake:Like that kind of thing.
  195. Surma:Kinda, yeah.
  196. Surma:So structs have a couple limitations
  197. Surma:and shared structs have all those and some more.
  198. Jake:Right.
  199. Surma:And so let's untangle it a bit.
  200. Surma:So for example, a struct, you can still extend.
  201. Jake:Okay.
  202. Surma:Like, you know, you can say class A extends B.
  203. Surma:You can do the same with structs, but you can only extend other structs.
  204. Surma:So you can't say struct A extends B when B is a class or an object,
  205. Surma:which with class or any other thing you can do.
  206. Jake:That makes sense.
  207. Jake:So can they...
  208. Jake:So do they have constructors?
  209. Jake:And do they have like prototype level getters, setters, methods, those things?
  210. Surma:So they have prototypes.
  211. Jake:Or is it just fields?
  212. Surma:They have constructors they can call super.
  213. Jake:Oh.
  214. Surma:And it's rarely observable, but one of the interesting constraints about structs
  215. Surma:is that their methods are not generic,
  216. Surma:meaning it is basically guaranteed that this inside any struct method
  217. Surma:must be an instance of the struct that it's defined in.
  218. Surma:And so, for example, one thing that doesn't work in structs,
  219. Surma:that does work in classes is called return override.
  220. Surma:So you can actually return an object from a constructor
  221. Jake:That's a super weird bit of JavaScript though, like, it's, yeah, it's super janky that that
  222. Surma:and that becomes the class rather than working on this object
  223. Surma:that doesn't work in...
  224. Surma:Yeah.
  225. Jake:even works.
  226. Surma:I guess it must be like, you know, classes were, I guess,
  227. Jake:And I'm surprised they kept that functionality for classes, rather than leaving it in old
  228. Jake:constructor space.
  229. Surma:introduced as syntactic sugar over prototypical inheritance.
  230. Jake:Did they?
  231. Surma:It's kind of like, it's the same thing.
  232. Surma:And because people understood or had learned,
  233. Surma:had Stockholm syndrome with prototypical inheritance.
  234. Surma:And so I think it makes sense with structs to actually shed that a little bit.
  235. Surma:I assume getters and setters are a thing.
  236. Jake:I think so.
  237. Surma:I don't see why they wouldn't, but I actually do not know for sure.
  238. Jake:If methods on a prototype are there, then it seems like, I mean, that's all getters
  239. Jake:and setters are kind of, I mean, sort of, but yes, they exist on the prototype.
  240. Jake:So the fact that the prototype chain exists makes it sound like this, yeah, getters and
  241. Jake:setters would work.
  242. Jake:But yes.
  243. Jake:Okay.
  244. Surma:That's pretty much structs.
  245. Jake:We can look at that later.
  246. Surma:But now we get into shared structs,
  247. Surma:which are defined in like syntactically the same thing,
  248. Surma:just they have a shared keyword.
  249. Surma:So instead of struct A, you say shared struct A.
  250. Jake:Is this a silly question?
  251. Jake:Well, not a silly question, but a pointless question.
  252. Jake:Is it shared struct all one word, or is it shared and struct?
  253. Surma:It's two words, two words.
  254. Jake:So shared might be used on other things later on.
  255. Surma:Maybe, maybe.
  256. Jake:Okay.
  257. Surma:It's all the same, really, but as I said, with some additional restrictions.
  258. Jake:Excellent.
  259. Jake:Exciting.
  260. Jake:Okay.
  261. Surma:Same restriction as with structs.
  262. Surma:You can only extend other shared structs now.
  263. Surma:So you can't have a shared struct A that extends a struct B.
  264. Surma:Struct B also has to be a shared struct for extend to work.
  265. Surma:And now it gets interesting.
  266. Surma:The prototype has to be null.
  267. Surma:And shared structs cannot contain methods, at least not yet.
  268. Surma:They are talking about potentially finding a way that these methods can also be shared.
  269. Surma:But that's a bigger effort because, you know, you can't post message functions.
  270. Surma:So how would you go about that?
  271. Jake:So this is com link style stuff, right?
  272. Surma:And there may be ways.
  273. Surma:Right, but I think in this case,
  274. Surma:they would look into like how could they actually maybe send the bytecode
  275. Surma:or something over with the object or share it even.
  276. Surma:Like I think that they want to avoid.
  277. Surma:The whole point is that these shared structs can be sent to another realm without copying.
  278. Surma:Like they're actually shared.
  279. Jake:And with methods, you've got the whole scoping problem, right?
  280. Surma:Yes.
  281. Surma:Why did you say that?
  282. Surma:Because the result of scoping is already a bit of a problem technically in shared structs
  283. Surma:because, you know, it's JavaScript.
  284. Surma:Technically, you could close over all kinds of crap that's outside the struct
  285. Surma:and they actually have to limit that.
  286. Surma:So that's why some of the additional constraints you have in shared structs
  287. Surma:is that properties can only be primitive values or other shared structs.
  288. Surma:So it's your booleans, your floats, your strings or other shared structs.
  289. Jake:And I guess that's why the prototype has to be null, because otherwise it would get
  290. Jake:a prototype that goes down to object, which isn't a shared struct, and it breaks the whole
  291. Jake:system, so.
  292. Surma:Amongst other things, yes.
  293. Surma:So for that reason, because as you may have noticed,
  294. Jake:Hang on.
  295. Surma:array wasn't in this list because array is not a primitive.
  296. Surma:There is also a shared array which has a fixed length.
  297. Jake:So that's different to shared array buffer.
  298. Jake:There's a shared array.
  299. Surma:Yeah, which is basically the array counterpart to a shared struct.
  300. Jake:The risk of derailing this, where does this fit in with records, and I think they're called
  301. Surma:Yes, go for it.
  302. Jake:records.
  303. Surma:That's the immutable proposal thing, right?
  304. Jake:Yes.
  305. Jake:Yes.
  306. Jake:Okay.
  307. Jake:So these are mutable, I guess, is the difference.
  308. Surma:Yes, these are definitely mutable.
  309. Surma:I would assume that maybe if records land, we get shared records.
  310. Jake:They should be shared by default, right, because they're like, they're just what they
  311. Jake:are.
  312. Surma:Actually, that's a good point.
  313. Surma:I would hope that a record would...
  314. Surma:Well, maybe not by default because records, I don't think,
  315. Jake:Oh, I see.
  316. Surma:have the restriction of not being able to hold arrays or non-primitive values.
  317. Surma:So there is a bit of untangling to it.
  318. Surma:I don't know.
  319. Surma:I haven't looked at the records proposal.
  320. Surma:There is something there, I think, where maybe some synergy can happen.
  321. Jake:Okay.
  322. Jake:Cool.
  323. Surma:Yeah, so with that in place, those are a lot of constraints.
  324. Surma:Like it's definitely, you know, you can't just use your array.
  325. Surma:You can't just use your object.
  326. Surma:You always have to use shared arrays and shared structs and all of that.
  327. Surma:But what you gain is that these structs can be sent to other ROMs
  328. Surma:like a worker without a copy.
  329. Surma:In that sense, it's fast because you send a pointer over,
  330. Surma:but you can also work on the same object from both sides
  331. Surma:because it's actually shared memory.
  332. Jake:Oh.
  333. Surma:It's like a shared array buffer, but you have a shape on top of it.
  334. Jake:Tell me about the race conditions and how they are solved.
  335. Surma:That is the third layer that I'm probably not going to talk too much about
  336. Jake:Oh, what?
  337. Surma:because it's...
  338. Surma:Well, actually, we can talk about it.
  339. Surma:There's mutexes.
  340. Jake:Oh, okay.
  341. Jake:Well, there you go.
  342. Surma:So it's up to you.
  343. Surma:Actually, we should talk a little bit about mutexes
  344. Surma:because that was the minor...
  345. Surma:Actually, I found it a bit weird with the proposal
  346. Surma:that they introduced proposed special syntax
  347. Jake:Hmm.
  348. Surma:that you could only access shared structs
  349. Surma:when you put the code in an unsafe block.
  350. Surma:Like literally a block that has the word unsafe in front of it, like Rust.
  351. Surma:And literally the proposal said, this does nothing.
  352. Surma:Like this is just to tell the developer
  353. Surma:that there is unsafe stuff happening here.
  354. Surma:And I found that really weird.
  355. Jake:It's a comment.
  356. Surma:It is basically... That's what I thought as well.
  357. Jake:What?
  358. Surma:The inside scoop is, that's going away.
  359. Jake:Okay.
  360. Jake:That's sensible.
  361. Surma:That was basically something that came out of discussions
  362. Surma:ahead of actually making the proposal at TC39
  363. Surma:when they were circulating it with other people.
  364. Surma:And apparently there was at least one person
  365. Surma:really strongly thinking that unsafe should be there.
  366. Surma:But most people at the official TC39 review were like,
  367. Surma:this is weird, this should not be happening.
  368. Jake:If it did something, then fair enough, but if it doesn't do anything.
  369. Surma:It does not.
  370. Surma:And also I guess it's worth saying, just like shared array buffer,
  371. Surma:shared structs will on the web only be available
  372. Surma:when you have your co-op and co-app headers set
  373. Surma:for the exact same reason, because it's shared memory.
  374. Surma:And I really... This co-op co-op shenanigans
  375. Surma:is getting on my nerves, but here we are.
  376. Surma:It's here to stay, I suppose.
  377. Jake:Yeah.
  378. Surma:Yes, exactly.
  379. Jake:Thank you, Meltdown Inspector.
  380. Surma:So if you look at the explainer, at least at the time of recording,
  381. Surma:you can still find the unsafe keyword
  382. Surma:and you will also find a restriction that talks about
  383. Surma:that shared structs cannot have private fields,
  384. Surma:which I found very weird.
  385. Jake:Yeah, there is a lot of JavaScript weirdness around, like, when private fields are in scope.
  386. Jake:That happens more often than I think.
  387. Surma:That's what I wanted to talk about.
  388. Surma:Right, so welcome back to OTMT.
  389. Surma:We just took a small little research break
  390. Surma:because something didn't quite add up.
  391. Surma:And I think I figured out what I was getting wrong.
  392. Surma:And I'm going to explain this now.
  393. Surma:And if I get it wrong, we'll just put something in the notes.
  394. Surma:So we said shared structs cannot have methods.
  395. Jake:Yeah.
  396. Jake:
  397. Surma:Specifically, the explainer says
  398. Surma:shared structs cannot have instance methods,
  399. Surma:which makes me think that they can have static methods.
  400. Surma:So that would mean that, for example, a static method
  401. Surma:would be something like shared struct name.method
  402. Surma:and you could pass in your instance
  403. Surma:because the prototype of the actual instance is null,
  404. Surma:so there cannot be any methods on it.
  405. Surma:But this way, you would be able to operate method-like
  406. Jake:I'm assuming, and tell me if I'm wrong, the way of making this all work multithread is
  407. Surma:on a shared struct.
  408. Surma:I don't even think you would transfer.
  409. Jake:still workers, right?
  410. Jake:Like, you were taking your struct and you were doing a transfer into a worker?
  411. Surma:I think you literally just...
  412. Surma:The structured clone implementation...
  413. Surma:It's like shared array buff, right?
  414. Jake:It's transfer by default, right?
  415. Surma:Yeah.
  416. Jake:Yeah, okay.
  417. Jake:So then, on the other side, you've now got this object.
  418. Surma:Yeah.
  419. Jake:So with shared array buffer, the constructor of the object you get back is the shared array
  420. Jake:buffer in your worker.
  421. Surma:Yeah.
  422. Jake:So how does it work with structs then?
  423. Jake:Because the worker wouldn't have had that, or might not have had that struct type defined.
  424. Surma:But it doesn't need to.
  425. Surma:The struct itself is just a struct with primitives in it.
  426. Surma:So it's then up to your code
  427. Surma:to then import the shared struct definition
  428. Surma:and use static methods to operate on it.
  429. Jake:Right, okay.
  430. Surma:That's how they untangle that problem
  431. Jake:Right.
  432. Jake:
  433. Surma:because the prototype has to be null, right?
  434. Surma:And this is now where the other constraint comes in.
  435. Surma:Actually, this is where I was saying,
  436. Surma:if you look at the explainer at the time of recording,
  437. Surma:it still mentions those unsafe blocks
  438. Surma:and it also mentions that shared structs
  439. Surma:are not allowed to have private fields,
  440. Surma:which I found a bit weird
  441. Surma:because I like having a private field every now and then.
  442. Surma:I mean, I kind of thought like,
  443. Jake:Sure.
  444. Surma:okay, if I don't have them, I'm just going to go back
  445. Surma:to making them start with an underscore
  446. Surma:to kind of like signal this is private,
  447. Jake:Okay, that makes sense.
  448. Surma:which, you know, that was a joke for the longest time.
  449. Surma:But they're actually removing unsafe blocks
  450. Surma:and they're also going to probably remove this constraint
  451. Surma:in that you are allowed to have private fields.
  452. Surma:The reason why private fields were forbidden in the first place
  453. Surma:is kind of interesting
  454. Surma:because private fields in JavaScript are really weird.
  455. Jake:Mm-hmm.
  456. Surma:I guess the weirdness mostly comes from
  457. Surma:that the privacy comes from lexical scoping.
  458. Jake:Yes.
  459. Surma:It's not about like in Java
  460. Surma:where you put the private word in front of it or something.
  461. Surma:It is basically you can only access this private field
  462. Surma:if it is in your lexical scope.
  463. Surma:So methods that are nested inside the class definition
  464. Surma:or the struct definition can access it.
  465. Surma:If you have like a lambda passed in or something
  466. Jake:And am I right that if I've got a method on my class which takes three instances of that
  467. Surma:and that passes into this object or something,
  468. Surma:that would not work because lexicographically
  469. Surma:that function would not have access.
  470. Jake:class, can I access the private fields of all of them?
  471. Surma:Yes, I think so.
  472. Jake:Should we do some live?
  473. Surma:Yeah, do it. Come on.
  474. Jake:Right, okay, here we go.
  475. Jake:Right.
  476. Jake:I mean, this goes to show how, like, the way this stuff works in JS is slightly.
  477. Jake:So priv equals hello, right?
  478. Jake:This is it.
  479. Jake:And then method, method, okay.
  480. Jake:And it takes an array of foos.
  481. Jake:So my class is called foo.
  482. Jake:It's taking an array of foos.
  483. Jake:And so I'm going to console.log, and I'm going to go foos.map, and I'm going to log out fpriv.
  484. Surma:Well, then it's got to be right.
  485. Jake:Well, TypeScript hasn't complained about it.
  486. Jake:So let's do new foo.
  487. Jake:And so I've got foo1, and I'm going to do foo2.
  488. Jake:This is great radio.
  489. Jake:And then so on foo1, I'm going to call method.
  490. Jake:This is so dumb.
  491. Jake:And then foo2 and foo1.
  492. Surma:And da-da-da-da.
  493. Jake:Why not?
  494. Jake:So let's see if both of these work.
  495. Jake:Right, right, right.
  496. Jake:I'm going to run this.
  497. Jake:Yeah, it works.
  498. Jake:Yeah, yeah, yeah.
  499. Jake:Okay.
  500. Surma:So here's where the weirder thing,
  501. Surma:which is the actual problem that they were thinking about.
  502. Surma:If you have a class, like your class,
  503. Surma:and you declare a nested class,
  504. Surma:instances of that nested class
  505. Surma:can access the private field of the class
  506. Surma:they are nested within.
  507. Jake:Yes.
  508. Jake:Yes, they can because it's lexically scoped.
  509. Surma:Lexical scoping.
  510. Jake:That's fun.
  511. Surma:And that is the reason why originally
  512. Surma:they forbade this in shared structs
  513. Surma:because it would mean that
  514. Surma:now certain layout information would have to be known
  515. Surma:in inner shared structs and outer shared structs
  516. Surma:and that just makes threading all kinds of wacky.
  517. Surma:And so they just said,
  518. Jake:Hmm.
  519. Surma:not just private fields, another thing.
  520. Surma:So now instead, they're going a bit more granular
  521. Surma:and saying like, no, you can have your private fields,
  522. Surma:but your shared structs must be declared at top level.
  523. Surma:So you cannot have that nesting scenario.
  524. Jake:Right.
  525. Jake:Okay, that makes sense.
  526. Surma:The main reasons why all of these things with inheritance,
  527. Jake:Oh, yes.
  528. Surma:like the extent keyword and this nest thing,
  529. Surma:why these things are problematic
  530. Surma:has to do with garbage collection most of the time.
  531. Surma:Maybe you have your main thread and your worker
  532. Surma:and because they are their own realms,
  533. Surma:they have their own GC running.
  534. Surma:And so that GC has to know
  535. Surma:which of these objects can be deleted,
  536. Surma:garbage collected, and which ones are not.
  537. Surma:That's how garbage collection works.
  538. Surma:But now you have basically a third magic realm
  539. Jake:Interesting.
  540. Surma:and that's the shared realm where all the shared stuff goes.
  541. Surma:And that one probably has its own GC as well.
  542. Surma:That's at least how I would like to think about it.
  543. Jake:If you're sharing something between a page and a worker, and it's out of reference in both of those,
  544. Jake:then you would hope that the shared reference has gone, right?
  545. Jake:That's what you're saying.
  546. Surma:Yes, but if there's one reference in at least one of them,
  547. Surma:it should stay alive, obviously.
  548. Jake:Yeah.
  549. Surma:And so basically the changes to the engine
  550. Surma:are quite significant here, I assume.
  551. Surma:And that's actually one of the things that Shu worked on
  552. Surma:for the longest because strings are primitives and are pooled.
  553. Jake:Hmm.
  554. Surma:That's why string equality is decently fast in JavaScript
  555. Surma:because same strings are pointing to the same thing under the hood.
  556. Surma:But now suddenly strings are primitive
  557. Surma:and need to be shared across realms.
  558. Surma:And now you have basically GC stuff that is weird.
  559. Jake:Hmm.
  560. Surma:Anyway, the changes have to be made
  561. Surma:to the garbage collector in the engine here
  562. Surma:is that a local realm, I'm going to call it a local realm,
  563. Surma:like a non-shared realm,
  564. Surma:can hold references to something in the shared realm.
  565. Surma:So the garbage collector in the shared realm
  566. Surma:needs to be aware if any other realm
  567. Surma:has a reference to one of the shared things it is looking after.
  568. Surma:But if you were to allow a shared object
  569. Surma:to now hold references back to something local,
  570. Surma:you get into weird cyclical territory
  571. Jake:Hmm.
  572. Surma:which was already hard to solve in just a local confined space.
  573. Surma:So now with a cross threads,
  574. Surma:that becomes basically impossible or really hard or really expensive.
  575. Surma:So that's why they need to be really careful
  576. Surma:that once you go shared, you stay in the shared space
  577. Surma:and there's no way for you to go back with references
  578. Surma:toward any of the other realms.
  579. Surma:So that's why shared structs can only extend
  580. Surma:from other shared structs and so on and so forth.
  581. Surma:And for example, one of the implications is,
  582. Jake:Okay.
  583. Surma:which apparently makes some people a bit sad,
  584. Surma:you cannot use a shared struct as the key in a weak map
  585. Surma:because that would make the liveliness of a local value
  586. Surma:dependent on the liveliness of a shared struct.
  587. Surma:And that is exactly one of those instances
  588. Surma:where now you're going from shared back to local and that's bad.
  589. Surma:So that's like a very niche implication,
  590. Jake:Oh.
  591. Surma:but apparently people care about that.
  592. Jake:Yeah, I guess.
  593. Jake:Because you could feel that something had gone out of reference in your realm,
  594. Surma:That's kind of the shared structs proposal condensed down with,
  595. Jake:but it could be sent to you again later on.
  596. Jake:Right, okay.
  597. Jake:Yeah, I get it.
  598. Jake:That's hard.
  599. Surma:you know, there's like a new mutex introduced in there,
  600. Surma:which allows you to make sure that not two realms
  601. Surma:are writing to the same property at the same time.
  602. Surma:It's behind the flag in Chrome.
  603. Jake:Hmm.
  604. Surma:There's still a bit more work to do.
  605. Surma:And I was told maybe mid 2025, we'll see it launched.
  606. Surma:Who knows?
  607. Jake:It's really exciting because I've seen people write a lot of code to basically do something like this,
  608. Jake:but backed by shared array buffer.
  609. Surma:Oh yeah, I have a library for that.
  610. Surma:Literally, you declare your struct ahead of time,
  611. Surma:what fields are in there, what size they are.
  612. Surma:And then I like marshal them in and out of a shared array buffer.
  613. Surma:And it's a lot of work and it's really hard to get right.
  614. Surma:And you don't have mutexes, right?
  615. Surma:That is something that I guess you can build it yourself.
  616. Jake:You've got Atomics, right?
  617. Jake:You could build it on top of Atomics, but not easy.
  618. Surma:Yeah, true.
  619. Surma:It's not what usually frontend engineering entails.
  620. Surma:So this was the first of the two proposals.
  621. Surma:And considering we've been chatting for like 40 minutes, I think,
  622. Surma:and the next one is the controversial one.
  623. Surma:I think we're going to do a pause here.
  624. Surma:We're going to call this one a day.
  625. Surma:We're going to make this the TC39 shared structs proposal episode.
  626. Jake:Well, the great thing is I don't have to wait weeks because we're just going to record these in a row.
  627. Jake:Everyone else is going to have to wait weeks, so it sucks to be them.
  628. Surma:Exactly, yeah.
  629. Jake:What a cliffhanger.
  630. Jake:Oh, well done.
  631. Jake:Well done, you.
  632. Surma:Unplanned, we're so good at this.
  633. Surma:I guess without wasting any more time of people.
  634. Jake:Maybe go feed Watson.
  635. Jake:I hear him barking in the background.
  636. Surma:Woof, woof.
  637. Jake:There's nothing else to say except woof, woof.
  638. Surma:Happy next time.
  639. Jake:Happy next time.
  640. Jake:Bye.
  641. Jake:We've got an opportunity here to cut and do two episodes.
  642. Surma:I was just thinking that because this is 40 minutes.
  643. Jake:So there's a couple of things we could do here.
  644. Jake:We could do the outro now and then record a new intro.
  645. Surma:Do we leave the original intro?
  646. Surma:Because I'm obviously saying I'm going to talk about two things
  647. Surma:and now we're kind of like going lol, psych.
  648. Surma:But I think that's fine.
  649. Jake:Up to you, yeah?
  650. Surma:Yeah, let's troll them.
  651. Jake:Yeah?
  652. Jake:You want to do that?
  653. Jake:Okay.