I believe I agree with all of them to some extent. The main thing I wanted to illustrate with this article was that the knee-jerk reaction of seeing a line of Scala and declaring it to be too complicated probably has more to do with unfamiliarity of syntax or concepts than it actually being complicated.
I hope this won't be my only posting on the subject - I will wait until I think I have something valuable to add, but there are many ways I use Scala right now that result in much more readable code - and for the record I definitely herald from the camp of "use Scala as a better Java and sprinkle in some functional stuff when appropriate" than beating the code with the full-on functional bat. That said, there are some places where the functional approach results in much more readable code I believe.
Above all, this is definitely intended in the spirit of "come on in, the water's fine". I love learning new stuff and Scala is a ton of fun to learn. Of course I would recommend Bill Venner, Martin Odersky and Lex Spoon's book on the subject (that's how I got going), but you can also learn a lot by looking at the Scala language site, or reading articles (Ted Newards Scala for the lazy Java programmer is a good resource too).
As far as the birthday song example goes - yes - it could be done more simply with templates, but part of the problem with a short article is coming up with something simple enough to remain on target, while illustrating the points (like looping, ternary operators, etc.) so contrived examples are usually the way to go. Hopefully you can see that these ideas would abstract out easily into a wider more complex space though.
Again, thanks for sharing opinions - it's good to talk about this stuff.
> I am not a Scala user, but neither Java nor Scala seem not > complicated. > > I would prefer the following syntax: >
> for n = 1 to 4 > print "Happy Birthday" > if n == 3 then > print " dear XXX" > else > print " to you" > end if > print "\n" > end for >
> What I mean is that both Java and Scala examples are quite > condensed and require lots of effort to see what is going > on.
That is really close to the Python solution:
for n in range(1,4+1): print "Happy Birthday", if n == 3: print "dear XXX" else: print "to you"
There are only two things here that seem non-obvious. The first is that the range function doesn't include the end number, so you have to add one to get it. The other is that the trailing comma on the print statement suppresses the carriage return. I like to think of basic Python as "executable pseudocode".
> > I am not a Scala user, but neither Java nor Scala seem > not > > complicated. > > > > I would prefer the following syntax: > >
> > for n = 1 to 4 > > print "Happy Birthday" > > if n == 3 then > > print " dear XXX" > > else > > print " to you" > > end if > > print "\n" > > end for > >
> > What I mean is that both Java and Scala examples are > quite > > condensed and require lots of effort to see what is > going > > on. > > That is really close to the Python solution: > >
> for n in range(1,4+1): > print "Happy Birthday", > if n == 3: > print "dear XXX" > else: > print "to you" >
> > There are only two things here that seem non-obvious. The > first is that the range function doesn't include the end > number, so you have to add one to get it. The other is > that the trailing comma on the print statement suppresses > the carriage return. I like to think of basic Python as > "executable pseudocode".
Indeed, as I wrote it I was thinking of it being Pythonesque. It may also resemble Ruby, methinks. It certainly has a Basic flavor...:-).
Nice article, Dick. Here's yet another way to write the example: for (s <- List("To You", "To You", "Dear XXX", "To You")) println("Happy Birthday "+s)
This one's pretty mundane. A more fancy purely functional way is this: List("To You", "To You", "Dear XXX", "To You") map ("Happy Birthday "+_) mkString "\n"
This will produce the 4 lines as a single string that still needs to be printed.
> That is really close to the Python solution: > >
> for n in range(1,4+1): > print "Happy Birthday", > if n == 3: > print "dear XXX" > else: > print "to you" >
> > There are only two things here that seem non-obvious. The > first is that the range function doesn't include the end > number, so you have to add one to get it. The other is > that the trailing comma on the print statement suppresses > the carriage return. I like to think of basic Python as > "executable pseudocode".
Off topic, but why wouldn't you just do this?
for n in range(4): print "Happy Birthday", if n == 2: print "dear XXX" else: print "to you"
1) 1 to 4 map ( i => "Happy Birthday %s" format (if (i == 3) "Dear XXX" else "To You") ) foreach println
Operator style, and println can be passed "as is", since it has the proper signature already.
2) About "<-", Programming in Scala calls it "in" (pg 730).
3) birthdaySong won't have a List of String. It will have a VectorView in Scala 2.8 or a RandamAccessSeq.Projection in Scala 2.7, which are very different things from List. For one thing, each time you access a member of it, the function you passed to "map" will be called to compute the value.
This usually has unexpected results when such functions have side-effects. For instance, if you use "map" to create threads and get their ids back. Each time you check the id you'll create a new thread and get a new id.
Good points, overall. The more galling thing was saying it would be hard to maintain!
> Of course, the best language would be perl right since > we're outputting human readable text. > > $name = "Dick Wall" > print <<ENDOFTEXT > Happy Birthday to you > Happy Birthday to you > Happy Birthday dear $name > Happy Birthday do you > ENDOFTEXT > > My point being that neither Java nor Scala solve the > problem the way it probably should be solved :) > > I'd consider both neutral with Scala being a bit more perl > like in that we have our magic '_' thing (what does it > mean again? is it 'this?')
val name = "Dick Wall" println(""" Happy Birthday to you Happy Birthday to you Happy Birthday dear %s Happy Birthday to you """ format name)
So, I beg to disagree. :-)
As for "_", it is a wildcard. Its meaning depends on context. In this particular context, it means "whatever parameter was passed".
Dick, good point about the GUI/logging etc (as my first instinct would be to favour the Java style code that performs well). Interestingly the result type isn't quite a list of strings - the repl gives me
res0: RandomAccessSeq.Projection[String] = RangeM(Happy Birthday To You, Happy Birthday To You, Happy Birthday Dear XXX, Happy Birthday To You)
I still can't help but think about these intermediate data structures that are being thrown around. I don't think Scala aggressively optimises this stuff. Could be especially important to keep in mind when considering the very functional code like that Vassil posted. Of course we don't want to prematurely optimise either. Maybe my intuition on this will change in time.
I think we overstretched the example a bit and forgot the initial goal Dick had in mind- to prove that Scala can be *readable*. Looking back at my example, I don't think I helped enforce the point he was trying to make. I was trying to showcase another advantage of Scala- create abstractions, which can scale transparently. My example would only benefit if
1) creation of each of the String objects took a significant amount of time 2) List.make, List.tabulate and List.map were parallel
Overall, let the compiler and JVM worry about optimizations. In the example you give, the garbage collector will take care about these short-lived objects.
This is a slightly different point I was trying to make about the simplicity of Scala. You don't rewrite your program if there's suddenly a new requirement to use a new algorithm. You change the library (e.g. another more performant actor library) or you fine-tune numerical computations using the @specialized annotation to avoid excessive autoboxing. I was trying to show Scala can be *flexible*.
If it comes to readability, here's a better (slightly modified) example I saw on Twitter:
Beats me, that's a surprise for me too. Both make and tabulate are implemented using a simple "while" and a counter.
Otherwise your comments in the README are correct- I believe I've seen tabulate in some language of the ML family, and zip is standard for Haskell, Clojure, etc.
I still think emulating Haskell/Clojure too much is not the best way to write elegant Scala code!
Flat View: This topic has 54 replies
on 4 pages
[
«
|
1234
|
»
]