Skip to content
Print

Defining Scala Design Idioms

14
Apr
2008

With any new language comes a certain amount of uncertainty as to what is “the right way” to do things.  Now I’m not just talking about recursion vs iteration or object-oriented vs straight procedural.  What I’m referring to is the design idioms which govern everything from naming conventions to array deconstruction.

This idioms are highly language specific and can even differ between languages with otherwise similar lexical elements.  Consider the following C++, Java, Ruby and Scala examples:

vector<string> first_names;
first_names.push_back("Daniel");
first_names.push_back("Chris");
first_names.push_back("Joseph");
 
for (vector<string>::iterator i = first_names.begin(); i != first_names.end(); ++i) {
    cout << *i << endl;
}

Java:

String[] firstNames = {"Daniel", "Chris", "Joseph"};
 
for (String name : firstNames) {
    System.out.println(name);
}

Ruby:

first_names = ['Daniel', 'Chris', 'Joseph']
 
first_names.each do |name|
  puts name
end

Scala:

val firstNames = Array("Daniel", "Chris", "Joseph")
 
for (name <- firstNames) {
  println(name)
}

As a matter of interest, the Scala example could also be shortened to the following:

val firstNames = Array("Daniel", "Chris", "Joseph")
firstNames.foreach(println)

All of these samples perform essentially the same task: traverse an array of strings and print each value to stdout.  Of course, the C++ example is actually using a vector rather than an array due to the evil nature of C/C++ arrays, but it comes to the same thing.  Passing over the differences in syntax between these four languages, what really stands out are the different ways in which the task is performed.  C++ and Java are both using iterators, while Ruby and Scala are making use of higher order functions.  Ruby and C++ both use lowercase variables separated by underscores, while Java and Scala share the camelCase convention.

This is a bit of a trivial example, but it does open the door to a much more interesting discussion: what are these idioms in Scala’s case?  Scala is a very new language which has yet to see truly wide-spread adoption.  More than that, Scala is fundamentally different from what has come before.  Certainly it draws inspiration from many languages – most notably Java, C# and Haskell – but even languages which are direct descendants can impose entirely different idioms.  Just look at the differences between the Java and the C++ examples above.  The practical, day-to-day implications of this become even more apparent when you consider object-oriented constructs:

// Book.h
class Book {
    std::string title;
    Author *author;
 
public:
    Book(string);
 
    std::string get_title();
    Author* get_author();
    void set_author(Author*);
};
 
// Book.cpp
Book::Book(string t) : title(t), author(0) {}
 
string Book::get_title() {
    return title;
}
 
Author* Book::get_author() {
    return author;
}
 
void Book::set_author(Author *a) {
    author = a;
}

The equivalent in Java:

public class Book {
    private String title;
    private Author author;
 
    public Book(String title) {
        this.title = title;
    }
 
    public String getTitle() {
        return title;
    }
 
    public Author getAuthor() {
        return author;
    }
 
    public void setAuthor(Author author) {
        this.author = author;
    }
}

And the (much shorter) Ruby code:

class Book
  attr_reader :title, :author
  attr_writer :author
 
  def initialize(title)
    @title = title
  end
end

This code uses standard, accepted idioms for class design in each of the three languages.  Notice how in C++ we avoid name-clashes between method formals and data members?  This is because the compiler tends to get a little confused if we try to combine name shadowing and the initialization syntax (the bit that follows the : in the constructor).  This contrasts strongly with Java which by convention encourages shadowing of fields by method formals.  It’s a very strong convention to do what I’ve done here, using this.fieldName to disambiguate between formals and fields.  Ruby stands apart from both of these languages by enforcing the use of prefix symbols on variable names to define the container.  There really can’t be any shadowing of instance variables by formals since all instance variables must be prefixed with the @ symbol.

The question here is: what conventions are applicable in Scala?  At first blush, it’s tempting to write a class which looks like this:

class Book(val title:String) {
  var author:Author = null
}

Because every variable/value in Scala is actually a method, the accessor/mutator pairs are already generated for us (similar to how it is in Ruby with attributes).  The problem here is of course redefining an accessor or mutator.  For example, we may want to perform a check in the author mutator to ensure that the new value is not null.  In C++ and Java, we would just add an if statement to the correct method and leave it at that.  Ruby is more interesting because of the auto-generated methods, but it’s still fairly easy to do:

class Book
  def author=(author)
    @author = author unless author.nil?
  end
end

Scala poses a different problem.  In our example above, we’ve essentially created a class with two public fields, something which is sternly frowned upon in most object-oriented languages.  If we had done this in Java, it would be impossible to implement the null check without changing the public interface of the class.  Fortunately Scala is more flexible.  Here’s a naive implementation of Book in Scala which performs the appropriate check:

class Book(val title:String) {
  private var author:Author = null
 
  def author = author
 
  def author_=(author:Author) {
    if (author != null) {
      this.author = author
    }
  }
}

Unfortunately, there are some fairly significant issues with the above code.  First off, it won’t compile.  Scala lacks separate namespaces for fields and methods, so you can’t just give a method the same name as a field and expect it to work.  This merging of namespaces actually allows a lot of interesting design and is on the whole a good thing, but it puts a serious crimp in our design.  The second problem with this example is closely related to the first.  Assuming the code did compile, at runtime execution would enter the author_= method, presumably pass the conditional and then execute the this.author = author statement.  However, the Scala compiler will interpret this line in the following way:

this.author_=(author)

That’s right, infinite recursion.  Usually this issue isn’t apparent because the compiler error will take precedence over the runtime design flaw, but it’s still something which merits notice.  Obviously, using the same names for variables as we do for methods and their formals just isn’t going to work here.  It may be the convention in Java, but we’ll have to devise something new for Scala.

Over the last few months, I’ve read a lot of Scala written by other people.  Design strategies to solve problems like these range all over the map, from totally separate names to prepending or appending characters, etc.  The community just doesn’t seem to be able to standardize on any one “right way”.  Personally, I favor the prepended underscore solution and would really like to see it become the convention, but that’s just me:

class Book(val title:String) {
  private var _author:Author = null   // notice the leading underscore
 
  def author = _author
 
  def author_=(author:Author) {
    if (author != null) {
      _author = author
    }
  }
}

The Scala community really needs to get together on this and other issues related to conventional design idioms.  I see a lot of code that’s written in Java, but with C or C++ idioms.  This sort of thing is rare nowadays, but was quite common in the early days of the language.  People weren’t sure what worked best in Java, so they tried to apply old techniques to the new syntax, often with disastrously unreadable results.  As Scala moves into the mainstream, we have to come to some sort of consensus as to what our code should look like and what conventions apply.  If we don’t, then the language will be forced to struggle through many of the same problems which plagued Java only a decade ago: new developers trying to get a handle on this foreign language, misapplying familiar constructs along the way.

Comments

  1. Using null in Scala code is not idiomatic at all; its use is only appropriate in places where you interact with Java-code (and maybe in constructors). So don’t do null checking at all.

    If you can’t give a default value, you really should use var author: Option[Author] = None
    If the client is sure there’s a set author, he can just “book.author.get” but it’s not good style either in my opinion.

    shadowman Monday, April 14, 2008 at 1:58 am
  2. Very good point. Personally, I don’t like the _ prefix, but I’m not sure what I would like instead of it. Maybe _ as a suffix. There was a discussion on the mailing list, don’t remember what the conclusion was (or if there was any).

    Erkki Lindpere Monday, April 14, 2008 at 6:58 am
  3. @shadowman

    You’re correct that null is highly discouraged in Scala. The main reason I used it is I was trying to show the equivalent Scala code to all of the above samples. In C++, Java and in Ruby, the language-specific equivalent of NULL is the default value for the author field. I didn’t want to take the time to explain why Option rather than null.

    With that said, you’re absolutely right that any definition of Scala idioms should loudly reiterate the evils of null. :-)

    Daniel Spiewak Monday, April 14, 2008 at 10:06 am
  4. Actually, now that I thought some more about it, I prefer _name as well. I was distracted by my own recent rant on __blabla__ in Python (see link to my blog), but actually I (perhaps somewhat hypocritically) support _name in Scala because:

    * if it’s strictly for private vars, it’s not so much of a problem: it’s not visible to clients (if they don’t have source) and not meant to be accessed anywhere else except the setter/getter (bar special cases).

    * $name would perhaps look nicer, but $ is used for lots of compiler-generated stuff so perhaps not a good idea.

    But what about this case:

    class Person(???name: String) {
    private[this] var _name = ???name
    def name = _name
    def name_=(name: String) = _name = name
    }

    What should the prefix for the constructor parameter be? Or would you do it like this:

    class Person1(private[this] var _name: String) {
    def name = _name
    def name_=(name: String) = _name = name
    }

    In which case you expose the ugly version (and internal representation) to the client

    Erkki Lindpere Monday, April 14, 2008 at 12:52 pm
  5. Yeah, constructor parameters are a problem. To be honest, I would probably use the underscores and let the ugly internal representation percolate out to the external API. It’s annoying, but it may be the only way to keep the convention consistent. The good news is that the constructor parameter names go away if you’re not compiling with debug symbols, so it’s a less significant issue than polluting a method name or similar. (well, sort-of go away, they stick around in the form of private methods)

    Daniel Spiewak Monday, April 14, 2008 at 12:56 pm
  6. If you get away from nulls and use Option[Address] instead, then I would use

    private var author_opt : Option[Author] = None

    then there is no naming issue.

    If I don’t use an Option, I personally like trailing underscores.

    Blair Zajac Monday, April 14, 2008 at 1:54 pm
  7. Trailing underscores are fine, but I have some serious misgivings about the type suffix you illustrate above. I think it’s a really bad habit to get into, suffixing variable names with an abbreviated type. I’ve certainly been guilty of it more than a few times myself, but each time it has ended in pain (either with super-verbose names, or with multiple variables with almost identical names and purposes). Either way you slice it, naming with type suffixes makes code far less readable.

    Daniel Spiewak Monday, April 14, 2008 at 1:57 pm
  8. Not all that familar with the language yet, but what about a pattern matching solution so there is only one public author function?

    K Monday, April 14, 2008 at 2:07 pm
  9. Hmm, I’m not sure what you mean by that. Unless you’re throwing around mutable containers left and right, you need at least two public “author methods”, one accessor and one mutator. Even then, you still have to have some sort of object state variable, so the problem hasn’t really gone away.

    Daniel Spiewak Monday, April 14, 2008 at 2:11 pm
  10. Something like this, always return the current value but allow a value to be set if its an Author (although haven’t tired compiling it, so code is probably wrong)

    private var _author:Author = null

    def author(x: Any): Author = x match {
    case a: Author =>
    if( a != null )
    _author = a
    _author
    case _ => _author
    }

    K Monday, April 14, 2008 at 2:27 pm
  11. Your code works, but I’m not sure why you would want to do things this way. For one thing, you’ve lost type checking on the author formals. This isn’t necessarily the case of course, you could rewrite your code to be type-safe. What may be a more serious issue is that we’ve actually changed the public class signature. Thus a class with your method would have a different signature from one with a public variable `author`.

    Daniel Spiewak Monday, April 14, 2008 at 2:32 pm
  12. Incidentally, you could rewrite the code like this:

    private var _author:Option[Author] = None

    def author(x:Option[Author]): Author = x match {
    case Some(a) => {
    _author = a
    _author
    }
    case _ => _author
    }

    Daniel Spiewak Monday, April 14, 2008 at 2:34 pm
  13. Correction:

    private var _author:Option[Author] = None

    def author(x:Option[Author]):Option[Author] = x match {
    case Some(a) => {
    _author = a
    _author
    }
    case _ => _author
    }

    Daniel Spiewak Monday, April 14, 2008 at 2:35 pm
  14. Daniel, I hope your post gets the attention of Odersky, Spoon, and Venners. Languages tend to adopt the convention followed in the most popular (often first) book written on it.

    Binil Thomas Monday, April 14, 2008 at 10:41 pm
  15. Ok, Ok I am being very pedantic, but a more idiomatic Ruby version of the first example would be:

    first_names = %w{Daniel Chris Joseph}

    first_names.each { |name| puts name }

    David Madden Tuesday, April 15, 2008 at 4:10 am
  16. @David

    The %* syntax was actually considered for deprecation in 1.9, so I’m not sure it can be considered to be “more idiomatic”. You’re write about the one-line Proc though. I thought about using it, but I’ve always though that “brace blocks” are less readable than then do/end syntax and I didn’t feel like trying to explain Ruby syntax elements in a post about Scala. :-)

    Daniel Spiewak Tuesday, April 15, 2008 at 7:49 am
  17. “I didn’t feel like trying to explain Ruby syntax elements in a post about Scala”

    Well, but that would highlight the topic much more, as mostly idioms result from specific syntax features available in different languages. That is exactly what makes learning a new language so hard, when trying to avoid writing your “old language” only in another syntax.

    So both examples of Ruby are useful to show the point.

    Well, this article may be the first step of a long series, as in my opinion the ‘uncertainty what is “the right way” ‘ reg. Scala indeed involves the bigger part, especially as it is based on Java.

    I just hit the problem with: “Yes, I know how to open a file and iterate through the lines in Java. Yes, it all worked when likewise done in Scala syntax. But is scaladish Java the intented way to do it?”

    Det Thursday, April 17, 2008 at 3:13 am
  18. Thanks, Daniel, for this very thorough discussion! Having seen too much Java written with a C accent, I’m very interested in what a native Scala accent would look like, and how that would affect one’s approach to a programming task. I’ve been using the Project Euler problems as a way of exploring Scala, and found one of them a nice motivation for Scala’s hybrid nature (http://joelneely.wordpress.com/2008/04/24/a-composite-function/).

    I agree with the goal in your concluding paragraph, but wonder how much history/experience a language community needs before starting to converge on “best practice” style and idiom conventions. (I recall criticisms of new-born Ada, asserting that the designers had attempted to standardize areas which were not sufficiently well-understood.) Finally, I wonder whether multiple styles may emerge in the use of a hybrid language, a Java-like style in code that’s primarily OO, along with a Haskell-like style in code that’s primarily FP. It’s going to be interesting to watch this develop!

    Joel Neely Thursday, May 1, 2008 at 5:21 am
  19. daniel, what do you think of this scala representation:

    case class Book( title:Option[String]) { var author:Option[Author]=None }

    1. handles title constructor
    2. handles avoiding null in favor of Option
    3. author is R/W

    usage:

    var b = Book( Some(“Fahrenheit 451″) )
    b.author = Some( Author(“Ray Bradbury”) )

    jherber Monday, August 11, 2008 at 8:33 pm
  20. @jherber

    Definitely +1 the use of Option over nullable values. The mutable field (author) is a bit unidiomatic however, especially for a case class. It’s pretty good though.

    I think that the more significant issue to resolve in Scala design idioms is how to deal with name classes, particularly in fields and methods. There was some discussion about this above, leading vs trailing underscores, suffixes, etc.

    Daniel Spiewak Tuesday, August 12, 2008 at 10:30 am
  21. I think it is really important to develop conventions and standards, especially for new languages such as Scala, and the designers could do well to share their own conventions used for their libraries.

    That all said, I ended up here looking for a way of Null checking in scala, and the comments did give the clear answer, don’t use null, use Option[...] instead; makes sense.

    However, your scala sample uses

    if (author != null) …
    .
    As far as i understand ‘!=’ is actually a function so I would expect that when author is null there to be a NullPointerException thrown attempting to evaluate a member (‘!=’) of null.

    Or dose scala treat null as a real object, supporting all the standard functions?

    Matthias Horn Monday, July 6, 2009 at 5:43 am
  22. @Matthias

    In this case, != would be a member of author. However, Scala does avoid the whole null equality issue very nicely by making null a value of type Null, which does define the == and != methods. Thus, the following works perfectly:

    val t: String = null
    t != null   // => false
    t == null  // => true
    null == null  // => true

    Gotta love Scala!

    Daniel Spiewak Tuesday, July 7, 2009 at 3:30 pm
  23. Hi, I realize this is a very old post but I came across Scala a little late and would like to have my naming conventions figured out. In C# I use CamelCase for accesors I wonder if same can be done in Scala.

    so

    class Book(val title:String) {
    private var author:Author = null

    def Author = author

    def Author_=(authorP:Author) {
    if (authorP != null) {
    author = authorP
    }
    }
    }

    I use suffix P to distinguish parameters from fields so I can avoid using “this”. Any thoughts?

    Babar Tuesday, February 9, 2010 at 8:41 am

Post a Comment

Comments are automatically formatted. Markup are either stripped or will cause large blocks of text to be eaten, depending on the phase of the moon. Code snippets should be wrapped in <pre>...</pre> tags. Indentation within pre tags will be preserved, and most instances of "<" and ">" will work without a problem.

Please note that first-time commenters are moderated, so don't panic if your comment doesn't appear immediately.

*
*