5 ms·
>With Scala you feel smart having just got something to work in a beautiful way but when you look around the room to tell your clojure colleague how clever you
by pkinsky 13y ago
>With Scala you feel smart having just got something to work in a beautiful way but when you look around the room to tell your clojure colleague how clever you are, you notice he left 3 hours ago and there is a post-it saying use a Map
I don't get this. Scala has a great collections library, including a Map type. What, exactly, is the author complaining about?
- nickik 13y agoHis point is that Scala and the Scala community dont just use maps, they always want everything in types and that is why every library does it that way. Its bad practice just to use a map. In Clojure land its the other way around even if we put something in a type (deftype) we right interface to make it look like its not (defrecord). Its not what is possible, but what is. And the fact is that all the Clojure web framework and library's use the same data structure even if the underlying implementation is different. See how ring uses much of the same thing as the pedestal service.
- yummyfajitas 13y agoYes, and there is a good reason why Scalaland uses types. Consider a Spray-like API using only maps: val cookies = Map("sessionid" -> "1234567") val headers = Map("Content-Type" -> "application/javascript") setCookies(headers) { setHeaders(headers) { complete { obj } } } With Scala's "make everything a different type" approach, that's a compile error - setCookies will expect a List[Cookie], not a List[HttpHeader]. Those of us living in Scalaland are not as smart as the Clojure guys. We make mistakes sometimes and find it handy when the compiler yells at us.
- kasey_junk 13y agoThis is actually a good example of something I don't like in Scala. They don't make this sort of differentiation easy enough. Adding a Haskell style newtype would be really, really useful.
- yummyfajitas 13y agoScala has value types. case class MyNewType(x: String) extends AnyVal What do you want to do that that isn't sufficient for?
- kasey_junk 13y agoAnyVal's would probably be sufficient except for the following: - Instantiation of the MyNewType happens all the time and is not obvious from inspection of the code (generics, use as another type if we implement a trait, etc). - If we want to call any of the methods on the wrapped type we have to call directly to the wrapped type violating Demeter. - Verbosity.
- yummyfajitas 13y agoIf we want to call any of the methods on the wrapped type we have to call directly to the wrapped type violating Demeter. You can also use tagged types: http://eed3si9n.com/learning-scalaz/Tagged+type.html http://eed3si9n.com/learning-scalaz/Tagged+type.html But most of the methods will untag the type. I.e., ("foo" @@ ValidJsonString).substring(3,7) will be a String, not a String @@ ValidJsonString.
- noelwelsh 13y agoUnboxed tagged types to the rescue: http://etorreborre.blogspot.co.uk/2011/11/practical-uses-for-unboxed-tagged-types.html http://etorreborre.blogspot.co.uk/2011/11/practical-uses-for... Scalaz implements this, so you can use it straight away. We use it mostly to control implicit selection.
- kasey_junk 13y agoTagged types also have their problems. 1st they don't propagate, call a function on the tagged type and it returns the underlying type. 2nd they aren't type safe against the tagged type, so you can pass tagged types into functions that take the underlying type by default. 3rd in practice my code with tagged types ends up having lots of boilerplate and/or magic code that is hard to understand. 4th there are some pretty heinous compiler bugs that you will encounter with tagged types.