Article Discussion
How Scala Changed My Programming Style
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.
53 posts on 4 pages.      
« Previous 1 2 3 4 Next »
The ability to add new comments in this discussion is temporarily disabled.
Most recent reply: November 29, 2018 2:45 AM by
Bill
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
How Scala Changed My Programming Style
April 28, 2009 9:00 PM      
In this short article, first published in December 2009 in the Parleys Magazine at the Devoxx conference in Antwerp, Belgium, Bill Venners describes how learning Scala has changed his programming style:

http://www.artima.com/scalazine/articles/programming_style.html

If you've programmed in Scala, how has it influenced your programming style? If you haven't yet tried Scala, what is your opinion of all this functional stuff?
Mark
Posts: 48 / Nickname: mthornton / Registered: October 16, 2005 11:22 PM
Re: How Scala Changed My Programming Style
April 28, 2009 11:46 PM      
boolean nameHasUpperCase = !name.toLowerCase().equals(name);


I suspect there are some strings (and Locale's) for which that expression will give the wrong answer.
Daniel
Posts: 11 / Nickname: djimenez / Registered: December 22, 2004 0:48 AM
Re: How Scala Changed My Programming Style
April 29, 2009 6:53 AM      
Imperative code seems to me to be a jumble of three parts: control structures, the data model, and calculation. (By control structures, I mean going through the data model to get to the pieces that are to be calculated upon; think finding a particular vertex in a graph to operate on, or getting the flozzle from the whosit contained by the thingamajig stored in the shigbaz.) But it wasn't until I started reading about, and attempting, functional programming techniques that I recognized this.

Your article provides an excellent example of these three parts: the for loop is the control structure, the data model is the string, and the calculation is "are any letters upper case?"

I'm thinking, following Fred Brooks, that the calculation part is the essential complexity, with the control structures and data model somewhat "accidental." I find imperative code to be a mix of the three, and therefore quite difficult to maintain. But, as your functional rewrite shows, when the control structures and data model are pushed into the background, the calculation is easier to see, thus easier to maintain / extend.

Of course, legacy code (in the Michael Feathers sense: huge and without tests) has methods tens-to-hundreds of lines long intermixing those three parts. In your experience, to what scale does functional rewriting work? Trivial examples, obviously; ten-line methods with one calculation embedded? Hundred-line methods with 2-5? Thousand line methods with 10-30? (None of us write those monstrosities, but the unfortunate amongst us have had to maintain them.) What are your logistics for refactoring from imperative to functional style?
Dave
Posts: 2 / Nickname: 64382 / Registered: December 29, 2008 5:19 PM
Re: How Scala Changed My Programming Style
April 29, 2009 9:21 AM      
Hi Bill. I love reading your clear articles (and the book you co-authored) about Scala. From you I try to learn how to better explain Scala to people myself.

Sometimes when people compare Java to other languages, they unfairly use the old-style “for” statement, when really a modern programmer would use for-each. You did that here. In this case:

for (char c : name.toCharArray())

would have been more fair.

Dave
James
Posts: 128 / Nickname: watson / Registered: September 7, 2005 3:37 AM
Re: How Scala Changed My Programming Style
April 29, 2009 9:27 AM      
> Hi Bill. I love reading your clear articles (and the book
> you co-authored) about Scala. From you I try to learn how
> to better explain Scala to people myself.
>
> Sometimes when people compare Java to other languages,
> they unfairly use the old-style “for” statement, when
> really a modern programmer would use for-each. You did
> that here. In this case:
>
> for (char c : name.toCharArray())
>
> would have been more fair.

Now that you mention is, the use of a boolean variable is also terrible style. I would do this:
boolean containsUpperCase(String s)
{
    for (char c : s.toCharArray()) {
       if (Character.isUpperCase(c)) return true;
    }
 
    return false;
}
Rupert
Posts: 3 / Nickname: rkit / Registered: December 9, 2005 7:32 AM
Re: How Scala Changed My Programming Style
April 29, 2009 10:09 AM      
in C++, you can do it like this:


template <typename ITER>
bool has_upper(ITER begin, ITER end) {
return end != std::find_if(begin, end, std::isupper);
}
Bill
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: How Scala Changed My Programming Style
April 29, 2009 11:14 AM      
> Hi Bill. I love reading your clear articles (and the book
> you co-authored) about Scala. From you I try to learn how
> to better explain Scala to people myself.
>
> Sometimes when people compare Java to other languages,
> they unfairly use the old-style “for” statement, when
> really a modern programmer would use for-each. You did
> that here. In this case:
>
> for (char c : name.toCharArray())
>
> would have been more fair.
>
Ah! That's a great approach, and one that had never occurred to me. I actually picked iterating through the characters of a string as an example because java.lang.String can't be treated as a sequential collection in Java. For most other collections in Java you could use the foreach syntax, and I wanted to show the most imperative style first (i.e., I wanted to show a realistic example that forces you to iterate with an index). The foreach syntax moves closer to the functional style, in that it doesn't require you to specify an end index, so it eliminates the potential for an off-by-one error.

I was trying to be fair to Java, though, by showing the Java one liner. I wanted to show you can do it in a more concise way in Java, and in general can program in a functional style in Java to some extent.

Another thing that's a bit interesting to me is that what you did explicitly by converting the String to a Char[] is also the approach Scala has to take, but it does so with an implicit conversion to RichString. RichString mixes in the Seq trait, so you get higher-order methods such as exists, which I used in the example, but also map, flatMap, etc., that make it possible to use strings as sequences of characters in for expressions in Scala.
Bill
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: How Scala Changed My Programming Style
April 29, 2009 11:25 AM      
> > Hi Bill. I love reading your clear articles (and the
> book
> > you co-authored) about Scala. From you I try to learn
> how
> > to better explain Scala to people myself.
> >
> > Sometimes when people compare Java to other languages,
> > they unfairly use the old-style “for” statement, when
> > really a modern programmer would use for-each. You did
> > that here. In this case:
> >
> > for (char c : name.toCharArray())
> >
> > would have been more fair.
>
> Now that you mention is, the use of a boolean variable is
> also terrible style. I would do this:
>
> boolean containsUpperCase(String s)
> {
>     for (char c : s.toCharArray()) {
>        if (Character.isUpperCase(c)) return true;
>     }
> 
>     return false;
> }
> 

>
Since when has the approach of setting a boolean variable inside a loop been considered terrible style? I'd just call it an imperative style. That's how I was taught to program in C, and how I continued to program in C++, and how I programmed in Java. I did this for years and years. When looking for something in a collection I'd initialize a boolean variable named found to false, then set it to true inside the loop. I wasn't clued into making little functions so I could avoid mutable variables like you've shown in your example until I was faced with val versus var in Scala. Trying to figure out how to get rid of vars, and puzzling over why I would care to to do that, is where I got the insight into how the functional style could make my code better.

Do many people already try and avoid mutable variables like this in Java?
Bill
Posts: 28 / Nickname: billpyne / Registered: January 29, 2007 4:12 AM
Re: How Scala Changed My Programming Style
April 29, 2009 0:32 PM      
> Since when has the approach of setting a boolean variable
> inside a loop been considered terrible style? I'd just
> call it an imperative style. That's how I was taught to
> program in C, and how I continued to program in C++, and
> how I programmed in Java.

I'm with you on this Bill. I was taught to set the variable so you could see the return variable's value in dbx before the return.

(Also, I was taught multiple calls to "return" in the same function were no-no's but I break that rule in some instances.)
James
Posts: 128 / Nickname: watson / Registered: September 7, 2005 3:37 AM
Re: How Scala Changed My Programming Style
April 29, 2009 1:28 PM      
> Since when has the approach of setting a boolean variable
> inside a loop been considered terrible style? I'd just
> call it an imperative style. That's how I was taught to
> program in C, and how I continued to program in C++, and
> how I programmed in Java. I did this for years and years.
> When looking for something in a collection I'd initialize
> a boolean variable named found to false, then set it to
> true inside the loop. I wasn't clued into making little
> functions so I could avoid mutable variables like you've
> shown in your example until I was faced with val versus
> var in Scala. Trying to figure out how to get rid of vars,
> and puzzling over why I would care to to do that, is where
> I got the insight into how the functional style could make
> my code better.
>
> Do many people already try and avoid mutable variables
> like this in Java?

OK you've got me. I'm really only speaking for myself here. There's no consensus (that I see) that this is bad style. But I have specific reasons for why I believe it to be so and the reasons I've often heard for contrary usually amounts to what you provide: "That's how I was taught to program in <language X>"

What you did here is not the worst case of this but it's a general problem I see in Java: extraneous variables, usually boolean flags. It actually makes sense in a some languages specifically those that do not guarantee all branches of a method return a value or that variables are assigned before they are used.

Generally I see things like this:
int getFoo(int in)
{
   int out = 0;
 
   switch (in) {
     case 1:
       out = 10;
       break;
     case 2:
       out = 200;
       break;
     case 3:
       out = 15;
       break;
   }
 
   return out;
}


This is then declared to be "good practice" because you know what getFoo returns: the value of 'out'. This to me is a 'turtles all the way down' kind of argument. Knowing the name of the variable that is returned at the end of the method is not important.

Consider the alternative style:
int getFoo(int in)
{
   switch (in) {
     case 1:
       return 10;
     case 2:
       return 200;
     case 3:
       return 15;
   }
}


Much simpler and if I ask you what it returns it returns 10 if in is 1, 200 if in is 2 and 15 if in is 3 and... Did you catch it? This doesn't return anything if something other than 1, 2 or 3 is provided. What's really cool about this in Java is that you don't have to catch that mistake. It won't compile. So if I'm coding on the tail end of a bender, I just saved myself some frustration. It might also make me realize that I don't want to return 0 for all other cases. I might want to do something else if a negative number was passed in.

In fact, I actually sometimes write code like you have done here, although it's usually out of laziness and flags are sometimes the right choice. The point I'm trying to make is that by switching to an unfamiliar paradigm you are able to lose a lot of baggage that you've accumulated that may not have anything to do with Java at all.

I actually completely agree with your overall premise here but it might seem like you set up a straw-man a bit (which I don't think was your intention.)
Bill
Posts: 409 / Nickname: bv / Registered: January 17, 2002 4:28 PM
Re: How Scala Changed My Programming Style
April 29, 2009 2:30 PM      
> > Since when has the approach of setting a boolean
> variable
> > inside a loop been considered terrible style? I'd just
> > call it an imperative style. That's how I was taught to
> > program in C, and how I continued to program in C++,
> and
> > how I programmed in Java. I did this for years and
> years.
> > When looking for something in a collection I'd
> initialize
> > a boolean variable named found to false, then set it to
> > true inside the loop. I wasn't clued into making little
> > functions so I could avoid mutable variables like
> you've
> > shown in your example until I was faced with val versus
> > var in Scala. Trying to figure out how to get rid of
> vars,
> > and puzzling over why I would care to to do that, is
> where
> > I got the insight into how the functional style could
> make
> > my code better.
> >
> > Do many people already try and avoid mutable variables
> > like this in Java?
>
> OK you've got me. I'm really only speaking for myself
> here. There's no consensus (that I see) that this is bad
> style. But I have specific reasons for why I believe it
> to be so and the reasons I've often heard for contrary
> usually amounts to what you provide: "That's how I was
> taught to program in <language X>"
>
> What you did here is not the worst case of this but it's a
> general problem I see in Java: extraneous variables,
> usually boolean flags. It actually makes sense in a some
> languages specifically those that do not guarantee all
> branches of a method return a value or that variables are
> assigned before they are used.
>
> Generally I see things like this:
>
> int getFoo(int in)
> {
>    int out = 0;
> 
>    switch (in) {
>      case 1:
>        out = 10;
>        break;
>      case 2:
>        out = 200;
>        break;
>      case 3:
>        out = 15;
>        break;
>    }
> 
>    return out;
> }

>
> This is then declared to be "good practice" because you
> know what getFoo returns: the value of 'out'. This to me
> is a 'turtles all the way down' kind of argument. Knowing
> the name of the variable that is returned at the end of
> the method is not important.
>
> Consider the alternative style:
>
> int getFoo(int in)
> {
>    switch (in) {
>      case 1:
>        return 10;
>      case 2:
>        return 200;
>      case 3:
>        return 15;
>    }
> }

>
> Much simpler and if I ask you what it returns it returns
> 10 if in is 1, 200 if in is 2 and 15 if in is 3 and... Did
> you catch it? This doesn't return anything if something
> other than 1, 2 or 3 is provided. What's really cool
> about this in Java is that you don't have to catch that
> mistake. It won't compile. So if I'm coding on the tail
> end of a bender, I just saved myself some frustration. It
> might also make me realize that I don't want to return 0
> for all other cases. I might want to do something else if
> a negative number was passed in.
>
> In fact, I actually sometimes write code like you have
> done here, although it's usually out of laziness and flags
> are sometimes the right choice. The point I'm trying to
> make is that by switching to an unfamiliar paradigm you
> are able to lose a lot of baggage that you've accumulated
> that may not have anything to do with Java at all.
>
> I actually completely agree with your overall premise here
> but it might seem like you set up a straw-man a bit (which
> I don't think was your intention.)
>
Sorry if I unintentionally strawed you. I just was curious if I had missed the Java community talking about this kind of thing. I need to look at the latest Effective Java again for this, because that's pretty influential on how people code, I'd expect.

It looks to me like you have subconscious functional urges trying to manifest themselves in your Java style. Bill Pyne made a good point about using the variables to look at intermediate values in debuggers. I also like to put intermediate values in variables in complex expressions just to give them a name to kind of explain what I'm calculating, just for code readability. But it also can help when debugging I think.

I also was told by someone at some point, maybe back in my C days, that it is better to just have one return statement in a function or method. But I was also told by others that they liked multiple returns to keep the method less nested. I think I usually leaned towards trying to just have one exit point, but I remember not being sure it was the best way.

Anyway, Java's switch statement is an example of how Java kind of pushes its users towards the imperative style. It is an imperative control construct because it doesn't result in a value. Java's equivalent construct, match, can do the same kind of thing. For example, I could say in Scala:


def getFoo(in: Int): Int = {
in match {
case 1 =>
return 10;
case 2 =>
return 200;
case 3 =>
return 15;
}
}


But match is a functional control construct because it results in a value. The value it results in in the previous example is called "Unit", which is a bit like void. But I could simply make it result in an Int like this:


def getFoo(in: Int) =
in match {
case 1 => 10
case 2 => 200
case 3 => 15
case _ => -1
}


The case _ at the end is a default case, like default in Java switch statements. Scala's match doesn't fall through, either, so you don't need break, and in fact Scala doesn't even have break. The result of this match expression will either be 10, 200, 15, or -1, and because it is the last expression of the method, that value will be returned. No explicit return is needed. When I look at your examples, I get the feeling you're wanting to do this kind of thing in Java, but that Java doesn't make it as easy as Scala. The other thing you did in your previous post was make a little function, which is something I do a lot more in Scala than I did in Java, because Scala encourages that style with its concise syntax for functions and support for local functions (which are functions declared inside other functions, and only available in that scope).
Bill
Posts: 28 / Nickname: billpyne / Registered: January 29, 2007 4:12 AM
Re: How Scala Changed My Programming Style
April 29, 2009 6:01 PM      
"What's really cool about this in Java is that you don't have to catch that mistake. It won't compile."

Oddly, I was just bitten today by a language that doesn't catch it at compile time. I added a few functions to my PL/SQL package on Tuesday 5 minutes before leaving. I forgot to put in the return statement to the functions - stupid mistake caused by rushing. It compiled fine but today I had a heck of a time debugging odd run-time behavior. I would have thought that checks for a return would be compile time given PL/SQL's ancestry being Ada and Ada's safety record.

Anyway, it makes me appreciate languages like Java that do perform the check a compile time.
James
Posts: 128 / Nickname: watson / Registered: September 7, 2005 3:37 AM
Re: How Scala Changed My Programming Style
April 29, 2009 6:24 PM      
> Sorry if I unintentionally strawed you. I just was curious
> if I had missed the Java community talking about this kind
> of thing. I need to look at the latest Effective Java
> again for this, because that's pretty influential on how
> people code, I'd expect.

Seriously, don't take it to heart. There was a the post above mentioning the foreach sugar in Java and I got on my soapbox trying to push my multiple return agenda. It wasn't really on-topic. Sorry.

> It looks to me like you have subconscious functional urges
> trying to manifest themselves in your Java style.

Absolutely. My experience with Scala and Python has definitely shown me that functional approaches can add a lot to OO. Bill and I were actually working together on a functional style library for Java (with an eye on Scala) until I got busy with other things and left him hanging.

I like a lot of things about Scala but I think it's a bit too arcane for the average IT shop to seriously consider. I want to get your book though and give it another chance.

> Bill Pyne made a good point about using the variables to
> look at intermediate values in debuggers. I also like to
> put intermediate values in variables in complex
> expressions just to give them a name to kind of explain
> what I'm calculating, just for code readability. But it
> also can help when debugging I think.

I don't use debuggers so that may be part of why I don't do that. In my experience, code that uses these intermediate variables is harder to follow and tends to have more bugs. If you keep your methods small and to the point, there's rarely a need for them. I write lots of short private methods that are only called from one place just to help organize and document code. When I do use intermediate variables, I don't initialize them to a default value unless that's the clearest and most correct logic or can't be avoided.
amin
Posts: 1 / Nickname: aahmad / Registered: February 28, 2007 0:26 AM
Re: How Scala Changed My Programming Style
April 29, 2009 9:24 PM      
Personally, traits are another feature of Scala that I really miss in Java.

And, as you alluded, functions-as-objects is a huge benefit to re-usability. In Java, you would need to define an interface to do the same thing, but the problem is that 3rd party code won't know about your interface, so you end up having to write little wrapper classes all over the place.
Tom
Posts: 2 / Nickname: boardtc / Registered: September 9, 2003 11:43 AM
Re: How Scala Changed My Programming Style
April 30, 2009 1:57 AM      
Thanks for the article. That's a great angle to think about the languages we have used.

val nameHasUpperCase = name.exists(_.isUpperCase)

Scala's exists reminds me of Groovy's each..essentially if I am following it _.isUpperCase is the closure.
53 posts on 4 pages.
« Previous 1 2 3 4 Next »