Skip to content
sps014Public

About

A blazing fast, statically typed cross platform programming language that for also works on web.

Resources

Stars

14 stars

Watchers

1 watching

Forks

Repository files navigation

Dream

Write expressive code. Ship native binaries and WebAssembly.

A statically typed, ahead-of-time compiled language with automatic memory management, specialized generics, and a standard library built for real applications.

Optimized ARC · GPU shaders in Dream · Typed web APIs · Seamless C, C++, and JavaScript interop · Native + WebAssembly

Get started · Documentation · Language tour · Examples

Get started

On macOS or Linux:

curl --proto '=https' --tlsv1.2 -sSf https://sps014.github.io/dream/install.sh | sh

On Windows, open PowerShell:

irm https://sps014.github.io/dream/install.ps1 | iex

Open a new terminal, then create and run a project:

dreamer init hello
cd hello
dreamer run

Your program lives in src/main.dream; project settings live in dream.toml. The generated starter prints Hello, world!. Replace it with the JSON example below to try a little more of the language.

Continue with the quickstart, language tour, or first complete project.

A first taste

import system;
import system.json;

@json
class Developer {
    name: string;
    languages: string[];

    public constructor(name: string, languages: string[]) {
        this.name = name;
        this.languages = languages;
    }
}

fun main() {
    let dev = Developer("Ada", ["Dream", "TypeScript"]);
    System.println(Json.serialize(dev));
}
{"name":"Ada","languages":["Dream","TypeScript"]}

Typed data, automatic cleanup, and JSON serialization generated at build time. Paste it into src/main.dream and run dreamer run.

Dream is pre-1.0 and actively evolving. Expect breaking changes as the language develops.

Why choose Dream?

Dream is for people who want familiar application code, ahead-of-time compilation, and control over where their program runs. If you know TypeScript, Rust, or C#, much of the syntax will feel familiar. The interesting part is how the pieces fit together.

Compile to the machine. Bring the same language to the web.

Build native executables for command-line tools and services, or compile to WebAssembly for the browser and Node. Share your core logic across targets, then use each environment's APIs where you need them. Code goes through LLVM's optimizer either way, and builds are deterministic: the same source produces byte-identical output. See environments.

Write GPU shaders in Dream.

Import system.gpu and write compute, vertex, and fragment shaders as Dream functions. Typed buffers and generated shader calls connect your application to the GPU. Shaders compile ahead of time, so no shader source or shader compiler ships with your program.

Start with WebGPU for native and browser programs, or choose Metal, Vulkan, Direct3D, or CUDA for platform-specific work. Rendering, ray tracing, automatic differentiation, and tensor hardware operations are available where the selected backend and GPU support them; CUDA is compute-only, and ray tracing requires a native backend.

Install the shader compiler before building a program with shaders:

dreamer toolchain install slang

Follow the GPU setup and first compute shader, draw with the rendering guide, or try the interactive spotlight. Explore ray tracing and machine learning for advanced workloads. The setup guide lists additional tools required by specific targets; GPU failures are returned as Result values with GpuError details.

Automatic memory that mostly compiles away.

Dream manages heap values with automatic reference counting (ARC). Objects are freed the moment their last owner lets go, with no garbage collector and no tracing pauses. Most of the counting is removed at compile time:

  • Moves on last use. Passing or storing a value for the last time hands it over instead of copying a reference. There is no move keyword to sprinkle through your code.
  • Borrow inference. Release builds work out which parameters only read their arguments and pass those without touching the count. Write borrow when you want the contract spelled out.
  • Retain/release elision. Pairs that cancel out are removed across branches, loops, and inlined calls.
  • Retain-free traversal. Walking a linked structure (node = node.next) or reading fields in a loop does no counting when the compiler can prove the source stays alive.
  • Cheap counts where it matters. Counts are plain, non-atomic integers unless a type is declared shared for tasks. Interned strings never change their count, and objects that never escape a function can be split into local values with no heap allocation.
  • Zero-cost generics. Generic code is specialized for each concrete type, so there is no runtime type dispatch.

Classes share identity; structs copy as values and live inline. Ordinary code cannot read freed memory, out-of-bounds indexing stops with a clear error instead of reading past the end, and classes that can form reference cycles must be marked @allow_cycle, which makes leaks visible. Read about ownership, memory management, and reference cycles.

Call C, C++, and JavaScript directly.

Declare a foreign function with the right attribute and call it like any Dream function. The compiler generates the glue and converts values at the boundary.

Interop Runs on What you get
C Native, browser, Node @c externs. Package C sources are built with the pinned clang for native and WebAssembly; desktop builds can also link system libraries. Native callbacks let C call back into Dream.
C++ Same as C @cpp maps classes, methods, constructors, and templates. std::optional, exceptions, and std::function map to Option, Result, and Dream closures.
JavaScript Browser, Node extern fun for known signatures, the dynamic js type for DOM nodes and other live values, callbacks in both directions, and extern async fun for Promises. An optional tree-shaken runtime ships only the host code your program uses.

Serve typed web APIs.

system.webapi builds native HTTP services. Routes are typed static methods, and the router is generated at compile time, so a handler cannot receive an argument of the wrong type.

import system;
import system.json;
import system.webapi;

@json
class Greeting {
    public message: string;

    public constructor(message: string) {
        this.message = message;
    }
}

@router("")
class Routes {
    @get("/hello/{name}")
    public static fun hello(@path name: string): Greeting {
        return Greeting("Hello, " + name);
    }
}

async fun main(): void {
    let app = WebApp();
    app.include_router(Routes.router()).unwrap();
    app.run("127.0.0.1", 8000).await.unwrap();
}

Run it with dream run app.dream and open http://127.0.0.1:8000/hello/Dream. Interactive Swagger documentation is served at /docs.

The framework also includes validated request models, dependency injection, middleware and CORS, password and token authentication, OAuth2/OIDC login, scopes, uploads, server-sent events, WebSockets, and TLS. Servers run on native targets. Start with the web server guide.

Keep abstractions in your source, specialize them at build time.

Write reusable collections and algorithms with generics. Dream specializes generic code for the concrete types you use, avoiding runtime type dispatch for those generic operations.

Use classes and interfaces for object-oriented designs, structs for value data, and enums and discriminated unions to model alternatives. Option and Result make missing values and recoverable failures part of a function's type. Explore the type system and error handling.

Wait concurrently. Compute in parallel. Own the lifetime of both.

Use async/await for work that waits and worker tasks for CPU parallelism. Structured task scopes join their children on success, failure, cancellation, and early error return, so concurrent work has a clear lifetime.

Start with structured concurrency, then use tasks and pools when you need parallel execution.

Extend the language using the language.

Dream source generators are ordinary Dream functions. They can inspect declarations, generate methods, and turn custom syntax blocks into checked Dream code during a build.

The @json in the opening example uses this same mechanism. Your own packages can ship derives and small domain-specific notations, too. See source generators for a complete example.

Build something useful

The standard library covers collections, files, JSON, HTTP, regex, dates, crypto, processes, logging, and testing. Dream also includes a web API framework with typed routes, validation, and generated OpenAPI documentation.

Each feature guide explains which environments it supports.

A toolchain for everyday work

Dreamer handles projects, dependencies, builds, tests, and packaging:

dreamer run                # Build and run your app
dreamer build --release    # Build an optimized version
dreamer test               # Run your project's tests
dreamer add <package>      # Add a dependency
dreamer pack               # Package a CLI app for sharing
dreamer toolchain doctor   # Check required build tools

Dream includes editor completion, diagnostics, formatting, and navigation. Follow editor setup, browse the Dreamer guide, or use troubleshooting if you get stuck.

Help shape Dream

Found a bug or have a language idea? Open a GitHub issue. For bugs, include a small program, the command you ran, and the error text.

To work on the compiler, runtime, or tools, start with the contributor handbook. For documentation changes, read the maintenance guide.

License

MIT

About

A blazing fast, statically typed cross platform programming language that for also works on web.

Resources

Stars

14 stars

Watchers

1 watching

Forks

Releases

Used by

Contributors

Languages