Fairy dust?

1,130 views
Skip to first unread message

Jim Heyne

unread,
Oct 3, 2015, 10:49:24 AM10/3/15
to Dart Misc
Fairy dust, anyone?
Foo foo *;
Bar bar *(foo);
Where * is syntactic sugar meaning "initialize the variable by invoking the appropriate constructor".

Wouldn't these debates become moot?
  • LHS v. RHS
  • var v. annotated
  • optional new
  • '&' 

Gen

unread,
Oct 3, 2015, 12:10:09 PM10/3/15
to Dart Misc
I think you have proposed yet another way to declare variables by replacing "new = " by "*".

Mike

unread,
Oct 3, 2015, 8:18:26 PM10/3/15
to Dart Misc
Or

Foo foo = new ();
List<Point> p = [new (0,0), new (10,10)];

Filipe Morgado

unread,
Oct 3, 2015, 8:30:16 PM10/3/15
to Dart Misc
Meh!

Not every declaration uses constructors.

What about:
final otherList = someList.map...??

Erik Ernst

unread,
Oct 5, 2015, 6:38:29 AM10/5/15
to Dart Misc
I think the reason why `var x = new XType(some, argument, s);` does not work sufficiently well is that it violates the language semantics to infer the type (it's ok for an editor to offer completion based on an optimistic assumption that a given approach to inference produces a "correct" result, but it is not ok to throw a type error in checked mode if the programmer violates a typing constraint that the compiler invented).

That's the reason why I've proposed adding explicit syntax for inference requests: Something like `? x = new XType(some, argument, s);` would give `x` the type `XType`, statically, dynamically, and correctly. ;-)

Other than that you couldn't reduce the syntax much (sure, `x = XType some s` omits `var`, `;`, and `new`, and uses functional style invocation, and infers the argument `argument`, but there is a truckload of reasons why those things don't fit well into Dart).



--
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.



--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

kc

unread,
Oct 5, 2015, 8:25:41 AM10/5/15
to Dart Misc
On Monday, October 5, 2015 at 11:38:29 AM UTC+1, Erik Ernst wrote:
I think the reason why `var x = new XType(some, argument, s);` does not work sufficiently well is that it violates the language semantics to infer the type

What are the language semantics?

 
(it's ok for an editor to offer completion based on an optimistic assumption that a given approach to inference produces a "correct" result, but it is not ok to throw a type error in checked mode if the programmer violates a typing constraint that the compiler invented).

That's the reason why I've proposed adding explicit syntax for inference requests: Something like `? x = new XType(some, argument, s);` would give `x` the type `XType`, statically, dynamically, and correctly. ;-)


Why not `let x = new XType(some, argument, s);` .

 
Other than that you couldn't reduce the syntax much (sure, `x = XType some s` omits `var`, `;`, and `new`, and uses functional style invocation, and infers the argument `argument`, but there is a truckload of reasons why those things don't fit well into Dart).

Why?

K.

Erik Ernst

unread,
Oct 5, 2015, 8:55:22 AM10/5/15
to Dart Misc
On Mon, Oct 5, 2015 at 2:25 PM, kc <kevin...@gmail.com> wrote:
On Monday, October 5, 2015 at 11:38:29 AM UTC+1, Erik Ernst wrote:
I think the reason why `var x = new XType(some, argument, s);` does not work sufficiently well is that it violates the language semantics to infer the type

What are the language semantics?

The semantics of a `var` declaration is that it declares a variable whose type is `dynamic`. This means that compilers cannot report typing problems with feature lookups (`x.foo(1,"blit")` is OK no matter whether there is a declaration of `foo` anywhere, and how it looks if it is declared) or when `x` is used in expressions, or in data flow (assignments of `x` to other variables, passing `x` as a parameter, returning `x`), no matter how wrong you may think it looks. And checked mode is not allowed to throw a `TypeError` if you assign a value to `x`, no matter whether it has type `XType` or not. In short, `x` is dynamic.

(it's ok for an editor to offer completion based on an optimistic assumption that a given approach to inference produces a "correct" result, but it is not ok to throw a type error in checked mode if the programmer violates a typing constraint that the compiler invented).

That's the reason why I've proposed adding explicit syntax for inference requests: Something like `? x = new XType(some, argument, s);` would give `x` the type `XType`, statically, dynamically, and correctly. ;-)


Why not `let x = new XType(some, argument, s);` .

That would work, too. That may look more familiar to JavaScript folks and SML-ites, but I do think that it smells like "immutability" as well as "inferred type" (and only the latter is on the agenda here, as far as I can see).

Other than that you couldn't reduce the syntax much (sure, `x = XType some s` omits `var`, `;`, and `new`, and uses functional style invocation, and infers the argument `argument`, but there is a truckload of reasons why those things don't fit well into Dart).

Why?

That's a thousand other heated debates, there's no way we would benefit from taking all those discussions right here. ;-)

  best regards,

kc

unread,
Oct 5, 2015, 9:09:54 AM10/5/15
to Dart Misc
On Monday, October 5, 2015 at 1:55:22 PM UTC+1, Erik Ernst wrote:
On Mon, Oct 5, 2015 at 2:25 PM, kc <kevin...@gmail.com> wrote:
On Monday, October 5, 2015 at 11:38:29 AM UTC+1, Erik Ernst wrote:
I think the reason why `var x = new XType(some, argument, s);` does not work sufficiently well is that it violates the language semantics to infer the type

What are the language semantics?

The semantics of a `var` declaration is that it declares a variable whose type is `dynamic`. This means that compilers cannot report typing problems with feature lookups (`x.foo(1,"blit")` is OK no matter whether there is a declaration of `foo` anywhere, and how it looks if it is declared) or when `x` is used in expressions, or in data flow (assignments of `x` to other variables, passing `x` as a parameter, returning `x`), no matter how wrong you may think it looks. And checked mode is not allowed to throw a `TypeError` if you assign a value to `x`, no matter whether it has type `XType` or not. In short, `x` is dynamic.

For Dart 2.0 does this semantics make sense - especially for developers who may come to Dart fresh under the impetus of Flutter?
 

(it's ok for an editor to offer completion based on an optimistic assumption that a given approach to inference produces a "correct" result, but it is not ok to throw a type error in checked mode if the programmer violates a typing constraint that the compiler invented).

That's the reason why I've proposed adding explicit syntax for inference requests: Something like `? x = new XType(some, argument, s);` would give `x` the type `XType`, statically, dynamically, and correctly. ;-)


Why not `let x = new XType(some, argument, s);` .

That would work, too. That may look more familiar to JavaScript folks and SML-ites, but I do think that it smells like "immutability" as well as "inferred type" (and only the latter is on the agenda here, as far as I can see).

I think type inference and immutability/single assignment play extremely well together. It's an easy win imo.

 

Other than that you couldn't reduce the syntax much (sure, `x = XType some s` omits `var`, `;`, and `new`, and uses functional style invocation, and infers the argument `argument`, but there is a truckload of reasons why those things don't fit well into Dart).

Why?

That's a thousand other heated debates, there's no way we would benefit from taking all those discussions right here. ;-)

For Dart 2.0 the Dart team needs to offer a clear story for developers.(Along ideally with tuples/value objects - which I believe you are interested in). Dev's can see a soon to be open sourced Swift - which will have good perf - and could gain traction on the server and IoT - where Dart is hoping to make inroads.

// Swift! A tuple with type inference!
let tup
= (1.0, 2.0);

// Named tuples!
let tup2
= (x: 1.0, y: 2.0);


K.

Erik Ernst

unread,
Oct 5, 2015, 9:43:47 AM10/5/15
to Dart Misc
On Mon, Oct 5, 2015 at 3:09 PM, kc <kevin...@gmail.com> wrote:
On Monday, October 5, 2015 at 1:55:22 PM UTC+1, Erik Ernst wrote:
On Mon, Oct 5, 2015 at 2:25 PM, kc <kevin...@gmail.com> wrote:
On Monday, October 5, 2015 at 11:38:29 AM UTC+1, Erik Ernst wrote:
I think the reason why `var x = new XType(some, argument, s);` does not work sufficiently well is that it violates the language semantics to infer the type

What are the language semantics?

The semantics of a `var` declaration is that it declares a variable whose type is `dynamic`. This means that compilers cannot report typing problems with feature lookups (`x.foo(1,"blit")` is OK no matter whether there is a declaration of `foo` anywhere, and how it looks if it is declared) or when `x` is used in expressions, or in data flow (assignments of `x` to other variables, passing `x` as a parameter, returning `x`), no matter how wrong you may think it looks. And checked mode is not allowed to throw a `TypeError` if you assign a value to `x`, no matter whether it has type `XType` or not. In short, `x` is dynamic.

For Dart 2.0 does this semantics make sense - especially for developers who may come to Dart fresh under the impetus of Flutter?

I don't expect this particular property of Dart to change (it's so deep that it is hard to tell what it won't break).

(it's ok for an editor to offer completion based on an optimistic assumption that a given approach to inference produces a "correct" result, but it is not ok to throw a type error in checked mode if the programmer violates a typing constraint that the compiler invented).

That's the reason why I've proposed adding explicit syntax for inference requests: Something like `? x = new XType(some, argument, s);` would give `x` the type `XType`, statically, dynamically, and correctly. ;-)


Why not `let x = new XType(some, argument, s);` .

That would work, too. That may look more familiar to JavaScript folks and SML-ites, but I do think that it smells like "immutability" as well as "inferred type" (and only the latter is on the agenda here, as far as I can see).

I think type inference and immutability/single assignment play extremely well together. It's an easy win imo.

Sure, but if the intention is only to allow for inference then the incorrect "immutable" connotation would just confuse people.

In fact, it's much less dangerous to allow a compiler to infer the type of a `final` variable. In that case you still need the spec to allow it (or you'll break, e.g., reflection), but you won't have the problem where you get a type error because of a violation of a constraint that the compiler invented (as in `var x = 1; x = 0.99;` which breaks if the compiler has invented the type `int` for `x`, and you did not intend that).

Other than that you couldn't reduce the syntax much (sure, `x = XType some s` omits `var`, `;`, and `new`, and uses functional style invocation, and infers the argument `argument`, but there is a truckload of reasons why those things don't fit well into Dart).

Why?

That's a thousand other heated debates, there's no way we would benefit from taking all those discussions right here. ;-)

For Dart 2.0 the Dart team needs to offer a clear story for developers.(Along ideally with tuples/value objects - which I believe you are interested in). Dev's can see a soon to be open sourced Swift - which will have good perf - and could gain traction on the server and IoT - where Dart is hoping to make inroads.

// Swift! A tuple with type inference!
let tup
= (1.0, 2.0);

// Named tuples!
let tup2
= (x: 1.0, y: 2.0);


I think I'll leave it at "yes, real values would be a nice addition". ;)

Bob Nystrom

unread,
Oct 5, 2015, 12:21:05 PM10/5/15
to General Dart Discussion

On Mon, Oct 5, 2015 at 6:43 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
The semantics of a `var` declaration is that it declares a variable whose type is `dynamic`. This means that compilers cannot report typing problems with feature lookups (`x.foo(1,"blit")` is OK no matter whether there is a declaration of `foo` anywhere, and how it looks if it is declared) or when `x` is used in expressions, or in data flow (assignments of `x` to other variables, passing `x` as a parameter, returning `x`), no matter how wrong you may think it looks. And checked mode is not allowed to throw a `TypeError` if you assign a value to `x`, no matter whether it has type `XType` or not. In short, `x` is dynamic.

For Dart 2.0 does this semantics make sense - especially for developers who may come to Dart fresh under the impetus of Flutter?

I don't expect this particular property of Dart to change (it's so deep that it is hard to tell what it won't break).

It has already changed within the confines of dart4web and DDC's strong mode:

// main.dart
main() {
  var i = 3;
  i = "not int";
}

$ dartanalyzer main.dart
Analyzing [main.dart]...
[error] Type check failed: "not int" (String) is not of type int (/Users/rnystrom/temp/temp.dart, line 3, col 7)
[warning] A value of type 'String' cannot be assigned to a variable of type 'int' (main.dart, line 3, col 7)
[hint] The value of the local variable 'i' is not used (main.dart, line 2, col 7)
1 error, 1 warning and 1 hint found.

– bob

Erik Ernst

unread,
Oct 5, 2015, 12:26:16 PM10/5/15
to Dart Misc
Sure, but that violates the spec which means that is a bug. So please help me fight for the ability to _request_ the inference explicitly. ;-)

--
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.

Bob Nystrom

unread,
Oct 5, 2015, 12:34:09 PM10/5/15
to General Dart Discussion
On Mon, Oct 5, 2015 at 9:26 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Sure, but that violates the spec which means that is a bug.

But a bug in the spec, or in DDC? ;)
 
So please help me fight for the ability to _request_ the inference explicitly. ;-)

Absolutely not.

We have a way to request inference. It's spelled "var". Using that for inference makes Dart consistent with TypeScript, Scala, C#, Flow, Kotlin, Swift, and probably some others I'm forgetting. Using the exact same syntax as those languages to mean something totally different (and almost always not what the user wants) is a complete usability failure.

In fact, I've seen time and time again where Dart users expect Dart to actually do that and are surprised that isn't already the standard behavior.

Likewise, we already have a perfectly valid, supported syntax to request no inference, "dynamic". We don't need two.

– bob


tatumizer-v0.2

unread,
Oct 5, 2015, 2:37:31 PM10/5/15
to Dart Misc
@Bob: how many of these languages treat
var x=0;
x="hello"
as a warning? And proceeds running at runtime with no errors?
There was a question about backward compatibility in another thread, your response was:
>This depends on what the inference is used for. If it's just for static analysis and warnings, I don't think we consider it a breaking change if new warnings appear. DDC's "strong mode" is doing this now.

I think it's getting a bit complicated. Strong mode, Checked mode... Not sure other languages have this. If they don't, then we are about to borrow just half a concept, which may lead to confusion.

Kasper Peulen

unread,
Oct 5, 2015, 2:50:28 PM10/5/15
to mi...@dartlang.org


On Mon, Oct 5, 2015 at 6:20 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:

It has already changed within the confines of dart4web and DDC's strong mode:

// main.dart
main() {
  var i = 3;
  i = "not int";
}

$ dartanalyzer main.dart
Analyzing [main.dart]...
[error] Type check failed: "not int" (String) is not of type int (/Users/rnystrom/temp/temp.dart, line 3, col 7)
[warning] A value of type 'String' cannot be assigned to a variable of type 'int' (main.dart, line 3, col 7)
[hint] The value of the local variable 'i' is not used (main.dart, line 2, col 7)
1 error, 1 warning and 1 hint found.


How do I enable these strong mode error/warnings. If I just run dartanalyzer main.dart, I don't get those error/warnings.

Alex Tatumizer

unread,
Oct 5, 2015, 3:55:48 PM10/5/15
to mi...@dartlang.org
I've been looking into various source files in github trying to find how many declarations are there that can potentially benefit from type inference. I can't find too many. Maybe my original expectation of 10% even looks too high.
But it, of course, depends on accounting rules.
My rules are:
1) "int" doesn't benefit - it's equally easy to write "int x=0" as it is "var x=0"
2) String doesn't benefit - everybody types "String" in no time
3) Uninitialized vars (wherever they are) don't benefit by definition
4) Function parameters and return values don't benefit (you have to declare their type anyway)
5) Declarations Foo foo = new Foo() potentially don't benefit (assuming support for ampersand or something is added)

If the remainder is 10% or less - no point adding a feature IMO(*). If anyone is proficient with analyzer API, it would make sense to collect more accurate statistics. It very well might be that the whole discussion is about (next to) nothing.

 (*) Interesting question. suppose it's N%. How small the value of N should be for you guys to agree that the feature is not worthwhile? We need to agree on the number beforehand :)

Frank Pepermans

unread,
Oct 5, 2015, 4:07:06 PM10/5/15
to mi...@dartlang.org

To be honest, I tend to type things whenever I get the chance. Even sometines unnecessarily generic types to end up with very ugly Foo <Bar <Baz>> things.

Then again, I come from a typed language background, I imagine most current Dart lib authors do.

The JS devs barely look at Dart yet arguably the whole optional typing was created to lure them in. Since that failed, why indeed bother still?

Bob Nystrom

unread,
Oct 5, 2015, 4:26:00 PM10/5/15
to General Dart Discussion
On Mon, Oct 5, 2015 at 11:37 AM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
@Bob: how many of these languages treat
var x=0;
x="hello"
as a warning?

Offhand, I know it's an error in C#, Scala, and TypeScript. Probably Kotlin too. Not sure about Flow and Swift. I think the former does flow typing (hence the name) and allows the type to change. It's probably an error in Swift.
 
I think it's getting a bit complicated. Strong mode, Checked mode... Not sure other languages have this. If they don't, then we are about to borrow just half a concept, which may lead to confusion.

It's always been complicated, in large part because the team internally has a lot of disagreement about this. :(

– bob

Bob Nystrom

unread,
Oct 5, 2015, 4:26:42 PM10/5/15
to General Dart Discussion

On Mon, Oct 5, 2015 at 11:50 AM, Kasper Peulen <kasper...@gmail.com> wrote:
How do I enable these strong mode error/warnings. If I just run dartanalyzer main.dart, I don't get those error/warnings.

Sorry, I copy/pasted the wrong line above. It should have been:

$ dartanalyzer --strong main.dart

– bob

kc

unread,
Oct 5, 2015, 8:06:06 PM10/5/15
to Dart Misc
Does the following give a clear story to developers (for locals):

// Explicit type
Point pe = new Point(1,1);

// type inference with mutable binding
var pm = new Point(1,1);

// type inference with immutable binding
let pi
= new Point(1,1);

// Dynamic/duck type
Any pa = new Point(1,1);



(1) 'Any' - something succinct instead of 'dynamic' - Any/any/dyn. Then 'var' can clearly be for type inference. 
(2) 'let' rather than 'final'. final has too much baggage from Java and would be better off purely as an class inheritance concept.
(3) Maybe go for mandatory annotations on all interfaces - it's not so onerous with (1) and (2). locals can use inference.

class Point {
   
Any a; // less painful with a succinct 'duck' type
   
int p;
   
Point(this.a, this.i);
}


K.

kc

unread,
Oct 5, 2015, 8:14:24 PM10/5/15
to Dart Misc
On Monday, October 5, 2015 at 2:43:47 PM UTC+1, Erik Ernst wrote:
On Mon, Oct 5, 2015 at 3:09 PM, kc <kevin...@gmail.com> wrote:
On Monday, October 5, 2015 at 1:55:22 PM UTC+1, Erik Ernst wrote:
On Mon, Oct 5, 2015 at 2:25 PM, kc <kevin...@gmail.com> wrote:
On Monday, October 5, 2015 at 11:38:29 AM UTC+1, Erik Ernst wrote:
I think the reason why `var x = new XType(some, argument, s);` does not work sufficiently well is that it violates the language semantics to infer the type

What are the language semantics?

The semantics of a `var` declaration is that it declares a variable whose type is `dynamic`. This means that compilers cannot report typing problems with feature lookups (`x.foo(1,"blit")` is OK no matter whether there is a declaration of `foo` anywhere, and how it looks if it is declared) or when `x` is used in expressions, or in data flow (assignments of `x` to other variables, passing `x` as a parameter, returning `x`), no matter how wrong you may think it looks. And checked mode is not allowed to throw a `TypeError` if you assign a value to `x`, no matter whether it has type `XType` or not. In short, `x` is dynamic.

For Dart 2.0 does this semantics make sense - especially for developers who may come to Dart fresh under the impetus of Flutter?

I don't expect this particular property of Dart to change (it's so deep that it is hard to tell what it won't break).

(it's ok for an editor to offer completion based on an optimistic assumption that a given approach to inference produces a "correct" result, but it is not ok to throw a type error in checked mode if the programmer violates a typing constraint that the compiler invented).

That's the reason why I've proposed adding explicit syntax for inference requests: Something like `? x = new XType(some, argument, s);` would give `x` the type `XType`, statically, dynamically, and correctly. ;-)


Why not `let x = new XType(some, argument, s);` .

That would work, too. That may look more familiar to JavaScript folks and SML-ites, but I do think that it smells like "immutability" as well as "inferred type" (and only the latter is on the agenda here, as far as I can see).

I think type inference and immutability/single assignment play extremely well together. It's an easy win imo.

Sure, but if the intention is only to allow for inference then the incorrect "immutable" connotation would just confuse people.

I meant for immutable bindings - not rhs. 'let' is basically a synonym for 'final' on locals - but I think dev's are more likely to use 'let' and buy into the clearer type inference story (which you note below).

K.

tatumizer-v0.2

unread,
Oct 5, 2015, 10:02:26 PM10/5/15
to Dart Misc
Another idea: come up with standard syntax for IDE to mark places where you want IDE to textually substitute inferred type.
E.g.  (just making it up) you write
\n=0;
\s="hello";
etc...
and then, whenever you like, hit CTRL-something, and behold, you text now looks like
int n=0;
String s="hello"
IDE will scan program for all backslashed names and replace each with appropriate "type name".
If left unprocessed by IDE, expression \name is, of course,  is not a valid syntax
How about that?


Message has been deleted

Filipe Morgado

unread,
Oct 5, 2015, 11:16:24 PM10/5/15
to Dart Misc
(Sorry for the deleted message, not easy on mobile)

I've never seen language users question so much the fundamentals of the language they're using.

They're still using it, so the designers must be doing something right.

But there has been a shift in the platform's expectations.

Dart was meant to get into Chrome and to be push to other browsers. That's where I get the unsound type system: SECURITY.

That's where Flash failed. Any flaw could be used whatever the platform/OS, taking control back from the browsers.

Flash is ahead of its time. Although the language could be improved, the runtime is quite a feat of engineering, still to be matched today. And the graphics/media libraries ... the best I've seen on the market. 2 clicks to target any platform and get performance. Kudos to Adobe.

Too bad political/comercial interests got over web productivity.
Although the specs, runtime and some graphics libraries were open-source, nobody could match them. So they got killed.

Back to Dart >.<

I seriously urge Dart to reconsider its unsoundness. It prevents many analyses/optimizations oportunities, on many levels. Most code will be unaffected.

C# is going functional. Functional seems to go native.

The sweet spot is hard to find. Maybe we should provide abstractions AND a way to avoid them. And leave it to the programmer to decide.

Lasse R.H. Nielsen

unread,
Oct 6, 2015, 3:19:29 AM10/6/15
to mi...@dartlang.org
On Mon, Oct 5, 2015 at 6:33 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:

On Mon, Oct 5, 2015 at 9:26 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Sure, but that violates the spec which means that is a bug.

But a bug in the spec, or in DDC? ;)

Neither. It's just DDC not implementing the Dart spec.
The language of DDC is not Dart. It's close, but it's not Dart, and that's not a bug, it's a feature.

Then again, there is no full implementation of Dart yet if we get really picky (the VM doesn't allow two labels on the same statement! It's NOT DART! *Muhahahahahah*).
 
 
So please help me fight for the ability to _request_ the inference explicitly. ;-)

Absolutely not.

We have a way to request inference. It's spelled "var".

Uhm, no. We have already used that for something else, so it is not, currently, a way to request inference.

We would have to change the spec to make that actually do (runtime) inference - that is, we still need the ability to request the ability, whether by changing how "var" works or in some other way.
 
Using that for inference makes

makes -> would make.
Currently it does not, not in Dart. It wouldn't mind changing that, but it's a breaking change, so we will ... need to fight for it.


It still has the problem that it doesn't work in the VM.
Using the static type of the initializer expression as the runtime type of the variable would mean that the VM can't implement this without adding the static type system - for no other reason than to infer that type.

I think it's more likely that the VM would remove checked mode than add static type checking.
 
Dart consistent with TypeScript, Scala, C#, Flow, Kotlin, Swift, and probably some others I'm forgetting. Using the exact same syntax as those languages to mean something totally different (and almost always not what the user wants) is a complete usability failure.

In fact, I've seen time and time again where Dart users expect Dart to actually do that and are surprised that isn't already the standard behavior.

Likewise, we already have a perfectly valid, supported syntax to request no inference, "dynamic". We don't need two.

True. So let's work towards making "var" mean "infer type (if possible)".

/L
--
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

Erik Ernst

unread,
Oct 6, 2015, 3:55:10 AM10/6/15
to Dart Misc
On Tue, Oct 6, 2015 at 9:19 AM, 'Lasse R.H. Nielsen' via Dart Misc <mi...@dartlang.org> wrote:
On Mon, Oct 5, 2015 at 6:33 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:
On Mon, Oct 5, 2015 at 9:26 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Sure, but that violates the spec which means that is a bug.

But a bug in the spec, or in DDC? ;)

Hi Bob, 

it could have been a bug in the spec if nobody had noticed this and nobody had implemented the specified semantics, but I think you will find it difficult to support that interpretation.

Neither. It's just DDC not implementing the Dart spec.
The language of DDC is not Dart. It's close, but it's not Dart, and that's not a bug, it's a feature.

Hi Lasse,

agreed, that's one way to explain the situation. But the point is that programmers need the language to be well-defined, and the purpose of specifying a language is exactly that. If the language has an only-approximately-determined semantics then nobody can write a reusable library and expect it to work "in general", it will have to be tested from scratch with each variant of the language (which could then mean: each compiler, each analyzer, etc.).

Then again, there is no full implementation of Dart yet if we get really picky (the VM doesn't allow two labels on the same statement! It's NOT DART! *Muhahahahahah*).

It's actually more dangerous to change the semantics of a given construct than it is to fail to support it entirely, because you'll discover the latter at compile time (and then you can complain to the implementers of the relevant tools) whereas the latter can hide away and make your program behave incorrectly a long time after deployment.
 
So please help me fight for the ability to _request_ the inference explicitly. ;-)

Absolutely not.

We have a way to request inference. It's spelled "var".

Uhm, no. We have already used that for something else, so it is not, currently, a way to request inference.

Depends on which language we are talking about, of course.  ;-)
 
We would have to change the spec to make that actually do (runtime) inference - that is, we still need the ability to request the ability, whether by changing how "var" works or in some other way.
 
Using that for inference makes

makes -> would make.
Currently it does not, not in Dart. It wouldn't mind changing that, but it's a breaking change, so we will ... need to fight for it.

That's the most serious problem, as I see it: It is a breaking change that will potentially change the behavior of programs in hundreds of locations per library. That's the reason why I'm advocating new syntax for the new semantics. I want that semantics, too! ;)

It still has the problem that it doesn't work in the VM.
Using the static type of the initializer expression as the runtime type of the variable would mean that the VM can't implement this without adding the static type system - for no other reason than to infer that type.

I think it's more likely that the VM would remove checked mode than add static type checking.

Or it might use another tool (the analyzer) to make the otherwise-inferred types explicit and then rely on the current implementation of checked mode. But this is all about implementation.
 
Dart consistent with TypeScript, Scala, C#, Flow, Kotlin, Swift, and probably some others I'm forgetting. Using the exact same syntax as those languages to mean something totally different (and almost always not what the user wants) is a complete usability failure.

In fact, I've seen time and time again where Dart users expect Dart to actually do that and are surprised that isn't already the standard behavior.

Likewise, we already have a perfectly valid, supported syntax to request no inference, "dynamic". We don't need two.

True. So let's work towards making "var" mean "infer type (if possible)".

Let's work towards getting support for inferred type annotations, in a way that doesn't potentially break all existing programs! ;-) 

  best regards,

Gen

unread,
Oct 6, 2015, 4:43:29 AM10/6/15
to Dart Misc
I would be comfortable with this syntax:
var x = expression // "var" means dynamic
var x; // "var" means dynamic
final x = expression // "final" means single assignment
let x = expression // "let" means a statically typed variable, strong mode and type inference
let x; // "let" means a statically typed variable, strong mode and type inference

Furthermore:
1) IMO, the keyword "new" should be made optional.
2) Once "let" as defined above is available, any compiler mode can be dropped.
Although compiler modes might be the way to have "pluggable typesystems".
The question is, how far a pluggable typesystem is useful and can be used in Dart and who would develop such a thing and for what reason.
But these are questions for another discussion thread.
3) I have not understood this remark:

Using the static type of the initializer expression as the runtime type of the variable would mean that the VM can't implement this without adding the static type system - for no other reason than to infer that type.


Gen

unread,
Oct 6, 2015, 6:15:05 AM10/6/15
to Dart Misc
I like that.
Although the replacement should be automatic once the expression is declared.
Maybe I would still write whatever keyword meaning static type inference in Dart 2.

Alex Tatumizer

unread,
Oct 6, 2015, 11:51:29 AM10/6/15
to mi...@dartlang.org
> Although the replacement should be automatic once the expression is declared.
I think non-automatic replacement is more interesting. E.g., it can infer types for unitialized variables, by looking into broader context.

Imagine this: you write entire function with backslashed variables, hit CTRL-blah - and something magical happens!
It's FUN!!! People will start migrating to dart in droves just for this feature alone!

No problem of backward compatibility any more. No SPEC changes. More inference heuristics can be introduced over time - and those will remain backward-compatible on the language level (Otherwise any such "improvement" will be a breaking change).

Not sure why people don't look into this option more seriously. Considering that the team can't agree on anything else, maybe here we have an opportunity for a good, mutually satisfying, compromise?

Erik Ernst

unread,
Oct 6, 2015, 11:53:17 AM10/6/15
to Dart Misc
I really like the approach where inference of type annotations is an IDE feature rather than a language semantics feature, I've recommended going that way many times. And this one looks cool, too! ;-D

--
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.

Bob Nystrom

unread,
Oct 6, 2015, 12:42:45 PM10/6/15
to General Dart Discussion
On Tue, Oct 6, 2015 at 12:55 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Tue, Oct 6, 2015 at 9:19 AM, 'Lasse R.H. Nielsen' via Dart Misc <mi...@dartlang.org> wrote:
On Mon, Oct 5, 2015 at 6:33 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:
On Mon, Oct 5, 2015 at 9:26 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Sure, but that violates the spec which means that is a bug.

But a bug in the spec, or in DDC? ;)

Hi Bob, 

it could have been a bug in the spec if nobody had noticed this and nobody had implemented the specified semantics, but I think you will find it difficult to support that interpretation.

Just because it's deliberate, that doesn't imply that it's necessarily useful or the best thing for our users.


Neither. It's just DDC not implementing the Dart spec.
The language of DDC is not Dart. It's close, but it's not Dart, and that's not a bug, it's a feature.

Hi Lasse,

agreed, that's one way to explain the situation. But the point is that programmers need the language to be well-defined, and the purpose of specifying a language is exactly that.

Sure, being well-defined is a useful property. But what we have defined has not gotten us piles of users so I think it's pretty clear we need to change. Defining an unappealing language very precisely is not a strategy that gets you millions of users. If it was, we'd all be writing SML or Oberon all day.

If the spec is unwilling to move, I am fine with at least having the implementation move towards something users want. At least something is getting better then.

If the language has an only-approximately-determined semantics then nobody can write a reusable library and expect it to work "in general", it will have to be tested from scratch with each variant of the language (which could then mean: each compiler, each analyzer, etc.).

We do that anyway. No bigints in dart2js. Various "dart:" libraries not available on some implementations. Operating system differents in "dart:io". Bugs in the different implementations. We've also had the need to test libraries on a variety of configurations because it turns out implementation do vary in reality whether the spec acknowledges that or not.

makes -> would make.
Currently it does not, not in Dart. It wouldn't mind changing that, but it's a breaking change, so we will ... need to fight for it.

That's the most serious problem, as I see it: It is a breaking change that will potentially change the behavior of programs in hundreds of locations per library. That's the reason why I'm advocating new syntax for the new semantics. I want that semantics, too! ;)

Consider two sets:
  1. The set of Dart "var" declarations where the variable is assigned a different type from its initializer.

  2. The set of "var" declarations in C#, Scala, TypeScript, Kotlin, Flow, and Swift where inference happens and teaches users to expect it.
We have empirical data from DDC that the first set is smaller than you might think. Many existing Dart libraries require no or very few changes to be error-free in strong mode. For example, the markdown package, which uses "var" heavily and is older than strong mode, DDC, and, hell, even dart2js, only required one declaration change to be error free. (The other change in that commit is a place where type inference pointed out a place where the code was straight up designed wrong and exposed a potential nasty type error in its public API.)

Meanwhile, the second set is dramatically larger. As a rough approximation, in 2014/Q4 (almost a year ago), there were 83,263 GitHub repos written in C#, Scala, TypeScript, or Swift. Dart had 1,957. Dart had 2% of the number of repos in languages where "var" means inference.

If you consider that most "var" declarations in Dart are actually fine if you treat them as inferred, that number gets even smaller. The set of code locations where "var" deliberately does not work with inference is so vanishingly tiny, it's not worth introducing an additional unfamiliar syntax to preserve them.

Let's work towards getting support for inferred type annotations, in a way that doesn't potentially break all existing programs! ;-) 

+1 for minimizing breakage.

Fortunately, we have a very graceful migration path.
  1. Run dartanalyzer --strong on your library.
  2. Fix the errors where a "var" variable changes type.
  3. Once enough libraries have gone through this transition, make strong mode the default.
We are already doing this for a number of packages, and an increasingly large set of internal teams at Google.

We have all the syntax we need, we just need to use it the way users expect.

– bob

Alex Tatumizer

unread,
Oct 6, 2015, 3:01:05 PM10/6/15
to mi...@dartlang.org
OK, let's try another tactic.
@Bob:
Some SW shops introduce very stringent coding standards, which require strong typing, be it hell or high water.
According to these standards, if foo() returns Stream<List<int>>, people have to write it as
Stream<List<int>> stream=foo();
If someone dares writing anything like
var stream = foo();
he gets demoted to the role of dishwasher for life, or until he repents (whichever comes first)

Do you have any empathy at all? How about backslashed names? Ampersand? (Actually, I'd like to have both)





Kasper Peulen

unread,
Oct 6, 2015, 3:44:34 PM10/6/15
to mi...@dartlang.org

@Alex I fail to really see your point. You say you don't use var, so this won't affect you at all, right?

And it seems like that people that do use "var" for local variables, like the new behavior. If I would use var, I would absolutely love this.

Alex Tatumizer

unread,
Oct 6, 2015, 3:57:35 PM10/6/15
to mi...@dartlang.org
You will see my point shortly.

it's very frustrating to type Stream<List<int>> stream= foo() by hand. BTW, as it is now, you won't get much of type completion on that out of box.

It's disgusting to see ActionGroup actionGroup = new ActionGroup(x,y,z)

Be it local var or otherwise, would you write just an untyped "var" in
var stream=foo()
when foo() returns Stream<List<int>>?

Now, my point: when you are required to use typed vars (or do it by your own choice - doesn't matter why), you still might be wondering why IDE cannot help you in doing so. Backslash solves this problem. Another problem - the utter ugliness of ActionGroup actionGroup = new ActionGroup(x,y,z) - is where ampersand comes in.





Mike

unread,
Oct 6, 2015, 4:40:04 PM10/6/15
to Dart Misc
@Alex

"the utter ugliness of ActionGroup actionGroup = new ActionGroup(x,y,z) - is where ampersand comes in."

see my suggestion near top of post which solves this as follows:

ActionGroup actionGroup = new (x,y,y);

The constructor called by new() is inferred by the LHS type annotation.

Bob Nystrom

unread,
Oct 6, 2015, 4:48:51 PM10/6/15
to General Dart Discussion
On Tue, Oct 6, 2015 at 12:00 PM, Alex Tatumizer <tatu...@gmail.com> wrote:
@Bob:
Some SW shops introduce very stringent coding standards, which require strong typing, be it hell or high water.
According to these standards, if foo() returns Stream<List<int>>, people have to write it as
Stream<List<int>> stream=foo();
If someone dares writing anything like
var stream = foo();
he gets demoted to the role of dishwasher for life, or until he repents (whichever comes first)

With basic type inference, var stream = foo(); is strongly typed.
 
Do you have any empathy at all?

I have a ton of empathy for people that want to get solid, reliable static checking without the verbosity of Java. I also empathize with people that like type annotating their locals, and I'm fine with Dart allowing that.
 
How about backslashed names?

This just seems like the normal auto-complete or snippet support every editor already has.
 
Ampersand? (Actually, I'd like to have both)

Unless you're fixing the grammar in an English sentence, punctuation is almost never the right solution. It's unreadable to a new user.

– bob

Alex Tatumizer

unread,
Oct 6, 2015, 4:50:02 PM10/6/15
to mi...@dartlang.org
@Mike: it won't work for factory constructors or named constructors.

Kasper Peulen

unread,
Oct 6, 2015, 5:07:55 PM10/6/15
to mi...@dartlang.org
But both of these problem would be solved by strong mode as well, if that becomes the standard. I would prefer that, then introducing new notation. My point is more, that I don't really see the point of people being against this so much. I absolutely agree with Bob, that this should be the way to go.

Btw, you do get IDE support for typing  Stream<List<int>> stream= foo(); I use that all the time.



Alex Tatumizer

unread,
Oct 6, 2015, 5:11:09 PM10/6/15
to mi...@dartlang.org
@Kasper: what tool did you use to produce beautiful animation?

Kasper Peulen

unread,
Oct 6, 2015, 5:13:18 PM10/6/15
to mi...@dartlang.org
Gyazo GIF 3.1.2, see https://gyazo.com/

On Tue, Oct 6, 2015 at 11:11 PM, Alex Tatumizer <tatu...@gmail.com> wrote:
@Kasper: what tool did you use to produce beautiful animation?

--
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.



--
Kasper

Erik Ernst

unread,
Oct 7, 2015, 3:34:14 AM10/7/15
to Dart Misc
Here's another one: We could use one of the mechanisms of natural language, and introduce entities by type:

    var Foo<List<int>>(some, args);
    ... the.Foo ...

just like "The old man brought a dog to the dinner. _The_dog_ constantly kept barking until..", that is, we introduce each new object using a suitable "creation" operation (in natural language we can use indefinite articles like "a" and many other things; in programming languages we would have a constructor invocation or an expression like a method call) and then we refer to it via the type (in natural language it would be a definite article plus a generic noun for the type: "the" "dog"; in programming languages we could use any names that disambiguate among these nameless objects, but we would probably have to insist that the same name is used throughout a given scope, and using the type-without-type-arguments would be an obvious choice).

Weird, right? ;-)

Mike

unread,
Oct 7, 2015, 4:06:13 AM10/7/15
to Dart Misc
@Alex

Agreed re factory constructors. You would still need

Foo foo = new Bar(x,y,z)

For named constructors you could use

Foo foo = new.named(x,y,z);

The point of my suggestion is to avoid the verbosity of types on both LHS and RHS which it would do in most cases. The var proposal in this thread effectively does the same but leaves the type information on the RHS.

tatumizer-v0.2

unread,
Oct 7, 2015, 12:21:40 PM10/7/15
to Dart Misc
@Erik: interestingly, dart already has the notion of "the" in some rudimentary form.
When you write
Foo foo = new Foo()..bar=1..baz="Hello", then first dot in cascade operator can be interpreted as "theObject" (and theObject is returned from operation).
From this perspective, proposed ampersand can be treated as "theType".
Maybe to make it less cryptic, it makes sense to write it as &Type. Now ampersand means exactly "the". Which naturally leads to another "the" : &name (which is a string), e.g.
Foo foo=new &Type(&name);
equivalent to
Foo foo=new Foo("foo");

Other variants of "the" are possible, e.g
class Foo() {
   &Class() {...constructor body...) // &Class means "Foo"
}
Not sure how many of them make sense, but it's a clear concept, and  I think many people will like it.
(@Bob:what do you think?)

This contrasts with current idea for "var inference", which, to my taste, is a non-concept -
that is, something ad hoc, limited, not very well thought out and as a consequence, potentially confusing.and error-prone. BTW, it can be interpreted as a kind of "the" - that is, "var x=0;" means "TheType x=0" - the difference is that in normal language, we first define the subject, and only then can refer to it via "the", "it", "he", "she" etc. But here, we have an inversion like "He was an unusual type, this Victor" or something.



  

Daniel Joyce

unread,
Oct 7, 2015, 12:34:02 PM10/7/15
to Dart Misc
Ugh, lets not abuse & which has very different meanings in other languages and might be confusing

Also, I don't get the sudden obsession with & and &Class?

Since Dart is class based, how is the constructor of Class declared? (metaclass)

&&Class? :)

Why not just use constructor() like Typescript, or ClassName() as Dart already does it?

--
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.
--
Daniel Joyce

The meek shall inherit the Earth, for the brave will be among the stars.

Erik Ernst

unread,
Oct 7, 2015, 1:05:06 PM10/7/15
to Dart Misc
Interesting, Alex! ;)

However, I still think it is better to infer the type and write a constructor invocation than it is to infer the constructor invocation (because the constructor invocation contains more information than the type annotation, and the type annotation is easily extracted from it). The problem is just that we currently don't have syntax allowing us to ask for inference of a type annotation. So that's more like `TheType x = e;` where `TheType` stands for the statically known type of `e` (and my old proposal to use `? x = e;` has exactly the same structure, of course).

But it is still not a safe decision to commit to the statically known type of `e`, even in the cases where the type annotations (and hence the statically known type of `e`) can be trusted at runtime. The problem is well-known: `var x = 1; x = 0.99;` breaks if we allow the semantics where `x` gets type `int` and that type is enforced (checked mode) when `0.99` is assigned. So the safe approach is to allow inference only for immutable variables. With mutable variables I'd prefer if programmers are forced into making the choice, even if it's just by performing an easy quick-fix.

But for "the" to be really useful, it should be available in the entire scope of the given entity, not just in the declaration, so we would be able to use `the.Foo` in many places (which would make sense for those who would otherwise have used the name `theFoo` ;-). 


--
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.

tatumizer-v0.2

unread,
Oct 7, 2015, 4:53:41 PM10/7/15
to Dart Misc
Consider the following example:
var result =
    <int>[1,2,3].map((x)=>"Hello");
What is the type of "result"? Turns out, it's Iterable<dynamic>.
But in
 var result =
    <int>[1,2,3].where((x)=>x>0);
the type is correctly inferred as Iterable<int>.

In case of map, there's no way to make inference work, even in principle, because there's no syntax to declare return type of mapping function. But even if returned type somehow could be figured out, there's no syntax to write declaration of "map" function so that compiler can deduce return type correctly.

Today, declaration of "map" is: Iterable map(f(E element))
Suppose, tomorrow dart adds extra feature to generics repertoire so we can write something like
Iterable<T> map(T f(E element))
Now dart CAN (in principle) figure out the return type of <int>[1,2,3].map((x)=>"Hello");
The problem is that adding a rule to the list of rules of type inference is a breaking change again!
What was Iterable<dynamic>, cannot suddenly become Iterable<String>.

What to do? Introduce another mode? "Stronger"? Then "Strongerer"?

tatumizer-v0.2

unread,
Oct 7, 2015, 5:54:05 PM10/7/15
to Dart Misc
> Also, I don't get the sudden obsession with & and &Class?
Since Dart is class based, how is the constructor of Class declared? (metaclass)

Those are just macros, like __LINE_ in C. But I agree they may not make much sense. Except &Type :)

Bob Nystrom

unread,
Oct 7, 2015, 6:04:47 PM10/7/15
to General Dart Discussion
On Wed, Oct 7, 2015 at 1:53 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
Suppose, tomorrow dart adds extra feature to generics repertoire so we can write something like
Iterable<T> map(T f(E element))
Now dart CAN (in principle) figure out the return type of <int>[1,2,3].map((x)=>"Hello");

DEP #22: Generic methods. The DDC and analyzer folks are hard at work implementing it.
 
The problem is that adding a rule to the list of rules of type inference is a breaking change again!
What was Iterable<dynamic>, cannot suddenly become Iterable<String>.

This may be alarming to purists, but we've already made it clear that DDC only supports a restricted subset of the language.

Personally, I don't like breaking changes, but I really don't like shipping a language that people aren't thrilled about. Maintaining rigorous compatibility with an unpopular product seems like a good way to ensure you're never popular.

– bob

tatumizer-v0.2

unread,
Oct 7, 2015, 10:48:21 PM10/7/15
to Dart Misc
@Bob: let me change sides for a moment - I will advocate for inference, but for more consistent inference.
How big is the problem to remove all limitations? Let's focus on "var", just to get a sense of it.
When there's an uninitialized var, compiler can take the type from any place it can see the assignment to this var (limit the search by same library, or even a file).
All other assignments must have same type (not a common denominator - exactly the same), otherwise it's an error.
If compiler cannot find any assignments - error.
Thus, "var" is not synonymous with "dynamic" any longer. It means "inferred type". And inferred type cannot be "dynamic".
Whatever is supposed to be really dynamic, should be explicitly declared dynamic.
Now you example
var x;
if (something) {
   //some work
   return 0; 
} else {
   // other work
   return 1;
}
will work just fine.
No matter what someone can think about the usefulness of inference, "var as inferred type" now looks like a concept,
Over time, compiler can add heuristics, covering more cases of inference, but nothing will be broken by those new rules - it's just there will be less places where compiler cannot figure out the type. 
How about that? Any known common counterexamples?





kc

unread,
Oct 8, 2015, 9:21:58 AM10/8/15
to mi...@dartlang.org
On Wednesday, October 7, 2015 at 11:04:47 PM UTC+1, Bob wrote:
 
Personally, I don't like breaking changes, but I really don't like shipping a language that people aren't thrilled about. Maintaining rigorous compatibility with an unpopular product seems like a good way to ensure you're never popular.

Bolded for truth. 

There does seem to be a civil war between Gilad's 'dynamic OO' vision and the more 'static functional' vision - which is where C# 7.0 is going (along with most other modern langs). Dev's who choose Dart want to keep their fingers on the keyboard working efficiently on text files with tools for static analysis, completion, re-factoring etc. Not the more dynamic Smalltalk vision (which is nice but doesn't seem to be what the Dart audience are after). 

Maybe Dart could have 2 modes for analysis - 'script' and 'strong' (ddc). Not a checked mode in the VM which locks ppl into an unexpressive type system without inference. (And if your app is all 'strong' then there's the option of whole program analysis for performance especially on mobile with Flutter).

Bob used the term 'uncanny valley'. How about:


K.

 

Bob Nystrom

unread,
Oct 8, 2015, 12:33:21 PM10/8/15
to General Dart Discussion
On Wed, Oct 7, 2015 at 7:48 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
@Bob: let me change sides for a moment - I will advocate for inference, but for more consistent inference.
How big is the problem to remove all limitations? Let's focus on "var", just to get a sense of it.
When there's an uninitialized var, compiler can take the type from any place it can see the assignment to this var (limit the search by same library, or even a file).

There are cases where this can get surprisingly complex. I don't have a comprehensive list of examples, but here's one that comes to mind:

var a;
closure() => a;
a = closure();

This isn't intractable, but it's not trivial either. I think in some cases, you end up having to do a fixpoint calculation in order to find its type. There may be cases where even that doesn't work. My understanding—and I'm by no means an expert here—is that flow-sensitive analysis can get pretty hairy.
 
All other assignments must have same type (not a common denominator - exactly the same), otherwise it's an error.
If compiler cannot find any assignments - error.

I think a simpler solution, which doesn't require any flow analysis is to just stipulate that you have to provide either an initializer or a type annotation when declaring a variable. If you do neither, it's an error.

Thus, "var" is not synonymous with "dynamic" any longer. It means "inferred type". And inferred type cannot be "dynamic".

It can be, it's just that the only way for that to happen is if the initializer is dynamic:

var i = 123 as dynamic;

In other words, "dynamic" means "I successfully inferred it to be dynamic", not "I failed to infer it".
 
Whatever is supposed to be really dynamic, should be explicitly declared dynamic.
Now you example
var x;
if (something) {
   //some work
   return 0; 
} else {
   // other work
   return 1;
}
will work just fine.

Did you mean those to be returns, or assignments to x? Assuming the latter...

This is a good example to bring up. I think the majority of the cases where you declare a local variable without an initializer are exactly like this—it gets initialized in both arms of a subsequent if, or maybe a switch.

Many languages that do inference for locals tend to be more expression-oriented to avoid this trap. I wonder if that would work for Dart. If we made if () and {} expressions (with very very low precedence!) then you could do:

var x = if (something) {
  0;
} else {
  1;
}

In the absence of that, I sometimes work around this by hoisting that calculation to a separate function:

var x = calculateValue(something);

I suppose if I wanted to be clever, I could do:

var x = () {
  if (something) {
    return 0;
  } else {
    return 1;
})();

But I think that style is perverse and wouldn't use it.

No matter what someone can think about the usefulness of inference, "var as inferred type" now looks like a concept,
Over time, compiler can add heuristics, covering more cases of inference, but nothing will be broken by those new rules - it's just there will be less places where compiler cannot figure out the type. 
How about that? Any known common counterexamples?

In general, yes, I agree with you. Our static tools should be free to improve the quality of inference they do to maximize the value users get out of it without having to go through the language spec. At the same time, I think it's important for inference to be simple enough for users to have an intuition about how it works and feel safe and confident relying on it.

I could be wrong, but my hunch is that going full flow-sensitive would be a bad fit for that.

Cheers!

– bob

Günter Zöchbauer

unread,
Oct 8, 2015, 12:51:38 PM10/8/15
to Dart Misc
try {} would be another example. 

Bob Nystrom

unread,
Oct 8, 2015, 12:56:03 PM10/8/15
to General Dart Discussion

On Thu, Oct 8, 2015 at 9:51 AM, Günter Zöchbauer <gzo...@gmail.com> wrote:
try {} would be another example. 

+1! +10, actually.

This would be super handy even without it helping inference. I have a ton of code like:

var blah;
try {
  blah = someThingThatCanFail();
} on SomeError catch (error) {
  blah = ...
}

blah.useIt();

I do that because I may not want to catch errors from later uses of blah, and I almost never want to have to indent the whole thing. This has been a pet peeve of mine forever.

– bob

Alex Tatumizer

unread,
Oct 8, 2015, 1:21:27 PM10/8/15
to mi...@dartlang.org
> My understanding—and I'm by no means an expert here—is that flow-sensitive analysis can get pretty hairy.
But my point is that it shouldn't be! Compiler will try a couple of heuristics, and if it fails - error, sorry, specify explicit type. BUT: in 99.9%of cases these simple heuristics will work, including both examples above (example with "some work" - I meant x= really, not return, sorry; and example with try/catch).

Without it, on top of being a flaky concept, the thing is very fragile, e.g.
Somebody writes
var blah = someThingThatCanFail(); // strongly typed! Exceptions propagate to caller.
//..some code
blah.doIt();

and then he, or somebody else, suddenly feels an urge to reorganize it in try/catch block. Without much thinking, he refactors:
var blah;
try {
  
   blah = someThingThatCanFail();
   // some code
}
blah.doIt();

And now what? blah is "dynamic"! The fact that compiler can't deduce type in so trivial situation is unexpected. It's not like some circular corner case - everything is in a plain sight.

Kasper Peulen

unread,
Oct 8, 2015, 2:56:46 PM10/8/15
to mi...@dartlang.org
On Thu, Oct 8, 2015 at 6:32 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote: 
This is a good example to bring up. I think the majority of the cases where you declare a local variable without an initializer are exactly like this—it gets initialized in both arms of a subsequent if, or maybe a switch.

Many languages that do inference for locals tend to be more expression-oriented to avoid this trap. I wonder if that would work for Dart. If we made if () and {} expressions (with very very low precedence!) then you could do:

var x = if (something) {
  0;
} else {
  1;
}

In the absence of that, I sometimes work around this by hoisting that calculation to a separate function:

var x = calculateValue(something);

I suppose if I wanted to be clever, I could do:

var x = () {
  if (something) {
    return 0;
  } else {
    return 1;
})();

But I think that style is perverse and wouldn't use it.

I find this very interesting, would like something like this, but how then would it work if there are multiple expressions in the if statement? Just returning the last one? 

var x = if (something) {
  var split = something.split(' ');
  split..removeAll(otherthing);
  split.last;
} else {
  1;
}

Implicit return looks a bit strange in dart. Wondering if there are solutions that are more dart like without implicit returns. One other option may be to provide some sugar for the (){...}() construction? 

--
Kasper

tatumizer-v0.2

unread,
Oct 8, 2015, 3:12:20 PM10/8/15
to Dart Misc
Just a couple of small observations.

> In other words, "dynamic" means "I successfully inferred it to be dynamic", not "I failed to infer it".
I think propagating "dynamic" can lead to a chain reaction that might be quite unexpected for user. E.g.
var x=somethingThatReturnsDynamic(param1, param2);
var y=x*2; // but you know it's int

In many situations, function for whatever reason returns dynamic, but you "know" it's int in your scenario. What you DON'T know is that the function somethingThatReturnsDynamic returns dynamic, you thought it should be "int". In this case, "dynamic" will propagate to "y" and further, with no end. I think it's better to put a barrier upfront. var y=x*2 should be an error to infer type - unless you invoke universal Object methods like hashCode  (BTW, I was surprised to see that current compiler infers the type of hashCode correctly, even for "dynamic" argument). So the issue of "dynamic" propagation is not quite clear-cut.


> At the same time, I think it's important for inference to be simple enough for users to have an intuition about how it works and feel safe and confident relying on it.
> I could be wrong, but my hunch is that going full flow-sensitive would be a bad fit for that.

I think first sentence is a bit inconsistent with the second. How anyone can feel "safe and confident" if things start losing types after minor refactoring, with no warning or anything? Especially with further propagation of "dynamic".



Jan Mostert

unread,
Oct 8, 2015, 3:30:45 PM10/8/15
to mi...@dartlang.org
var x = if (something) {
  0;
} else {
  1;
}

That looks atrocious! Wouldn't this existing syntax be cleaner ?

var x = (something) ? 0 : 1;

If you need something more complex, you can probably do: var x = (something) ? (){return 0;} : (){return 1;};
Or would x's type be anonymous function in this case?

With the Try example, wouldn't this solve it or would x be of type anonymous function if this is done?

var x = (){
  try {
    ...
  } catch(e){
    return 1;
  }
  return 0;
};

Java did something called try-with-resource, just wondering if that kind of syntax might be useful in the try-catch case.


--

Günter Zöchbauer

unread,
Oct 8, 2015, 3:35:38 PM10/8/15
to Dart Misc
I run into this regularly because I prefer final over var to indicate that a variable is not supposed to change after initialization but that doesn't work with if{}else{} or try{}.

Jan Mostert

unread,
Oct 8, 2015, 3:44:06 PM10/8/15
to Dart Misc
It does work with the shorthand if-else notation:

final x = (1==1) ? 0 : 1;
print(x); // prints 0

... but for full if-else and try-catch, I can see the dilemma, it gets a type of Closure if you wrap if / try in an anonymous function.



Kasper Peulen

unread,
Oct 8, 2015, 3:49:53 PM10/8/15
to mi...@dartlang.org
@Jan Mostert wait a second, you find this atrocious:

var x = if (something) {
  var split = something.split(' ');
  split..removeAll(otherthing);
  split.last;
} else if(something else) {
  1;
} else {
  2;
}

And this you find good looking then?

var x = something ? (){
  var split = something.split(' ');
  split..removeAll(otherthing);
  split.last;
}() : (something else) ? 1 : 2;

--
Kasper

Alex Tatumizer

unread,
Oct 8, 2015, 3:50:09 PM10/8/15
to mi...@dartlang.org
When I see situations like this, the question is: can I find a good name to make it a nested named function? And in many cases, the answer is yes (sometimes you need a small refactoring for this). Especially for case of try/catch - I prefer to have try/catch for a full body of nested function, not for a fragment of it. This works very well in dart (but it's much more difficult in java, because of the lack of closures and nested functions).

Bob Nystrom

unread,
Oct 8, 2015, 3:56:03 PM10/8/15
to General Dart Discussion
On Thu, Oct 8, 2015 at 11:56 AM, Kasper Peulen <kasper...@gmail.com> wrote:
I find this very interesting, would like something like this, but how then would it work if there are multiple expressions in the if statement? Just returning the last one? 

Yup. A block statement would return the result of the last statement.
 

var x = if (something) {
  var split = something.split(' ');
  split..removeAll(otherthing);
  split.last;
} else {
  1;
}

Implicit return looks a bit strange in dart.

Yes. I think it's a neat idea, but it may be a bridge too far for Dart.

– bob

Bob Nystrom

unread,
Oct 8, 2015, 4:00:10 PM10/8/15
to General Dart Discussion
On Thu, Oct 8, 2015 at 12:12 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
Just a couple of small observations.
> In other words, "dynamic" means "I successfully inferred it to be dynamic", not "I failed to infer it".
I think propagating "dynamic" can lead to a chain reaction that might be quite unexpected for user. E.g.
var x=somethingThatReturnsDynamic(param1, param2);
var y=x*2; // but you know it's int

In many situations, function for whatever reason returns dynamic, but you "know" it's int in your scenario. What you DON'T know is that the function somethingThatReturnsDynamic returns dynamic, you thought it should be "int".

The language can't read your mind (yet). In cases where you have extra knowledge that isn't visible to the static analyzer, it's your job to tell it:

var x = somethingThatReturnsDynamic(param1, param2) as int; // "I know it returns an int."
var y = x * 2; // Now analysis knows this is an int too.
 
In this case, "dynamic" will propagate to "y" and further, with no end. I think it's better to put a barrier upfront. var y=x*2 should be an error to infer type

Dynamic is a type in Dart, and it's a useful one in some cases. I don't think it makes sense to make it off limits to inference. I just think we need to clearly distinguish between "succeeded to infer dynamic" and "failed to infer".

- unless you invoke universal Object methods like hashCode  (BTW, I was surprised to see that current compiler infers the type of hashCode correctly, even for "dynamic" argument). So the issue of "dynamic" propagation is not quite clear-cut.

> At the same time, I think it's important for inference to be simple enough for users to have an intuition about how it works and feel safe and confident relying on it.
> I could be wrong, but my hunch is that going full flow-sensitive would be a bad fit for that.

I think first sentence is a bit inconsistent with the second. How anyone can feel "safe and confident" if things start losing types after minor refactoring, with no warning or anything?

I didn't say they should! :)

If we, for example, make it an error to have an untyped "var" without an initializer then the user can't fall off the inference train without knowing they have.

– bob

Jan Mostert

unread,
Oct 8, 2015, 4:23:41 PM10/8/15
to General Dart Discussion
@Kasper, I find both atrocious, was just pointing out that there's already an atrocious way to do it that doesn't require a new feature in Dart.
But as Gunter pointed out, when using final variables, it might be needed.




--

Alex Tatumizer

unread,
Oct 8, 2015, 4:24:57 PM10/8/15
to mi...@dartlang.org
> If we, for example, make it an error to have an untyped "var" without an initializer then the user can't fall off the inference train without knowing they have.
This is a possibility. Basically, I think this would be good enough - simple and doesn't lead to surprises.


Alex Tatumizer

unread,
Oct 8, 2015, 4:44:30 PM10/8/15
to mi...@dartlang.org
Just one nitpick: when compiler sees uninitialized var, it should print error message asking to specify type, without mentioning "or initialize". Every now and then, I see examples when java's static analysis tool complains about potential null - and, to pacify it, people initialize with some irrelevant value, which makes the problem much worse - instead of failing on null pointer, program now runs with absurd data, and can go very far with that.


Matthew Butler

unread,
Oct 8, 2015, 8:43:46 PM10/8/15
to Dart Misc


On Thursday, October 8, 2015 at 5:44:30 PM UTC-3, tatumizer-v0.2 wrote:
Just one nitpick: when compiler sees uninitialized var, it should print error message asking to specify type, without mentioning "or initialize". 

C# did this. It used to drive me nuts. Particularly in JS (which I dealt with at the same time as C# code), I got into the habit of declaring variables at the top of a method. I try that in C#, and it blows up at me because I'm not yet ready to initialize it. If I want to provide a type I would. Making me do it when I declare by either providing a type, or supplying a value of the correct type is just annoying legwork then. 

Jan Mostert

unread,
Oct 9, 2015, 2:02:33 AM10/9/15
to Dart Misc
Is it all possible to introduce a new language feature like declaring that the variable is in a limbo state awaiting to be initialised and once it's initialised, only then it can be used?

final await x; // or whatever syntax you want to use to say that you're awaiting x to be initialised before it can be used.
final await y; 

if-statements can now stay exactly as is and the same for the try-catch as well as closures;

print(x) would throw an error because x is not yet initialised.

if (something) {
   // using x here would fail as it's not yet initialised 
    x = 1;
  // using x here would succeed, but no further assignments to x would be allowed because it's declared as final.
    y = 2;
} else {
  x = 0;
  y = 3;
}

x = 3; here would throw an exception because x is final and can only be initialised once.

final await z;
try {
  ...
  z = 1;
} catch(e){
  z = 2;
}

The advantage of this await syntax over final x = if(something) { .. is that you're not limited to one variable only, you're not mutilating try-catch and if-else syntax which are already in a recognisable form by anyone coming from just about any language.

Is this syntax something that's achievable in Dart?


--

Günter Zöchbauer

unread,
Oct 9, 2015, 3:23:01 AM10/9/15
to Dart Misc
That would work for me, even without special syntax. 
It must be initialized somewhere and must not be read before it's initialized.

Lasse R.H. Nielsen

unread,
Oct 9, 2015, 4:18:42 AM10/9/15
to mi...@dartlang.org
On Thu, Oct 8, 2015 at 6:32 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:


Many languages that do inference for locals tend to be more expression-oriented to avoid this trap. I wonder if that would work for Dart. If we made if () and {} expressions (with very very low precedence!) then you could do:

var x = if (something) {
  0;
} else {
  1;
}


That only requires making { stmts; expr } an expression - that is: an expression that executes statements before evaluating to a value - then you can use then you can use the conditional expression (?:) with block-expressions in the branches.
(Or any other syntax for the same thing - it does exist in other languages - like an expressions statement embeds an expression in a statement for effect, a "statement expression" would embed a statement in an expression, and then add a value).

The current approach, as you write below, would be (){stmts;return expr;}(), but that wouldn't always be the same thing because not all statements can safely be moved across function boundaries.

On the other hand, some of the cases where it would't be the same thing is when the stmts contains function-local control flow - break, continue or return.
Adding a way for an *expression* to have such may be a can of worms - compilers will have to handle control flow that happens in the middle of an expression (other than throw), and there has to be rules for what happens if you try it in field initializers or initializer lists (likely: it fails to compile).
Nothing impossible, but some invariants will no longer hold.

(The remaining case is await expressions, it may not be sufficient to make the function async and await its result).
 
In the absence of that, I sometimes work around this by hoisting that calculation to a separate function:

var x = calculateValue(something);


It's actually slightly hackish that languages have abstractions over expressions (functions) that allow statements, but they don't allow statements in expressions directly. One could see that as a failure - the language supports Tennent's principle of abstraction, but not the principle of correspondence. You an abstract any expression into a function call, but you can't inline any function invocation as an expression. 
 
I suppose if I wanted to be clever, I could do:

var x = () {
  if (something) {
    return 0;
  } else {
    return 1;
})();

But I think that style is perverse and wouldn't use it.

If you can write a function, you can *likely* give it a name.
In some cases, like initializer lists, the function then needs to be static and outside the current scope, which would mean that it doesn't have access to type parameters - until we add generic functions. (Principle of abstraction failure: we can't abstract over type parameters).
 
/L
--
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

Erik Ernst

unread,
Oct 9, 2015, 4:41:00 AM10/9/15
to Dart Misc
On Wed, Oct 7, 2015 at 10:53 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
Consider the following example:
var result =
    <int>[1,2,3].map((x)=>"Hello");
What is the type of "result"? Turns out, it's Iterable<dynamic>.
But in
 var result =
    <int>[1,2,3].where((x)=>x>0);
the type is correctly inferred as Iterable<int>.

Depends on what 'correct' means. ;)  Until we get polymorphic methods (such that functions/methods like `map` can have a type argument, not just classes), there is no way `map` could produce a result whose type argument is derived from the type of the function given as an argument. For that function, `(x) => "Hello"`, the type is "dynamic -> String", but this information is lost on `map`. For `where`, the problem doesn't exist because the type argument is taken from the class, not the method invocation, so we can easily get `Iterable<int>` there.

In case of map, there's no way to make inference work, even in principle, because there's no syntax to declare return type of mapping function.

For a "=>" function, the return type is the statically known type of the returned expression. But you're right that we will have to give it a name in order to be able to declare a type for a "() {}" function.
 
But even if returned type somehow could be figured out, there's no syntax to write declaration of "map" function so that compiler can deduce return type correctly.

Today, declaration of "map" is: Iterable map(f(E element))
Suppose, tomorrow dart adds extra feature to generics repertoire so we can write something like
Iterable<T> map(T f(E element))

That is under construction, but not trivial to do (similar problems have been solved for Java, Scala, C# etc. many years ago, but there are always new twists --- especially with respect to the treatment of type argument reification and "firstclass-ness" of poly methods, i.e., whether you can give a type argument to a function-valued variable).

Now dart CAN (in principle) figure out the return type of <int>[1,2,3].map((x)=>"Hello");
The problem is that adding a rule to the list of rules of type inference is a breaking change again!

Whether poly methods will be a breaking change is not obvious either, but you can go pretty far simply by saying that every type argument which is not given is implicitly given as `dynamic`.

But we want polymorphic methods, please!! ;-)

  best regards,

--
Erik Ernst  -  Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 København K, Denmark
CVR no. 28866984

Erik Ernst

unread,
Oct 9, 2015, 5:12:19 AM10/9/15
to Dart Misc
On Thu, Oct 8, 2015 at 4:48 AM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
@Bob: let me change sides for a moment - I will advocate for inference, but for more consistent inference.
How big is the problem to remove all limitations? Let's focus on "var", just to get a sense of it.
When there's an uninitialized var, compiler can take the type from any place it can see the assignment to this var (limit the search by same library, or even a file).
All other assignments must have same type (not a common denominator - exactly the same), otherwise it's an error.

It's not an easy trade-off: This particular rule (exactly the same type) might be inconvenient, but inference of a common denominator would be rather unstable during editing, and in particular it could invalidate already inserted completions. I'd still prefer tool support for inserting a declared type, rather than being bitten by unintended types that I can't see..
 
If compiler cannot find any assignments - error.
Thus, "var" is not synonymous with "dynamic" any longer. It means "inferred type". And inferred type cannot be "dynamic".
Whatever is supposed to be really dynamic, should be explicitly declared dynamic.
Now you example
var x;
if (something) {
   //some work
   return 0; 
} else {
   // other work
   return 1;
}
will work just fine.
No matter what someone can think about the usefulness of inference, "var as inferred type" now looks like a concept,
Over time, compiler can add heuristics, covering more cases of inference, but nothing will be broken by those new rules - it's just there will be less places where compiler cannot figure out the type. 
How about that? Any known common counterexamples?

It will break all substantial usages of dynamic types (say, some variable plays a conceptual role, but different representations are used along the way: `var document = "Hello"; .. document.toUpperCase() .. document = new MyDocumentType(); .. document.myFancyFeature() ..`).

  best regards,

Gen

unread,
Oct 9, 2015, 8:24:24 AM10/9/15
to Dart Misc
IMO:
1) The inferred type of a variable should be the same for all related variable bindings. Anything but simple is probably bad with regard to type inference.
E.g.
var x = new List<int>();
if (...){
  x = new List<num>();// Compilation error
}

2) The benefit of using "var" (meaning type inference) is that "var" remains even when the inferred type changes.
E.g. "var x = new HashMap<String,int>()" can easily be changed to "var x = new LinkedHashMap<String, double>()".

Vadim Tsushko

unread,
Oct 9, 2015, 9:43:46 AM10/9/15
to Dart Misc

пятница, 9 октября 2015 г., 14:12:19 UTC+5 пользователь Erik Ernst написал:

It will break all substantial usages of dynamic types (say, some variable plays a conceptual role, but different representations are used along the way: `var document = "Hello"; .. document.toUpperCase() .. document = new MyDocumentType(); .. document.myFancyFeature() ..`).


I guess it do not work already with current implementation of strong mode?
To make it work with strong mode we probably should change `var` to `dynamic` at `document` variable declaration.


 

Erik Ernst

unread,
Oct 9, 2015, 10:32:41 AM10/9/15
to Dart Misc
This is exactly the reason why balkanization of a language is a problem: You can't know what programs mean. As far as I can see, a language specification is the most appropriate device for getting answers to that question, and that answer is in line with the behavior of the dart virtual machine (`dart`) and `dart2js` compiled code (with `var`, the type of the declared variable is `dynamic`). I think we all want inference, so that's not the issue.

I'm just pushing for a way to do it that doesn't fuzzify the language semantics. ;)

  best regards,

tatumizer-v0.2

unread,
Oct 9, 2015, 12:00:00 PM10/9/15
to Dart Misc
@Erik, what do you think about the idea of allowing only initialized vars? So "var x;" without initializer is an error. Now "var" always means "inferred type". Isn't it a good idea?




Erik Ernst

unread,
Oct 9, 2015, 12:41:31 PM10/9/15
to Dart Misc
I like initialized vars (meaning: variables whose declaration includes an initializing expression), and I'd recommend using `final` wherever possible, too. But entirely outlawing `var x;` might be a little bit too harsh.

The cases that came up recently were about blocks returning values, and the motivation was that

```
    MyType x = longAndComplexExpressionProbablyMultiLine
       ? equallyLongThingWithThreeLevelsOfNestedBraces
       : etcEtc;
```

where the old-fashioned imperative style (just use `MyType x;` and then spend as many lines as needed on initializing it) seems to be justified now and then. I'll do a lot to avoid uninitialized variables in practice, though.

But I'm not happy about "other than that, `var` means inferred type", because that isn't Dart as specified. Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)  I have no problems supporting these ideas, I just don't want them to make the semantics fuzzy.


On Fri, Oct 9, 2015 at 6:00 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
@Erik, what do you think about the idea of allowing only initialized vars? So "var x;" without initializer is an error. Now "var" always means "inferred type". Isn't it a good idea?




--
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.

tatumizer-v0.2

unread,
Oct 9, 2015, 12:51:01 PM10/9/15
to Dart Misc
> But I'm not happy about "other than that, `var` means inferred type"
But there's no "other than that"! "var" will mean "inferred type", period. It doesn't ban uninitialized variables in general. It DOES ban uninitialized variable written as "var x;".
In your example, everything is fine-  you didn't say "var x;" - you said "MyType x;" - there's no problem with that, type is explicitly defined.

Bob Nystrom

unread,
Oct 9, 2015, 1:04:50 PM10/9/15
to General Dart Discussion

On Fri, Oct 9, 2015 at 9:41 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)


– bob

tatumizer-v0.2

unread,
Oct 9, 2015, 1:13:19 PM10/9/15
to Dart Misc
Slightly different perspective: with new "var" rules as discussed above, you can now interpret any variable declaration in dart in general as variant of "final_type x". When you specify type explicitly, e.g. "int x;", then final_type is "int". When you say "var x", compiler should get information about the type from somewhere, and it will do it like always does for anything "final": take from initializer.

BTW, that justifies the idea of not going in great lengths trying to figure out type from somewhere else: after all, we don't do it for "final" either (except one case: initializing finals in constructor - but it's not a big difference)

Gen

unread,
Oct 9, 2015, 2:03:29 PM10/9/15
to Dart Misc
But I'm not happy about "other than that, `var` means inferred type", because that isn't Dart as specified. Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)  I have no problems supporting these ideas, I just don't want them to make the semantics fuzzy.

1) I have proposed to use "let" for type inference and maybe strong mode. I see no need to change the meaning of "var".
2) Why not change the specification for the next Dart version ? Do I miss something ?
Besides, I do not read the dry specification of a language unless there is no better documentation available for a certain feature.

kc

unread,
Oct 10, 2015, 9:52:35 AM10/10/15
to Dart Misc
On Friday, October 9, 2015 at 5:41:31 PM UTC+1, Erik Ernst wrote:
I like initialized vars (meaning: variables whose declaration includes an initializing expression), and I'd recommend using `final` wherever possible, too. But entirely outlawing `var x;` might be a little bit too harsh.

The cases that came up recently were about blocks returning values, and the motivation was that

```
    MyType x = longAndComplexExpressionProbablyMultiLine
       ? equallyLongThingWithThreeLevelsOfNestedBraces
       : etcEtc;
```

where the old-fashioned imperative style (just use `MyType x;` and then spend as many lines as needed on initializing it) seems to be justified now and then. I'll do a lot to avoid uninitialized variables in practice, though.

But I'm not happy about "other than that, `var` means inferred type", because that isn't Dart as specified. Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)  I have no problems supporting these ideas, I just don't want them to make the semantics fuzzy.

The useful in production part is the horse. The Spec is the cart.

It's seriously dangerous for a projects health not to deliver something useful!

K.
 

Erik Ernst

unread,
Oct 12, 2015, 4:22:11 AM10/12/15
to Dart Misc
On Fri, Oct 9, 2015 at 6:51 PM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
> But I'm not happy about "other than that, `var` means inferred type"
But there's no "other than that"! "var" will mean "inferred type", period.

Of course, if you are taking a particular decision for granted then there is no need to have a discussion.

I just happen to think that real world programmers need to understand their programs as they write and maintain them, and silently introducing non-standard semantics into a tool which is said to implement Dart is not helpful for them. In contrast, if you use new syntax for new semantics then it's trivial to detect that it is being used (and was most likely intended to be used!).

It doesn't ban uninitialized variables in general. It DOES ban uninitialized variable written as "var x;".
In your example, everything is fine-  you didn't say "var x;" - you said "MyType x;" - there's no problem with that, type is explicitly defined.

I said so because the underlying topic at that point was "why would you ever need an uninitialized variable?", and I did not want to gratuitously mix that topic up with the discussion about declared type inference.

  best regards,

Erik Ernst

unread,
Oct 12, 2015, 4:32:17 AM10/12/15
to Dart Misc
Well, I'm not quite sure what your point is, but there might be a connection to the fact that the page about running python in a sandboxed environment that you are linking to mentions different versions of python (2.5 and 2.7) but it doesn't even mention version 3.0 (Py3k). Maybe you are saying that it is impossible to migrate an entire community from one version of a language to another (not so backward compatible) version, because they seem to carefully avoid Py3k?

As far as I can see, we won't _improve_ on that if we choose to introduce incompatible semantics silently, rather than under a new language version number.  ;-)

  best regards,

Erik Ernst

unread,
Oct 12, 2015, 4:37:46 AM10/12/15
to Dart Misc
On Fri, Oct 9, 2015 at 8:03 PM, Gen <gp78...@gmail.com> wrote:
But I'm not happy about "other than that, `var` means inferred type", because that isn't Dart as specified. Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)  I have no problems supporting these ideas, I just don't want them to make the semantics fuzzy.

1) I have proposed to use "let" for type inference and maybe strong mode. I see no need to change the meaning of "var".

Using `let` for immutable variables with inferred type would be great, no problems there!
 
2) Why not change the specification for the next Dart version ? Do I miss something ?
Besides, I do not read the dry specification of a language unless there is no better documentation available for a certain feature.

Language specifications aren't useful because everybody reads them, they are useful because bits and pieces of them can be studied carefully by tool implementers whenever there is a "How should the language behave in this situation?" question. Heck, even authors of books/blogs/whatever about the language might need to do the same thing, so hopefully you won't miss anything in the end. ;-)

  best regards,

Gen

unread,
Oct 12, 2015, 5:41:50 AM10/12/15
to Dart Misc

Language specifications aren't useful because everybody reads them, they are useful because bits and pieces of them can be studied carefully by tool implementers whenever there is a "How should the language behave in this situation?" question. Heck, even authors of books/blogs/whatever about the language might need to do the same thing, so hopefully you won't miss anything in the end. ;-)

I fully agree.
I meant that any feature or behavior of a language should be intuitive or safe (= compilation error) enough so that I do not need to read the specification.
IMO, the strategy to allow non-obvious differences between language versions or different platforms is bad.
The notorious example: No arbitrary size integers when compiled to Javascript.
Anything non-obvious should be made clear in obvious ways and not just somewhere in the spec or on stackoverflow.com.
The spec of a language is comparable to the end-user license agreement for programs.
I do not want having to read it and some people might not even understand it even if they tried.
Besides I wonder how far Dart will differ from platform to platform and over time after reading https://github.com/dart-lang/dart_enhancement_proposals/blob/master/Meetings/2015-09-30%20DEP%20Committee%20Meeting.md

Erik Ernst

unread,
Oct 12, 2015, 10:34:42 AM10/12/15
to Dart Misc
On Mon, Oct 12, 2015 at 11:41 AM, Gen <gp78...@gmail.com> wrote:

Language specifications aren't useful because everybody reads them, they are useful because bits and pieces of them can be studied carefully by tool implementers whenever there is a "How should the language behave in this situation?" question. Heck, even authors of books/blogs/whatever about the language might need to do the same thing, so hopefully you won't miss anything in the end. ;-)

I fully agree.
I meant that any feature or behavior of a language should be intuitive or safe (= compilation error) enough so that I do not need to read the specification.
IMO, the strategy to allow non-obvious differences between language versions or different platforms is bad.
The notorious example: No arbitrary size integers when compiled to Javascript.

Yup, that's a nasty one, but there are such a truckload of technical reasons why we won't have a proper `int` type when compiling to JavaScript code. I've given up on that one (currently ;-).

Anything non-obvious should be made clear in obvious ways and not just somewhere in the spec or on stackoverflow.com.

That sounds good, but I'm afraid it relies on familiarity rather than consistency, and you can't really tell what it takes for something to be "familiar" to everyone (and how do we even know that we've asked "everyone"?). So you can't ever check precisely whether we have now covered "anything non-obvious" or not in any given document or diagnostic message.

I think we'll have to rely on human judgment for that. If something is expected to be unfamiliar to many programmers then we'll have to try to help them see the issue and build the needed intuition. But stackoverflow.com might still help us now and then, and that's fine for the cases that still need more coverage, somehow.

The spec of a language is comparable to the end-user license agreement for programs.
I do not want having to read it and some people might not even understand it even if they tried.

Oh yes, we want standardization of those thingies as well, such that we will never have to read them.  ;-D
 
Besides I wonder how far Dart will differ from platform to platform and over time after reading https://github.com/dart-lang/dart_enhancement_proposals/blob/master/Meetings/2015-09-30%20DEP%20Committee%20Meeting.md

I'm pushing for consistency (platform-to-platform) and for changes (version-to-version) that do not just feel good, but also allow programmers to maintain their code without having to many weird "oh, but that means something different today" bugs.

Bob Nystrom

unread,
Oct 12, 2015, 12:13:28 PM10/12/15
to General Dart Discussion

On Mon, Oct 12, 2015 at 1:32 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Fri, Oct 9, 2015 at 7:04 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:

On Fri, Oct 9, 2015 at 9:41 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)

Well... :)

Well, I'm not quite sure what your point is, but there might be a connection to the fact that the page about running python in a sandboxed environment that you are linking to mentions different versions of python (2.5 and 2.7) but it doesn't even mention version 3.0 (Py3k). Maybe you are saying that it is impossible to migrate an entire community from one version of a language to another (not so backward compatible) version, because they seem to carefully avoid Py3k?

Sorry, I should have been less snarky and more clear.

My point is that Google itself supports a language that is widely used for large production applications, and that language—Python—has no specification whatsoever.

A spec doesn't seem to be the most important stepping stone on the path to success. It's certainly valuable, but I think if we get too hung up on what the spec does and doesn't permit we may get distracted from the much more important question, what is and isn't most helpful for our users.

– bob

Erik Ernst

unread,
Oct 13, 2015, 4:32:55 AM10/13/15
to Dart Misc
On Mon, Oct 12, 2015 at 6:12 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:

On Mon, Oct 12, 2015 at 1:32 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
On Fri, Oct 9, 2015 at 7:04 PM, 'Bob Nystrom' via Dart Misc <mi...@dartlang.org> wrote:

On Fri, Oct 9, 2015 at 9:41 AM, 'Erik Ernst' via Dart Misc <mi...@dartlang.org> wrote:
Am I really the only one around to think that it is seriously dangerous for a programming language that aims to be useful in production if its semantics is less than well-defined? ;)

Well... :)

Well, I'm not quite sure what your point is, but there might be a connection to the fact that the page about running python in a sandboxed environment that you are linking to mentions different versions of python (2.5 and 2.7) but it doesn't even mention version 3.0 (Py3k). Maybe you are saying that it is impossible to migrate an entire community from one version of a language to another (not so backward compatible) version, because they seem to carefully avoid Py3k?

Sorry, I should have been less snarky and more clear.

OK. (Cool, just learned a new word ;-).

My point is that Google itself supports a language that is widely used for large production applications, and that language—Python—has no specification whatsoever.


It is not endorsed by ECMA or ISO, but its intention and style seems to be quite similar to other language standardization documents .. e.g., in Sect. 5.2.1:

    An identifier occurring as an atom is a name. See section Identifiers and     
    keywords for lexical definition and section Naming and binding for 
    documentation of naming and binding.

.. and they even worked so hard on it that they've got a separate document for seven different versions.

A spec doesn't seem to be the most important stepping stone on the path to success. It's certainly valuable, but I think if we get too hung up on what the spec does and doesn't permit we may get distracted from the much more important question, what is and isn't most helpful for our users.

I'm not so hung up on a particular format, but I do think that it is useful for real-world programmers to know what their programs will do, also when the next version of a compiler comes out. I just think that a language specification is a reasonable means to that end.

  best regards,

kc

unread,
Oct 13, 2015, 8:14:14 AM10/13/15
to mi...@dartlang.org
On Tuesday, October 13, 2015 at 9:32:55 AM UTC+1, Erik Ernst wrote:

It is not endorsed by ECMA or ISO, but its intention and style seems to be quite similar to other language standardization documents .. e.g., in Sect. 5.2.1:

It's more a question of process and attitude. ECMA/TC52 and 'The Spec' were part of the collective hallucination that Dart was going to be adopted by the other browser vendors. Well this thread is appropriately titled because that was fairy dust. And Dart is left with a fairly cumbersome language design process.

You have expressed some interest in value objects/immutability. David Morgan has done some very interesting work in this area. If I was on the Dart team I would be *intensely* interested in how projects were using these concepts with an eye to providing lang support. Do the Dart team need to see a 4th or 40th third party implementation of value objects/types before something happens.


I'm not so hung up on a particular format, but I do think that it is useful for real-world programmers to know what their programs will do, also when the next version of a compiler comes out. I just think that a language specification is a reasonable means to that end.

Right. The area where The Spec has failed is in communicating with real-world developers and creating a sense of shared understanding of it's core ideas and semantics. (Sometimes it seems even Dart team members are confused).

Compare with Swift. The Swift Language Guide is very readable and the Swift team are able to move quickly as they evolve the language.

Also, the impression from the tech lead meeting was either the language designers get a move on or the implementation teams will get on and do their own thing to meet the goals of Flutter and Fletch.
 
K. 

Benjamin Strauß

unread,
Oct 13, 2015, 8:55:18 AM10/13/15
to Dart Misc
Am Dienstag, 13. Oktober 2015 14:14:14 UTC+2 schrieb kc:

It's more a question of process and attitude. ECMA/TC52 and 'The Spec' were part of the collective hallucination that Dart was going to be adopted by the other browser vendors. Well this thread is appropriately titled because that was fairy dust. And Dart is left with a fairly cumbersome language design process.

ECMA was part of that. The specification itself existed before TC52 was created. I believe a language needs a proper specification regardless if it's in a standards body or not. Java is specced by Oracle only.
 

I'm not so hung up on a particular format, but I do think that it is useful for real-world programmers to know what their programs will do, also when the next version of a compiler comes out. I just think that a language specification is a reasonable means to that end.

Right. The area where The Spec has failed is in communicating with real-world developers and creating a sense of shared understanding of it's core ideas and semantics. (Sometimes it seems even Dart team members are confused).

A language specification is not for real-world developers. A language spec exists so that engineers can properly implement compilers, VMs, analyzers, etc.

The thing that should create an understanding of a language for "normal" developers is a language guide.

Erik Ernst

unread,
Oct 13, 2015, 9:35:37 AM10/13/15
to Dart Misc
On Tue, Oct 13, 2015 at 2:14 PM, kc <kevin...@gmail.com> wrote:
On Tuesday, October 13, 2015 at 9:32:55 AM UTC+1, Erik Ernst wrote:
It is not endorsed by ECMA or ISO, [..]
It's more a question of process and attitude. [..]

You have expressed some interest in value objects/immutability. David Morgan has done some very interesting work in this area. If I was on the Dart team I would be *intensely* interested in how projects were using these concepts with an eye to providing lang support. Do the Dart team need to see a 4th or 40th third party implementation of value objects/types before something happens.

I'm indeed interested in first class values, but that's potentially a huge addition to the language so I don't expect that to happen very quickly. I'm maybe even more interested in fixing the function type subtype rule (return types should require covariance), and that's a near-one-liner change in the compilers. But things take time when they may potentially break existing code.

Here's another view on the speed: JavaScript went from ES5 (December 3, 2009) to ES6 (still in draft state almost 6 years later), whereas Dart had three versions of its language specification accepted as ECMA standards during the past <18 months. So the Dart standard is moving quite fast compared to others.

  best regards,

kc

unread,
Oct 13, 2015, 9:39:44 AM10/13/15
to Dart Misc

Benjamin Strauß

unread,
Oct 13, 2015, 9:55:40 AM10/13/15
to Dart Misc
I don't know what your point is.

kc

unread,
Oct 13, 2015, 10:05:29 AM10/13/15
to Dart Misc
On Tuesday, October 13, 2015 at 2:35:37 PM UTC+1, Erik Ernst wrote:

I'm indeed interested in first class values, but that's potentially a huge addition to the language so I don't expect that to happen very quickly. I'm maybe even more interested in fixing the function type subtype rule (return types should require covariance), and that's a near-one-liner change in the compilers. But things take time when they may potentially break existing code.

Quickly? Have you even considered contacting David to get the ball rolling on values types?
 

Here's another view on the speed: JavaScript went from ES5 (December 3, 2009) to ES6 (still in draft state almost 6 years later), whereas Dart had three versions of its language specification accepted as ECMA standards during the past <18 months. So the Dart standard is moving quite fast compared to others.

Good grief. JS is no example for anything. Three versions of a specification that no one is much interested in is not much use.

Swift was able to move swiftly. Look at 1.2 to 2.0. I'm guessing it's existing code base was bigger.

K.

Erik Ernst

unread,
Oct 13, 2015, 10:27:34 AM10/13/15
to Dart Misc
On Tue, Oct 13, 2015 at 4:05 PM, kc <kevin...@gmail.com> wrote:
On Tuesday, October 13, 2015 at 2:35:37 PM UTC+1, Erik Ernst wrote:

I'm indeed interested in first class values, but that's potentially a huge addition to the language so I don't expect that to happen very quickly. I'm maybe even more interested in fixing the function type subtype rule (return types should require covariance), and that's a near-one-liner change in the compilers. But things take time when they may potentially break existing code.

Quickly? Have you even considered contacting David to get the ball rolling on values types?

Have you? ;)

  best regards,

kc

unread,
Oct 13, 2015, 10:48:34 AM10/13/15
to Dart Misc
On Tuesday, October 13, 2015 at 3:27:34 PM UTC+1, Erik Ernst wrote:


On Tue, Oct 13, 2015 at 4:05 PM, kc <kevin...@gmail.com> wrote:
On Tuesday, October 13, 2015 at 2:35:37 PM UTC+1, Erik Ernst wrote:

I'm indeed interested in first class values, but that's potentially a huge addition to the language so I don't expect that to happen very quickly. I'm maybe even more interested in fixing the function type subtype rule (return types should require covariance), and that's a near-one-liner change in the compilers. But things take time when they may potentially break existing code.

Quickly? Have you even considered contacting David to get the ball rolling on values types?

Have you? ;)

I enquired how Ad's were using values/immutability with Dart. Which seems to be more than anyone form the Dart team has done.

I don't work for Google, I'm not on the Dart team and I'm not part of the language design team. It's your job - or another member of the Dart team -  to reach out.

K.

Erik Ernst

unread,
Oct 13, 2015, 11:10:55 AM10/13/15
to Dart Misc
On Tue, Oct 13, 2015 at 4:48 PM, kc <kevin...@gmail.com> wrote:
On Tuesday, October 13, 2015 at 3:27:34 PM UTC+1, Erik Ernst wrote:
On Tue, Oct 13, 2015 at 4:05 PM, kc <kevin...@gmail.com> wrote:
On Tuesday, October 13, 2015 at 2:35:37 PM UTC+1, Erik Ernst wrote:

I'm indeed interested in first class values, but that's potentially a huge addition to the language so I don't expect that to happen very quickly. I'm maybe even more interested in fixing the function type subtype rule (return types should require covariance), and that's a near-one-liner change in the compilers. But things take time when they may potentially break existing code.

Quickly? Have you even considered contacting David to get the ball rolling on values types?

Have you? ;)

I enquired how Ad's were using values/immutability with Dart. Which seems to be more than anyone form the Dart team has done.

I don't work for Google, I'm not on the Dart team and I'm not part of the language design team. It's your job - or another member of the Dart team -  to reach out.

Part of the job is to set priorities, and making 'reflectable' work well has to go above language design at this point.

tatumizer-v0.2

unread,
Oct 13, 2015, 12:09:38 PM10/13/15
to Dart Misc
From Bob's original announcement.
> One interesting outcome of it is that we're going to give each of the teams that owns a Dart implementation—the VM, dart4web, and Fletch—more leeway in what they support. They have the freedom to ship something that works for their platform but may not be supported on the other ones.

I don't quite understand this aesopian language. "Leeway"? What does it actually mean, in simple terms? That dart from now splits into 2 (or 3?) different languages/dialects?
Then why not just say so? Maybe it would be a good thing - there's a chance that useful features are added at least somewhere. Object literals, for example... They are absolutely necessary for UI programming.

Another thing: apart from the language, there are libraries. Actually, most of the value of the language is in those libraries. Additions to core libraries have same status wrt backward compatibility as the language itself. But things often don't get publicly discussed (Example: Zone. Created in complete secrecy. What Spec?  There's no documentation at all).








Bob Nystrom

unread,
Oct 13, 2015, 1:53:22 PM10/13/15
to General Dart Discussion
On Tue, Oct 13, 2015 at 9:09 AM, tatumizer-v0.2 <tatu...@gmail.com> wrote:
I don't quite understand this aesopian language. "Leeway"? What does it actually mean, in simple terms? That dart from now splits into 2 (or 3?) different languages/dialects?

It means an implementation does not require approval from all of the other implementation teams before they can make a change or choose to support or not support something.

One good example is bigints. dart2js has never supported them, and has no plan to. What we're saying is that decisions like that are OK.

There is a tension here. We obviously want to maximize compatibility across the different implementations. Code-reuse is the whole reason to even have different implementations of the same language.

At the same time, it's clear that we can't be perfectly compatible without making unrealistic sacrifices in performance or other areas. A dart2js that did support bigints would be less valuable to end users even though it was more compatible because—as far as anyone can tell—the perf and codesize hit of supporting bigints in JS would outweight their utility.

Then why not just say so? Maybe it would be a good thing - there's a chance that useful features are added at least somewhere. Object literals, for example... They are absolutely necessary for UI programming.

I can't predict the future, but I think we're hoping most platform-specific differences will be much smaller scale than that. More things like not having bigints or maybe some core library method throwing UnsupportedError. But, again, I'm just taking a guess here.

But things often don't get publicly discussed (Example: Zone. Created in complete secrecy. What Spec?  There's no documentation at all).

"Secrecy" implies an intent to hide. In most cases it's not that something is done in secret, it's simply that the changes aren't written down and shared publicly before they happen. In many cases, library changes are discussed in person with the relevant people, then they make the change.

– bob

kc

unread,
Oct 14, 2015, 10:18:59 AM10/14/15
to Dart Misc
On Tuesday, October 13, 2015 at 4:10:55 PM UTC+1, Erik Ernst wrote:

Part of the job is to set priorities, and making 'reflectable' work well has to go above language design at this point.


Reflectable? Right, because mirrors were apparently designed without consideration for resource usage/performance. A fairy dust philosophy especially for mobile.

Priorities? How about some multi-tasking. Or at least give developers insight as to what Dart's priorities are. The C# team are able to show their thinking, direction and priorities. There should be a mid-way between virtually no communication and a heavy weight DEP process with 50 page proposals which may-or-may-not who-knows turn into something.

Value objects/immutability should be useful for both semantics and performance with Flutter/Fletch - which is where Dart needs a result.

K.
It is loading more messages.
0 new messages