Kasper Peulen
2015-12-14 21:11:46 UTC
The last couple of weeks, I've been exploring strong mode.
And I try to not left type local variables, but use inference instead.
One type of construct that feels a bit off in this scenario, is
initializing a local variable to null, and do an if ... else ... construct
to calculate the value.
Same for try ... catch kind of constructs.
In this way, there is no type inference possible.
My question is, how do you guys do this? And what would be a good style?
I have here maybe a good example, I'm coding right now. Please don't put
too much attention about the actual code, I just want to give an example,
for a general concept:
class Car {
final Position start;
final Position end;
final bool horizontal;
final int length;
final List<Position> positions;
factory Car(Position start, bool horizontal, int length) {
var end;
if (horizontal) {
end = start + new Position(length - 1, 0);
} else {
end = start + new Position(0, length - 1);
}
var positions;
if (length == 2) {
positions = <Position>[start, end];
} else {
if (horizontal) {
positions = <Position>[start, start + new Position(1, 0), end];
} else {
positions = <Position>[start, start + new Position(0, 1), end];
}
}
return new Car._(start, end, horizontal, length, positions);
}
Car._(this.start, this.end, this.horizontal, this.length, this.positions);
}
So there is no type inference possible here. And strong mode gets worried.
So there are a couple of possibilities to get type inference to work,
probably the shortest one (and maybe the least readable):
factory Car(Position start, bool horizontal, int length) {
var end = horizontal
? start + new Position(length - 1, 0)
: start + new Position(0, length - 1);
var positions = length == 2
? <Position>[start, end]
: horizontal
? <Position>[start, start + new Position(1, 0), end]
: <Position>[start, start + new Position(0, 1), end];
return new Car._(start, end, horizontal, length, positions);
}
Another option is using, two extra static functions:
static Position _getEnd(Position start, bool horizontal, int length) {
if (horizontal) {
return start + new Position(length - 1, 0);
} else {
return start + new Position(0, length - 1);
}
}
static List<Position> _getPositions(
Position start, bool horizontal, int length, Position end) {
if (length == 2) {
return <Position>[start, end];
} else {
if (horizontal)
return <Position>[start, start + new Position(1, 0), end];
else
return <Position>[start, start + new Position(0, 1), end];
}
}
factory Car(Position start, bool horizontal, int length) {
var end = _getEnd(start, horizontal, length);
var positions = _getPositions(start, horizontal, length, end);
return new Car._(start, end, horizontal, length, positions);
}
Generally, I would not go for this, it is quite much extra chars to type
(annotating all the types of those two functions).
And for two functions that I only use one time, only in the factory
constructor.
There is yet another alternative, which may look a bit ugly, but does a
good job in some sense imo:
factory Car(Position start, bool horizontal, int length) {
var end = () {
if (horizontal) {
return start + new Position(length - 1, 0);
} else {
return start + new Position(0, length - 1);
}
}();
var positions = () {
if (length == 2) {
return <Position>[start, end];
} else {
if (horizontal)
return <Position>[start, start + new Position(1, 0), end];
else
return <Position>[start, start + new Position(0, 1), end];
}
}();
return new Car._(start, end, horizontal, length, positions);
}
So, now what style do you guys think fits the job best here, to get
inference working?
I think the problem is, that there is no clear winner. It is also quite
hard to think about some language addition that could give a clear winner
here.
Here is some thought I had today. Basically, allowing the get keyword in
local scope, as some sugar for anonymous functions that immediately execute.
factory Car(Position start, bool horizontal, int length) {
var end = get {
if (horizontal) {
return start + new Position(length - 1, 0);
} else {
return start + new Position(0, length - 1);
}
}
var positions = get {
if (length == 2) {
return [start, end];
} else {
if (horizontal)
return [start, start + new Position(1, 0), end];
else
return [start, start + new Position(0, 1), end];
}
}
return new Car._(start, end, horizontal, length, positions);
}
Any thoughts? Other ideas? And maybe more practically, how would you write
this kind of code using Dart today?
And I try to not left type local variables, but use inference instead.
One type of construct that feels a bit off in this scenario, is
initializing a local variable to null, and do an if ... else ... construct
to calculate the value.
Same for try ... catch kind of constructs.
In this way, there is no type inference possible.
My question is, how do you guys do this? And what would be a good style?
I have here maybe a good example, I'm coding right now. Please don't put
too much attention about the actual code, I just want to give an example,
for a general concept:
class Car {
final Position start;
final Position end;
final bool horizontal;
final int length;
final List<Position> positions;
factory Car(Position start, bool horizontal, int length) {
var end;
if (horizontal) {
end = start + new Position(length - 1, 0);
} else {
end = start + new Position(0, length - 1);
}
var positions;
if (length == 2) {
positions = <Position>[start, end];
} else {
if (horizontal) {
positions = <Position>[start, start + new Position(1, 0), end];
} else {
positions = <Position>[start, start + new Position(0, 1), end];
}
}
return new Car._(start, end, horizontal, length, positions);
}
Car._(this.start, this.end, this.horizontal, this.length, this.positions);
}
So there is no type inference possible here. And strong mode gets worried.
So there are a couple of possibilities to get type inference to work,
probably the shortest one (and maybe the least readable):
factory Car(Position start, bool horizontal, int length) {
var end = horizontal
? start + new Position(length - 1, 0)
: start + new Position(0, length - 1);
var positions = length == 2
? <Position>[start, end]
: horizontal
? <Position>[start, start + new Position(1, 0), end]
: <Position>[start, start + new Position(0, 1), end];
return new Car._(start, end, horizontal, length, positions);
}
Another option is using, two extra static functions:
static Position _getEnd(Position start, bool horizontal, int length) {
if (horizontal) {
return start + new Position(length - 1, 0);
} else {
return start + new Position(0, length - 1);
}
}
static List<Position> _getPositions(
Position start, bool horizontal, int length, Position end) {
if (length == 2) {
return <Position>[start, end];
} else {
if (horizontal)
return <Position>[start, start + new Position(1, 0), end];
else
return <Position>[start, start + new Position(0, 1), end];
}
}
factory Car(Position start, bool horizontal, int length) {
var end = _getEnd(start, horizontal, length);
var positions = _getPositions(start, horizontal, length, end);
return new Car._(start, end, horizontal, length, positions);
}
Generally, I would not go for this, it is quite much extra chars to type
(annotating all the types of those two functions).
And for two functions that I only use one time, only in the factory
constructor.
There is yet another alternative, which may look a bit ugly, but does a
good job in some sense imo:
factory Car(Position start, bool horizontal, int length) {
var end = () {
if (horizontal) {
return start + new Position(length - 1, 0);
} else {
return start + new Position(0, length - 1);
}
}();
var positions = () {
if (length == 2) {
return <Position>[start, end];
} else {
if (horizontal)
return <Position>[start, start + new Position(1, 0), end];
else
return <Position>[start, start + new Position(0, 1), end];
}
}();
return new Car._(start, end, horizontal, length, positions);
}
So, now what style do you guys think fits the job best here, to get
inference working?
I think the problem is, that there is no clear winner. It is also quite
hard to think about some language addition that could give a clear winner
here.
Here is some thought I had today. Basically, allowing the get keyword in
local scope, as some sugar for anonymous functions that immediately execute.
factory Car(Position start, bool horizontal, int length) {
var end = get {
if (horizontal) {
return start + new Position(length - 1, 0);
} else {
return start + new Position(0, length - 1);
}
}
var positions = get {
if (length == 2) {
return [start, end];
} else {
if (horizontal)
return [start, start + new Position(1, 0), end];
else
return [start, start + new Position(0, 1), end];
}
}
return new Car._(start, end, horizontal, length, positions);
}
Any thoughts? Other ideas? And maybe more practically, how would you write
this kind of code using Dart today?
--
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.
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
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+***@dartlang.org.