Summary:
Learning a new programming language sometimes influences how you code in other languages, too. In this essay, Bill Venners shares how learning Scala influenced his programming style.
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: November 29, 2018 2:45 AM by
|
Hi Morgan,
> From Bill's article: > > "The exists method iterates through a collection of > objects and passes each element in turn to the passed > function object" > > Why the heck is this call "exists"??? > > Actually, I think the name is o.k., it's Bill's > description that is wrong - the "exists" matches that > reverse E (or is it forward???) thing from math, right? > > But it's still a fairly technical term - how about > "eachOr" or "checkEach" whatever??? > The way I'd say it in English is that the method answers the question, "Does a n element exist in this collection for which this Boolean "predicate" function is true?" That whole thing got shorted to simply, exists.
|
|
|
> > boolean isFoo()
> {
> boolean returnValue = false;
>
> for (item : things) {
> if (item.hasBar()) returnValue = true;
> }
>
> // more code ...
>
> return returnValue;
> }
>
> > In the first example, I can see immediately that if one of > the items has bar, the method returns true. If that's all > the information I need, I'm done. In the second, all I > know is that returnValue is set to true at that point in > the method. I might think that probably means the method > returns true in that case but I can't be sure. I must > look through the rest of the code or risk error. Most of > the time it will be but I've seen cases where it would set > later. I often found this kind of logic while hunting > down bugs because the later assignment to the return > variable was in error. > This is exactly the benefit that I've found to prefer vals over vars in Scala. When you assign to a val (like a final variable in Java), you know it isn't going to change, so you don't have to look down through the rest of the method to see if it did. It makes code easier to read simply because of that one difference. In Java I probably used 5% final variables and 95% normal variables, but in Scala it is the other way around. I use probably 95% vals and 5% vars. That's a big way my programming style changed when moving to Scala, and is another example of my style becoming more functional. Another thing, which someone else pointed out, is that the problem you have with this kind of single return code would be reduced if the methods were smaller. And you, James, mentioned you like to make little private helper methods yourself. I'm not sure I use helper functions yet as much as I will in the future, but I use them some. David Pollak has lately been saying he tries to make his functions in Scala all one-liners. I wasn't so sure about going that far, but decomposing things into short, clear functions I think can help readability. Lastly, the irony I see in the multi-return style you're recommending James is that you're doing it to get benefits you get if the language would let you more easily program in a functional style. Java just makes it hard because so many of its control constructs don't result in a value. When everything results in a value, it is easier to see each function as just one expression, which results in a value. You don't need an explicit return, because that last value is returned implicitly. But that's the same as having "one return" in the method.
|
|
|
> This is exactly the benefit that I've found to prefer vals > over vars in Scala. When you assign to a val (like a final > variable in Java), you know it isn't going to change, so > you don't have to look down through the rest of the method > to see if it did. It makes code easier to read simply > y because of that one difference. In Java I probably used > 5% final variables and 95% normal variables, but in Scala > it is the other way around. I use probably 95% vals and 5% > vars. That's a big way my programming style changed when > moving to Scala, and is another example of my style > becoming more functional.
Agreed. The var vs. val choice is forced up front. My approach would be to mark almost everything as val unless and until I decide I need to make it a var and even then, I would contemplate if that's the right choice.
> Another thing, which someone else pointed out, is that the > problem you have with this kind of single return code > would be reduced if the methods were smaller. And you, > James, mentioned you like to make little private helper > methods yourself. I'm not sure I use helper functions yet > as much as I will in the future, but I use them some. > David Pollak has lately been saying he tries to make his > functions in Scala all one-liners. I wasn't so sure about > going that far, but decomposing things into short, clear > functions I think can help readability.
I actually like the way blocks in Scala allow you to do that kind of thing inside a method. I can see how it might get out of control but in a lot of cases, you wouldn't need another method.
> Lastly, the irony I see in the multi-return style you're > recommending James is that you're doing it to get benefits > you get if the language would let you more easily program > in a functional style. Java just makes it hard because so > many of its control constructs don't result in a value. > When everything results in a value, it is easier to see > each function as just one expression, which results in a > value. You don't need an explicit return, because that > last value is returned implicitly. But that's the same as > having "one return" in the method.
I think you are misinterpreting my argument. My point was never to demonstrate that Scala isn't an improvement over Java. I think it definitely has a lot to offer and that Java has many flaws. My point was that the comparison you showed was a little unfair, kind of like a car race where one car has bags of concrete in the trunk. Scala still wins IMO and making Java look worse than it really is might make your argument appear weaker.
Basically, we have these rules that we follow in Java "because they are good" and we complain about the resulting code. Then we take a new language and declare those rules don't apply in it. But really, a lot of those rules never really applied in Java either. Bringing these kinds of things into the comparison is just noise and makes it harder to see the real differences.
|
|
|
No strong opinion on multiple returns, cause I use both styles schizophrenically. With the advent of multicore processors, I use many more final vars (and especially fields) in Java. When declaring a new class, the default visibility for fields is final. They change to non-final only if required.
as to syntax, guess I'll have to invent my own language. :-)
but, instead of
name.exists(_.isUpperCase)
if you are going to use mathematics-like language, why not use mathematics-like language
thereExists(x elementOf name)suchThat(x.isUpperCase) or, a bit shorter thereExists(x elementOf name, x.isUpperCase)
Less OO, which normally I'd complain about, but, IMO way clearer, and I was never that fond of the underline.
|
|
|
> > But it's still a fairly technical term - how about > > "eachOr" or "checkEach" whatever??? > > > The way I'd say it in English is that the method answers > the question, "Does a n element exist in this collection > for which this Boolean "predicate" function is true?" That > whole thing got shorted to simply, exists.
I think Morgan's right that this is a very mathematical name for this. The statement would be:
"at least one element exists such that [predicate] is true for that element."
A more intuitive name might be: atLeastOne(). This is an example (not the best) of what I think will hold Scala back. It designed with a very academic mindset. I know that the intention was to cater to business with Scala but I don't consider it successful in that aspect. There are a lot of really smart developers out there who have never taken a class in discrete mathematics or studied set theory. If I were going to champion Scala where I work, I would be required to explain a lot of these terms. And this is one of the simpler concepts in Scala. A lot of really educated developers don't know what a fold is. I'd never encountered the term before I started learning Scala. It might be hugely useful but how will people know without an explanation in plan terms?
|
|
|
> Less OO, which normally I'd complain about, but, IMO way > clearer, and I was never that fond of the underline.
I not big on the underline either. It seems too Perl-esque to me. I mean, why underline, why not implicit variables?
One the other hand, as long as it's consistent and there aren't too many other 'things to know' to use Scala, I'm OK with it.
On a side note, the python for comprehension syntax is nice, IMO:
[x.foo() for x in list]
|
|
|
> > This is exactly the benefit that I've found to prefer > > Lastly, the irony I see in the multi-return style > you're > > recommending James is that you're doing it to get > benefits > > you get if the language would let you more easily > program > > in a functional style. Java just makes it hard because > so > > many of its control constructs don't result in a value. > > When everything results in a value, it is easier to see > > each function as just one expression, which results in > a > > value. You don't need an explicit return, because that > > last value is returned implicitly. But that's the same > as > > having "one return" in the method. > > I think you are misinterpreting my argument. My point was > never to demonstrate that Scala isn't an improvement over > Java. I think it definitely has a lot to offer and that > Java has many flaws. My point was that the comparison you > showed was a little unfair, kind of like a car race where > one car has bags of concrete in the trunk. Scala still > wins IMO and making Java look worse than it really is > might make your argument appear weaker. > Oh, I was trying to be fair to Java. That's why I showed that Java can actually do it in one line. Had I thought of the foreach approach that Dave B showed, I would have showed that too. I have tried hard not to try and push Scala up by putting other languages, especially Java, down. Instead, I try and show the differences and talk about the plusses and minusses of both.
I'm not sure why you thought I was suggesting you were trying to say Scala isn't an improvement over Java. I didn't get that impression. The "irony" I saw was that to get at the benefits of the functional style in Java, Java syntax actually pushed you in the other direction.
As far as using the boolean variable, that's not me being unfair to Java. That's me being true to how I programmed in Java for 10 years, and how I think most people program in Java from the code I've seen over the years. That's the idiom, and returning from inside a for loop, which you showed, would I think be frowned upon by many Java programmers.
> Basically, we have these rules that we follow in Java > "because they are good" and we complain about the > resulting code. Then we take a new language and declare > those rules don't apply in it. But really, a lot of those > rules never really applied in Java either. Bringing these > kinds of things into the comparison is just noise and > makes it harder to see the real differences. > Which rules to you mean? Sorry, can you be more explicit? If you mean he rule of having just one return, that doesn't quit add up because in Scala that's also the rule of thumb, except that you see it as one expression that doesn't need an explicit return.
|
|
|
> Less OO, which normally I'd complain about, but, IMO way > clearer, and I was never that fond of the underline. > The underscore is an optional placeholder syntax. Other possibilities, in increasing order of verbosity, are: name.exists(x => x.isUpperCase)
name.exists((x) => x.isUpperCase)
name.exists((x: Char) => x.isUpperCase)
But if someone else uses an underscore and you're reading your code, you'll have to look at it. It can be a cryptic if not used well, but if used well it reduces a bit of boilerplate.
|
|
|
> > > But it's still a fairly technical term - how about > > > "eachOr" or "checkEach" whatever??? > > > > > The way I'd say it in English is that the method > answers > > the question, "Does a n element exist in this > collection > > for which this Boolean "predicate" function is true?" > That > > whole thing got shorted to simply, exists. > > I think Morgan's right that this is a very mathematical > name for this. The statement would be: > > "at least one element exists such that [predicate] is true > for that element." > > A more intuitive name might be: atLeastOne(). This is an > example (not the best) of what I think will hold Scala > back. It designed with a very academic mindset. I know > that the intention was to cater to business with Scala but > I don't consider it successful in that aspect. There are > a lot of really smart developers out there who have never > taken a class in discrete mathematics or studied set > theory. If I were going to champion Scala where I work, I > would be required to explain a lot of these terms. And > this is one of the simpler concepts in Scala. A lot of > really educated developers don't know what a fold is. I'd > never encountered the term before I started learning > Scala. It might be hugely useful but how will people know > without an explanation in plan terms? > Scala was designed in academia, but by a guy who has a very practical outlook and was aiming to solve real world problems. I don't agree with all his naming choices either. For example, I think it would be better to have called "foreach" simply "each", like in Ruby. Because foreach seems to violate the camel case convention, and is longer. But exists honestly I never thought of as mathematical until the "backwards E" was brought in this forum discussion. I just figured he grabbed one English word from the English sentence you'd use to describe what the method call does.
I also didn't know what a fold was before I encountered Scala, but that surely doesn't mean it should be left out. It just needs to be explained, taught, learned. And you don't need to use it until you learn it, but of course if someone else uses it and you're reading their code, you'll have to learn it at that point. But fold is very fundamental and useful and should be learned by all Scala programmers eventually.
By the way, on fold, once in Junior high school I remember in some choir we prepared a round to sing at a conference, and I had to sing something that included "fold in eggs." It was a song about making a cake or something. I had never heard of "folding in eggs," and asked about it. I was told it is a baking term in which you mix the egg in one stroke at a time until it is mixed, and when I found out what folds mean in Scala, it reminded me of what it means in baking. You start with a start value (the egg), and then one element at a time, fold it into the collection. At the end, you have a different batter/collection that you can do something else with.
|
|
|
> On a side note, the python for comprehension syntax is > nice, IMO: > > [x.foo() for x in list] > Yes, Python is nice in a lot of ways. The equivalent in Scala is called a "for comprehension" or "for expression," and looks like this:
for (x <- list) yield x.foo
|
|
|
Hi James,
> A more intuitive name might be: atLeastOne(). This is an > example (not the best) of what I think will hold Scala > back. It designed with a very academic mindset. > One more thing on Scala's academic-ness. I saw James Gosling give his "Feel of Java Revisited" talk last year, and one of the things he reemphasized was that his goal was to almost "trick" mainstream C programmers into using things that had been proven in academia, but hadn't been accepted by the mainstream commercial software world. Things like garbage collection and exceptions. These were "academic" features of "academic" languages back then, not mainstream languages. Gosling actually used the word "fraud" in his talk, saying that Java was a well orchestrated fraud, it looked like C on the outside, but on the inside, it was moving the art forward by getting things out from academia into the real world.
So folds in Scala I think have the same problem. They are seen as academic, because they haven't been used by the mainstream, and they in fact are academic in that sense. But that doesn't mean they aren't darned useful, and so the question is really to what extent will Scala help popularize the concept of folds, as well as other things from the functional world. I think Scala does indeed look a lot less like Java than Java looked like C, so there's a chance it is too great a leap for some folks. It remains to be seen how people react, but so far the reactions seem pretty positive. It may be a self selecting group, though. In other words, the people that would even bother to look at Scala this early might be the kind of people who are open to leaping a bit and learning some new ways of doing things.
|
|
|
> I'm not sure why you thought I was suggesting you were > trying to say Scala isn't an improvement over Java. I > didn't get that impression. The "irony" I saw was that to > get at the benefits of the functional style in Java, Java > syntax actually pushed you in the other direction. I guess I get that impression because you keep telling about features of Scala when I already know Scala, or at least all the features you are talking about. Since I have tried to make that clear a couple times, it makes me think that you are not understanding me. I'm angry or anything, I'm just want to communicate effectively. > As far as using the boolean variable, that's not me being > unfair to Java. That's me being true to how I programmed > in Java for 10 years, and how I think most people program > in Java from the code I've seen over the years. That's the > idiom, and returning from inside a for loop, which you > showed, would I think be frowned upon by many Java > programmers. And again, this is exactly my point. It's not a feature of Java. It's something that people do in Java because think Java is like C. Given that Java is not really much like C, I fail to understand why it makes any more sense to use this idiom in Java than it does to use it in Scala. Are you saying that we must accept this as part of Java merely because some people say we should? If developers starting using this idiom in Scala does it become part of Scala? > Which rules to you mean? Sorry, can you be more explicit? > If you mean he rule of having just one return, that > doesn't quit add up because in Scala that's also the rule > of thumb, except that you see it as one expression that > doesn't need an explicit return. The source for List.exists() follows: override def exists(p: A => Boolean): Boolean = {
var these = this
while (!these.isEmpty) {
if (p(these.head)) return true
these = these.tail
}
false
}
Caveat: it's possible that the author of this method is not familiar with the idioms of Scala or of the single return rule of thumb in general.
|
|
|
> Scala was designed in academia, but by a guy who has a > very practical outlook and was aiming to solve real world > problems.
I said as much in my post that you are responding to. I did not say no attempt was made. I said the attempt was not successful in my opinion.
I don't want to be rude but when I look at Scala I have to wonder if the creators had any "real world" experience to pull from when attempting to solve "real world" problems. If not, I then have to question why they believed they knew what the "real world" needs. Even the obviously business targeted XML support was in no way what the "real world" needed.
> I also didn't know what a fold was before I encountered > Scala, but that surely doesn't mean it should be left out. > It just needs to be explained, taught, learned. And you > don't need to use it until you learn it, but of course if > someone else uses it and you're reading their code, you'll > have to learn it at that point. But fold is very > fundamental and useful and should be learned by all Scala > programmers eventually.
Again this seems to me like you are not understanding me. I never said it should be left out. What I said was that this is unfamiliar to most developers. If Scala is to be an accessible language, I think a little more effort will be needed explain these features to non-academics. Having said that, I haven't read your book yet so maybe this is a bad example.
|
|
|
> I'm angry or anything,
Crud! That's "NOT angry".
|
|
|
Jeez man, you sure have lots of free time :) Judging from your 'copious' output in these forums!
|
|