Discussion:
[dart-misc] Dart Language and Library Newsletter (2017-08-18)
'Florian Loitsch' via Dart Misc
2017-08-18 16:29:15 UTC
Permalink
Github link:
https://github.com/dart-lang/sdk/blob/e6e8d35323dbc431d9b9aed32b20d5462702999f/docs/newsletter/20170818.md

Earlier newsletters:
https://github.com/dart-lang/sdk/blob/1daab67666ce4f7fe5f04b1349000a5492af6302/docs/newsletter/20170811.md
https://github.com/dart-lang/sdk/blob/d94cecba3ceaf6578315764a07292ea0d5e082c3/docs/
newsletter/20170804.md
https://github.com/dart-lang/sdk/blob/d94cecba3ceaf6578315764a07292ea0d5e082c3/docs/
newsletter/20170728.md

Dart Language and Library Newsletter

Welcome to the Dart Language and Library Newsletter.
<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#if-you-missed-it>If
you missed it

Did you know that you can write trailing commas to arguments and
parameters? This feature was added to the specification about a year ago.

It's main use-case is to unify parameter and argument lists that span
multiple lines. For example, Flutter <http://flutter.io/> uses it
extensively to keep tree-like instantiations nicely aligned:

return new Material(
// Column is a vertical, linear layout.
child: new Column(
children: <Widget>[
new MyAppBar(
title: new Text(
'Example title',
style: Theme.of(context).primaryTextTheme.title,
),
),
new Expanded(
child: new Center(
child: new Text('Hello, world!'),
),
),
],
),

Note how every argument list ends with a comma. The dartfmt tool knows
about these trailing commas and ensures that the individual entries stay on
their own lines so that it is easy to move them around with cut and paste.

Recently, we also updated the specification to allow trailing commas in
asserts. This makes the syntax of asserts more consistent with function
calls.
<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#function-type-syntax>Function
Type Syntax

A few months ago, we added a new function type syntax to Dart (we mentioned
it in our first newsletter).

// Examples:typedef F = void Function(int); // A void function that
takes an int.
void foo(T Function<T>(T x) f) { // foo takes a generic function.
...
}
class A {
// A has a field `f` of type function that takes a String and returns void.
void Function(String) f;
}

Before we added the new function-type syntaxes, we evaluated multiple
options. In this section I will summarize some of the discussions we had.
<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#motivation>
Motivation

The new function-type syntax intends to solve three issues:

1. the old typedef syntax doesn't support generic types.
2. the old function syntax can't be used for fields and locals.
3. in the old syntax, providing only one identifier in an argument
position is interpreted as name and not type. For example: typedef
f(int); is *not* a typedef for a function that expects an int, but for a
function that expects dynamic and names the argument "int".

With Dart 2.0 we will support generic methods, and also generic closures.
This means that a function can accept a generic function as argument. We
were lacking a way to express this type.

Dart 1.x has two ways to express function types: a) an inline syntax for
parameters and b) typedefs.

It was easy to extend the inline syntax to support generic arguments:

// Takes a function `factoryForA` that is generic on T.void foo(A<T>
factoryForA<T>()) {
A<int> x = factoryForA<int>();
A<String> x = factoryForA<String>();
}

However, there was no easy way to do the same for typedefs:

typedef A<T> FactoryForA<T>();// Does *not* do what we want it to do:
FactoryForA f; // A function that returns an
`A<dynamic>`.FactoryForA<String> f2; // A function that returns an
`A<String>`.
f<int>(); // Error: `f` is not generic.

We had already used the most consistent place for the generic method
argument as a template argument to the typedefitself. If we could go back
in time, we could change it as follows:

typedef<T> List<T> TemplateTypedef();TemplateTypedef<int> f; // A
function that returns a List<int>.TemplateTypedef f; // A function
that returns a List<dynamic>.
typedef List<T> GenericTypedef<T>();GenericTypedef f; // A function
that is generic.List<int> ints = f<int>();List<String> strings =
f<String>();

Given that this would be a breaking change we explored alternatives that
would also solve the other two issues. In particular the new syntax had to
work for locals and fields, too.

First and foremost the new syntax had to be readable. It also had to solve
the three mentioned issues. Finally, we wanted to make sure, we didn't
choose a syntax that would hinder future evolution of the language. We made
sure that the syntax would work with:

- nullability: the syntax must be nullable without too much hassle:

(int)->int?; // A function that is nullable, or that returns a
nullable integer?
Problem disappears with <-
int <- (int)? ; vs int? <- (int)

- union types (in case we ever want them).

<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#common-characteristics>Common
Characteristics

For all the following proposals we had decided that the arguments could
either be just the type, or optionally have a name. For example, (int)->int is
equivalent to (int id)->int. Especially with multiple arguments of the same
type, providing a name can make it much easier to reason about the type: (int
id, int priority) -> void. However, type-wise these parameter names are
ignored.

All of the proposals thus interpret single-argument identifiers as types.
This is in contrast to the old syntax where a single identifier would state
the name of the parameter: in void foo(bar(int)) {...} the int is the name
of the parameter to bar. This discrepancy is hopefully temporary, as we
intend to eventually change the behavior of the old syntax.
<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#right---arrow>Right
-> Arrow

Using -> as function-type syntax feels very natural and is used in many
other languages: Swift, F#, SML, OCaml, Haskell, Miranda, Coq, Kotlin, and
Scala (with =>).

Examples:

typedef F = (int) -> void; // Function from (int) to void.typedef
F<T> = () -> List<T>; // Template Typedef.typedef F = <T>(T) ->
List<T>; // Generic function from T to List<T>.

We could even allow a short form when there is only one argument: int->int.

We have experimented with this syntax: [
https://codereview.chromium.org/2439573003/]

Advantages:

- easy to learn and familiar to many developers.
- could support shorthand form int->int.

Open questions:

- support shorthand form?
- whitespace. Should it be (int, int) -> String or (int, int)->String,
etc.

Disadvantages:

- Relatively late token. The parser would have to do relatively big
lookaheads.
- Works badly with nullable types:

typedef F = (int) -> int?; // Nullable function or nullable int?//
Could be disambiguated as follows:typedef F = ((int)->int)?; //
Clearly nullable function.


<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#left---arrow>Left
<- Arrow

This section explores using <- as function-type syntax. There is at least
one other language that uses this syntax: Twelf
<http://www.cs.cmu.edu/~twelf/guide-1-2/twelf_3.html>.

Examples:

typedef F = void <- (int); // Function from (int) to void.typedef
F<T> = List<T> <- (); // Template Typedef.typedef F = List<T> <-
<T>(T); // Generic function from T to List<T>.

Could also allow a short form: int<-int. (For some reason this seems to
read less nicely than int->int.)

We have experimented with this syntax: [
https://codereview.chromium.org/2466393002/]

Advantages:

- return value is on the left, similar to normal function signatures.
This also simplifies typedefs, where the return value is more likely to
stay on the first line.
- faster to parse, since the <- doesn't require a lot of look-ahead.
- relatively similar to ->.
- no problems with nullable types:

typedef F = int <- (int)?; // Nullable function.typedef F = int?
<- (int); // Returns nullable int.


Open Questions:

- whitespace?
- support shorthand form?

Disadvantages:

- <- is ambiguous: x<-y ? foo(x) : foo(y) // if x < (-y) ....
- Not as familiar as ->.

<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#function>
Function

Dart already uses Function as general type for functions. It is relatively
straightforward to extend the use of Function to include return and
parameter types. (And no: it's not Function<int, int> since that wouldn't
work for named arguments).

typedef F = void Function(int); // Function from (int) to
void.typedef F<T> = List<T> Function(); // Template Typedef.typedef F
= List<T> Function<T>(T); // Generic function from T to List<T>.

This form does not allow any shorthand syntax, but fits nicely into the
existing parameter syntax.

Before we accepted this syntax, we had experimented with this syntax: [
https://codereview.chromium.org/2482923002/]

Advantages:

- very similar to the syntax of the corresponding function declarations.
- no ambiguity.
- (almost) no new syntax. That is, the type can be immediately
extrapolated from other syntax.
- no open questions wrt whitespace.
- symmetries with existing use of Function:

Function f; // a function.Function(int x) f; // a function that
takes an int.double Function(int) f; // a function that takes an int
and returns a double.


Disadvantages:

- longer.

<https://gist.github.com/floitschG/f5eaf5048da7194071b0119276b2e920#conclusion>
Conclusion

We found that the Function-based syntax fits nicely into Dart and fulfills
all of our requirements. Due to its similarity to function declarations it
is also very future-proof. Any feature that works with function
declarations should work with the Function-type syntax, as well.
--
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.
a***@gmail.com
2017-08-24 23:39:41 UTC
Permalink
I *really* don't understand the syntax in the given examples for the new
Function types.

// Examples:
void foo(T Function<T>(T x) f) {
...
}


I think I understand that *T* means the type returned is the same as the
type passed, but what's up with the diamond and f? It just looks why too
busy. Maybe it could be broken up by defining the different parts
separating?
--
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.
r***@gmail.com
2017-08-25 01:01:44 UTC
Permalink
You just need to think about it differently.

Function arguments in Dart are always "name value". So:

Function<T>(T x) f

is declaring an argument "f" of type "Function<T>(T x)". As for the type
itself, it's:

Function<return>(args...)

This is just using the normal generics syntax like List<int> does.


--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone
elsehttp://refi64.com

On Aug 24, 2017 at 7:06 PM, <aggieborn <***@gmail.com>> wrote:

I *really* don't understand the syntax in the given examples for the new
Function types.

// Examples:
void foo(T Function<T>(T x) f) {
...
}


I think I understand that *T* means the type returned is the same as the
type passed, but what's up with the diamond and f? It just looks why too
busy. Maybe it could be broken up by defining the different parts
separating?
--
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.
a***@gmail.com
2017-08-25 03:18:18 UTC
Permalink
The example was actually:

T Function<T>(T x) f

So is it defining the return type twice? I haven't actually used this and
don't see a use for it other than to be like JavaScript. Which I don't
think Dart needs to emulate. But I digress.
Post by r***@gmail.com
You just need to think about it differently.
Function<T>(T x) f
is declaring an argument "f" of type "Function<T>(T x)". As for the type
Function<return>(args...)
This is just using the normal generics syntax like List<int> does.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone elsehttp://refi64.com
I *really* don't understand the syntax in the given examples for the new
Function types.
void foo(T Function<T>(T x) f) {
...
}
I think I understand that *T* means the type returned is the same as the
type passed, but what's up with the diamond and f? It just looks why too
busy. Maybe it could be broken up by defining the different parts
separating?
--
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
--
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.
r***@gmail.com
2017-08-25 03:36:08 UTC
Permalink
Ohhh that makes more sense. I'm sorry; I mixed it up.

Just mentally replace "function" with a function name and it'll all make
sense:


T Function<T>(T x)
T myfunc<T>(T x)


It's just the type of a generic function.

FWIW the main "use case" is mostly consistency: this is an actual type,
whereas the old syntax mixed the type with the name.


--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone
elsehttp://refi64.com

On Aug 24, 2017 at 10:18 PM, <aggieborn <***@gmail.com>> wrote:

The example was actually:

T Function<T>(T x) f

So is it defining the return type twice? I haven't actually used this and
don't see a use for it other than to be like JavaScript. Which I don't
think Dart needs to emulate. But I digress.
Post by r***@gmail.com
You just need to think about it differently.
Function<T>(T x) f
is declaring an argument "f" of type "Function<T>(T x)". As for the type
Function<return>(args...)
This is just using the normal generics syntax like List<int> does.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone elsehttp://refi64.com
I *really* don't understand the syntax in the given examples for the new
Function types.
void foo(T Function<T>(T x) f) {
...
}
I think I understand that *T* means the type returned is the same as the
type passed, but what's up with the diamond and f? It just looks why too
busy. Maybe it could be broken up by defining the different parts
separating?
--
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
--
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.
'Erik Ernst' via Dart Misc
2017-08-25 07:29:18 UTC
Permalink
Post by r***@gmail.com
Ohhh that makes more sense. I'm sorry; I mixed it up.
Just mentally replace "function" with a function name and it'll all make
T Function<T>(T x)
T myfunc<T>(T x)
It's just the type of a generic function.
Right, the fact that function types are so similar to function declarations
was the main motivation for having this syntax, even though it's not the
most concise choice.

FWIW the main "use case" is mostly consistency: this is an actual type,
Post by r***@gmail.com
whereas the old syntax mixed the type with the name.
Also the ability to use function types in a larger number of situations
(such as `List<void Function(int)>` and `int Function() f = () => 42;`)
without a typedef.
Post by r***@gmail.com
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone elsehttp://refi64.com
T Function<T>(T x) f
So is it defining the return type twice? I haven't actually used this and
don't see a use for it other than to be like JavaScript. Which I don't
think Dart needs to emulate. But I digress.
Post by r***@gmail.com
You just need to think about it differently.
Function<T>(T x) f
is declaring an argument "f" of type "Function<T>(T x)". As for the type
Function<return>(args...)
This is just using the normal generics syntax like List<int> does.
--
Ryan (ラむアン)
Yoko Shimomura, ryo (supercell/EGOIST), Hiroyuki Sawano >> everyone elsehttp://refi64.com
I *really* don't understand the syntax in the given examples for the new
Function types.
void foo(T Function<T>(T x) f) {
...
}
I think I understand that *T* means the type returned is the same as the
type passed, but what's up with the diamond and f? It just looks why too
busy. Maybe it could be broken up by defining the different parts
separating?
--
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
--
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
--
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
--
Erik Ernst - Google Danmark ApS
Skt Petri Passage 5, 2 sal, 1165 KÞbenhavn K, Denmark
CVR no. 28866984
--
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.
Continue reading on narkive:
Loading...