Scala
Clojure
Programming
Object-oriented Programming
Code Creation

How to create a scala object in clojure

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Clojure cannot declare a Scala object directly, but it can use one once the Scala code is compiled and placed on the classpath. The practical workflow is to define the singleton in Scala, compile it, then access its generated JVM class from Clojure through normal interop.

Compile the Scala Object First

A Scala object becomes a JVM class with a singleton instance stored in a static field named MODULE$. That detail is what Clojure uses.

Create a small Scala source file:

scala
1package demo
2
3object Greeter {
4  def hello(name: String): String = s"Hello, $name"
5}

Compile it so the class files are available to the Clojure process:

bash
scalac -d classes src/demo/Greeter.scala

In a deps.edn based Clojure project, make sure both the compiled classes and the Scala runtime are on the classpath:

clojure
{:paths ["src" "classes"]
 :deps {org.clojure/clojure {:mvn/version "1.11.1"}
        org.scala-lang/scala-library {:mvn/version "2.13.14"}}}

Without the Scala runtime dependency, many Scala-generated classes will fail at runtime even though the class files exist.

Access the Singleton from Clojure

Once the Scala classes are on the classpath, import the generated class ending in $, then read its MODULE$ field to get the singleton instance.

clojure
1(ns app.core
2  (:import [demo Greeter$]))
3
4(def greeter-instance
5  (.-MODULE$ Greeter$))
6
7(println (.hello greeter-instance "Clojure"))

That prints a greeting by calling the Scala method on the singleton object.

This is the part that surprises most people:

  • The Scala source name is Greeter.
  • The generated JVM class for the object is Greeter$.
  • The singleton value lives in Greeter$.MODULE$.

After that, method calls are ordinary JVM interop.

Use Companion Objects and Factory Methods

Scala objects are often used as factories. Clojure can call those factory methods in the same way.

scala
1package demo
2
3final case class User(name: String, age: Int)
4
5object UserFactory {
6  def adult(name: String): User = User(name, 18)
7}
clojure
1(ns app.user
2  (:import [demo UserFactory$]))
3
4(def factory
5  (.-MODULE$ UserFactory$))
6
7(def user
8  (.adult factory "Riley"))
9
10(println user)

This pattern is useful when a Scala library exposes singleton helpers, builders, parsers, or configuration entry points.

Common Pitfalls

The biggest problem is trying to import Greeter instead of Greeter$. For a Scala singleton, the object instance is not exposed as a normal Java static method container. You usually need the generated $ class and its MODULE$ field.

Another common issue is forgetting the Scala runtime dependency. Even if your Clojure code can see the compiled classes, calls may still fail if scala-library is missing from the classpath.

Method signatures can also be confusing. Scala features such as default parameters, overloaded methods, implicits, and symbolic method names may generate JVM methods that are less friendly from Clojure. If interop feels awkward, inspect the compiled API with javap or provide a thin Scala wrapper with simple JVM-friendly method names.

Finally, do not assume Clojure is creating the Scala object. Clojure is only consuming a singleton that Scala already compiled. If you control the Scala side, keep that API small and explicit. It makes interop much easier.

Summary

  • You do not create a Scala object in Clojure source; you compile it in Scala and use it from Clojure.
  • A Scala singleton is exposed through a generated class ending in $.
  • The actual singleton instance is stored in the static MODULE$ field.
  • Add both the compiled classes and scala-library to the Clojure classpath.
  • If a Scala API is hard to call from Clojure, add a small Scala wrapper with simpler JVM-visible methods.

Course illustration
Course illustration

All Rights Reserved.