8 ms·
Ah, synchronizedCollection, the... hang on... wait a sec... one more sec, someone's doing something... now? no, not yet, wait... how about... NOW! synchron
by mark242 13y ago
Ah, synchronizedCollection, the...
hang on...
wait a sec...
one more sec, someone's doing something...
now? no, not yet, wait...
how about... NOW! synchronizedCollection, the global lock for Java's mutable datatypes.
Here's the fundamental difference between Java and Scala: if I say, in Scala, val people = List[String]("quacker", "mark242") then by default people is an immutable list. I don't have to do anything special. In Java, either I'm suddenly using the Guava libraries to get something similiar (but not the same), or I'm doing all kinds of funky dances around list iterators, or I'm using Arrays.copyOf, or what have you. In any case, you have all of this extraneous code, when it isn't necessary.
Quick: give me a list comprehension method in Java that takes a list of Strings and returns that list, filtered, of Strings that are only five characters or longer. Make it null-safe and thread-safe. This isn't difficult-- you're thinking about 6-7 lines of Java code in your head, right? Null check, synchronized, new ArrayList, for(s in sList), that kind of thing, right?
In Scala, it's this. Some would argue you don't even need a separate method.
def getFiveCharacters(s: List[String]) = s.filter(_.length >= 5)
If I have millions of things stored in an immutable data structure, do I not have to copy the entire structure when I want to modify anything within?
Dear god, man, what are you doing wrong in your Java code? This is the exact scenario where you want an immutable list, otherwise you'll be running synchronized code and precisely one core of your CPU will be glowing red like lava, while your other CPU cores sit idle.
I just did this in the scala repl:
(0 to 1000000).toList.par.filter(_ % 100 == 0)
What that does is grab all of the integers from 0 to 1,000,000, convert them to an immutable List, then filter that List (yes-- an iterator! with a filtered copy!) by only taking numbers divisible by 100. The whole thing takes a couple hundred ms in the repl (which is fantastic, since it's compiling then executing the code) and almost no memory overhead. For code that is absolutely thread safe. And the ".par" makes this run in parallel on all my CPU cores.
- anonymoushn 13y ago> Null check, synchronized, new ArrayList, for(s in sList), that kind of thing, right? > In Scala, it's this. Some would argue you don't even need a separate method. It seems a bit unfair to force null checks on the Java code and then present a Scala alternative that throws NPE in two different places.
- mark242 13y agoA good Scala programmer will never write the word null in their code. Ever. If I was overly concerned that the method was going to be called by Java code, I'd put this: Option(s).getOrElse(List[String]()).filter(str => Option(str).fold(false)(_.length > 5))
- anonymoushn 13y agoThat should do it. I would probably go for def foo(s: List[String]): List[String] = s match { case l: List[String] => l.filter(_ match { case str: String => str.length > 5; case _ => false}); case _ => List[String]()} It's a bit uglier, but I had to develop a habit of not spewing objects everywhere because of the constraints of the application I work on. You're right that this is primarily a concern if the Scala dev wants to talk to Java. However, if the Scala dev does not want to talk to Java, perhaps a statically typed FP language with an HM type system would be a better fit.
- jebblue 13y agoI couldn't grok the original 1 liner, definitely not the second one and no way the last one. If there is a segment of programmers who grok and like it, cool. It still doesn't fix the performance problem of copying 1 million things before you can act on them because the copy would still have to happen on 1 core, or 1 core at a time, unless maybe the Scala compiler optimizes the code to divide the list among the cores available, if not though then immutability doesn't help performance during the copy.
- anonymoushn 13y agoYou don't have to use immutable collections. If you want to use them, you should probably consider the cost of the operations you are using. Which particular operations are you worried about? Most updates to an immutable hash table or sorted map should copy only a small part of the collection, for instance.