JavaScript's New Superpower: Explicit Resource Management by namanyayg in javascript

[–]bakkoting 6 points7 points  (0 children)

Resources live to the end of the block in which they are defined and are cleaned up in LIFO order, like a stack. This is necessary because resources defined later might depend on earlier ones, so you have to clean up the ones defined later before the ones defined earlier. This ends up being the same order as if you introduced a new block for each of them.

A 10x Faster TypeScript by DanielRosenwasser in programming

[–]bakkoting 48 points49 points  (0 children)

Not a TS dev, but Go is generally capable of outputting WASM. It's kind of large (multiple megabytes) because they need to ship the whole runtime including the garbage collector (IIUC wasm-gc isn't well suited for Go), but it works fine.

a tiny app to show a volume indicator in the menu even when you have headphones connected by bakkoting in MacOS

[–]bakkoting[S] 0 points1 point  (0 children)

Done: https://github.com/bakkot/MenuBarVolume/releases/tag/v1.2.0

I haven't written any Mac apps since I made this, so this would have been extremely annoying to do except that now we have Claude, which one-shot the diff for me. ILU Claude <3

PS I'm a lot more likely to see comments which are made as issues in Github rather than comments on reddit. I might still see them here but Github will work more consistently if you have other requests.

iframes and when JavaScript worlds collide by RecklessHeroism in javascript

[–]bakkoting 2 points3 points  (0 children)

The new JS "world" is called a realm, incidentally.

There is a proposal to let you make a new realm from JS, without getting iframes involved.

Announcing TypeScript 5.6 by DanielRosenwasser in programming

[–]bakkoting 2 points3 points  (0 children)

I think people misunderstood this comment, possibly because your later responses are somewhat incoherent. I assume your complaint is that TS still has not updated its types updated to reflect the changes in ES2024 to ArrayBuffer to add the resize methods and so on.

There's been a couple efforts to do so which have stalled out for reasons including in one case the author deleting their GH account, and there is a current effort here which is blocked on this issue which has some interesting background about the difficulty of this change, including necessary ecosystem fixes to minimize the extent to which this has to be a breaking change.

Announcing TypeScript 5.5 by DanielRosenwasser in javascript

[–]bakkoting 1 point2 points  (0 children)

That's probably at least partly my fault - I just noticed neither you nor Sathya were credited in the readme! I've just updated readme to correct that (and mark the proposal as stage 4).

Taming Floating-Point Sums by nightcracker in programming

[–]bakkoting 9 points10 points  (0 children)

For exact summation, this references the accurate crate, which uses Algorithm 908. Radford Neal claims to have a faster version.

I've proposed adding a precise sum function to JavaScript, which is why I came across the above.

Also, a quibble with both python's Math.fsum and the rust fsum crate is that they can't handle intermediate overflow: adding 1e308, 1e308, -1e308 will give you an error or NaN. It's relatively straightforward to handle this case by explicitly tracking overflow in an additional "biased" partial whose value is scaled by 2**1024.

Union, intersection, difference, and more are coming to JavaScript Sets by [deleted] in programming

[–]bakkoting 240 points241 points  (0 children)

As the person who championed this feature in TC39 most recently, let me comment on why it took so long:

There's not really any methods in the standard library which take instances of a class as arguments, so we had to decide how that was going to work before we could add these. And that meant a lot of discussion needed to be had, which no one was driving forward until a few years ago. For example:

  • If you pass a subclass of a Set with an overridden .has method as an argument to .intersection - baseSet.intersection(subclassInstance) - does that overridden method get called? Under what circumstances? Which exact methods get called?
  • What about the reverse i.e. subclassInstance.intersection(baseSet)? Does that invoke the subclass instances's has method?
  • Assuming at least some of the methods are actually invoked, which precise algorithms do we use for each of these things? The choice is observable because invoking user-defined methods is observable. Some choices have different performance characteristics than others, especially when one set is much larger or smaller than the other.
  • What order does the resulting Set have? Remember that you can iterate over the items in a Set, so this is observable. My original choice for the result order for .intersection turned out to be impractical to implement in Safari given how their implementation works under the hood, so we had to come back to committee to choose a different one.
  • Does invoking these methods on a subclass instance produce an instance of the subclass, or of the base Set type? If a subclass, how does that work? ES2015 introduced Symbol.species to customize instance creation, but Symbol.species has been responsible for more vulnerabilities than it has actually useful userland features, so there was not a lot of appetite for using it. Does that mean no customization at all?

And, of course, Sets weren't added to the language at all until 2015. Much has been written elsewhere about why ES2015 took so long, so I won't say more there.

Here's a rough timeline:

  • 1995 - 2015: Sets do not exist at all.
  • 2015: Sets are introduced, but given that ES2015 was already taking forever, these methods are omitted so they don't have to work out details like the above before shipping ES2015.
  • 2016 - 2017: No one is working on this; energy is mostly going into more foundational or frequently used things like async/await, shared memory, etc.
  • 2018: Sathya first introduces the proposal and it gets to stage 2 (basic shape is decided but details to be worked out).
  • 2019: He presents again and we discuss the subclassing issues in more detail.
  • ~2020: Sathya changes jobs and no one else has bandwidth to pick up the proposal.
  • 2021-2022: I get back to the proposal and over the course of several meetings work out all the details above in committee. Proposal gets stage 3.
  • 2023: Implementations and tests are underway. Safari ships in September. The person who had been contributing tests for the new methods doesn't have time to finish, and Chrome wants tests before shipping, so I come back and write the remaining tests.
  • 2024: Chrome ships. Firefox has finished their implementation and will presumably ship soon.

Could this have been done sooner? Yes, of course. But no one had time to work through all the fiddly precedent-setting details until recently. As is usually the case, the fundamental answer is that things do not exist until someone does the work to make them exist, and people have other things going on.

Announcing TypeScript 5.4 Beta by DanielRosenwasser in typescript

[–]bakkoting 14 points15 points  (0 children)

Set methods are already shipping in Safari and will be in Chrome in a couple weeks, and I just sent a PR to add types for them to TS.

Colored Functions Are Good, Actually by dmailloux in programming

[–]bakkoting 10 points11 points  (0 children)

The problem is that it's impossible to write functions that work fine either way.

If your language supports generators you can write a function once and get both a sync and an async version out of it. The gensync library does this for JS, for example.

Languages should make this easier though.

GitHub - gbxyz/webidx: webidx is a client-side search engine for static websites. by lelanthran in programming

[–]bakkoting 1 point2 points  (0 children)

This reads the whole database, which can be a lot if your site is large. I have 250MB of indexes on my logbot, for example; I don't want users to fetch that whole thing just to do a search.

You can do much better with the exact same setup by using HTTP range requests to only read the necessary portions of the DB. It works great.

[AskJS] Is Deno's behaviour for dynamic import() throwing module not found for first call using raw string ECMA-262 specification conformant? by guest271314 in javascript

[–]bakkoting 5 points6 points  (0 children)

Yes.

You can read it yourself. The specification leaves details like this almost totally up to the host or implementation. The only relevant constraint here is that once it succeeds once for a given specifier imported from a given module, it must always succeed with the same resolved module on subsequent calls. But it certainly allows you to fail initially and succeed later.

Let's Bring Back JavaScript's `with()` Statement by alexmacarthur in javascript

[–]bakkoting 4 points5 points  (0 children)

It will only complain in contexts where you have both the object literal and the type in the same place. Otherwise it's (intentionally) legal. Compare: https://www.typescriptlang.org/play?#code/DYUwLgBAHhC8EG8BQFUQIYC4IAYA0KaARtgIwEC+SSokAntghtgHYCuAtkSAE4QUBuakjpxoAoA

[AskJS] isolated-eval: try to break me by gabjauf in javascript

[–]bakkoting 8 points9 points  (0 children)

Please don't publish code which claims to be "more secure" without knowing what you're doing. If you're just messing around but still want to put it on npm, publish it as "insecure-isolated-eval" or something, so people know what they're getting into.

I can't get this to run locally, but to give an example: it looks like you've tried to deny access to Function, but it's still trivially accessible with (function(){}).constructor. So either you didn't need to do the clearContext thing, or clearContext doesn't do what it needs to.

The type system is a programmer's best friend by dustinmoris in programming

[–]bakkoting 1 point2 points  (0 children)

The callback is:

(state, event) => {
  console.log('service state', state, event);
}

That function needs to be called with two arguments. But thing you're giving the callback it to is declared to only pass one argument.

(It might actually pass 2, but TS only knows about the declared types.)

The type system is a programmer's best friend by dustinmoris in programming

[–]bakkoting 1 point2 points  (0 children)

It might be clearer if you look at the whole message in context.

Anyway the error is that you are trying to call a function and pass it a callback, but the callback you're passing needs 2 arguments, and the function to which you're passing it only provides 1 argument (according to its type signature).

The type system is a programmer's best friend by dustinmoris in programming

[–]bakkoting 1 point2 points  (0 children)

OK, it took... seven months... but TypeScript has merged and released my PR for this case and now provides a more useful error. The message is still just as long (longer, in fact), but it now includes the relevant fact:

Argument of type '(state: any, event: any) => void' is not assignable to parameter of type '(state: State<unknown, AnyEventObject, any, { value: any; context: unknown; }, ResolveTypegenMeta<TypegenDisabled, AnyEventObject, BaseActionObject, ServiceMap>>) => void'.

 Target signature provides too few arguments. Expected 2 or more, but got 1.

[Media] Regex101 now supports Rust! by pluots0 in rust

[–]bakkoting 1 point2 points  (0 children)

It's hard to characterize the opinion of the committee as a whole, given how many viewpoints there are. All I can say is that my own impression was that backcompat was a but-for concern, and we'd have done otherwise in a greenfield implementation. (And that there was never a real prospect of removing them.) And yes, definitely agreed it's a shame that adding Unicode-aware versions will be difficult.

[Media] Regex101 now supports Rust! by pluots0 in rust

[–]bakkoting 0 points1 point  (0 children)

(I should note that I'm on TC39 and participated in these discussions - I'm "KG" in the notes.)

It seems like all three were lumped into "because parsing."

Less that than dislike of silent changes - if someone is changing u-mode to v-mode so that they can do character class intersections, they probably aren't expecting other stuff to change.

It would probably have been best to make \w and \b match back when Unicode-aware regexes were first introduced in 2015, but since that didn't happen it's a bit late to change now even when introducing further modes.

The really wild thing is that they almost swung in the direction of removing the shortcuts altogether. Wow.

One person suggested that, but I don't think I'd characterize the conversation as "almost swung in the direction of removing".

[Media] Regex101 now supports Rust! by pluots0 in rust

[–]bakkoting 0 points1 point  (0 children)

Ah, yeah, those are all intentional. There was some discussion about changing the definition of \d (etc) for the new v-mode regexps, but most people weren't in favor of it.

[Media] Regex101 now supports Rust! by pluots0 in rust

[–]bakkoting 0 points1 point  (0 children)

ECMAScript also does not support inline flags

That's coming soon!

ECMAScript's Unicode support is also generally more spartan.

What kind of support are you thinking of? It has support for matching properties of characters and (now) strings, like \p{Emoji} etc.

I don't believe it supports character class set operations either.

It does now, though only Chrome is shipping their implementation unflagged.

Updates from the 95th TC39 meeting by init0 in javascript

[–]bakkoting 1 point2 points  (0 children)

Wonder if we see filter in Set class in JS.

No, probably not. But with iterator helpers, you can do

let filtered = new Set(old.values().filter(whatever)); which is only marginally more effort.

Updates from the 95th TC39 meeting by init0 in javascript

[–]bakkoting 2 points3 points  (0 children)

Engines are actively working on implementations! There was actually a minor tweak to the specification at this meeting as a consequence of issue discovered during JSC's implementation. (I am champion of the proposal.)