Discussion:
[dart-misc] Introducing Built Collections
David Morgan ☯
2015-04-10 10:38:23 UTC
Permalink
Hi everyone,

http://www.dartdocs.org/documentation/built_collection/0.0.1/index.html#built_collection/built_collection

I'm pleased to announce a new open source library for those who like a bit
of immutability in their collections.

The link has lots more info, but the short of it is: the library provides
new types splitting the SDK collection interfaces in half:

+ List --> BuiltList (immutable) and ListBuilder (mutable)
+ Set --> BuiltSet (immutable) and SetBuilder (mutable)
+ Map --> BuiltMap (immutable) and MapBuilder (mutable)

Code example:

var list = new BuiltList<int>([1, 2, 3]);
var updatedList = (list.toBuilder()..add(4)..add(5)).build();
var updatedMoreList = (updatedList.toBuilder()..where((x) => (x >
2))).build();

And a few nice points:

MyClass(this.builtList); // no need to copy defensively, it's immutable!
if (builtList1 == builtList2) { ... // deep comparison
var lists = new Set<BuiltList<int>>(); // deep hashCode, can be used in
sets/maps
new BuildList<int>([null]); // throws, nulls aren't allowed

Background:

I work at Google on a project that uses Dart, rather than the Dart team
itself. We've found this approach to collections to be very useful in
building immutable data types to represent UI state and for RPCs. We
decided to rewrite the custom collections we were using for open source
release in the hope that others would find them useful. So, enjoy :) ...
and please do provide feedback, to me directly or on the github issue
tracker: https://github.com/google/built-collection-dart

Regards

Morgan
--
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+***@dartlang.org.
Cristian Garcia
2015-04-10 21:05:28 UTC
Permalink
ᐧ
David,

Deep comparison and immutability sound sweet! I'd take that there is a
performance penalty to get these benefits, do you have any benchmarks on
this?

Thanks.
--
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+***@dartlang.org.
David Morgan ☯
2015-04-11 07:18:31 UTC
Permalink
That depends on precisely what you're doing with it.

If, for example, using BuiltList means you save doing lots of defensive
copies, it might well be faster than List.

It's not intended for use in computation, but rather for publishing
results. So your inner loop should be using List or ListBuilder rather than
creating lots of new BuiltLists. Once you've used mutable lists to do the
heavy lifting, you can use immutable lists to safely publish them / pass
them around.

BuiltList and ListBuilder do work together to save copying where possible.
This could be improved, still, so I'm interested in hearing about use cases
where it's not yet fast enough.

For what we're using them for, for data models of things displayed in a the
browser, they're certainly fast enough: if you're going to be rendering
something, just putting it in a collection is always going to be
comparatively cheap. Under the hood the built collections use the SDK ones,
so performance is basically a matter of the SDK base + the extra null/type
checks.
Post by Cristian Garcia
ᐧ
David,
Deep comparison and immutability sound sweet! I'd take that there is a
performance penalty to get these benefits, do you have any benchmarks on
this?
Thanks.
--
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+***@dartlang.org.
David Morgan ☯
2015-04-11 16:25:51 UTC
Permalink
Yes, binding with AngularDart is a big part of how we use them. Immutable
collections make it clear when you're updating something, because it's
always a field assignment.

This goes with the "mutable to calculate, build to publish" idea.
Can you use BuiltList with AngularDart?
ᐧ
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-11 22:15:00 UTC
Permalink
There are classes UnmodifiableMapView,, UnmodifiableListView in
dart:collection library.
Probably, your classes are slightly "more unmodifiable"... are you sure
this is a sufficient justification?


.
--
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+***@dartlang.org.
David Morgan ☯
2015-04-12 08:31:10 UTC
Permalink
Thanks Alex, yes, I'm quite sure ;) we've been using this approach for well
over a year, but have only just got around to rewriting for an open source
version. So you can consider the ideas well tested, even if the
implementation is new.

Here are a few comparisons with the unmodifiables:

// Creating an updated version with an extra element.
new UnmodifiableListView<int>(new List<int>.from(unmodifiableList)..add(1));
(builtList.toBuilder()..add(1)).build();

// Interaction with APIs that take "List".
UnmodifiableListView --> throws on mutate
builtList.toList() --> copies on mutate, so read-only use is efficient, but
mutates still work

// Efficiency.
UnmodifiableListView --> requires a full copy per update, or you keep the
mutable version around and break immutability
Build Collections --> manages hiding the mutable version for you, for
correctness + efficiency; it would be possible to support e.g. adding
single elements with no copying at all

In general, the Built Collections are exactly what we need for our use
case: collections that are part of a complex data model, e.g. things that
will be displayed to and edited by the user, or sent/received by RPC.

Hope that answers your question :)

Cheers

Morgan
Post by Alex Tatumizer
There are classes UnmodifiableMapView,, UnmodifiableListView in
dart:collection library.
Probably, your classes are slightly "more unmodifiable"... are you sure
this is a sufficient justification?
.
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-12 15:20:56 UTC
Permalink
Is it the same
as http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.html?
(The argument can be made that calling immutable map "ImmutableMap",
however straightforward, may have some cognitive advantages over
"BuiltMap", no?).

Basically, from logical perspective, it's the same as the aforementioned
UnmodifiableMap. In both cases, it's a value object. If you want to (kind
of) modify it, you have to create another object.
(which suggests another possible style of naming, like MapValue, ListValue
.. never mind. I just don't like "Built", to be honest).
--
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+***@dartlang.org.
Cogman
2015-04-13 16:53:55 UTC
Permalink
So, just throwing this in here. If I were to design a language and a
library for that language. I wouldn't call my collections "immutable".
Rather, a List would be immutable by default and if you wanted a mutable
list you would have the interface "MutableList".

In my experience, most interfaces don't care about getting mutable
collections, so why make mutability the default? It also helps with the
hierarchy of things. Because immutability fundamentally implies less
functionality than mutability, it makes sense that immutable data
structures are higher on the hierarchy than mutabible ones.

I'll get off my soapbox now :).
Is it the same as
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.html
?
(The argument can be made that calling immutable map "ImmutableMap",
however straightforward, may have some cognitive advantages over
"BuiltMap", no?).
Basically, from logical perspective, it's the same as the aforementioned
UnmodifiableMap. In both cases, it's a value object. If you want to (kind
of) modify it, you have to create another object.
(which suggests another possible style of naming, like MapValue,
ListValue .. never mind. I just don't like "Built", to be honest).
--
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
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-13 17:16:20 UTC
Permalink
Hi Cogman, how would you populate such immutable object? I don't like
builder - too much ceremony.
I was thinking about it lately, and my best take so far is this: provide
initialization function in constructor, e.g.
var firstMap=new ImmutableMap((map) {
// inside this function, it's a normal, modifiable map
map["foo"]="bar";
// etc.
});

Another constructor would provide a way to create ImmutableMap based on
existing map:
var secondMap = new ImmutableMap(firstMap, (map) {
map.remove("foo");
map["bar"]="baz";
}
No builders required.
Or maybe there is a better way?

Making everything immutable by default is too late anyway (remember
discussion about "final" by default?).
--
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+***@dartlang.org.
Cogman
2015-04-13 19:24:42 UTC
Permalink
@Alex, Yeah, it is too late for the discussion in dart. Just voicing my
opinion in case anyone goes off and makes a new language.

For the population problem, there are a couple of ways to tackle it. You
could always throw on the mutable collection a "Make immutable" or some
other method that copies out the elements of the mutable list into a
immutable list. You could use the builder, though I get that you don't
like it, they aren't too terrible usually.

If you had the hierarchy I suggested (List is immutable and then you have
MutableLists that are subtypes) then you probably wouldn't use either of
them, you would simply have all of your methods demand immutable
collections and then give them mutable collections. The parameter type
would be the contract that says "I will not modify this".
Post by Alex Tatumizer
Hi Cogman, how would you populate such immutable object? I don't like
builder - too much ceremony.
I was thinking about it lately, and my best take so far is this: provide
initialization function in constructor, e.g.
var firstMap=new ImmutableMap((map) {
// inside this function, it's a normal, modifiable map
map["foo"]="bar";
// etc.
});
Another constructor would provide a way to create ImmutableMap based on
var secondMap = new ImmutableMap(firstMap, (map) {
map.remove("foo");
map["bar"]="baz";
}
No builders required.
Or maybe there is a better way?
Making everything immutable by default is too late anyway (remember
discussion about "final" by default?).
--
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
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-13 19:44:01 UTC
Permalink
I understand that this is purely theoretical discussion. Nonetheless,
here's my rationale for encapsulating all modification logic in a function.

Essentially, Builder pattern is trying to create kind of brackets begin ...
end

E.g., in the parent's lib, if you want to "modify" a BuiltMap, you first
call "toBuilder()" and then "builder.build()".
So the whole pattern is about begin...end. In java, you may need it, for
the lack of better options, but in dart, you pass a function that does the
whole population - so "begin" is where function starts executing, and end
is where it returns. We have same thing without any extra words/concepts.
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-13 22:29:41 UTC
Permalink
@David: not sure this can be of any interest for you, but here are some
Built Collections do a deep comparison against other Built Collections of
the same type, only. Hashing is used to make repeated comparisons fast.
Built Collections are Hashable ... Built Collections do compute, and cache,
a deep hashCode...

The library is trying to do the impossible. There's no guarantee that
keys/values are immutable. Just because they are placed in immutable
container doesn't make them immutable themselves. Making this deep
equals/hashCode a default means that library promises more than it can
accomplish. But even if it could, there's a big question whether such
default would be warranted. I can't think of too many common use cases
where such "deep treatment" is necessary (except testing).
Built Collections Reject Nulls ... Built Collections Require Generic Type
Parameters... Built Collections Reject Wrong-type Elements, Keys and Values

This is an attempt to create a small island of java in dart. I don't think
it's a good idea - it's inconsistent with the rest of the language/libs.
It's like trying to be more pious than the Pope.

Take it lightly though, you can always say: this is what we needed, so
that's what we implemented. I can't argue with that.

P.S. Good quote:
Perfection is achieved, not when there is nothing more to add, but when
there is nothing left to take away (Antoine de Saint-Exupery)
--
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+***@dartlang.org.
Jonas Kello
2015-04-14 06:31:34 UTC
Permalink
I agree with Thomas, this should have been the built in default from the
start. It may not be perfect for the theorist, but for those who actually
practise programming in large multi-person projects this is essential. I
have been in projects where defensive copying was a pattern and it was not
pretty at all. Basically for all projects where multiple persons are
involved you will have code that you write that is published to be consumed
by someone else's code which in turn will publish that to be consumed by
someone else's code etc. If you don't know if things are mutable in those
scenarios you will fall in to the defensive copy pattern.

It is also useful for caching. You do not want to cache things that are
mutable. If someone keeps a reference around and then mutates it, the cache
will also be updated which is probably not what you want. Been there done
that too.

So anyway, thanks a lot for publishing this package! :-)

/Jonas
Post by Alex Tatumizer
@David: not sure this can be of any interest for you, but here are some
Built Collections do a deep comparison against other Built Collections
of the same type, only. Hashing is used to make repeated comparisons fast.
Built Collections are Hashable ... Built Collections do compute, and cache,
a deep hashCode...
The library is trying to do the impossible. There's no guarantee that
keys/values are immutable. Just because they are placed in immutable
container doesn't make them immutable themselves. Making this deep
equals/hashCode a default means that library promises more than it can
accomplish. But even if it could, there's a big question whether such
default would be warranted. I can't think of too many common use cases
where such "deep treatment" is necessary (except testing).
Built Collections Reject Nulls ... Built Collections Require Generic
Type Parameters... Built Collections Reject Wrong-type Elements, Keys and
Values
This is an attempt to create a small island of java in dart. I don't think
it's a good idea - it's inconsistent with the rest of the language/libs.
It's like trying to be more pious than the Pope.
Take it lightly though, you can always say: this is what we needed, so
that's what we implemented. I can't argue with that.
Perfection is achieved, not when there is nothing more to add, but when
there is nothing left to take away (Antoine de Saint-Exupery)
--
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+***@dartlang.org.
David Morgan ☯
2015-04-14 15:36:42 UTC
Permalink
Post by Jonas Kello
I agree with Thomas, this should have been the built in default from the
start. It may not be perfect for the theorist, but for those who actually
practise programming in large multi-person projects this is essential. I
have been in projects where defensive copying was a pattern and it was not
pretty at all. Basically for all projects where multiple persons are
involved you will have code that you write that is published to be consumed
by someone else's code which in turn will publish that to be consumed by
someone else's code etc. If you don't know if things are mutable in those
scenarios you will fall in to the defensive copy pattern.
Yes, I think the need for something like this gets bigger the more people
you have committing code. It's also a matter of the type of code. We're
building business logic over complex structured data, we really felt the
need for a strict approach to data.
Post by Jonas Kello
It is also useful for caching. You do not want to cache things that are
mutable. If someone keeps a reference around and then mutates it, the cache
will also be updated which is probably not what you want. Been there done
that too.
So anyway, thanks a lot for publishing this package! :-)
You're welcome, please send feature requests / bug reports :)
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-15 15:40:27 UTC
Permalink
@David: it seems that the word "with" is already hijacked by java and
others, where it is assigned a meaning diametrically opposite to our
intentions.
Pattern of its usage in java is: returning "this" after change, thus
allowing cascade of modifications.
E.g.
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/ec2/model/InstanceState.html#withCode%28java.lang.Integer%29

In dart, this kind of "with" is unnecessary (that's what cascade operator
is for), but still, maybe there's another word lurking somewhere, which can
be even better than "with"? (In dart, there's a couple of people very
skilled in naming, maybe someone can comment?).

General problem description (of which we have a trivial variant):
In a class Foo, provide a method that sets property x and returns NEW
instance of Foo containing the modification (old instance is not affected).
Find the best name for the method (which still might be "with", but I'm
note sure).
--
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+***@dartlang.org.
David Morgan ☯
2015-04-15 15:50:59 UTC
Permalink
I was pondering using "call":

list = list((b) => b.add(1));

It's minimal :) ... not particularly self-explanatory, but the whole thing
is already not very self-explanatory ... (nor is the cascade operator, for
that matter).
Post by Alex Tatumizer
@David: it seems that the word "with" is already hijacked by java and
others, where it is assigned a meaning diametrically opposite to our
intentions.
Pattern of its usage in java is: returning "this" after change, thus
allowing cascade of modifications.
E.g.
http://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/ec2/model/InstanceState.html#withCode%28java.lang.Integer%29
In dart, this kind of "with" is unnecessary (that's what cascade operator
is for), but still, maybe there's another word lurking somewhere, which can
be even better than "with"? (In dart, there's a couple of people very
skilled in naming, maybe someone can comment?).
In a class Foo, provide a method that sets property x and returns NEW
instance of Foo containing the modification (old instance is not affected).
Find the best name for the method (which still might be "with", but I'm
note sure).
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-15 16:47:06 UTC
Permalink
Plot thickens. Turns out,"with" is a reserved word in dart, so it won't
work anyway. "call" is not intuitive, as you noticed. Damn.
Instead of writing heavy tomes on design patterns, could people just
publish API designer vocabulary or something?
It's the same thing, just much shorter. That's probably why no one bothered
writing one: no money to be made on short book.
--
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+***@dartlang.org.
David Morgan ☯
2015-04-15 17:42:04 UTC
Permalink
How about

var list = new BuiltList<int>.build((b) => b..add(1)..add(2));
list = list.rebuild((b) => b..add(3)..add(4));

?
Post by Alex Tatumizer
Plot thickens. Turns out,"with" is a reserved word in dart, so it won't
work anyway. "call" is not intuitive, as you noticed. Damn.
Instead of writing heavy tomes on design patterns, could people just
publish API designer vocabulary or something?
It's the same thing, just much shorter. That's probably why no one
bothered writing one: no money to be made on short book.
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-15 17:58:12 UTC
Permalink
"build" looks ok. "rebuild" ... Hm. Maybe not bad either. :-). If you call
the thing BuiltList, it's only logical to name operations "build" and
"rebuild"
Maybe we have a winner?
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-15 19:21:40 UTC
Permalink
Another variant of naming is FixedList, with methods "fix" and "refix"
--
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+***@dartlang.org.
David Morgan ☯
2015-04-17 15:47:47 UTC
Permalink
Just published v0.1.0 with "build" and "rebuild".
Post by Alex Tatumizer
"build" looks ok. "rebuild" ... Hm. Maybe not bad either. :-). If you call
the thing BuiltList, it's only logical to name operations "build" and
"rebuild"
Maybe we have a winner?
--
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+***@dartlang.org.
David Morgan ☯
2015-05-14 08:33:26 UTC
Permalink
And now with BuiltListMultimap :)

BuiltSetMultimap to follow at some point. Quicker if someone asks for it :)
Post by David Morgan ☯
Just published v0.1.0 with "build" and "rebuild".
Post by Alex Tatumizer
"build" looks ok. "rebuild" ... Hm. Maybe not bad either. :-). If you
call the thing BuiltList, it's only logical to name operations "build" and
"rebuild"
Maybe we have a winner?
--
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+***@dartlang.org.
Ron Gonzalez Lobo
2015-05-14 17:53:23 UTC
Permalink
Awesome!

Mit freundlichen GrÌßen

Ron Gonzalez Lobo
Post by David Morgan ☯
And now with BuiltListMultimap :)
BuiltSetMultimap to follow at some point. Quicker if someone asks for it :)
Post by David Morgan ☯
Just published v0.1.0 with "build" and "rebuild".
Post by Alex Tatumizer
"build" looks ok. "rebuild" ... Hm. Maybe not bad either. :-). If you
call the thing BuiltList, it's only logical to name operations "build" and
"rebuild"
Maybe we have a winner?
--
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
--
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+***@dartlang.org.
Alex Tatumizer
2015-05-14 18:05:30 UTC
Permalink
Meanwhile, dart added unmodifiable maps and unmodifiable lists
https://code.google.com/p/dart/source/detail?r=45733
(list was added a bit earllier).

Apparently, dart at some point became sentient and learned how to read our
posts. If it likes something, it just silently adds it to the
implementation.
--
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+***@dartlang.org.
David Morgan ☯
2015-06-12 06:41:26 UTC
Permalink
...and now with BuiltSetMultimap :)

Dart will continue to evolve, of course. But true immutable types (i.e.
different interface to the mutable ones, as with the Built Collections)
won't be going into the SDK any time soon, there's pretty strong agreement
on that from the Dart team.

I do have a couple of issues open for changes to the SDK, there are a few
subtle points about providing immutable collections:

https://github.com/dart-lang/sdk/issues/23328 -- EfficientLenth: currently
the internal collections code uses a private interface to mark efficient
iterables. This means collections that don't implement List/Set sometimes
lead to unnecessary copying when used as Iterable with the SDK. (With Built
Collections you can use .toList(), .toSet() to avoid copying because they
use copy-on-write wrappers, but this is very non-obvious; you'd have to
inspect the SDK code to find out when it's needed).

https://github.com/dart-lang/sdk/issues/23327 -- const collection literals:
(actually just const lists): there's no way to tell at runtime if a List is
a const literal, so you can't avoid defensive copying when initializing
from a List literal, even if it's const.

Const Map literals do end up as a different type, so you can avoid copying
those if you like. But const Map literals have linear-time lookup, so I'm
not convinced it's better to reuse them than to copy into a hash map. Not
quite sure what the best solution is there.
Post by Alex Tatumizer
Meanwhile, dart added unmodifiable maps and unmodifiable lists
https://code.google.com/p/dart/source/detail?r=45733
(list was added a bit earllier).
Apparently, dart at some point became sentient and learned how to read our
posts. If it likes something, it just silently adds it to the
implementation.
--
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+***@dartlang.org.
David Morgan ☯
2015-07-15 14:55:56 UTC
Permalink
A quick heads-up that resolves a point made way up the thread (...can't
find the post...).

The point was: the assumptions made by Built Collections (deep
immutability, hashcode, equality) only make sense when you are dealing with
objects that play by the rules.

It was a good point, and is resolved by open sourcing a few more pieces
that make the whole picture make a lot more sense. These are just kicking
off, so there's no code to use yet, but it'll give an idea where things are
headed.

http://github.com/google/built_value.dart -- code generation for easy
implementation of "good value types", i.e. immutable, hashable, comparable;
much like @AutoValue in Java
http://github.com/google/enum_class.dart -- for when you want enums with
the power of classes
http://github.com/google/built_json.dart -- JSON serialization for
built_collection/built_value/built_enum

With these together you'll be able to build a full immutable/builderable
object model for your app with JSON serialization for server/client or
in-browser communication. Hopefully this starts to sound genuinely useful :)

I'll start a new thread when there is something for people to use, just
wanted to give a heads-up in case people are interested in getting involved
beforehand.

Cheers

Morgan
--
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+***@dartlang.org.
Anders Holmgren
2015-07-16 21:58:42 UTC
Permalink
Cool. Look forward to taking a look when you push. JSON de/serialisation has long been a hot topic in the dart world. Glory goes to s/he that solves it in a way that is to the liking of the masses.

The enum class is interesting. Firstly, cause it points out how close to useless dart enums are and secondly (thanks to the first point) I end up building a lot of bespoke enum classes so code gen support will be welcome.

I really hope dart enums get a make over at some point though
--
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+***@dartlang.org.
Jonas Kello
2015-09-04 20:54:52 UTC
Permalink
built_json looks really interesting! Seems like no code yet, any news on it?

/Jonas
Post by David Morgan ☯
A quick heads-up that resolves a point made way up the thread (...can't
find the post...).
The point was: the assumptions made by Built Collections (deep
immutability, hashcode, equality) only make sense when you are dealing with
objects that play by the rules.
It was a good point, and is resolved by open sourcing a few more pieces
that make the whole picture make a lot more sense. These are just kicking
off, so there's no code to use yet, but it'll give an idea where things are
headed.
http://github.com/google/built_value.dart -- code generation for easy
implementation of "good value types", i.e. immutable, hashable, comparable;
http://github.com/google/enum_class.dart -- for when you want enums with
the power of classes
http://github.com/google/built_json.dart -- JSON serialization for
built_collection/built_value/built_enum
With these together you'll be able to build a full immutable/builderable
object model for your app with JSON serialization for server/client or
in-browser communication. Hopefully this starts to sound genuinely useful :)
I'll start a new thread when there is something for people to use, just
wanted to give a heads-up in case people are interested in getting involved
beforehand.
Cheers
Morgan
--
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+***@dartlang.org.
'David "Morgan" Morgan' via Dart Misc
2015-09-07 07:28:07 UTC
Permalink
I hope so :)

enum_class is out, built_value will be next, then built_json. I'll post
here when they're released, of course you can also subscribe to github
notifications.
Post by Jonas Kello
built_json looks really interesting! Seems like no code yet, any news on it?
/Jonas
Post by David Morgan ☯
A quick heads-up that resolves a point made way up the thread (...can't
find the post...).
The point was: the assumptions made by Built Collections (deep
immutability, hashcode, equality) only make sense when you are dealing with
objects that play by the rules.
It was a good point, and is resolved by open sourcing a few more pieces
that make the whole picture make a lot more sense. These are just kicking
off, so there's no code to use yet, but it'll give an idea where things are
headed.
http://github.com/google/built_value.dart -- code generation for easy
implementation of "good value types", i.e. immutable, hashable, comparable;
http://github.com/google/enum_class.dart -- for when you want enums with
the power of classes
http://github.com/google/built_json.dart -- JSON serialization for
built_collection/built_value/built_enum
With these together you'll be able to build a full immutable/builderable
object model for your app with JSON serialization for server/client or
in-browser communication. Hopefully this starts to sound genuinely useful :)
I'll start a new thread when there is something for people to use, just
wanted to give a heads-up in case people are interested in getting involved
beforehand.
Cheers
Morgan
--
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
--
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+***@dartlang.org.
David Morgan ☯
2015-04-14 15:23:35 UTC
Permalink
Thanks Alex :) all feedback is appreciated. Answers inline.
Post by Alex Tatumizer
@David: not sure this can be of any interest for you, but here are some
Built Collections do a deep comparison against other Built Collections
of the same type, only. Hashing is used to make repeated comparisons fast.
Built Collections are Hashable ... Built Collections do compute, and cache,
a deep hashCode...
The library is trying to do the impossible. There's no guarantee that
keys/values are immutable. Just because they are placed in immutable
container doesn't make them immutable themselves. Making this deep
equals/hashCode a default means that library promises more than it can
accomplish. But even if it could, there's a big question whether such
default would be warranted. I can't think of too many common use cases
where such "deep treatment" is necessary (except testing).
It's useful for what we're doing, more detail below.

I'm comfortable with breaking for things that can't work with mutable
types; if you come from the Java world, at least, you're used to this.
There, all the containers that use hashing assume immutability.
Post by Alex Tatumizer
Built Collections Reject Nulls ... Built Collections Require Generic
Type Parameters... Built Collections Reject Wrong-type Elements, Keys and
Values
This is an attempt to create a small island of java in dart. I don't think
it's a good idea - it's inconsistent with the rest of the language/libs.
It's like trying to be more pious than the Pope.
Indeed, this is very strict. I'm not 100% sure about all these decisions,
but I wanted to release with everything as strict as possible. It's easier
to loosen up later than tighten up later.
Post by Alex Tatumizer
Take it lightly though, you can always say: this is what we needed, so
that's what we implemented. I can't argue with that.
:)

Our use case is for structured data that the user will interact with.

Here, you frequently need a type with a handful of fields, one or two of
which might be collections; and in those collections, you often need more
structured types.

So, pretty much, it's immutable types from top to bottom, with collections
as part of that. Because you might use any of these structured types in a
set or map, it's useful if they're immediately hashable and comparable.

Re: strictness, we have a big codebase and lots of developers, and we find
more strictness makes things more maintainable at scale.
Post by Alex Tatumizer
Perfection is achieved, not when there is nothing more to add, but when
there is nothing left to take away (Antoine de Saint-Exupery)
Yes :) ... unfortunately the requirements gathering process is sometimes
neverending ;)
--
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+***@dartlang.org.
David Morgan ☯
2015-04-13 20:02:53 UTC
Permalink
Nice idea!

You can still combine it with the cascade operator, e.g.:

list = list.with((b) { b..add(4)..add(5); });
c.f.
list = (list.toBuilder()..add(4)..add(5)).build();

For me the extra {} is a little unfortunate for inline use. Maybe:

list = list.with((b) => b..add(4)..add(5));

What do you think?
Post by Alex Tatumizer
I understand that this is purely theoretical discussion. Nonetheless,
here's my rationale for encapsulating all modification logic in a function.
Essentially, Builder pattern is trying to create kind of brackets begin
... end
E.g., in the parent's lib, if you want to "modify" a BuiltMap, you first
call "toBuilder()" and then "builder.build()".
So the whole pattern is about begin...end. In java, you may need it, for
the lack of better options, but in dart, you pass a function that does the
whole population - so "begin" is where function starts executing, and end
is where it returns. We have same thing without any extra words/concepts.
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-14 15:18:21 UTC
Permalink
Post by David Morgan ☯
list = list.with((b) => b..add(4)..add(5));
Yes, basically, that's what I meant. I like this variant :-)
--
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+***@dartlang.org.
David Morgan ☯
2015-04-14 15:33:46 UTC
Permalink
Post by Alex Tatumizer
Post by David Morgan ☯
list = list.with((b) => b..add(4)..add(5));
Yes, basically, that's what I meant. I like this variant :-)
I think we can add something along those lines, I will take a look. Thanks!

I do think "toBuilder" and "build" still have a place, for when you want to
pass around the builder. But hopefully that should be a minority of cases.
--
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+***@dartlang.org.
David Morgan ☯
2015-04-12 19:00:08 UTC
Permalink
Yes, it's partly inspired by the Guava collections. In particular,
rejecting nulls is directly from Guava.

There are a few differences, largely due to Java/Dart differences:

+ Dart has a very expressive, non-mutating Iterable interface. So, instead
of implementing mutable interfaces and throwing on attempt to mutate, we
can create new interfaces based on Iterable. For cases where you need the
mutable interfaces we use copy-on-write for efficient toList, toMap, toSet.
+ Java has no need for runtime type checking, so this isn't a question for
Guava. We've gone for runtime type checks as a good default, we'll revisit
that if it turns out to be too expensive.

The best name for BuiltList would be just "List", but that was taken ;)

There is a reason for "Built": deep immutability requires immutable value
types, and we create those following the builder pattern. So, it's built
all the way down: built values containing built collections containing more
built values. We like builders :) ... and Dart's cascade operator makes
them particularly easy to implement and use.

Cheers

Morgan
Is it the same as
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.html
?
(The argument can be made that calling immutable map "ImmutableMap",
however straightforward, may have some cognitive advantages over
"BuiltMap", no?).
Basically, from logical perspective, it's the same as the aforementioned
UnmodifiableMap. In both cases, it's a value object. If you want to (kind
of) modify it, you have to create another object.
(which suggests another possible style of naming, like MapValue,
ListValue .. never mind. I just don't like "Built", to be honest).
--
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+***@dartlang.org.
David Morgan ☯
2015-04-13 19:48:23 UTC
Permalink
Yes, it's partly inspired by the Guava collections. In particular,
rejecting nulls is directly from Guava.

There are a few differences, largely due to Java/Dart differences:

+ Dart has a very expressive, non-mutating Iterable interface. So, instead
of implementing mutable interfaces and throwing on attempt to mutate, we
can create new interfaces based on Iterable. For cases where you need the
mutable interfaces we use copy-on-write for efficient toList, toMap, toSet.
+ Java has no need for runtime type checking, so this isn't a question for
Guava. We've gone for runtime type checks as a good default, we'll revisit
that if it turns out to be too expensive.

The best name for BuiltList would be just "List", but that was taken ;)

There is a reason for "Built": deep immutability requires immutable value
types, and we create those following the builder pattern. So, it's built
all the way down: built values containing built collections containing more
built values. We like builders :) ... and Dart's cascade operator makes
them particularly easy to implement and use.

Cheers

Morgan
Is it the same as
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.html
?
(The argument can be made that calling immutable map "ImmutableMap",
however straightforward, may have some cognitive advantages over
"BuiltMap", no?).
Basically, from logical perspective, it's the same as the aforementioned
UnmodifiableMap. In both cases, it's a value object. If you want to (kind
of) modify it, you have to create another object.
(which suggests another possible style of naming, like MapValue,
ListValue .. never mind. I just don't like "Built", to be honest).
--
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+***@dartlang.org.
kc
2015-04-15 23:32:32 UTC
Permalink
The Fletch project is using the diff-an-immutable tree strategy. Maybe they
could use something like this.

K.
Post by David Morgan ☯
Yes, it's partly inspired by the Guava collections. In particular,
rejecting nulls is directly from Guava.
+ Dart has a very expressive, non-mutating Iterable interface. So,
instead of implementing mutable interfaces and throwing on attempt to
mutate, we can create new interfaces based on Iterable. For cases where you
need the mutable interfaces we use copy-on-write for efficient toList,
toMap, toSet.
+ Java has no need for runtime type checking, so this isn't a question
for Guava. We've gone for runtime type checks as a good default, we'll
revisit that if it turns out to be too expensive.
The best name for BuiltList would be just "List", but that was taken ;)
There is a reason for "Built": deep immutability requires immutable value
types, and we create those following the builder pattern. So, it's built
all the way down: built values containing built collections containing more
built values. We like builders :) ... and Dart's cascade operator makes
them particularly easy to implement and use.
Cheers
Morgan
Is it the same as
http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableMap.html
?
(The argument can be made that calling immutable map "ImmutableMap",
however straightforward, may have some cognitive advantages over
"BuiltMap", no?).
Basically, from logical perspective, it's the same as the aforementioned
UnmodifiableMap. In both cases, it's a value object. If you want to (kind
of) modify it, you have to create another object.
(which suggests another possible style of naming, like MapValue,
ListValue .. never mind. I just don't like "Built", to be honest).
--
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+***@dartlang.org.
Alex Tatumizer
2015-04-16 03:54:37 UTC
Permalink
Strong(er) typing is coming?
https://code.google.com/p/dart/source/detail?r=45190
--
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+***@dartlang.org.
'Paul Brauner' via Dart Misc
2015-04-16 08:18:55 UTC
Permalink
Fatal Warnings would be a good name for a band :)
Post by Alex Tatumizer
Strong(er) typing is coming?
https://code.google.com/p/dart/source/detail?r=45190
--
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
--
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+***@dartlang.org.
'Karl Klose' via Dart Misc
2015-04-16 08:38:26 UTC
Permalink
The fatal warnings flag is a tool to ensure that the code does not have any
static type warnings (for example, in a build step). It has the same effect
as running the analyzer with fatal warnings first and only compile the code
if that succeeded, but it does not change the way dart2js analyzes the
program and generates JavaScript code.
Post by Alex Tatumizer
Strong(er) typing is coming?
https://code.google.com/p/dart/source/detail?r=45190
--
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
--
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+***@dartlang.org.
'David "Morgan" Morgan' via Dart Misc
2015-04-16 14:43:09 UTC
Permalink
Unfortunately the analyzer currently has some big holes for type safety.

In particular, methods that take an Iterable are vulnerable to the
"Iterable<dynamic> is Iterable<anything>" problem:

new ListBuilder<int>().addAll(['string']);

The analyzer doesn't complain about this: a List<dynamic> can contain
String and a List<dynamic> is a List<int>.

It would be possible to skip checking every element if a List<int> is
passed in, and do individual element checks only for List<dynamic>. That
would encourage you to write:

new ListBuilder<int>().addAll(<int>['string']);

I'm not sure that's a good solution either because it adds boilerplate.

I'm hopeful that something will come along from the Dart team that helps
here, and the runtime type checks are just an interim solution.

Cheers

Morgan
Post by 'Karl Klose' via Dart Misc
The fatal warnings flag is a tool to ensure that the code does not have
any static type warnings (for example, in a build step). It has the same
effect as running the analyzer with fatal warnings first and only compile
the code if that succeeded, but it does not change the way dart2js analyzes
the program and generates JavaScript code.
Post by Alex Tatumizer
Strong(er) typing is coming?
https://code.google.com/p/dart/source/detail?r=45190
--
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
--
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
--
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+***@dartlang.org.
Continue reading on narkive:
Loading...