3 ms·
This post neatly demonstrates some things I don't like about Scala. Background: I've spent thirty or forty hours programming toy projects in Scala. That's not a
by jamesaguilar 15y ago
This post neatly demonstrates some things I don't like about Scala. Background: I've spent thirty or forty hours programming toy projects in Scala. That's not a whole lot, but it's enough that some things should start making sense . . . and they haven't.
(1 to 10) map { _ * 2 }
(1 to 1000).reduceLeft( _ + _ )
List(49, 58, 76, 82, 88, 90) partition ( _ > 60 )
I guess one common syntax for this pattern isn't sufficient. :( To be perfectly clear about my objection, these are the same basic operation: call a function on an iterable with an additional function argument. One is dotfree and uses braces. One uses a dot. And one is dotfree and uses parens. I feel like it would be a lot better if there were only one way to do this.
(words.foldLeft(false)( _ || tweet.contains(_) ))
|| . . . in every other language that means "logical or". What non-intuitive connotation does it have here?
val results = XML.load("http://search.twitter.com/search.atom?&q=scala)
Oh man, why can't it be XML.parse(URL.fetch(...)).
(n: Int) => (2 to n) |> (r =>
r.foldLeft(r.toSet)((ps, x) => if (ps(x)) ps -- (x * x to n by x) else ps))
This language has a damn operator fetish. This is sort of ok . . . I suppose these operators mean something to someone, but why do they have to also break conventions by doing things like creating a binary --.
Despite these complaints, and many others, I'm still weirdly drawn to this language. I want a smaller version of this. Managed, non-crazy (I'm looking at you, Go), and providing functional features. But I want that in a package that doesn't give me ten million billion different ways to do the same thing.
- saurik 15y ago(words.foldLeft(false)( _ || tweet.contains(_) )) > || . . . in every other language that means "logical or". What non-intuitive connotation does it have here? The "non-intuitive connotation" || has here is "logical or". The idea of "foldLeft" is that you are taking the previous value and operating on it to obtain the next value. In this case, you start with "false" (the default assumption: that the string does not contain any of the words) and then check, one by one, whether any of the words are in the tweet: for each word, you || the new result against the previous value.
- saurik 15y agoval results = XML.load("http://search.twitter.com/search.atom?&q=scala) > Oh man, why can't it be XML.parse(URL.fetch(...)). XML.load(io.Source.fromURL("http://search.twitter.com/search.atom?&q=scala").reader)
- tommorris 15y agoIn Scala '||' does mean logical OR. The example given is using the logical OR to fold across booleans. Imagine this expression: (a || b || c || d || e || f || g || h) If any of those values are true, the whole expression evaluates as true. It only evaluates as false if all the values are false. Now consider a simple example in Scala: val res1 = List(false, false, false, false, true) res1.foldLeft(false) { _ || _ } Here the foldLeft function is 'accumulating' the value of the boolean by doing an OR comparison with the starting value (false). For all but the last one, it is doing (false || false -> false), then it hits the last one and does (false || true -> true). It's a neat trick, and useful if you were using a programming language that had foldLeft but not exists. In Scala, you have exists. So you can do this instead: res1.exists(_ == true) Or for the example given, something like this: words.exists(tweet.contains(_))
- jamesaguilar 15y agoOh, fail me for that particular point. I should have looked at what function was being called rather than just the syntax.
- DavidMcLaughlin 15y ago> One is dotfree and uses braces. One uses a dot. And one is dotfree and uses parens. I feel like it would be a lot better if there were only one way to do this. I don't disagree with the principal of your complaint, coming from working with Perl I know of the potential horrors of having such flexibility. But just to explain why you can have both braces and parens here. In Scala, if you have a single parameter to a function, you can use braces. This is to allow you to create your own DSLs and control structures. The standard example is: def withPrinter(file: File)(op: PrintWriter => Unit) { val writer = new FileWriter(file) try { op(file) } finally { writer.close() } } Which for these types of blog posts we could call as: withWriter(new File("test.txt"))(_.println("test")) But in real applications where function bodies might be more complex, then you can have control abstractions like this: withWriter(new File("test.txt")) { writer => writer.println("test") } So used in a tasteful and sensible way, it's a really nice feature.