Function.prototype.new

It's completely out of scope

It is? Is this request about improving how languages in general interop with JavaScript, or how python specifically interops with JavaScript?

So to unwind the proclamation of "this is how it must be":

  • Most programming languages lack a way to syntactically express the intent to construct vs the intent to invoke for the same function. This is a JS paradigm that doesn't exist in most other languages, and thus these other languages don't have syntactic support for expressing this different intent.
  • Some of these language may have a convention to describe if a function constructs a new object instance. Maybe that's capitalization for the function, maybe it's a function name which literally start with the prefix "New", maybe it's a ".new" method attached on the function, or maybe it's just in the static type system.

Given this, I don't understand the comparison to the new Class(...args) syntax of JavaScript since that cannot be the expected way to express things by programmers in these other languages.

I also fail to see why Class.new(...args) would be the natural way to express this for all the various programming languages that may interop with JS.

Some level of clunky has to be expected when doing interop between languages that don't have entirely matching concepts. IMO each language interop layer should define the best way to match the feature of each side with the other. JavaScript should not be prescribing to these interop layers that Class.new() is the way (if that is even expressible along Class() in that other language, as not all languages identify functions as object namespaces)

It doesn’t matter what the hosting PL supports, this issue is about JS bindings and JS supports namespaces and Class.new will be a JS proxy. Without Class.new there’s no way to intercept the proxy construct trap in a natural way and Class.new represents new Class in JS and there’s nothing to explain.

If the hosting PL supports new Class syntax the issue doesn’t exist, if it doesn’t the solution is to express that desire in JS via Class.new.

all we're trying to do is to ensure our users that they can swap runtimes when they feel like it's needed

I'm sorry, I still don't understand what it is, exactly, you're trying to support here.

  • If the use-case is "something wants to be able to parse and execute JS itself, provided as a string, in a different language runtime" then the syntax to construct new objects in that JS is new Foo(), same as in a normal JS runtime.
  • If the use-case is "something wants to write native code that interoperates with some JS, such that you can write code in MyLang and it gets mapped into JS invocations", then you can invent whatever you need for class construction. As was stated previously, every language has its own ideosyncratic way of indicating object construction; it's not clear why Foo.new() would be good, since the lang in question might construct objects in a different way than that anyway. And this mismatch isn't limited to object construction; many syntactic operations in JS might be expressed differently in the second language, or not have a syntactic expression at all and always have to be written in userland (and vice versa, for operations in the second lang that might not translate to JS clearnly).

Are you instead talking about a third, different use-case?

You've also indicated learnability, and I presume that comes from the second case, where someone using a second lang that's translating itself into JS calls might learn that Foo.new() is the way to construct objects in JS and be confused when they go to write actual JS. How is that different from literally everything that's different between the two languages, tho? If I'm writing Python I can write a list comprehension; you can probably auto-translate that to a flatMap() call in JS, but someone expecting to translate their code to JS naively would be surprised by it breaking. What makes new special here, such that it needs fixing?

1 Like

That’s why I’m proposing this and offer already a solution that works.

I’m not try to solve anything, we already have MicroPython and Pyodide code fully interchangeable and both support Class.new already.

If you read your argument though, if users of PytjonMonkey think you need to pm.new(pm.Class)(…args) to create an instance you will fail with JS and you’ll think JS is weird.

I’m trying to push for this to avoid bastardizing JS for new programmers / learners instead with a unified solution that’s easy to reason about and can already work everywhere with the poly, even in Node or bun or deno, not just via PLs bindings.

We write Class.new already, it’s been years, we'll try to align other PLs as they land as JS WASM interoperability every single time despite the outcome of this proposal.

Every other alternative is more future hostile for no reasons or benefits for our users.

So yes, it seems that the value you're arguing for here is that adding this to JS won't help JS devs per se; it'll help the ecosystem of related tools by encouraging them to handle this sort of thing in a particular way, which is more likely to be directly-translatable to arbitrary other langs than the current new Class syntax is.

New JS syntax that isn't for JS devs, and isn't even directly useful for any application, but rather just helps provide a consistency argument for the design of non-JS languages to rally around, is gonna be a hard sell.

1 Like

FWIW there was a (now inactive) proposal for %constructor%.construct(). It looks like the motivation was more for class<->function constructor imperopability. The inactive proposals rationale just says "Withdrawn". The open issues seem to suggest this could be replaced by callable constructors (which we don't have for classes?) or Proxy (which have issues with private members). Not sure if any of the arguments for it would apply today.

Edit: Looking closer at this proposal, I don't think its doing the same thing that is being proposed here with the new() method.

As mentioned, I’m ok with this never landing, because it secures current state of real-world affairs.