Ticket #113 (new defect)

Opened 2 years ago

Last modified 1 year ago

(Resolved) int converts from everything

Reported by: graydon Assigned to: brendan
Type: defect Priority: trivial
Milestone: M2 Component: Spec
Version: 4 Keywords:
Cc:

Description

the builtin int type currently has a converter from *. This makes it somewhat useless as an annotation on a field. If the only motivation for this feature is to provide builtins with a way of achieving ES3-like ToInt? operations, I think we would be serving the user community much better by re-writing the relevant portions of the builtins to simply *call* ToInt?, and make the int converter much tighter (or perhaps give it no converter at all).

same argument applies to other builtin types.

Attachments

Change History

  Changed 2 years ago by lth

The analogy is probably with Number, which also has a converter from * (in ES3) and which works by calling ToNumber?.

But Number is a little special, since it was the only numeric type in ES3 and you needed some hook for converting *something* to number.

I'm inclined to agree with you that the converters to int,uint,double,and decimal should be constrained by Numeric, probably.

  Changed 1 year ago by brendan

  • owner set to brendan

Taking -- seems we agree (Jeff, weigh in if you have second thoughts) on this change. As lth proposes, and to match what AS3 does in its strict mode (but not in its standard mode which almost no one uses), the meta static function convert parameter would have a narrower type annotation: Numeric.

The backward-compatible standard library would have to bear the cost of ES3's ToInt?32, etc. in full (really, the problematic part is ToNumber?, which takes *).

/be

follow-up: ↓ 4   Changed 1 year ago by jeffdyer

  • priority changed from minor to major
  • milestone changed from M1 to M2

Flex users want legacy builtins to be specifically typed, rather than * typed so that strict mode would report more errors. The argument here seems to be to cause standard mode to report such errors and to express legacy interfaces with type *. This means that users (such those of Flex) have no way to get strict checking when calling old interfaces. Furthermore, this means that explicit conversions will be peppered throughout the builtin and host object models. Perhaps this is progress but it was not obviously so to us when developing AS3 (and in part we were trying to be sympathetic to implementors of JavaScript?.)

A key question is which mode is the normal mode for new uses, strict or standard? If it is strict then it seems we want to keep the more specific types with magic conversion behavior for builtins. If it is standard then we can downgrade the object interfaces use * and loose strict checking in strict mode.

We should also consider whether we want to give users the ability to define meta static convert methods on their classes. Not doing so would take way some of the magic of type annotations and limit the damage to the few numeric builtins.

An interesting experiment would be to rewrite the builtins that expect one of the numeric values to expect * and see how it works for user and implementor.

Jd

in reply to: ↑ 3   Changed 1 year ago by jeffdyer

Replying to jeffdyer:

Flex users want legacy builtins to be specifically typed, rather than * typed so that strict mode would report more errors. The argument here seems to be to cause standard mode to report such errors and to express legacy interfaces with type *. This means that users (such those of Flex) have no way to get strict checking when calling old interfaces. Furthermore, this means that explicit conversions will be peppered throughout the builtin and host object models. Perhaps this is progress but it was not obviously so to us when developing AS3 (and in part we were trying to be sympathetic to implementors of JavaScript?.) A key question is which mode is the normal mode for new uses, strict or standard? If it is strict then it seems we want to keep the more specific types with magic conversion behavior for builtins. If it is standard then we can downgrade the object interfaces use * and loose strict checking in strict mode. We should also consider whether we want to give users the ability to define meta static convert methods on their classes. Not doing so would take way some of the magic of type annotations and limit the damage to the few numeric builtins. An interesting experiment would be to rewrite the builtins that expect one of the numeric values to expect * and see how it works for user and implementor. Jd

Replying to self:

The AS3 design predates the AS3 (aka intrinsic) namespace and namespace shadowing, which work together to allow us to provide both loosely typed and specifically typed version of the legacy builtins. Given these we should be fine loosening the public interface to legacy objects.

Jd

  Changed 1 year ago by brendan

Lars points out the RefImpl? uses * not int or uint in the builtins, already -- in order to be compatible with ES1-3 in standard *and* strict modes. So that's at odds with AS3 in the latter mode. But as you say maybe 'use namespace intrinsic' saves those AS3 users who want stricter ES1-3 builtins as well as early binding.

/be

  Changed 1 year ago by lth

  • component changed from Proposals to Spec

We've decided to abandon user-defined constructors and the "to" operator anyway, so what happens here is defined by system rules. I think we all agree that numbers are interconvertible, strings are interconvertible, and everything converts to boolean. But we've nixed conversion of random stuff to number, for example.

  Changed 1 year ago by jresig

It appears as if I stumbled across this issue, as well. From the reference implementation:

>> var t: double;
>> t = "foo";
foo
>> t
NaN
>> var tt: int;
>> tt = "foo";
foo
>> tt
0

Let me know if this is something different and if I should file a follow-up bug for it.

  Changed 1 year ago by brendan

John, that is alas with the last RI we put up for download, which is out of date. Here's the latest results:

>> var t:double = "foo"
[locn] builtins/Error.es:86:55-86.55
[stack] [init t()]
**ERROR** EvalError: uncaught exception: TypeError: incompatible types w/o conversion: val="foo" type=[ns public '__ES4__']::string  wanted=[ns public '__ES4__']::double  (near builtins/Error.es:86:55-86.55)
>> var u:int = "foo"
[stack] [init t() | init u()]
**ERROR** EvalError: uncaught exception: TypeError: incompatible types w/o conversion: val="foo" type=[ns public '__ES4__']::string  wanted=[ns public '__ES4__']::int  (near builtins/Error.es:86:55-86.55)
>> var v:double = 42
>> var w:int = 3.14
>> v
42
>> w
3

All good. This spec bug remains, I suppose, until the spec is complete.

/be

  Changed 1 year ago by jresig

Oops - I'm pulling from monotone, but it appears as if I was a couple days out of sync. I just re-pulled and I can confirm that this was resolved. Thanks!

  Changed 1 year ago by lth

  • priority changed from major to trivial
  • summary changed from int converts from everything to (Resolved) int converts from everything
Note: See TracTickets for help on using tickets.