Writing the same regular expression logic in multiple JVM languages

I tried writing three regular expressions in a the most common JVM languages.

  1. Find first match
  2. Find all matches
  3. Replace first match

My experience in these languages range from use it many times a week (Groovy) to this is the first thing I’ve written in it (Clojure).

I’m going to be using these in a presentation. So if you see anything in here that is a bad idiom in the language, do let me know!

Kotlin

The WordPress syntax highlighter doesn’t have Kotlin as a choice

val text = "Mary had a little lamb"
val regex = Regex("\\b\\w{3,4} ")
print(regex.find(text)?.value)
-----------------------------------------
val text = "Mary had a little lamb"
val regex = "\\b\\w{3,4} ".toRegex()
regex.findAll(text)
  .map { it.groupValues[0] }
  .forEach { print(it) }
-----------------------------------------
val text = "Mary had a little lamb."
val wordBoundary = "\\b"
val threeOrFourChars = "\\w{3,4}"
val space = " "
val regex = Regex(wordBoundary +
  threeOrFourChars + space)
     
println(regex.replaceFirst(text, "_"))

Scala

Thanks to dhinojosa for the code review and feedback that smart quotes don’t require backslashes inside!

val text = "Mary had a little lamb"
val regex = """\b\w{3,4} """.r
val optional = regex findFirstIn text
      
println(optional.getOrElse("No Match"))
-----------------------------------------
val text = "Mary had a little lamb."
val regex = """\b\w{3,4} """.r
val it = regex findAllIn text
      
it foreach print
-----------------------------------------
val text = "Mary had a little lamb."
val wordBoundary = """\b"""
val threeOrFourChars = """\w{3,4}"""
val space = " "
val regex = new Regex(wordBoundary + threeOrFourChars + space)
     
println(regex replaceFirstIn(text, "_"))

Closure

(println(
  re-find #”\b\w{3,4} ", 
          "Mary had a little lamb"))
-----------------------------------------
(println(
  re-seq #”\b\w{3,4} ", 
          "Mary had a little lamb"))
-----------------------------------------
(ns clojure.examples.example
   (:gen-class))
(defn Replacer []
   (def text "Mary had a little lamb.")
   (def wordBoundary "\\b")
   (def threeOrFourChars "\\w{3,4}")
   (def space " ")
   (def regex (str wordBoundary 
        threeOrFourChars space))
   (def pat (re-pattern regex))
   (println(clojure.string/replace-first 
       text pat "_")))
(Replacer)

Groovy

def text = 'Mary had a little lamb'
def regex = /\b\w{3,4} /

def matcher = text =~ regex
print matcher[0]
-----------------------------------------
def text = 'Mary had a little lamb'
def regex = /\b\w{3,4} /

def matcher = text =~ regex
print matcher.findAll().join(' ')
-----------------------------------------
def text = 'Mary had a little lamb'
def regex = /\b\w{3,4} /

def matcher = text =~ regex
print matcher.findAll().join(' ')

[2018 oracle code one] emerging languages bowl

Emerging Languages Bowl

Speaker: Trisha Gee (JetBrains) and Eugene Petrenko (JetBrains) – moderated by Raghavan “Rags” Srinivas

For more blog posts, see The Oracle Code One table of contents


Rags talked about how this is a different format than the usual “script bowl”. I’ve never been so not disappointed

Java (Trisha)

  • Inspired features from scripting languages
    • Lambdas
    • Streams – would be hard to use without lambdas because would need anonymous inner classes
    • RPEL
    • var
  • Not a functional language, but idioms that came from functional languages
  • Not in Java
    • Immutable “var” – do you use var/val, var/let, var/final var? We have “final var”, but it isn’t immutable. Just prevents re-assignment. But are getting immutable collections.
  • Future
    • data classes [records]- Kotlin has this. Preview feature in Java 12
    • multi-line strings – Groovy has this.
    • Switch statements/pattern matching. Preview feature as well
  • Preview features are a good thing because can discuss with real code

Kotlin (Eugene)

  • Statically typed
  • Now official on Android
  • Concise – minimal boilerplate
  • Safe – avoid classes of errors like null pointers
  • Interoperable – use JVM and Android libraries
  • Tool friendly – works with any Java IDE
  • Can combine Java and Kotlin in same module
  • Kotlin invented in 2000. Version 1 came out in 2005
  • Can target Java 1.6 (or higher if want)

“The only way to learn a new programming language is by writing programs in it” -Dennis Richie

IntelliJ has plugin which gives sample tasks

Kotlin demo

  • fun main() {} – function – defaults to void return type
  • fun main() : ReturnType {} – function with return type. Can use generics in types
  • “Hello ${abc}” – string interpolation
  • Triple quotes – multi line string
  • trimIndent() – extra method
  • var/val – mutable/immutable
  • var x : String – not nullable
  • var x : String? – nullable
  • if ( x is Type) – auto casts inside if statement
  • fun Class.method() = impl – add method from outside class. It can even use instance variables from inside the class.
  • sealed class – all subclasses must be defined in same file
  • when/is – pattern matching

My take: I don’t know what the session was supposed to be, but this was fine. It was 10 minutes of Trisha and Eugene introducing Kotlin for 30. I have seen the intro to Kotlin talk before though. That said, I still needed Google for what one thing did.

 

DevNexus 2018 – Bulletproofing your foot for Kotlin

Title: Bulletproofing your foot for Kotlin
Speakers: Enrique Zamudio

Slides (from the Devoxx version of this talk)

For more blog posts, see the DevNexus 2018 live blogging table of contents


About Kotlin

  • Created by JetBrains (makers of IntelliJ)
  • Static typing
  • JVM language
  • Can run on front end or back end
  • Good for Android

Data classes

data class Person(val name:String val birthDate:Date)
  • No need to write getters/setters.
  • toString() and equals() automatically added.
  • However hashCode() is not automatically added.

Destructuring

val p = Person("John", now)
val (n, f) = p
  • Like Scala
  • Stores each field in a variable
  • Similarly can do for ((k,v) in map) when iterating through a map

Functions

fun foo() {}

Takes no params, calls a function and returns Unit (void)

fun bar(f:() -> (Unit)) = f())

Method reference like in Java. Since a top level function, nothing before the ::

bar(::foo)

Passing a lambda directly to a function:

bar ( { println() })

Runs on Java 7

String interpolation

println "Name: $n"

Works like in Groovy

Type inference

Immutable (final) String:

val p = "hello"

Mutable:

var q = "hi"

Recommend specifying type for method so faster.

Smart casts

 val p:Any = "string"
if p is String) {
  println(p.toUppercase())
}
  • Any is a root class
  • Once you check the type, you can use it rather than having to cast.
  • Can still write explicit cast println((p as String).toUpperCase()). Stupid cast?

Typesafe null

var p:String? = "hello"
p = null
if (p != null) {foo(x)}
  • Want to catch errors at compile time
  • If just write var, can’t assign null.
  • Have to explicitly say it is ok by making it an “optional string”
  • Cannot pass an optional string to a method that takes a regular string [cool!]
  • Write guard to check if not null. That is a smart cast to turn String? into String so can call method that takes String
  • ?. returns null if it is null vs a runtime exception. So safe way is to write s?.length
  • The elvis operator ?: from Groovy is also supported.
  • BEWARE: There’s also a kill switch. Writing foo(p!!) you are forcing Kotlin to pass the String? into String without the check. It is a way to say you know what you are doing. Then you get a runtime error if it is null instead of a compiler error.

Operator overloading

class Foo(val x:Int) {
  operator fun plus(o:Foo) = Foo(o.x=x)
}
  • Can only overload simple operators – math operators and index (square square brackets)
  • BEWARE: only way to tell if can use overloading is to look at the class code (or release notes). It’s not in the docs.

Extension methods

fun Person.debug() { println("") {
  • Can add methods to a class even if don’t have the source code.
  • BEWARE: don’t use extension operators. Someone looking at the class won’t know they are there. Not obvious where to look for the code.

Non local returns

  • BEWARE: do not use.
  • Allows writing a return within a closure. In Groovy, it would return from the closure. In Kotlin, it returns from the whole method.
  • Can write return@forEach to return from just the closure. But yech.

My take

This was my first exposure to Kotlin. Some of the features are really cool!