Scala: Suggestion for an idea for a hands on session
I want to give a Scala presentation and I want to do it by taking an application and evolve it from something which use开发者_如何学Gos java idioms to something that uses the power of scala (traits, pattern matching, implicit convertions, functional programming).
I'm especially interested in something that demonstrates a design change, rather than syntactic sugar. Something where the end scala code is evidently easier to maintain and extend.
So any ideas? (I'm not asking for code examples, just the rough ideas of what example to use and what design principles can be demonstrated).
A wonderful example is developing a little interpreter for a dynamic mini-language.
The basic java implementation requires the classical interpreter design pattern, whereas a functional scala-approach can use many wonderful functional idioms like
- case classes
- pattern matching
- higher-order functions
or maybe even monads in order to produce very clean and easily understandable code.
Just compare
class Number implements Expression {
private int number;
public Number(int number) { this.number = number; }
public int interpret(HashMap<String,Integer> variables) { return number; }
}
with
case NumberLiteral(i) => Integer(i)
See the interpreter examples at the scala page.
To help you choose among the features and build some nice code examples, here are some ideas:
- try to stick on your audience business domain. Try to take example (even basics) from their usual applications.
- try to guess your audience main language (java, perl, C++) and make syntax comparisons in your examples.
- have a look at: A tour of scala and Scala snippets and pick features to preasent, which you like and you are comfortable with.
- try to remember your early steps with scala and situations where you were impressed (or puzzled).
I think you may be being too ambitious in your scope. Just showing people a new and unfamiliar syntax is likely to "lose" them a little, so adding in yet more drastic changes may be a step too far. Don't forget: you can always do a second presentation if the first is popular!
I did pretty much this at my company a while back; it was only as I was giving the presentation that I suddenly grasped how strange and incomprehensible some scala syntax was appearing to the audience (or perhaps it was my delivery style!). I found that the following went down well:
An iterative approach - take a single Java method (not a whole program) and then convert to really dumb like-for-like Scala (type declarations and all). Now apply one set of scala substitutions (e.g. type inference), followed by another (e.g. type aliases) followed by another (e.g. closures) etc. The end result of this would probably be about a third of the Java code, much more readable and concise, which can be contrasted as people are now familiar with what is going on. It's amazing to what extent Java is just a jumbled bunch of types and keywords when viewed in comparison with something like scala.
Take a while to explain all the asides - for example, go through pattern-matching in some detail and how it works. Don't skim over extractors or
case x :: xs
. I found people were really interested in this and what was so great about it!Functional programming style takes a while to sink in. It's not reasonable to get people to start understanding this stuff straight away. I've been programming in Scala for over a year and I'm still confused by some of it.
Using the REPL is really cool for some low-level things like showing how everything in scala (including synchronized,
try-catch
etc) is an expression with a type.
When you've justified the awesomeness of the lower-level stuff, hopefully you'll have whetted people's appetite for more. (I was looking at the implementations of the ternary operator with a - scala-familiar - colleague just last week and he found it slightly confusing. Attempting to introduce an entire app to a bunch of newbies is way too much!)
The spelling corrector example was used to explain Python in the Stackoverflow Devdays. A short scala implementation may be a start:
import util.matching.Regex.MatchIterator
val alphabet = 'a' to 'z' toArray
def train(features : MatchIterator) = (Map[String, Int]() /: features)((m, f) => m + ((f, m.getOrElse(f, 0) + 1)))
def words(text : String) = ("[%s]+" format alphabet.mkString).r.findAllIn(text.toLowerCase)
val dict = train(words(io.Source.fromFile("big.txt").mkString))
def edits(s : Seq[(String, String)]) = (for((a,b) <- s; if b.length > 0) yield a + b.substring(1)) ++
(for((a,b) <- s; if b.length > 1) yield a + b(1) + b(0) + b.substring(2)) ++
(for((a,b) <- s; c <- alphabet if b.length > 0) yield a + c + b.substring(1)) ++
(for((a,b) <- s; c <- alphabet) yield a + c + b)
def edits1(word : String) = edits(for(i <- 0 to word.length) yield (word take i, word drop i))
def edits2(word : String) = for(e1 <- edits1(word); e2 <-edits1(e1)) yield e2
def known(words : Seq[String]) = for(w <- words; found <- dict.get(w)) yield w
def or[T](candidates : Seq[T], other : => Seq[T]) = if(candidates.isEmpty) other else candidates
def candidates(word: String) = or(known(List(word)), or(known(edits1(word)), known(edits2(word))))
def correct(word : String) = ((-1, word) /: candidates(word))(
(max, word) => if(dict(word) > max._1) (dict(word), word) else max)._2
List("osters", "musters", "mixters") map correct foreach println
It demonstrates higher order functions, tuple support, regex support, call by name, for expressions. OO features (type system, traits, objects, packages and visibility) are missing. (I aimed at a short implementation.) But you can these to get to a OO implementation. For example you can add some traits like Dictionary, Corrector etc.
精彩评论