Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Getting Started

As with any language, the very first thing we have to do is write a "Hello world" program. Go on, you have to.

Create a file named "test.md" and into it insert the following code:

module test
writeln("Hello world!")

Once you've done that, grab MDCL, the standalone MiniD interpreter (it works on Windows and through Wine on Linux), and run it like so:

$ mdcl test

At which point you'll get the standard first-thing-you-do-in-any-programming-language greeting.

How about a program that asks the user for a number and prints the square of it?

module test

function square(num) =
	num * num

write("Enter a number: ")
local num = toInt(readln())
writefln("The square of {} is {}.", num, square(num))

Doesn't look too scary, no? Running it with MDCL will give you a prompt, at which you enter a number, and you'll get an answer.

A quick word on modules

Each MiniD script file (which have the file extension ".md") corresponds to a module, the top-level organizational entity in the language. You can have any number of modules in arbitrary hierarchies.

A module is actually a big function. Everything after the module declaration is treated as the body of the function. This "module function" is run when the module is first imported in order to declare all the variables in it.

Normally, when you're writing scripts either as standalone programs or to be embedded into your application, you split them up into modules which are saved to disk. But for quick tests, you can run MDCL in interactive mode, where each line you type in is immediately executed, giving you the opportunity to try out some code and see what it does without having to create a file.

Interactive Mode

To run MDCL in interactive mode, just run it without parameters, or run it with the -i parameter.

$ mdcl
MiniD Command-Line interpreter 2.0 beta
Use the "exit()" function to end.
>>>

It prints the version and a message telling you that the exit function ends. Then you get a ">>>" prompt. This means that it's ready to accept input.

>>> writeln("hello!")
hello!
>>>

Here we've just executed a single line of code, and you see that the results are seen immediately.

>>> 4 + 5
 => 9
>>>

If you enter some code that can be evaluated as an expression, MDCL will run it and give the result (or results, if there are more than one). In that case, the results will be printed after a "=>" symbol.

>>> function square(num) =
...     num * num
>>>

Here we're defining a function -- square -- but you'll notice that after we hit enter after the first line, we got a different prompt, "...". This means "go on, you need to type more to finish the statement." So as soon as everything you've typed in can be evaluated, it is. No error means the function was successfully defined. You can then use it:

>>> square(10)
 => 100
>>>

And again, it's evaluated as an expression and the result is printed.

If you do something wrong, you'll get an error:

>>> function foo()
... {
...     local x
...     local x
... }
Error: <no location available>: stdin(4:8): Local 'x' conflicts with previous definition at stdin(3:8)

>>>

This is a compile-time error. You can also get runtime errors:

>>> square("foo")
Error: square(1): Cannot perform the arithmetic operation 'opMul' on a 'string' and a 'string'

>>>

Loading modules into MDCL and the main function

Sometimes you'd like to get some functionality out of a module when using MDCL in interactive mode. This is easy: just import it. Say that you had a module "utils" that had a function "foo" in it. Here's how you'd access that function:

>>> import utils
>>> utils.foo()
This is utils.foo speaking!
>>>

If you've modified utils in an editor and would like to reload it in an already-running MDCL session, you can use the modules.reload function:

>>> modules.reload("utils")
 => namespace utils {
foo = script function foo(5)
}
>>> utils.foo()
This is an updated version of utils.foo!
>>>

Notice when you use modules.reload, it returns the namespace of the module that was reloaded; that's what you're seeing there after the "=>".

One last thing to discuss is the main function. If a module file declares a global function named main, MDCL will run that function after importing and initializing a module. For example:

module test

writeln("before main")

function main()
{
    writeln("This is main!")
}

writeln("after main")

When you run this in MDCL, you'll get the following output:

$ mdcl test
before main
after main
This is main!
$

Notice that "after main" shows up before "This is main!", since main is called after the entire module has been initialized.

One other thing to mention about main is that it can take arguments. When you run that module in MDCL, you can pass arguments to main on the command line. For example, here's a script that prints out all its command-line arguments:

module test

function main(vararg)
{
    writefln("I got {} arguments.", #vararg)

    for(i: 0 .. #vararg)
        writefln("Arg {} = {}", i, vararg[i])
}

And when run:

$ mdcl test foo bar baz
I got 3 arguments.
Arg 0 = foo
Arg 1 = bar
Arg 2 = baz
$

Global versus Local variables

When using interactive mode in MDCL, global and local variables are slightly different than in "normal" MiniD code. The way MDCL works is that it treats every line (or group of lines, if the continuation prompt was used) something like the body of its own function. Because of this, local variables that you declare will only be usable on that line:

>>> local x = 5
>>> x
Error: stdin(1): Attempting to get nonexistent global 'x'

>>> local x = 5; writeln(x)
5
>>>

So, most things that you'll be using in MDCL will be global. When you declare functions, classes, or namespaces, they default to global; that's why the 'square' example worked before. And if you need a global variable, you'll have to explicitly declare it first:

>>> global x = 5
>>> x
5
>>> x++
>>> x
6
>>>

That's it

So, with some very simple examples and a bit of experience using MDCL, we can move on to the language proper. To Types!