Maybe this is just a day at the beach for some of you fancy type programmers.
One invert function:
- works on sequential collections, parallel collections, Iterators,
Arrays, Strings, etc.
- preserves Stream laziness (something not presently accomplished by
e.g. zipped)
- is installed with an implicit conversion which takes only three
type parameters (for Tuple3) and no implicit parameters
(this being important in Predef for implicit search performance reasons)
The one change I had to make to the collections (and it should be
immaterial unless you need it) to achieve this lovely sameness of
implementation is to add this interface:
trait Container[+A, +CC[X] <: GenTraversableOnce[X]] extends Any
with GenTraversableOnce[A]
Because there is so far as I can tell no common parent to Iterator and
Traversable which preserves the shape of the container.
I just called it "Container". It doesn't have to be that, but please
for god's sake don't suggest I should call it
"GenTraversableOnceLike". Let's have something sanely named at the
very top of the hierarchy to which we can program when we're not
overly concerned with the distinctions among the many different ways
of bunching stuff.
Feedback solicited. (Silence is endorsement.) The total patch is quite
small, see for yourself.
Container sounds very ... C++ like (nothing wrong with that).
Depending on the things you want to cover ... what about Collection?
PS: Any news about the idea to reduce the number of traits in the collection hierarchy?
Thinking a bit about it, I pretty much like Collection. It will be familiar to Java people. This would fix one of the long-standing concerns that almost no one knows or can figure out which common collection type should be used.
On Wed, May 2, 2012 at 11:12 AM, Simon Ochsenreither
<simon.ochsenreit...@googlemail.com> wrote:
> Container sounds very ... C++ like (nothing wrong with that).
> Depending on the things you want to cover ... what about Collection?
> PS: Any news about the idea to reduce the number of traits in the collection
> hierarchy?
> Thinking a bit about it, I pretty much like Collection. It will be familiar
> to Java people. This would fix one of the long-standing concerns that almost
> no one knows or can figure out which common collection type should be used.
Think about all the confused emails and posts on StackOverflow when
Java converts find out that Iterator <: Collection...
On Wed, May 2, 2012 at 11:12 AM, Simon Ochsenreither
<simon.ochsenreit...@googlemail.com> wrote:
> Depending on the things you want to cover ... what about Collection?
That's fine with me, I thought of that one too. I thought maybe the
deprecated one was still floating around, but it's gone, so I don't
see a problem with it.
> This would fix one of the long-standing concerns that almost no one knows or can figure out which common collection type should be used.
Yes, it would be nice if people weren't always (understandably, it's
confusing and there are unnecessary penalties for trying to be
general) selecting overly specific types.
On Wed, May 2, 2012 at 11:15 AM, David Hall <d...@cs.berkeley.edu> wrote:
> Think about all the confused emails and posts on StackOverflow when
> Java converts find out that Iterator <: Collection...
Okay, let's just call it Stuff.
trait Stuff[+A, +CC[X] <: Stuff[X, CC]]
I'm only half kidding. Ready for some five-character standard names,
I am. They don't make them like you guys anymore, Seq Set and Map.
On Wed, May 2, 2012 at 8:31 PM, Paul Phillips <pa...@improving.org> wrote:
> On Wed, May 2, 2012 at 11:15 AM, David Hall <d...@cs.berkeley.edu> wrote:
> > Think about all the confused emails and posts on StackOverflow when
> > Java converts find out that Iterator <: Collection...
> Okay, let's just call it Stuff.
> trait Stuff[+A, +CC[X] <: Stuff[X, CC]]
> I'm only half kidding. Ready for some five-character standard names,
> I am. They don't make them like you guys anymore, Seq Set and Map.
Bag
-- Viktor Klang
Akka Tech Lead
Typesafe <http://www.typesafe.com/> - The software stack for applications
that scale
> On Wed, May 2, 2012 at 11:15 AM, David Hall <d...@cs.berkeley.edu> wrote:
> > Think about all the confused emails and posts on StackOverflow when
> > Java converts find out that Iterator <: Collection...
> Okay, let's just call it Stuff.
> trait Stuff[+A, +CC[X] <: Stuff[X, CC]]
> I'm only half kidding. Ready for some five-character standard names,
> I am. They don't make them like you guys anymore, Seq Set and Map.
On Wed, May 2, 2012 at 3:31 PM, Paul Phillips <pa...@improving.org> wrote:
> On Wed, May 2, 2012 at 11:15 AM, David Hall <d...@cs.berkeley.edu> wrote:
>> Think about all the confused emails and posts on StackOverflow when
>> Java converts find out that Iterator <: Collection...
> Okay, let's just call it Stuff.
Hah! No. Please. :-)
> trait Stuff[+A, +CC[X] <: Stuff[X, CC]]
One problem with with the above is that only collections with a single
type parameter can match it. So Map will never match (becomes
Iterable), nor BitSet (becomes Set). OTOH, your patch doesn't drag
Stuff down to every class -- just define it at the top-most level, so
I presume this isn't relevant to the issues you are trying to deal
with, but I thought I might as well raise the issue anyway, just in
case.
If that's not a problem, I'm happy with it (I'm happy with anything
that makes it possible for the user to interact with collections in
any other way than calling methods on them).
> I'm only half kidding. Ready for some five-character standard names,
> I am. They don't make them like you guys anymore, Seq Set and Map.
On Wed, May 2, 2012 at 11:35 AM, Daniel Sobral <dcsob...@gmail.com> wrote:
> One problem with with the above is that only collections with a single
> type parameter can match it. So Map will never match (becomes
> Iterable), nor BitSet (becomes Set). OTOH, your patch doesn't drag
> Stuff down to every class -- just define it at the top-most level, so
> I presume this isn't relevant to the issues you are trying to deal
> with, but I thought I might as well raise the issue anyway, just in
> case.
Any attempt to address arity-genericity with our current language
capabilities would rapidly defeat my ambition of having something
standard, pithily named, and simpler than anything which yet exists.
We already have plenty of complicated ways for people to do things.
I'm more than happy with squashing Map down to Iterable and BitSet
down to Set.
> On Wed, May 2, 2012 at 11:15 AM, David Hall<d...@cs.berkeley.edu> wrote:
>> Think about all the confused emails and posts on StackOverflow when
>> Java converts find out that Iterator<: Collection...
> Okay, let's just call it Stuff.
> trait Stuff[+A, +CC[X]<: Stuff[X, CC]]
> I'm only half kidding. Ready for some five-character standard names,
> I am. They don't make them like you guys anymore, Seq Set and Map.
At risk of being stoned by people who want, y'know, things to compile *quickly*, I'll point out that I think there's a More Generic Thing here than just collections.
+10 points from me if invert does the above for any arrow, not just Function1, using that arrow's definition of (&&&) and (***)
+all of the points from me if invert captures the whole idea that certain pairs of type constructors of arbitrary but fixed arity F[_, _, ...], G[_, _, ...] can be ‘transposed’ in a general way to yield a function for any A, B, ..., M, N, ... of type
F[G[A, B, ...], G[M, N, ...], ...] => G[F[A, M, ...], F[B, N, ...], ...]
(And here's the point where one of the Scalaz guys pop up and tell me they have this already. :-) Please do, if so!)
> Maybe this is just a day at the beach for some of you fancy type
> programmers.
> One invert function:
> - works on sequential collections, parallel collections, Iterators,
> Arrays, Strings, etc.
> - preserves Stream laziness (something not presently accomplished by
> e.g. zipped)
> - is installed with an implicit conversion which takes only three
> type parameters (for Tuple3) and no implicit parameters
> (this being important in Predef for implicit search performance
> reasons)
> The one change I had to make to the collections (and it should be
> immaterial unless you need it) to achieve this lovely sameness of
> implementation is to add this interface:
> trait Container[+A, +CC[X] <: GenTraversableOnce[X]] extends Any
> with GenTraversableOnce[A]
> Because there is so far as I can tell no common parent to Iterator and
> Traversable which preserves the shape of the container.
> I just called it "Container". It doesn't have to be that, but please
> for god's sake don't suggest I should call it
> "GenTraversableOnceLike". Let's have something sanely named at the
> very top of the hierarchy to which we can program when we're not
> overly concerned with the distinctions among the many different ways
> of bunching stuff.
> Feedback solicited. (Silence is endorsement.) The total patch is quite
> small, see for yourself.
> scala> (1 to 10 par, 1 to 10 par, 1 to 10 par).invert
> warning: there were 3 feature warnings; re-run with -feature for details
> res7: scala.collection.parallel.immutable.ParSeq[(Int, Int, Int)] =
> ParVector((1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6),
> (7,7,7), (8,8,8), (9,9,9), (10,10,10))
----------------------------------------
This message is intended exclusively for the individual(s) or entity to which it is addressed. It may contain information that is proprietary, privileged or confidential or otherwise legally exempt from disclosure. If you are not the named addressee, you are not authorized to read, print, retain, copy or disseminate this message or any part of it. If you have received this message in error, please notify the sender immediately by e-mail and delete all copies of the message.
Now I just wonder where it should be placed ... scala.collection.Collectionlooks a bit unfortunate. I guess we would need to Collection to Predef in this case ...
I wouldn't try to do it with the same function - I don't aspire to
that level of genericity anyway. But it's easy enough to go at least
to +5 (which I realize you must know.) And significantly further, I'm
sure, but one has to be steeled for battle.
class F1Ops[T1, T2](x: (T1, T2)) {
def merge[In, R1, R2](implicit w1: T1 => In => R1, w2: T2 => In =>
R2): In => (R1, R2) =
(p: In) => (x._1(p), x._2(p))
> At risk of being stoned by people who want, y'know, things to compile *quickly*, I'll point out that I think there's a More Generic Thing here than just collections.
> +10 points from me if invert does the above for any arrow, not just Function1, using that arrow's definition of (&&&) and (***)
My guess was you were writing *** though not sure. There are things with
*** that are not arrows by the way.
> +all of the points from me if invert captures the whole idea that certain pairs of type constructors of arbitrary but fixed arity F[_, _, ...], G[_, _, ...] can be ‘transposed’ in a general way to yield a function for any A, B, ..., M, N, ... of type
> F[G[A, B, ...], G[M, N, ...], ...] => G[F[A, M, ...], F[B, N, ...], ...]
Isn't this just writing it at the type-level? The type system is
turing-complete
> (And here's the point where one of the Scalaz guys pop up and tell me they have this already. :-) Please do, if so!)
Probably. The *** method is derived from any instance of the Split
type-class, which is not fully generalised.
trait Split[=>:[_, _]] extends Category[=>:] { self =>
def split[A, B, C, D](f: A =>: B, g: C =>: D): (A, C) =>: (B, D)
>> Maybe this is just a day at the beach for some of you fancy type
>> programmers.
>> One invert function:
>> - works on sequential collections, parallel collections, Iterators,
>> Arrays, Strings, etc.
>> - preserves Stream laziness (something not presently accomplished by
>> e.g. zipped)
>> - is installed with an implicit conversion which takes only three
>> type parameters (for Tuple3) and no implicit parameters
>> (this being important in Predef for implicit search performance
>> reasons)
>> The one change I had to make to the collections (and it should be
>> immaterial unless you need it) to achieve this lovely sameness of
>> implementation is to add this interface:
>> trait Container[+A, +CC[X] <: GenTraversableOnce[X]] extends Any
>> with GenTraversableOnce[A]
>> Because there is so far as I can tell no common parent to Iterator and
>> Traversable which preserves the shape of the container.
>> I just called it "Container". It doesn't have to be that, but please
>> for god's sake don't suggest I should call it
>> "GenTraversableOnceLike". Let's have something sanely named at the
>> very top of the hierarchy to which we can program when we're not
>> overly concerned with the distinctions among the many different ways
>> of bunching stuff.
>> Feedback solicited. (Silence is endorsement.) The total patch is quite
>> small, see for yourself.
>> scala> (1 to 10 par, 1 to 10 par, 1 to 10 par).invert
>> warning: there were 3 feature warnings; re-run with -feature for details
>> res7: scala.collection.parallel.immutable.ParSeq[(Int, Int, Int)] =
>> ParVector((1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6),
>> (7,7,7), (8,8,8), (9,9,9), (10,10,10))
> ----------------------------------------
> This message is intended exclusively for the individual(s) or entity to
> which it is addressed. It may contain information that is proprietary, > privileged or confidential or otherwise legally exempt from disclosure. > If you are not the named addressee, you are not authorized to read, > print, retain, copy or disseminate this message or any part of it. > If you have received this message in error, please notify the sender > immediately by e-mail and delete all copies of the message.
I vote against. Consistency in naming is hugely important for any library
and in particular for collections. Container breaks that consistency
because it uses a different name than all the other classes that fulfill
conceptually the same role. It's also a potential misnomer, because
containment implies persistence, so it's a stretch to say that an iterator
contains its elements.
Most importantly, we have so many fires to fight right now, that it would
be a welcome relief not to have to change the root classes of collections.
The only change to collections I would consider at the present stage is a
reduction in the number of base classes, not an augmentation. Yes, there is
a tiny loss of genericity but I personally would not care too much about
that.
On Thu, May 3, 2012 at 12:40 AM, Tony Morris <tonymor...@gmail.com> wrote:
> On 03/05/12 05:13, Ryan Hendrickson wrote:
> > At risk of being stoned by people who want, y'know, things to compile
> *quickly*, I'll point out that I think there's a More Generic Thing here
> than just collections.
> > +10 points from me if invert does the above for any arrow, not just
> Function1, using that arrow's definition of (&&&) and (***)
> My guess was you were writing *** though not sure. There are things with
> *** that are not arrows by the way.
> > +all of the points from me if invert captures the whole idea that
> certain pairs of type constructors of arbitrary but fixed arity F[_, _,
> ...], G[_, _, ...] can be ‘transposed’ in a general way to yield a function
> for any A, B, ..., M, N, ... of type
> > F[G[A, B, ...], G[M, N, ...], ...] => G[F[A, M, ...], F[B, N, ...],
> ...]
> Isn't this just writing it at the type-level? The type system is
> turing-complete
> > (And here's the point where one of the Scalaz guys pop up and tell me
> they have this already. :-) Please do, if so!)
> Probably. The *** method is derived from any instance of the Split
> type-class, which is not fully generalised.
> trait Split[=>:[_, _]] extends Category[=>:] { self =>
> def split[A, B, C, D](f: A =>: B, g: C =>: D): (A, C) =>: (B, D)
> }
> >> Maybe this is just a day at the beach for some of you fancy type
> >> programmers.
> >> One invert function:
> >> - works on sequential collections, parallel collections, Iterators,
> >> Arrays, Strings, etc.
> >> - preserves Stream laziness (something not presently accomplished by
> >> e.g. zipped)
> >> - is installed with an implicit conversion which takes only three
> >> type parameters (for Tuple3) and no implicit parameters
> >> (this being important in Predef for implicit search performance
> >> reasons)
> >> The one change I had to make to the collections (and it should be
> >> immaterial unless you need it) to achieve this lovely sameness of
> >> implementation is to add this interface:
> >> trait Container[+A, +CC[X] <: GenTraversableOnce[X]] extends Any
> >> with GenTraversableOnce[A]
> >> Because there is so far as I can tell no common parent to Iterator and
> >> Traversable which preserves the shape of the container.
> >> I just called it "Container". It doesn't have to be that, but please
> >> for god's sake don't suggest I should call it
> >> "GenTraversableOnceLike". Let's have something sanely named at the
> >> very top of the hierarchy to which we can program when we're not
> >> overly concerned with the distinctions among the many different ways
> >> of bunching stuff.
> >> Feedback solicited. (Silence is endorsement.) The total patch is quite
> >> small, see for yourself.
> >> scala> (1 to 10 par, 1 to 10 par, 1 to 10 par).invert
> >> warning: there were 3 feature warnings; re-run with -feature for details
> >> res7: scala.collection.parallel.immutable.ParSeq[(Int, Int, Int)] =
> >> ParVector((1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5), (6,6,6),
> >> (7,7,7), (8,8,8), (9,9,9), (10,10,10))
> > ----------------------------------------
> > This message is intended exclusively for the individual(s) or entity to
> > which it is addressed. It may contain information that is proprietary,
> > privileged or confidential or otherwise legally exempt from disclosure.
> > If you are not the named addressee, you are not authorized to read,
> > print, retain, copy or disseminate this message or any part of it.
> > If you have received this message in error, please notify the sender
> > immediately by e-mail and delete all copies of the message.
> This message is intended exclusively for the individual(s) or entity to
> which it is addressed. It may contain information that is proprietary, > privileged or confidential or otherwise legally exempt from disclosure. > If you are not the named addressee, you are not authorized to read, > print, retain, copy or disseminate this message or any part of it. > If you have received this message in error, please notify the sender > immediately by e-mail and delete all copies of the message.
Please, if you don't want me to read a message - don't send it.
How shall I know before reading, that I shall not read it, when you send
it to me, and the disclaimer is at the end?
I don't accept this disclaimer - not for this mail, not for any future
mail. Tell you lawyers.
Notice, that in my legal scope, you can't define such a contract from
one side.
On Thu, May 3, 2012 at 8:18 AM, Stefan Wagner <hirnst...@arcor.de> wrote:
> Please, if you don't want me to read a message - don't send it.
Note that this is common (especially American) legal boilerplate. Some
people can't even control it: their corporate mail systems attach it to any
email they send, whether they like it or not.
Stupid, yes, but usually not something the sender is including by their own
will. It's usually the fault of corporate lawyers...
>> This message is intended exclusively for the individual(s) or entity to
>> which it is addressed. It may contain information that is proprietary, >> privileged or confidential or otherwise legally exempt from disclosure. >> If you are not the named addressee, you are not authorized to read, >> print, retain, copy or disseminate this message or any part of it. >> If you have received this message in error, please notify the sender >> immediately by e-mail and delete all copies of the message.
> Please, if you don't want me to read a message - don't send it.
> How shall I know before reading, that I shall not read it, when you send
> it to me, and the disclaimer is at the end?
> I don't accept this disclaimer - not for this mail, not for any future
> mail. Tell you lawyers.
> Notice, that in my legal scope, you can't define such a contract from
> one side.
That particular horse died of vicious violence many times over.
Regards,
Roland Kuhn
Typesafe – The software stack for applications that scale.
twitter: @rolandkuhn
PS: at least the disclaimer is in a position where it is easily ignored.
It's incredibly rude to hijack my thread to air your grievances about
something unrelated. Please, this is "scala-language" and it's plenty
difficult keeping people focused as it is.
On Thu, May 3, 2012 at 5:18 AM, Stefan Wagner <hirnst...@arcor.de> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> Am 02.05.2012 21:13, schrieb Ryan Hendrickson:
>> This message is intended exclusively for the individual(s) or entity to
>> which it is addressed. It may contain information that is proprietary,
>> privileged or confidential or otherwise legally exempt from disclosure.
>> If you are not the named addressee, you are not authorized to read,
>> print, retain, copy or disseminate this message or any part of it.
>> If you have received this message in error, please notify the sender
>> immediately by e-mail and delete all copies of the message.
> Please, if you don't want me to read a message - don't send it.
> How shall I know before reading, that I shall not read it, when you send
> it to me, and the disclaimer is at the end?
> I don't accept this disclaimer - not for this mail, not for any future
> mail. Tell you lawyers.
> Notice, that in my legal scope, you can't define such a contract from
> one side.
> - --
> Tschööö--->...Stefan
> - ---------------------------
> Don't visit my homepage at:
> http://home.arcor-online.net/hirnstrom > -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.10 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
> This message is intended exclusively for the individual(s) or entity to
> which it is addressed. It may contain information that is proprietary, > privileged or confidential or otherwise legally exempt from disclosure. > If you are not the named addressee, you are not authorized to read, > print, retain, copy or disseminate this message or any part of it. > If you have received this message in error, please notify the sender > immediately by e-mail and delete all copies of the message.
Please, if you don't want me to read a message - don't send it.
How shall I know before reading, that I shall not read it, when you send
it to me, and the disclaimer is at the end?
I don't accept this disclaimer - not for this mail, not for any future
mail. Tell you lawyers.
Notice, that in my legal scope, you can't define such a contract from
one side.
> It's incredibly rude to hijack my thread to air your grievances about
> something unrelated. Please, this is "scala-language" and it's plenty
> difficult keeping people focused as it is.
> On Thu, May 3, 2012 at 5:18 AM, Stefan Wagner <hirnst...@arcor.de> wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> > Am 02.05.2012 21:13, schrieb Ryan Hendrickson:
> >> This message is intended exclusively for the individual(s) or entity to
> >> which it is addressed. It may contain information that is proprietary,
> >> privileged or confidential or otherwise legally exempt from disclosure.
> >> If you are not the named addressee, you are not authorized to read,
> >> print, retain, copy or disseminate this message or any part of it.
> >> If you have received this message in error, please notify the sender
> >> immediately by e-mail and delete all copies of the message.
> > Please, if you don't want me to read a message - don't send it.
> > How shall I know before reading, that I shall not read it, when you send
> > it to me, and the disclaimer is at the end?
> > I don't accept this disclaimer - not for this mail, not for any future
> > mail. Tell you lawyers.
> > Notice, that in my legal scope, you can't define such a contract from
> > one side.
> > - --
> > Tschööö--->...Stefan
> > - ---------------------------
> > Don't visit my homepage at:
> > http://home.arcor-online.net/hirnstrom > > -----BEGIN PGP SIGNATURE-----
> > Version: GnuPG v1.4.10 (GNU/Linux)
> > Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
On May 3, 2:28 am, Paul Phillips <pa...@improving.org> wrote:
> On Wed, May 2, 2012 at 11:12 AM, Simon Ochsenreither <simon.ochsenreit...@googlemail.com> wrote:
> > This would fix one of the long-standing concerns that almost no one knows or can figure out which common collection type should be used.
> Yes, it would be nice if people weren't always (understandably, it's
> confusing and there are unnecessary penalties for trying to be
> general) selecting overly specific types.
I am thinking the problem is that the interface names are too general,
and thus end up as conflated gibberish, e.g. "GenTraversableOnceLike".
I would vote for naming the interface "Invert". Orthogonality is
important.
But why not a more general fold operation and interface named
"Foldable"?
I understand a fold can create a new copy of the abstraction it is
folding over. Foldable could contain a fold method and an invert
method. The invert method calls the fold method. Then subtypes only
have to implement the fold method.
Also, a Traversable combines a Functor.map and Foldable.fold in a
single pass of the iteration:
Applicative programming with effects, McBride & Paterson
The Essence of the Iterator Pattern, Gibbons & Oliveira