[Fwd: Fail-fast on non-existing [[Get]]]

# Herby Vojčík (13 years ago)

This did not get to the list, reposting...

# Yehuda Katz (13 years ago)

Yehuda Katz (ph) 718.877.1325

On Tue, Oct 16, 2012 at 12:51 PM, Herby Vojčík <herby at mailbox.sk> wrote:

This did not get to the list, reposting...

-------- Original Message -------- From: Herby Vojčík <herby at mailbox.sk> Subject: Fail-fast on non-existing [[Get]] Date: Fri, 12 Oct 2012 22:42:05 +0200 To: ECMAScript discussion <es-discuss at mozilla.org>

Hello!

I have just looked the video on channel9 between Lars Bak and Anders Hejlsberg, and it gave me one idea.

It seems people sometimes worry about (basically because of a typo) that they [[Get]] a non-existing property but as it stands, it just returns undefined and goes happily on.

I see two solutions:

  • add something to the freeze, seal, preventExtensions family which would set an object to the fail-fast [[Get]] state.
  • use a Proxy in the proto chain to trap the unknown [[Get]] and throw early

Using a proxy for your own objects to throw seems reasonable, but see below for breakage to existing JS patterns. Adding it globally (via Object.protoype.proto) would almost certainly break other JS code on the page.

Consider this very common pattern:

obj.foo = obj.foo || bar;

As a matter of practice, lots of JS code relies on the soft-fail behavior, for good reason, and trying to change that behavior would not likely result in happiness for consumers of the code that introduced this change.

# Herby Vojčík (13 years ago)

Yehuda Katz wrote:

Yehuda Katz (ph) 718.877.1325

On Tue, Oct 16, 2012 at 12:51 PM, Herby Vojčík <herby at mailbox.sk <mailto:herby at mailbox.sk>> wrote:

This did not get to the list, reposting...

-------- Original Message --------
From: Herby Vojčík <herby at mailbox.sk <mailto:herby at mailbox.sk>>
Subject: Fail-fast on non-existing [[Get]]
Date: Fri, 12 Oct 2012 22:42:05 +0200
To: ECMAScript discussion <es-discuss at mozilla.org
<mailto:es-discuss at mozilla.org>>

Hello!

I have just looked the video on channel9 between Lars Bak and Anders
Hejlsberg, and it gave me one idea.

It seems people sometimes worry about (basically because of a typo) that
they [[Get]] a non-existing property but as it stands, it just returns
undefined and goes happily on.

I see two solutions:
   - add something to the freeze, seal, preventExtensions family which
would set an object to the fail-fast [[Get]] state.
   - use a Proxy in the proto chain to trap the unknown [[Get]] and
throw early

Using a proxy for your own objects to throw seems reasonable, but see below for breakage to existing JS patterns. Adding it globally (via Object.protoype.proto) would almost certainly break other JS code on the page.

Consider this very common pattern:

obj.foo = obj.foo || bar;

I was too dense, again. By no means in Object.prototype.proto. I meant "in the prototype chain for the class of object I want to throw on unknown [[Get]]. IOW, under Object.prototype.proto.

(I put it in the P.S. down there...)

As a matter of practice, lots of JS code relies on the soft-fail behavior, for good reason, and trying to change that behavior would not likely result in happiness for consumers of the code that introduced this change.

Sure.

# Tom Van Cutsem (13 years ago)

2012/10/16 Herby Vojčík <herby at mailbox.sk>

I see two solutions:

  • add something to the freeze, seal, preventExtensions family which would set an object to the fail-fast [[Get]] state.
  • use a Proxy in the proto chain to trap the unknown [[Get]] and throw early

Do you think this needs a solution at all? If yes, which option would you favour?

The second option is easy to accomplish but pretty invasive since it requires you to inherit from a particular object. If you have an abstraction that already inherits from something else, you're hosed.

Personally, I'm not convinced this is a big enough problem to warrant another "mode" for Javascript objects.

# Brendan Eich (13 years ago)

Tom Van Cutsem wrote:

2012/10/16 Herby Vojčík <herby at mailbox.sk <mailto:herby at mailbox.sk>>

I see two solutions:
  - add something to the freeze, seal, preventExtensions family which
would set an object to the fail-fast [[Get]] state.
  - use a Proxy in the proto chain to trap the unknown [[Get]] and
throw early

Do you think this needs a solution at all? If yes, which option would
you favour?

The second option is easy to accomplish but pretty invasive since it requires you to inherit from a particular object. If you have an abstraction that already inherits from something else, you're hosed.

Personally, I'm not convinced this is a big enough problem to warrant another "mode" for Javascript objects.

This has come up in TC39, and on this list. Waldemar would like a way (not the default) to seal a class so typo'ed member names throw:

esdiscuss/2012-May/022837

However, since then, I recall hearing Waldemar say that the private at-name syntax in classes (for him) made the case that maximally minimal classes hang together in ES6, without any "const class" or sealed class option.

I agree it's not a big enough problem to add a "mode" or anything like that. Opt-in by class could be helpful. TypeScript has its optional member syntax (?:) and can give warnings. It seems to me this kind of tool-time help might be enough.

# Yehuda Katz (13 years ago)

On Wed, Oct 17, 2012 at 2:55 PM, Brendan Eich <brendan at mozilla.org> wrote:

Tom Van Cutsem wrote:

2012/10/16 Herby Vojčík <herby at mailbox.sk <mailto:herby at mailbox.sk>>

I see two solutions:
  - add something to the freeze, seal, preventExtensions family which
would set an object to the fail-fast [[Get]] state.
  - use a Proxy in the proto chain to trap the unknown [[Get]] and
throw early

Do you think this needs a solution at all? If yes, which option would
you favour?

The second option is easy to accomplish but pretty invasive since it requires you to inherit from a particular object. If you have an abstraction that already inherits from something else, you're hosed.

Personally, I'm not convinced this is a big enough problem to warrant another "mode" for Javascript objects.

This has come up in TC39, and on this list. Waldemar would like a way (not the default) to seal a class so typo'ed member names throw:

mail.mozilla.org/**pipermail/es-discuss/2012-May/**022837.htmlesdiscuss/2012-May/022837

However, since then, I recall hearing Waldemar say that the private at-name syntax in classes (for him) made the case that maximally minimal classes hang together in ES6, without any "const class" or sealed class option.

I agree it's not a big enough problem to add a "mode" or anything like that. Opt-in by class could be helpful. TypeScript has its optional member syntax (?:) and can give warnings. It seems to me this kind of tool-time help might be enough.

As I understand it, the idea is to allow gets only after a prior set.

There is a mode in Ruby that warns if you try to access an uninitialized instance variable, but people consider it annoying because it breaks common patterns (and in Ruby, unlike JavaScript, ||= is an operator, so it can skip warning in that case). I suspect that people trying to use objects that threw when trying to get uninitialized property would be extremely frustrated, and rightly so.