Hello, world!

In the fine tradition of programming, we are going to display a friendly, optimistic greeting message. This message is written to the standard output stream, so if you are running Avail from the workbench, then the greeting will be written into the transcript.

If you have installed Avail on your system, then you can find a local copy of this file in your installation directory.

On Windows, the default installation directory is C:\Program Files\Avail; assuming that you installed the product to its default location, then you can find Hello World at C:\Program Files\Avail\src\examples\Tutorial.avail\Hello World.avail.

On Mac OS X, Linux, and Unix, the default installation directory is /usr/local/avail; assuming that you installed the product to its default location, then you can find Hello World at /usr/local/avail/src/examples/Tutorial.avail/Hello World.avail.

If you wish to edit these files, then you may wish to copy them into your home directory first; the default installation directories are system locations, so you will need to escalate your privileges in order to make modifications. For this reason, it is more convenient to work on local copies installed under your own module root. The README file included with the product contains information on setting up the AVAIL_ROOTS environment variable so that you can work on your own projects. You can also find this information here.

At the time of writing, Avail does not have an integrated development environment. In order to write or edit Avail modules, you are encouraged to obtain a programmer's editor with good support for Unicode composition and code templates.

An Avail program is described by a collection of source modules. A source module is just a plain-text file that encodes some part of an Avail program. Over the course of many tutorials, you will glean what exactly goes into a source module. For now, let's concentrate on the two major parts of every source module: the module header and the module body.

Let's start by looking at the header.

The purpose of the header is to describe the module in very broad strokes. To that effect, it includes metadata that says what the module is named, upon which modules it depends, what syntax it introduces, and so forth. Let's break this header down.

Line 33. Every module header (and thus source module) begins with the Module keyword and its name. In this case, the module is named Hello World. This "string" is arbitrary and may include any Unicode character, but must match the name of the file (sans the .avail extension). If the module name recorded here does not match the file name, then the compiler issues an error message. This is an important crosscheck that you are working on the right module!

Line 34. Remember how I said that an Avail program is described by a collection of source modules? Hello World.avail is not our entire program. It is merely the tip of an enormous iceberg. That iceberg is the Avail standard library, which is helpfully called Avail. (When Avail appears in this style, I will specifically mean the Avail module, not the Avail programming language.) The Uses keyword introduces the list of modules that our module needs to import in order to gain access to features that it wants to use. In this case, the standard library contains everything that we need to deliver a boisterous greeting to planet Earth, so it is the only module that we need to import.

(It is worth mentioning that the Avail standard library has a deeper obligation than the standard libraries of other programming languages. Without the Avail standard library, there is literally no syntax other than the rigid syntax of module headers. If you didn't Use "Avail", then you wouldn't be able to declare types, perform arithmetic, use control structures, etc. Some of these restrictions might be okay if you were working with a domain-specific language, but not so for general purpose programming.)

Line 35. Most programming languages require that each complete program implement a privileged main operation that specifies where execution should begin. While this uniformity is simple, it is also simpleminded. It is often the case that a corpus of code could reasonably have many viable entry points, each of which serves as the starting place for some useful application. The keyword Entries precedes a list of operations that should be considered viable outermost operations that can be invoked from outside the program. Our module defines a single entry point, "Greet".

Line 36. The keyword Body marks the end of the module header, and consequently the beginning of the module body. So let's turn our attention to the module body now.

Line 38 defines an operation named "Greet". In Avail, a named operation is called a method. Much will be said about methods at a later time, but right now what's important is that this method's name matches the name given after the keyword Entries on line 35. If the compiler doesn't find a method named "Greet" while parsing the source module, then it will issue an error message to the effect that a declared entry point doesn't exist.

The standard library exports a method named "Method_is_" — pronounced method blank is blank — whose purpose is to define new methods. The blanks, formally called underscores, indicate argument positions in the grammar specified by the method name. "Method_is_" accepts two arguments. The first is a string that represents the name of the new method. The second is a function that supplies code to implement the method. The number of arguments permitted by the function — its arity — must agree with the number of argument positions present in the method name. "Greet" has no blanks, so the associated function must not accept any arguments.

A place in the source code where a method is used is termed a call site. At the call site of "Method_is_" on line 38, the actual arguments are "Greet" and [Print: "Hello, world!\n";]. So the new method will be called "Greet", which is what we expect.

But what will the new method do? You've probably already figured this out, even if you haven't worked out the details: the new "Greet" method will print "Hello, world!\n". The square brackets — [(U+005B) and ](U+005D) — delimit a function. The contents of the square brackets are the function body, i.e., the code that the function executes when it is applied (or called or invoked). In this case, the code comprises a single statement: Print: "Hello, world!\n";. Every statement ends with a semicolon;(U+003B), and must produce a side effect. A side effect is an observable consequence, like defining a new method or printing something.

The standard library exports a method named "Print:_" — pronounced print blank — which accepts a string that should be printed immediately to the standard output stream. At our call site, this argument is "Hello, world!\n". Harking back to a tradition of many other programming languages, the escape sequence\n represents a line feed.

And that's it! Whew! That was a whole lot more explanation than code, but we covered a lot of basic ground together.