dotcl.win-x64
0.1.21
dotnet add package dotcl.win-x64 --version 0.1.21
NuGet\Install-Package dotcl.win-x64 -Version 0.1.21
<PackageReference Include="dotcl.win-x64" Version="0.1.21" />
<PackageVersion Include="dotcl.win-x64" Version="0.1.21" />
<PackageReference Include="dotcl.win-x64" />
paket add dotcl.win-x64 --version 0.1.21
#r "nuget: dotcl.win-x64, 0.1.21"
#:package dotcl.win-x64@0.1.21
#addin nuget:?package=dotcl.win-x64&version=0.1.21
#tool nuget:?package=dotcl.win-x64&version=0.1.21
dotcl
Common Lisp implementation on .NET. Lisp source is compiled to CIL (Common Intermediate Language) and runs on the .NET JIT — so the same Lisp image runs on Windows, macOS, and Linux across x86-64 and ARM64 without per-platform porting work.
Broadly conforms to the ANSI Common Lisp standard — verified against the ansi-test suite.
What dotcl is good for
- Embedding Common Lisp in .NET applications.
dotcl.runtimeis a regular .NET library; you load it from any C# / F# / VB.NET project, evaluate Lisp code, and call back and forth. - Writing .NET code in Lisp. The
dotnet:package gives direct access to .NET types:(dotnet:new "System.Text.StringBuilder"),(dotnet:invoke sb "Append" "x"),(dotnet:static "System.Math" "Sin" 1.0). You can subclass .NET types from Lisp viadotnet:define-class— the compiler emits real .NET classes, so frameworks like MAUI, ASP.NET Core, and MonoGame just see them as ordinary subclasses. - Cross-platform CL with NuGet ecosystem access. Any NuGet package is reachable from Lisp; any Quicklisp library that doesn't rely on SBCL-only internals tends to work too (asdf, alexandria, etc. are routinely loaded).
Quick start
# Install dotcl as a global .NET tool (works on any host with .NET SDK 10+).
dotnet tool install --global dotcl
# REPL
dotcl repl
# Evaluate a form
dotcl --eval "(format t \"hello, ~a~%\" (lisp-implementation-type))"
# Run a file
dotcl --load my-program.lisp
For Roswell users, per-RID tarballs are also published on each release page.
Prerequisites
- .NET SDK 10+ — see install table below
Installing .NET SDK 10
| OS | Command |
|---|---|
| macOS (Homebrew) | brew install --cask dotnet-sdk |
| Ubuntu 24.04+ | sudo apt install dotnet-sdk-10.0 |
| Debian | add the Microsoft package repository, then apt install dotnet-sdk-10.0 — see official guide |
| Windows (winget) | winget install Microsoft.DotNet.SDK.10 |
| Windows (Scoop) | scoop install dotnet-sdk |
| Cross-platform script | dotnet-install.sh / dotnet-install.ps1 |
| Other | https://dotnet.microsoft.com/download |
Building from source
If you want to hack on dotcl itself rather than just use it, clone the repo and bootstrap with Roswell:
make cross-compile # uses Roswell/SBCL to bootstrap the compiler
make compile-asdf-fasl # pre-compiles ASDF (required by samples)
make install # builds and installs the local nupkg as `dotcl`
After the first cross-compile, dotcl can self-host: DOTCL_LISP=dotcl make cross-compile rebuilds the compiler using dotcl itself.
Building on Windows
You only need this if you are hacking on dotcl itself — to use dotcl,
install the dotcl tool or grab a per-RID tarball above; no make or
Roswell required.
To build from source on Windows:
make— the build needs GNU Make. Git Bash (bundled with Git for Windows) ships GNU Make and works; run the commands above from a Git Bash prompt. WSL works too.- Path translation — run the build from Git Bash (
/c/...paths) rather than a shell that rewrites paths to Cygwin form (/cygdrive/c/...). The Roswell/SBCL bootstrap reads the paths verbatim, so/cygdrive/...paths it can't open surface as aSB-INT:SIMPLE-FILE-ERRORduringmake cross-compile. dotclnot found aftermake install—make installregistersdotclas a .NET global tool under~/.dotnet/tools, which is onPATHin PowerShell but often not in Git Bash. Add it there withexport PATH="$HOME/.dotnet/tools:$PATH"(or rundotclfrom PowerShell).
A GUI in five minutes
A cross-platform desktop window from one plain Lisp file — no C# project,
no csproj. nuget (bundled, dotcl 0.1.16+) resolves NuGet packages
and their transitive dependencies at run time:
;;;; hello-gui.lisp — run with: dotcl --load hello-gui.lisp
(require "dotnet-class") ; dotnet:define-class (ships with dotcl)
(require "nuget") ; NuGet resolver (ships with dotcl)
(nuget:require "Avalonia.Desktop" :version "12.0.4")
(nuget:require "Avalonia.Themes.Fluent" :version "12.0.4")
(dotnet:load-assembly "Avalonia.Desktop")
(dotnet:load-assembly "Avalonia.Themes.Fluent")
(dotnet:define-class "Hello.App" ("Avalonia.Application")
(:ctor ()
(dotnet:invoke (dotnet:invoke self "get_Styles") "Add"
(dotnet:new "Avalonia.Themes.Fluent.FluentTheme")))
(:methods
("OnFrameworkInitializationCompleted" () :returns Void :override t
(let ((win (dotnet:new "Avalonia.Controls.Window"))
(button (dotnet:new "Avalonia.Controls.Button"))
(clicks 0))
(dotnet:invoke win "set_Title" "Hello from Common Lisp")
(dotnet:invoke win "set_Width" 420d0)
(dotnet:invoke win "set_Height" 240d0)
(dotnet:invoke button "set_Content" "Click me")
(dotnet:invoke button "set_HorizontalAlignment"
(dotnet:static "Avalonia.Layout.HorizontalAlignment" "Center"))
(dotnet:invoke button "set_VerticalAlignment"
(dotnet:static "Avalonia.Layout.VerticalAlignment" "Center"))
(dotnet:add-event button "Click"
(lambda (s e) (declare (ignore s e))
(dotnet:invoke button "set_Content"
(format nil "~r click~:p from Lisp!" (incf clicks)))))
(dotnet:invoke win "set_Content" button)
(dotnet:invoke (dotnet:invoke self "get_ApplicationLifetime")
"set_MainWindow" win)))))
(let* ((builder (dotnet:static-generic "Avalonia.AppBuilder" "Configure" (list "Hello.App")))
(builder (dotnet:static "Avalonia.AppBuilderDesktopExtensions" "UsePlatformDetect" builder))
(args (dotnet:static-generic "System.Array" "Empty" (list "System.String"))))
(dotnet:static "Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions"
"StartWithClassicDesktopLifetime" builder args))
The first run downloads Avalonia from NuGet (a minute or two); after that
it starts in seconds. The same file is in
examples/hello-gui.lisp. Note the Lisp side is
ordinary object wiring — the same dotnet:new / dotnet:invoke /
dotnet:add-event calls work against WinForms, WPF, or any other .NET UI
toolkit you have on hand.
Showcase
paalam — a NeeView-style image / comic / PDF viewer (Avalonia). UI and application logic are Common Lisp end to end: CLOS protocol for page sources (folder / zip / rar / PDF), Lisp threads for prefetch,
dotnet:ffifor PDFium text extraction, installers for Windows / macOS / Linux. Read it as the scaled-up version of the five-minute example above.playa — an Emacs-style split-tiling video / music player (Avalonia + LibVLCSharp). Split the window into panes and play a different video in each, every pane with its own playlist, volume and position. UI and application logic are Common Lisp end to end — even the
Avalonia.Applicationsubclass is emitted from Lisp viadotnet:define-class— with C# only for boot and the native input shims. Lisp is ahead-of-time compiled at build time via project-core.
Samples
Working integrations in samples/:
- MauiLispDemo — a .NET MAUI app (Windows + Android) where
Application/ContentPage/ view model are all defined in Lisp viadotnet:define-class. - AspNetLispDemo — ASP.NET Core controller written in Lisp, with attribute routing.
- MonoGameLispDemo —
Gamesubclass in Lisp; theDrawoverride runs on the MonoGame frame loop and animates the background colour. - McpServerDemo — Model Context Protocol server exposing a Lisp REPL to MCP clients (Claude Desktop, etc.).
Each sample's README.md walks through the boot pattern.
Architecture
- Compiler (
compiler/, written in Lisp): transforms S-expressions into a flat list of CIL instructions (SIL). - Runtime (
runtime/, written in C#): object representation, reader, CIL assembler (PersistedAssemblyBuilder-based for.fasloutput andReflection.Emitfor in-memory codegen), and the standard library functions that aren't expressible in pure Lisp. - Bootstrap is by cross-compile: a Roswell SBCL runs
compiler/cil-compile.lispto emitcompiler/cil-out.sil, which the .NET runtime loads to bring up the Lisp environment. From that point dotcl can rebuild itself.
Architectural detail and design history are in
DESIGN.md.
License
MIT. See LICENSE.
Learn more about Target Frameworks and .NET Standard.
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.