Recently code for a spellchecker in Kotlin was posted on a blog. What is interesting about the code is that it can almost be converted to Scala using only find and replace (“fun” -> “def”, “<” -> “[", ">" -> "]“).
More interesting is that idiomatic Scala code is much less verbose than the Kotlin version. The Scala version (21 lines) is almost half the size of the Kotlin version (40 lines). The Java published on the blog linked above is 43 lines.
Scala version here:
package com.wordpress.capecoder
import scala.io.Source
object ScalaSpellChecker {
private val DICTIONARY_WORDS = "/usr/share/dict/words";
def checkSpelling(input : String) = {
val words = readDictionary()
!input.toLowerCase().split(" ").exists(!words.contains(_))
}
private def readDictionary = Source.fromFile(DICTIONARY_WORDS).getLines.toSet+"scala"
def main(args : Array[String]) {
val defaultInput = "scala fuses functional and OO programming"
val valid = checkSpelling(if (args.size > 0) args(0) else defaultInput)
println("Is the text valid? "+valid)
}
}
Kotlin version here:
package com.richardlog.spellcheck
import java.io.*
import java.io.File
import java.util.Set
class KotlinSpellChecker {
private val DICTIONARY_WORDS = File("/usr/share/dict/words");
fun checkSpelling(input : String) : Boolean {
val words = readDictionary()
for (word in input.toLowerCase().split(" ")) {
if (!words.contains(word)) {
println("$word is not in the dictionary");
return false;
}
}
return true;
}
private fun readDictionary() : Set {
val words = hashSet("kotlin") // add kotlin to dictionary
val stream = FileInputStream(DICTIONARY_WORDS).buffered();
try {
val reader = InputStreamReader(stream, "UTF-8");
reader.forEachLine( { words.add(it)} )
} finally {
stream.close();
}
return words;
}
}
fun main(args : Array) {
val defaultInput = "Kotlin is an island"
val valid = KotlinSpellChecker().checkSpelling(if (args.size > 0) args[0] else defaultInput)
println("Is the text valid? $valid")
}
Note that I knocked the Scala version together in about 5 minutes so there may still be some minor syntax errors/typos.
An alternative to
!input.toLowerCase().split(” “).exists(!words.contains(_))
could be
!input.toLowerCase().split(” “).toSet diff dictionary isEmpty
If the sentence contains special characters (comma, exclamation mark…) it will be considered to be misspelled (the Kotlin version also contains this bug).
My Kotlin Version:
import java.io.File
class KotlinSpellChecker {
private val DICTIONARY_WORDS = File(“/usr/share/dict/words”)
val readDictionary = {DICTIONARY_WORDS.readLines().toSet() + “kotlin” }
public fun ckeckSpelling(input: String) {
val words = readDictionary()
!input.toLowerCase().split(” “).any{!words.contains(it)}
}
fun main(args: Array = array(“Kotlin is an island”)){
val valid = KotlinSpellChecker().ckeckSpelling(args[0])
println(“Is the text valid? $valid”)
}
}
This is an interesting comparison. I believe you get the same number of lines with Groovy as with Scala reason being that in Groovy you don’t need FileInputStream nor InputStreamReader. You can just say new File(“…”).readLines{ line -> line.toLowercase() … }. Once the Kotlin stdlib has hose things as well, the line count for the solution in Kotlin will be similar to Scala and Groovy.
I would be interested in seeing how the line count compares for some larger Scala sample that makes use of implicits, for example, or other constructs not found in Kotlin.