Allow possibility to override explicit conversion operator

373 views
Skip to first unread message

dangli...@gmail.com

unread,
Oct 19, 2013, 12:50:57 PM10/19/13
to mi...@dartlang.org
For better type conversion allow to override explicit conversion operator.

Example:

class Byte {
  int _value;

  Byte(this._value) {
    //
  }
  
  operator explicit(other) {
    if(other is int) {
      return new Byte(other);
    } else if(other is Byte) {
        return this;
    }
    throw new ArgummnetError('other: $other');   
  }

  int get value = _value;
}

class Integer {
  int _value;

  Integer(this._value) {
    //
  }

  operator explicit(other) {
    if(other is int) {
      return new Integer(other);
    }  else if(other is Byte) {
        return new Integer(other._value);
    } else if(other is Integer) {
        return this;
    }
    throw new ArgummnetError('other: $other');   
  }

  int get value = _value;
}

int test1() {
  var integer = 128 as Integer;
  integer = integer + 512;
  return integer.value;
}

Byte test2() {
  var integer = 128 as Integer;
  var byte = 128 as Byte;
  byte = byte * 5;
  integer = byte + byte as Integer;
  return integer as Byte;
}

Also this short form would be very useful.
"(type) value"

And the same examples with shor form.

int test1() {
  var integer = (Integer)128;
  integer = integer + 512;
  return integer.value;
}

Byte test2() {
  var integer = (Integer)128;
  var byte = (Byte)128;
  byte = byte * 5;
  integer = (Integer)byte + byte;
  return (Byte)integer;
}

In both cases this works just as other overridden operators.
The same as (by example) + operator.

Code generated by the compiler. The same as for other operators.
Difference in that the used static members of type into which produced the transformation.

0 as Byte // Byte.explicit(0)

int test1() {
  var integer = Integer.explicit(128);
  integer = integer.add(512);
  return integer.value;
}

Byte test2() {
  var integer = Integer.explicit(128);
  var byte = Byte.explicit(128);
  byte = byte.mul(5);
  integer = Integer.explicit(byte.add(byte));
  return Byte.explicit(integer);
}

Issue: Allow possibility to override explicit conversion operator

Lasse R.H. Nielsen

unread,
Oct 19, 2013, 2:10:41 PM10/19/13
to mi...@dartlang.org
That sounds like a change to what the "as" operator does as well. It is a cast operator, not a conversion operator. If you do "1.0 as int", it will throw.

/L


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

dangli...@gmail.com

unread,
Oct 19, 2013, 2:44:59 PM10/19/13
to mi...@dartlang.org
>> That sounds like a change to what the "as" operator does as well. It is a cast operator, not a conversion operator. If you do "1.0 as int", it will throw.

Please read this article: Using Conversion Operators (C# Programming Guide)

This is an example of an explicit conversion operator. This operator converts from the type Byte to a value type called Digit. Because not all bytes can be converted to a digit, the conversion is explicit, meaning that a cast must be used, as shown in the Main method.

Digit d = (Digit)b;  // explicit conversion

This opertion also know as cast (explcit conversion).
We (I and you) have different views on what was going on.
For me "cast" is the same as conversion (user programmable). But for you (in the context of Dart language) this is not the same because Dart this not support.
I propose to add this funtionality. It is not hard. Just adding another overriden operator (static method to type).

Perhaps "as" behavior should be left unchanged.
But adding "cast" in Dart as overriden conversion operator would be useful.

воскресенье, 20 октября 2013 г., 0:10:41 UTC+6 пользователь Lasse Reichstein Holst Nielsen написал:

dangli...@gmail.com

unread,
Oct 19, 2013, 3:06:31 PM10/19/13
to mi...@dartlang.org
>> That sounds like a change to what the "as" operator does as well. It is a cast operator, not a conversion operator. If you do "1.0 as int", it will throw.

I am not right and you are not right.
As you say "as" operator is a cast operator, not a conversion operator.
Not. It not a cast operator (my and your mistake).
It perform certain types of conversions between compatible types.
I.e. conversions between compatible types but not a cast.
You think it is a cast (wrong).
I think it convert between incompatible types (wrong).

I am talking about real conversion between incompatible types (cast).
I.e.
var byte = (int8) 128; // int8.explicit(128)
var integer = (int32) byte; // int32.explicit(byte)

Sorry, utilizing "as" operator was my mistake. Only explict cast.

var byte = new int8(129); // throw ArgumentError, my opinion
var byte = (int8) 129; // create new Byte(1), converted

Lasse R.H. Nielsen

unread,
Oct 19, 2013, 5:19:10 PM10/19/13
to mi...@dartlang.org
The "as" operator does two things, a static cast and a runtime type check. It's defined in the section called "Type cast" of the specification.

For the expression "e is T", it does the following:
- At compile time, the static type of the expression is T, not the static type of 'e'.
- At runtime, it checks if the value of 'e' is assignable to T. If it is, it evaluates to that value, otherwise it throws.

There is no value conversion at any point. You could say that it does "type conversion" at compile time, but that's exactly what a cast is.


As for the cast operator, could it just be done with a static method called "cast"?
I.e.:
  var byte = int8.cast(129);
?
/L


--
For other discussions, see https://groups.google.com/a/dartlang.org/
 
For HOWTO questions, visit http://stackoverflow.com/tags/dart
 
To file a bug report or feature request, go to http://www.dartbug.com/new

To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.

dangli...@gmail.com

unread,
Oct 19, 2013, 5:55:37 PM10/19/13
to mi...@dartlang.org
>> As for the cast operator, could it just be done with a static method called "cast"?
>> I.e.
>> var byte = int8.cast(129);

I do not mind.
The name of the static method is not principial (for me).
Possibility of using this functionality as in other languages are principial.

This is good but not elegant.
var byte = int8.cast(129);

This means the same thing but clear and elegant.

var byte = (int8) 129;

In C# this called overloaded "explicit" operator and declared not as the static method but as the operator (overloadable).

This means that this specified by language and supported by compiler.
Also this often used for numeric type conversion. I am about using "cast" operations but not about of implementing such operator.
Nevertheless, this functionality implemented as an overloadable operator because it is irreplaceable in some cases.

P.S.
You are talking about "as" operator but in examples you use an another ("is") operator. For me "as" and "is" operators are not the same. Please correct me if I am wrong.

воскресенье, 20 октября 2013 г., 3:19:10 UTC+6 пользователь Lasse Reichstein Holst Nielsen написал:

dangli...@gmail.com

unread,
Oct 19, 2013, 6:21:01 PM10/19/13
to mi...@dartlang.org
>> There is no value conversion at any point. You could say that it does "type conversion" at compile time, but that's exactly what a cast is.

Just understands what you want to say.
You are right. It not convert types. I know.
It find appropriate type in type hierarchy (test) and return the same value but downcasted or throw exception.

I am already saying that this was my mistake using "as" for type conversion.

But I am talking about the real type conversion. As we know the "explicit type conversion" is a type conversion which is explicitly defined within a program (instead of being done by a compiler for implicit type conversion).

This is typical example of use.
var byte = (uint8) 257; //  safely converted to uint8(1)

And the typical example of implementation.
uint8 operator explicit(other) {
  // user code

}

воскресенье, 20 октября 2013 г., 3:19:10 UTC+6 пользователь Lasse Reichstein Holst Nielsen написал:
The "as" operator does two things, a static cast and a runtime type check. It's defined in the section called "Type cast" of the specification.

Lasse R.H. Nielsen

unread,
Oct 19, 2013, 7:43:40 PM10/19/13
to mi...@dartlang.org
On Sat, Oct 19, 2013 at 11:55 PM, <dangli...@gmail.com> wrote:

P.S.
You are talking about "as" operator but in examples you use an another ("is") operator. For me "as" and "is" operators are not the same. Please correct me if I am wrong.

Ack, yes, that was a typo. Please read it as "e as T". The "is" and "as" operators do different things.
/L

dangli...@gmail.com

unread,
Oct 19, 2013, 7:46:32 PM10/19/13
to mi...@dartlang.org
Why I am ralkung about "explicit type conversion"?
This is because  exists another kind of type conversion. It called "implicit type conversion".
Implicit type conversion, also known as coercion, is an automatic type conversion by the compiler.

Look as this example.
var zero = 0;
var i = zero;
int32 i32 = zero;

Why this not works in checked mode and works in unchecked mode (but not as we wish)?
This is because in checked mode the compiler generate code that performed type checks.

But what happened if we tell to compiler to perform some special type checks in unchecked mode?
How this can programmed? In which way?

This can be done by defining "implicit type conversion" operator.

Example.
If you (in theory) override "implicit type conversion" operator as in the following code:

class int32 {
  int _value;

  int32(this._value);

  int32 operator implicit(other) {
    if(other is int) {
      return new int32(other);
    }

    throw new ArgumentError();
  }
}

Then this fact (re-declaration) must tell to compiler to perform type checks for usage of value storage of specified type.
In our case compiler must (in all modes) generate code that perform implicit type conversion for variables, fields, setters and parameters annotated as "int32".

Example of generated code for "int32" storages:

int32 i32 = zero; // i32 = zero is int32 ? zero : int32.implicit(zero)

This approach allows use this "simple" assignments for some special types (that have overloaded implicit type conversion operator).

int8 byte = 0; // generated code => byte = 0 is int8 ? 0 : int8.implicit(0)

This add some overhead in unchecked mode (only for types that overload this opertor) but very very very useful.
Also this allow use this approach in Javascript output.
One requirement  for corect work - type in current scope must be defined implicilty.
I.e.

int32 i1 = 0; // Work. runtimeTime is int32
i1 = 5; // Work. runtimeTime is int32
var i2 = returnTheSameValue(i1);
i2 = 5; // Not work. Scoped type is "var" for i2. implicit not called for dynamic types.

Reply all
Reply to author
Forward
0 new messages