Very nice examples but perhaps better to lose the reference to "LSP"
or make it clearer?
If the next line after setting res2 is: assert(res2.isInstanceOf[BitSet])
then I don't quite get substitutable behavior if I am expecting a BitSet.
LSP within certain bounds for sure but not blanket LSP.

Also, I am not sure what you mean by "100% safe". Perhaps you mean
statically type-checked according to the scala type system (which is what
you kind of say later in the same sentence - which I think sums it up nicely
and adequately).

Not trying to nit-pick. I just find type-safety to be a small subset of the
potentially desirable properties of programs. I would hate someone to
think that any program I wrote was "100% safe" just because it compiled
or met some type systems constraints.

Cheers, Paul.

On Thu, Nov 24, 2011 at 7:28 PM, Kevin Wright <kev.lee.wri...@gmail.com> wrote:
> I guess I missed the point in my (rather terse) example.
> What I was demonstrating is that the expression doesn't just change the
> contents of the collection, but also the type of the collection itself.  For
> example:
> val bitSet = BitSet(1,2,3) //a BitSet can only hold integers, it subclasses
> Set[Int]
> val res1 = bitSet map {2*} //BitSet(2,4,6)
> val res2 = bitSet map {_.toString} //Set("1","2","3") BitSets can't hold
> strings, so returns a Set[String], as per the Liskov Substitution
> Principle.
> val myMap = Map(1 -> "x", 2 -> "y", 3 -> "z") //a Map[K,V] is also a
> collection of K->V pairs
> val res3 = myMap map {x => x._1.toString ->
> x._2} //Map("1"->"x","2"->"y","3"->"z"), a Map[String, String]
> val res4 = myMap map {case (a,b) => a.toString -> b} //more readable via
> pattern matching
> val res5 = myMap map {_._1} //List(1,2,3), a List[Int]
> val res6 = myMap map {_._2} //List("x","y","z"), a List[String]
> This is all 100% safe and statically typed, and is made possible by the
> "scary" CanBuildFrom implicit parameter that Stephen mention in his article.
> I don't believe that Fantom can do this, not least because it doesn't have
> highly-optimised collection types such as BitSet, it doesn't consider Maps
> to subclass collections of pairs, and it doesn't support creation of your
> own paramaterised collection types.  So far as I'm aware, Scala is the only
> language in existence that directly supports such a scheme (though I imagine
> it would be totally possible to duplicate using something like Lisp macros)
> It looks threatening in the documentation, but when you actually use this
> stuff it's really quite effortless.  The best part is that these collections
> are defined entirely in library code using completely standard syntax
> without a single line of compiler support required.  Anybody could have
> implemented them without touching the compiler, and it's completely possible
> to implement your own collection types that fit transparently into this
> hierarchy (although you *do* have to understand the full method signatures
> at that point)
> 2011/11/24 Cédric Beust ♔ <ced...@beust.com>
>>
>> On Wed, Nov 23, 2011 at 3:05 PM, Kevin Wright <kev.lee.wri...@gmail.com>
>> wrote:
>>>
>>> They're also core to the mechanism that allows collections to just do the
>>> Right Thing(tm).  For example:
>>> someBitSet map {_.toString}
>>
>> Right, but you can achieve the same result without needing implicits. I'll
>> just show how Fantom does it but I'm sure the same applies to
>> Gosu/Ceylon/Kotlin:
>>     // a set of A instances, where A has a toUppercase method
>>     aSet := [ A("foo"), A("bar") ]
>>     l := aSet.map | v->Str | { v.toUppercase }
>>     echo(l)
>>     echo(l.typeof)
>> [FOO, BAR]
>> sys::Str[]
>> The signature of map() is exactly what you would expect: it takes a
>> function that takes an element of the collection and returns "something",
>> and the type of your expression is "list of something" (here we transformed
>> a list of A's into a list of strings).
>> It's really not rocket science, and the fact that you need implicits to
>> achieve this result is an implementation detail that's very specific to
>> Scala.
>> Sure, you can handwave it with "You don't need to understand the exact
>> details of the API", but the truth is... you really do. Not a week goes by
>> without me having to go check out a Javadoc or the signature of java.util or
>> Guava method. And saying that only library authors need to know about
>> implicits, CanBuildFrom and its triple generic signature is creating a rift
>> between the Scala developers (people who know and people who don't), which
>> is worrisome.
>
> --
> You received this message because you are subscribed to the Google Groups
> "The Java Posse" group.
> To post to this group, send email to javaposse@googlegroups.com.
> To unsubscribe from this group, send email to
> javaposse+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/javaposse?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups "The 
Java Posse" group.
To post to this group, send email to javaposse@googlegroups.com.
To unsubscribe from this group, send email to 
javaposse+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/javaposse?hl=en.

Reply via email to