Embracing Scala 3 migration

Scala 3 is near, what about software in production?

  • Older Scala (2.11 - 578, 2.12 - 9141, 2.13 - 900)
    • lack of backward binary compatibility 
  • Coupled software
    • hard or impossible to extract separated modules
  • Old scala deprecated libraries (like spray.io, casbah)
    • lack of proper interface for separation
    • hard to replace the library gradually
  • Different programming styles over the years
    • Synchronous
    • Async with `Future`
    • Tagless final
    • Free Monad

How to migrate existing software?

  1. Split the software
    • extract small modules with clear boundaries
    • establish proper interfaces
  2. Upgrade libraries, module by module
    • Ideally to those with support for both 2.12 and 2.13
  3. Upgrade Scala version (2.13)
    • Enable cross compilations in modules (if needed)
    • It can be done together with point 2.
  4. Upgrade to Scala 3
    • Apply Scalafix module by module
    • No need for cross-compilation
🧐
 

Crucial first step - software modularization

  • What are the natural candidates for separate modules?
  • What are the problematic parts?
  • Can we do that gradually?
  • Can we automate the process?

Maybe some visual help?

Applying graph theory

  • Particular nodes
    • Betweenness centrality
    • Clustering coefficient
    • Modularity class
  • Whole graph
    • Finding communities
    • Average node degree
    • Graph diameter
    • Modularity 

Where we want to be

 hypothesis:

the code structure of any program can be represented as a directed graph, precise enough to be valuable in various analyses and visualizations

Semantic Code Graph

Semantic Code Graph in Scala

class A()
object AFactory {
  def createA() = {
    new A()
  }
}

Semantic Code Graph in Scala

class A()
object AFactory {
  def createA() = {
    new A()
  }
}

Code Syntax + Semantics

  • Code Structure
    • Scala Trees
  • Code Semantics
    • SemanticDB

Common format

syntax = "proto3";

message Location {
    string uri = 1;
    int32 startLine = 2;
    int32 startCharacter = 3;
    int32 endLine = 4;
    int32 endCharacter = 5;
}

message Edge {
    string to = 1;
    string type = 2;
    Location location = 3;
    map<string, string> properties = 4;
}

message GraphNode {
    string id = 1;
    string kind = 2;
    Location location = 3;
    map<string, string> properties = 4;
    string displayName = 5;
    repeated Edge edges = 6;
}

message SemanticGraphFile {
    string uri = 1;
    repeated GraphNode nodes = 2;
}

Graph Buddy

Semantic Code Graph seamlessly integrated with IDE

Demo

Graph Buddy process

Graph Buddy architecture

Future use cases

  • Project visualizations
    • getting insight on how the current software is structured
  • Project modularization guidance
    • possible modules extractions
    • exposing architectural smells
    • finding critical for migration places
  • Release changes analysis
    • are we on right track with our migration?

Towards Scala 3 with Semantic Code Graph

By liosedhel

Towards Scala 3 with Semantic Code Graph

  • 851