--
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.
>> However, this doesn't seem natural to most programmers, instead, they assume that generics are covariant.
Are you sure for the most programmers?
>> As I understand, the design of Dart takes or would take all that complexity into the runtime for dynamic manipulation.
Not.
The overhead only when check type parameters.
I am trying write example. In two hour possible to write all required type checks.
But i have problem for writing this in Dart language 1.0.
:-()
I cannot continue to write in Dart because I have these troubles.
1.
This code can be compiled in Dart
action is _Function <int, int>
But this cannot be compiled
var action = _Function <int, int>;
Of course, this is a syntax error. But I have question to Gilad Bracha:
"Where in Dart 'typeof'"?
var type = typeof (_Function <int, int>);
typeCheck (type);
How to pass as parameters generic types in Dart?
2.
Another problem.
Mirrors not support generic type parameters and arguments.
I was not successful.
P.S.
Conclusion.
So not worry about complexity.
Not so complex and without big overhead.
If something as me (just a guy from vilage. humor) can write prototype in a few hours that means that the Dart VM can be refactored in few days.
Overhead not so significant judging by what I've managed to write in my unfinished prototype.
Some work only in requirements to refactor concept of functions in Dart.
Instead of just this "legacy" interface.
abstract class Function {}
Required that all "new" generic function implements these interfaces.
class Function1<TRet> implements Function {
}
class Function2<T1, TRet> implements Function {
}
And so on to "FunctionN", where N is natural number that specifies "maximun -1" number of parameters that generic functions can have. My be 25?
And also (by default, that I am trying wrote in my prototype) all arguments are contravariant and return type parameter covariant.
Also modifier "in" not required to be implemented in Dart before this work.
This is redundant because generic methods directly implements "Function".
abstract class Function2<in T1, TRet> implements Function {
}
This rule can be described in language specification.
If the type implements "Function" and defines type parameters then the last type parameter is covariant and the rest of all other are contravariant.
>> - "is" and "as" would have to take type parameters/arguments dynamically into account
The "type test" expression use the same unified runtime type check that used internally for all type check.
There is no difference who and where performed type check.
>> mirrors would have to take type parameters/arguments dynamically into account
Ask this question to Gilad Bracha. Dart has version 1.0 but mirrors still not fully implemented.
Also I can say that mirrors in Dart is not an externally implemented. They based on VM implementation.
Still the bridge to VM is not implemented carefully.
>> All info should be available at runtime.
Any information ALWAYS available at runtime if it not erased.
Another problem in that the not all information can be stored in ready for immediate use form.
A good example of this case is a operations of typecheck. They always required some computations.
>> Are additional runtime type info and checks difficult and expensive for programmers and the VM ?
No. Try this example. Also read comments in code
main() {
// You will have exception when invoke this function.
// Is this expensive for programmers and the VM?
foo(1);
}
foo(String s) { // Breaking on exception: type 'int' is not a subtype of type 'String' of 's'.
}
Another example.
main() {
int i = 0;
String s = "";
// Is this expensive for programmers and the VM?
// type 'String' is not a subtype of type 'int' of 'i'.
i = s;
}
>> I have to trust the experts in the Dart team; the Dart VM it is not their first (world class) VM.
I urge you did the opposite opinion?
>> For now I have no use for runtime type info related overhead.
Not understand. Google language translator is not good here.
Please explain this problem in more detail.
P.S.
Runtime type check just a calculations.
Example based on "mirrors" but in practice this very fast because used native comparison of pointers in C++.
mov eax, [ebp+32] // current_type
mov edx, [ebp+36] // base_type
cmp eax, edx
je return_true
lea edi, ebp+32+intrefaces
mov ecx, [ebp+32+intrefaces_count]
rep scasd
etc
static bool _testSupertype(ClassMirror fromClass, ClassMirror toClass, [Variance variance = Variance.COVARIANCE]) {
if(variance == Variance.INVARIANCE && toClass != fromClass) {
return false;
}
ClassMirror current = fromClass;
if(variance == Variance.CONTRAVARIANCE) {
var temp = toClass;
toClass = fromClass;
fromClass = temp;
current = temp;
}
while(true) {
if(current == toClass) {
return true;
}
for(var interface in current.superinterfaces) {
if(interface == toClass) {
return true;
}
}
current = toClass.superclass;
if(current == OBJECT) {
break;
}
}
return false;
}
}
Sometimes I'd prefer generic methods, purely for documentation purposes when you'd like a bound on the type
For instance, on the Iterable interface, I'd prefer to write
T fold<T>(T initialValue, T combine(T current, E element)
rather than
dynamic fold(dynamic initialValue,
dynamic combine(dynamic current, E element))
(in real code, dropping the dynamic annotation, since inferred) because it makes it clear that the return type is determined by the initialvalue and combine arguments and makes it clear that they expect the same type.
It's only a marginal improvement over the current type signature though. Fold is a bad example, because you should have an intuitive notion of what it does, but in my own code, but I think generic methods are an improvement in the presence of higher order function arguments.
Also, generic methods play nicely with top level functions. At the moment, the only way to write
listExtensionMethod(List<E> list, E arg)
is to ignore both the list generic and argument type.
At the call site, I wouldn't bother actually calling the method with the generic type, so generic methods in dart would be a documentation only feature (even checked mode could only check if the argument types had a common base type -- which is always true).
But again, not a real improvement. As for variance, I like the implicit covariance. It makes sense considering the spirit of the type system in dart.
tl;dr provide generic method type signatures but no way of calling a generic method with a specific type argument
>> Sometimes I'd prefer generic methods, purely for documentation purposes when you'd like a bound on the type
Not only you.
>> (in real code, dropping the dynamic annotation, since inferred) because it makes it clear that the return type is determined
by the initialvalue and combine arguments and makes it clear that they expect the same type.
Your statement "return type is determined by the initialvalue" is not true.
1.
This function always return T or null.
T fold<T>(T initialValue, T combine(T current, E element)
2.
But return type of this function not depends on the initialvalue.
fold(initialValue, combine(current, element);
In first case it is guaranteed by the programming language.
In first case you may only rely on the documentation or on the correctness of the algorithm that result will that you expect.
That's the beauty generic functions. They are predictable.
понедельник, 18 ноября 2013 г., 10:35:39 UTC+6 пользователь Thomas Stephenson написал:
But, as I mentioned on another thread, by far the bigger issue for me is the loss of refactoring due to lack of generic methods. Particularly on absolutely core methods like Iterable.map
That's going to hurt a lot as codebases grow.
A
1) Most programmers don't understand co/contravariant type arguments. So we'll just make them work the way most people expect them to work, even when that is not sound.My response: So what if most programmers don't understand variance? One in four people in America think the sun rotates around the earth. That doesn't make it true. Also, I sometimes tutor students from my old high school who are interested in computer science. I haven't yet met a student who wasn't able to properly grasp the concepts of variance after some explanation. Why is variance different than any other particularly tricky aspect of programming that everyone just needs to learn and move on? It's not actually that difficult. The kids I've tutored had more trouble with basic boolean algebra and algorithmic complexity than with variance.
2) Dart's type system is unsound, and we are unapologetic about this. Types in Dart are meant for documentation. Of course we have this checked-mode thing that will throw an error at runtime.My response: With all due respect, this is nonsense. Types are constraints. They are meant to be enforced, one way or the other. There is no real point to them otherwise. In fact, if they are not enforced, or especially if they are too loosely enforced, then types are counterproductive. They make the programmer (ESPECIALLY the inexperienced kinds of programmers that Dart seems to be targeted towards) believe things that are not true, such as that Dog object arguments are actually Dogs and not Cats or Insects. Also, a type check is a type check, and you've gained nothing by moving the type check to the runtime. If you can detect an error before it happens, how does it serve the programmer to ignore the error until the code runs? It doesn't.