Python is the default choice for machine learning. But many teams using functional languages wonder if they have to switch. At Flexiana, we prioritize Clojure, but we also use Python.
With libpython-clj, Clojure can tap into Python’s machine learning libraries without leaving the JVM. You get the expressiveness and REPL workflow you love, plus solid speed.
In this series, let’s walk you through training a model in Python and integrating it right into your Clojure codebase. No hype, just straightforward steps to get machine learning running in Clojure.
Why This Matters Now
- **Python’s role: **Python is the default for machine learning. It has TensorFlow, PyTorch, and scikit‑learn. If you are building models, you are probably using Python. That is fine. It is common and ef…
Python is the default choice for machine learning. But many teams using functional languages wonder if they have to switch. At Flexiana, we prioritize Clojure, but we also use Python.
With libpython-clj, Clojure can tap into Python’s machine learning libraries without leaving the JVM. You get the expressiveness and REPL workflow you love, plus solid speed.
In this series, let’s walk you through training a model in Python and integrating it right into your Clojure codebase. No hype, just straightforward steps to get machine learning running in Clojure.
Why This Matters Now
- **Python’s role: **Python is the default for machine learning. It has TensorFlow, PyTorch, and scikit‑learn. If you are building models, you are probably using Python. That is fine. It is common and effective.
- **The issue:**It creates a problem for teams that prefer other languages.
- Flexiana’s stance: We are a Clojure‑first company at Flexiana. We work with functional programming, the REPL, and the JVM every day. We use Python when it makes sense. But our core is Clojure. So we asked a simple question: *Do we need to leave Clojure to use modern ML tools?
- **Typical workflow pain: **Many companies feel stuck in Python‑only workflows. Data scientists train models in Python. Developers then wrap those models in services to fit the main stack. It works, but it adds friction. It creates hand‑offs and silos. And it makes functional teams feel as if they are working on the edges.
- A better path with libpython‑clj: With libpython‑clj, you do not have to pick one ecosystem and drop the other. You can keep Clojure’s clarity and still call Python’s ML libraries. Train a model in Python. Load it in Clojure. Use it in your codebase. No extra wrappers. No awkward bridges. Just a clean, direct path.
- Why now: ML is now part of everyday software. Finance, healthcare, retail—many production systems use it. Most of those systems already run on the JVM. If you build in Clojure, you shouldn’t have to step out of your stack to add ML.
- Why Clojure helps: Think of it like this- Python gives you the tools. Clojure gives you the environment. The REPL enables you to move faster. The functional style keeps code easy to reason about. The JVM fits into enterprise systems without fuss. Together, you get solid ML and clean integration.
That is what this series is about. ML in Clojure is not only possible; it is also practical. It is practical. You can keep your language and still use Python’s ecosystem. And you can fit ML into your stack without compromise.
Python vs Clojure Adoption in Machine Learning (2025)
| Aspect | Python (ML Adoption) | Clojure (ML Adoption) |
|---|---|---|
| Community Size | Extensive, global community. Dominant in ML and data science. | Small but growing. Groups like Scicloj are active. |
| Library Ecosystem | Mature ML stack: TensorFlow, PyTorch, scikit‑learn, Keras. | Uses Python interop via libpython‑clj. Few native ML libraries. |
| Industry Adoption | Common across finance, healthcare, retail, and research. | Limited to enterprises. Often used in specialized or experimental work. |
| Learning Curve | Easier start. Lots of tutorials and courses. | Steeper start. Lisp syntax and functional style take time. |
| Integration with JVM | Indirect. Runs outside the JVM and often requires wrappers or services. | Native JVM language. Fits cleanly into enterprise stacks. |
| Performance in ML Tasks | Strong for training. Good GPU/TPU support. | Suitable for orchestration and integration. Training is usually done in Python. |
| Current Trend (2025) | Still the top ML language in most surveys. | Growing interest in bridging Python ML into Clojure with libpython‑clj. |
Sources:
- Python vs Clojure Comparison (2025)
- Clojure vs Python Professional Comparison
- Scicloj Project Update July 2025
Is ML in Clojure Possible?
Python dominates machine learning. The libraries are mature. The community is enormous. The tools fit Python well. But Clojure is not shut out. With its functional style and JVM roots, Clojure can also work with ML. The key is interop.
Enter clj-python & libpython-clj
Chris Nuernberger built libpython‑clj to make this simple. Instead of wrapping models in services or switching stacks, Clojure can communicate directly with Python.
What is libpython‑clj?:
libpython‑clj is a bridge between Clojure and Python. It embeds the CPython runtime inside the JVM. You can call Python functions and use ML libraries from Clojure. Import TensorFlow, PyTorch, or scikit‑learn without leaving your REPL.
How it works
╰┈➤ JVM + CPython bridge: libpython‑clj runs CPython inside the JVM process.
╰┈➤ Direct calls: You call Python functions like Clojure functions.
╰┈➤ Shared workflow: Train a model in Python. Load and use it in your Clojure codebase.
This cuts friction—no extra wrappers. No microservices. No awkward hand‑offs. Just a clean, direct path that keeps Clojure as your primary language while using Python’s ML ecosystem.
How ML Looks in libpython-clj
Machine learning in Clojure with libpython‑clj is simple. You pull Python’s ML tools into your Clojure workflow. You stay in the REPL. You don’t need extra services.
Example workflow: Importing TensorFlow/PyTorch models into Clojure
╰┈➤ Train the model in Python: Use TensorFlow or PyTorch. Save the model when you’re done.
╰┈➤ Load the model in Clojure: Import Python modules with libpython‑clj. Call Python functions from Clojure.
╰┈➤ Run predictions in Clojure: Pass your data. Get results back without leaving the JVM.
axasxa
asdasd
asadad
aasasdasdaa
add code here which is processed by below image

Note: This is a simple placeholder. Your code will depend on the model and library you use.
Visual placeholder: Clojure ↔ Python ML pipeline
╰┈➤ Step 1: Train the model in Python (TensorFlow/PyTorch).
╰┈➤ Step 2: Save the model file.
╰┈➤ Step 3: Import with libpython‑clj inside Clojure.
╰┈➤ Step 4: Run inference in your Clojure codebase.

Demonstrating ML in Action
Machine learning in Clojure with libpython‑clj follows a simple process.
Example: Training and integrating a model
╰┈➤ Step 1: Train in Python: Use TensorFlow or PyTorch to build and train your model, then save it as a .pt (PyTorch) or SavedModel (TensorFlow).
╰┈➤ Step 2: Load in Clojure: You can import Python modules with libpython‑clj and load the saved model into the JVM.
╰┈➤ Step 3: Integrate: You can wrap inference in small Clojure functions and connect predictions to your data flow and test quickly in the REPL.
What works well
╰┈➤ Seamless API calls: You can call Python ML functions directly from Clojure without needing wrappers or microservices.
╰┈➤ **REPL‑driven dev: **It lets you test predictions, inspect tensors, and adjust data instantly.
What needs care
╰┈➤ Boxed math: Passing boxed numbers or generic sequences can slow performance.
╰┈➤ **Interop overhead:**Frequent cross-language calls can add latency.
Fixes
╰┈➤ Utility functions: Write utility functions if you want to convert data between Clojure types and Python‑friendly arrays or tensors.
╰┈➤ Optimized interop: You can batch calls, reduce crossings, cache modules, and reuse model objects.
Code comparison
Python (train and save):

Clojure (load and infer):

Note: Real PyTorch loading usually restores a model class and its state_dict. The snippet above is a placeholder to show the flow.
And that is the idea: Python handles training. Clojure handles clean integration and deployment. Together, you get solid ML with a straightforward path to production.
Why Care About Clojure in the ML World?
Expressiveness vs verbosity (functional programming)
╰┈➤ Clear transformations: Clojure’s functional style allows you to express data flows in fewer lines.
╰┈➤ Less boilerplate: You write what is essential. Transformations stay front and center.
╰┈➤ Easier pipelines: Short and direct code makes ML steps easier to read and maintain.
Performance (JVM optimization)
╰┈➤ Mature runtime: The JVM offers you good optimization, threading, and memory management.
╰┈➤ Enterprise-friendly: You can plug ML into your already existing systems without any significant rewrites.
╰┈➤ Stable under load: You get predictable performance for production workflows.
Readability for imperative programmers
╰┈➤ **Clean structure: **Clojure has a clean, simple structure and syntax. The focus stays on the data.
╰┈➤ REPL-first workflow: With Clojure, you can test, inspect, and iterate quickly.
╰┈➤ Low ceremony: Clojure has fewer moving parts. You can easily see what each step does.
🔗 Clojure official site: https://clojure.org
Business Case for ML in Clojure
╰┈➤ Reduced dependency on Python-only teams: You are not stuck relying on Python teams for everything anymore. With Clojure, your own developers can jump in to handle integration and deployment, while the Python folks focus on what they do best- training the models. That way, you can reduce risk, and scaling goes much smoother.
╰┈➤ Faster prototyping with REPL: Clojure’s REPL changes the game for prototyping. You get instant feedback- test predictions and tensors, as well as tweak your data right there in the loop. You see what works (and what does not) before you commit to building anything significant.
╰┈➤ Integration with enterprise JVM ecosystems: You can plug models into your company’s JVM systems directly. Less friction. Smoother deployment. Everything lines up with the tools your team already knows and trusts.
ROI chart comparing Python-only ML vs. hybrid Clojure + Python.
╰┈➤ Python-only: Higher dependency on specialized teams. Slower integration. More overhead.
╰┈➤ Hybrid: Shared ownership. Faster iteration. Better fit for enterprise workflows.

FAQs (People Also Ask Integration)
Using Python ML in Clojure
- Question: Can you use Python ML libraries in Clojure?
- Answer: Yes. You can bridge the CPython runtime with libpython‑clj and call Python code from Clojure.
Speed and performance
- Question: Is Clojure faster than Python for ML?
- Answer: It depends. You can train models in Python for speed, and use Clojure for orchestration, integration, and deployment.
Choosing the stack
- Question: Why not just use Python?
- Answer: You can use Clojure for JVM interop, a REPL‑driven workflow, and clear functional code that fits enterprise systems.
Adoption and case studies
- Question: What companies use Clojure for ML?
- Answer: You can reference case studies (Flexiana, fintech, healthcare) as placeholders until specific examples are approved.
Model integration workflow
- Question: How do you integrate a trained model into Clojure?
- Answer: You can load the model with libpython‑clj, wrap conversions in utility functions, and call inference from your Clojure codebase.