Beginner

Hello World in Dylan

Your first Dylan program - the classic Hello World example with Docker setup

Every programming journey starts with Hello World. Let’s write our first Dylan program and experience this unique language that combines dynamic flexibility with efficient compilation.

The Code

Dylan programs require a project structure with a library definition file and a source file. Our Docker setup handles this automatically, but let’s understand the pieces.

Create a file named hello.dylan:

1
2
3
Module: hello

format-out("Hello, World!\n");

This simple source file contains our Hello World code. The Module: header tells Dylan which module this code belongs to.

Understanding the Code

Let’s break down this program:

  • Module: hello - A header that specifies which module this source file belongs to. In Dylan, code is organized into modules within libraries.
  • format-out - A function from the format-out module that outputs formatted text to standard output, similar to printf in C.
  • "Hello, World!\n" - A string literal with a newline character. Dylan strings use double quotes.

Why the Module Header?

Dylan uses a sophisticated module system inherited from its Lisp heritage. Every source file must declare which module it belongs to. Modules provide namespacing and control what names are visible to other code.

Running with Docker

The easiest way to run this without installing Open Dylan locally:

1
2
3
4
5
# Pull the Dylan Docker image
docker pull codearchaeology/dylan:latest

# Run the program
docker run --rm -v $(pwd):/app codearchaeology/dylan:latest

Our Docker image includes Open Dylan and automatically handles the library and module definitions when it detects a hello.dylan file.

How the Build Works

When you run the Docker command, it:

  1. Detects hello.dylan in the mounted /app directory
  2. Creates a Dylan project structure with library and module definitions
  3. Compiles the project using dylan-compiler
  4. Runs the resulting binary

Expected Output

Hello, World!

Understanding Dylan Project Structure

A complete Dylan project typically includes several files:

Library Definition (library.dylan)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
Module: dylan-user

define library hello
  use common-dylan;
  use io;
end library;

define module hello
  use common-dylan;
  use format-out;
end module;

This defines:

  • A library named hello that uses the common-dylan and io libraries
  • A module named hello that uses the common-dylan and format-out modules

Source File (hello.dylan)

The source file we created earlier contains the actual program code.

Build Configuration (dylan-package.json)

Modern Open Dylan uses a JSON-based package configuration.

Key Concepts

  1. Libraries and Modules - Dylan code is organized into libraries (compilation units) containing modules (namespaces). This provides strong encapsulation.

  2. format-out - The standard way to output text. It’s part of the io library and uses format strings similar to printf.

  3. No Main Function - Top-level expressions in a module are executed when the program starts.

  4. Object-Oriented - Everything in Dylan is an object, including numbers and functions.

Alternative: Using format

You can also use the more powerful format function for formatted output:

1
2
3
Module: hello

format(*standard-output*, "Hello, World!\n");

Or with format directives:

1
2
3
4
Module: hello

let name = "World";
format-out("Hello, %s!\n", name);

Common format directives:

  • %s - String (uses print-object)
  • %d - Decimal integer
  • %= - Dylan print representation
  • %% - Literal percent sign

Dylan vs Other Languages

Java:

1
2
3
4
5
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Python:

1
print("Hello, World!")

Common Lisp:

1
(format t "Hello, World!~%")

Dylan:

1
format-out("Hello, World!\n");

Notice how Dylan’s syntax resembles Python or Pascal more than its Lisp ancestors, despite sharing many concepts with Common Lisp.

Variables and Types

Dylan supports both untyped and typed variable declarations:

1
2
3
4
5
6
7
8
// Untyped variable
let greeting = "Hello";

// Typed variable
let count :: <integer> = 42;

// Constants
let pi :: <float> = 3.14159;

Type names in Dylan are surrounded by angle brackets: <integer>, <string>, <float>.

Functions in Dylan

Here’s how you’d define a simple function:

1
2
3
4
5
6
define method greet (name :: <string>) => ()
  format-out("Hello, %s!\n", name);
end method;

// Call it
greet("World");
  • define method creates a method (Dylan’s version of functions)
  • => () indicates no return value
  • The end method; closes the definition

Dylan’s Multiple Dispatch

One of Dylan’s most powerful features is multiple dispatch:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
define method describe (x :: <integer>)
  format-out("An integer: %d\n", x);
end method;

define method describe (x :: <string>)
  format-out("A string: %s\n", x);
end method;

describe(42);        // "An integer: 42"
describe("hello");   // "A string: hello"

The appropriate method is chosen based on the runtime type of all arguments.

About Open Dylan

Our Docker image uses Open Dylan, the open-source Dylan implementation that combines:

  • Gwydion Dylan - CMU’s open-source compiler
  • Functional Developer - Harlequin’s commercial implementation

Open Dylan provides:

  • Native code compilation
  • Cross-platform support (Linux, macOS, Windows)
  • Modern tooling with the deft package manager
  • Active community development

Next Steps

Continue exploring Dylan’s unique features:

  • Classes and the object system
  • Multiple dispatch in depth
  • The module and library system
  • Macros and metaprogramming
  • Generic functions and method combinations

Dylan rewards exploration. Its combination of dynamic language flexibility with static language performance offers a unique programming experience.

Welcome to Dylan!

Running Today

All examples can be run using Docker:

docker pull codearchaeology/dylan:latest
Last updated: