斯卡拉:建议进行实际操作

时间:2010-01-10 10:24:46

标签: scala functional-programming

我想提供一个Scala演示文稿,我希望通过一个应用程序来实现它,并将其从使用java习语的东西演变为使用scala(特征,模式匹配,隐式转换,函数编程)的东西。

我特别感兴趣的是能够展示设计变化的东西,而不是语法糖。最终scala代码显然更容易维护和扩展。

那么任何想法? (我不是要求代码示例,而是要求使用什么示例和可以演示哪些设计原则的粗略想法)。

4 个答案:

答案 0 :(得分:4)

一个很好的例子就是为动态迷你语言开发一个小解释器

基本的java实现需要经典的interpreter design pattern,而功能性的scala方法可以使用许多精彩的功能习惯用法,如

  • 案例类
  • 模式匹配
  • 高阶函数

或甚至monads,以便生成非常干净且易于理解的代码。

比较

class Number implements Expression {
    private int number;
    public Number(int number)       { this.number = number; }
    public int interpret(HashMap<String,Integer> variables)  { return number; }
}

case NumberLiteral(i) => Integer(i)

请参阅scala page上的解释器示例。

答案 1 :(得分:3)

为了帮助您选择这些功能并构建一些不错的代码示例,以下是一些想法:

  • 尝试坚持您的受众群体业务领域。尝试从他们的常用应用程序中获取示例(甚至是基础知识)。
  • 尝试猜测您的受众主要语言(java,perl,C ++)并在示例中进行语法比较。
  • 查看:A tour of scalaScala snippets,然后选择要预备的功能,您喜欢并且感觉很舒服。
  • 尝试记住你使用scala的早期步骤以及你感到印象深刻(或困惑)的情况。

答案 2 :(得分:3)

我认为你的范围可能过于雄心勃勃。只是向人们展示一种新的,不熟悉的语法可能会“失去”它们,所以加入更激烈的变化可能是一个太过分的步骤。不要忘记:如果第一个很受欢迎,你可以随时做第二次演示!

我一时间在我的公司做了很多这件事;它只是,因为我正在给演示文稿,我突然意识到一些scala语法出现给观众有多奇怪和难以理解(或许这是我的传递风格!)。我发现以下情况很好:

  1. 迭代方法 - 采用单个Java方法(不是整个程序),然后转换为非常类似于Scala(类型声明)和所有)。现在应用一组scala替换(例如类型推断),然后是另一组(例如类型别名),然后是另一组(例如闭包)等。最终结果可能是Java代码的大约三分之一,更具可读性和简洁,可以对比,因为人们现在已经熟悉了正在发生的事情。令人惊讶的是,与scala相比,Java只是一堆混乱的类型和关键字。

  2. 花点时间解释所有旁白 - 例如,详细介绍模式匹配及其工作原理。不要浏览提取器或case x :: xs。我发现人们对此非常感兴趣,而且它真是太棒了!

  3. 功能编程风格需要一段时间才能融入其中。让人们立即开始理解这些内容是不合理的。我已经在Scala编程超过一年了,我仍然对其中的一些感到困惑。

  4. 使用REPL对于一些低级别的事情来说非常酷,比如显示scala中的所有内容(包括synchronized,try-catch等)是一个带有类型的表达式。

  5. 当你证明了较低级别的东西的可怕性时,希望你会激起人们对更多东西的兴趣。 (我上周刚看了一个与scala熟悉的同事的三元运算符的实现,他发现它有点令人困惑。尝试将一个整个应用程序引入到一堆新手中太过分了!)

答案 3 :(得分:1)

使用spelling corrector示例在Stackoverflow Devdays中解释Python。 short scala implementation可能是一个开始:

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 

它演示了更高阶函数,元组支持,正则表达式支持,名称调用,表达式。缺少OO功能(类型系统,特征,对象,包和可见性)。 (我的目标是一个简短的实现。)但是你可以通过这些来实现OO。例如,您可以添加一些特征,如字典,校正器等。