Getting Started
What is Ghost?
Ghost is a small scripting language that supports both functional and object-oriented programming. It is designed to be easy to learn, and easy to use.
Installing Ghost
Homebrew
On a Mac, Homebrew is the shortest way in. Ghost lives in the project's own tap, alongside Lumen and anything else the project ships:
brew tap ghost-language/tap
brew install --cask ghost-language/tap/ghost
Homebrew asks you to trust a tap outside its own before it will load anything from it. Trusting this one covers every cask in it, now and later:
brew trust --tap ghost-language/tap
Upgrading later is brew upgrade --cask ghost.
Ghost is a cask rather than a formula because it ships pre-built binaries rather than building from source, which is what Homebrew asks a cask to be used for. That also makes it macOS-only — on Linux and Windows, take a build from the download page.
Go Install
If you have Go installed, you may use go install:
go install ghostlang.org/x/ghost
Direct Download
Builds for macOS, Linux, and Windows are on the download page, which lists everything attached to the latest release and picks out your platform. They come from Ghost's GitHub releases page, which you can also browse directly.
A downloaded archive is quarantined by macOS and refused on first run, since the binaries are not notarised. Clear it with xattr -dr com.apple.quarantine ghost, or install the cask above, which does it for you.
Building Ghost
If you're on a Unix or Mac machine, you can easily download the source code and build directly:
git clone https://github.com/ghost-language/ghost
cd ghost
make
This downloads and builds the latest version of Ghost found on GitHub. You will be put inside a fresh instance of ghost if everything was successful.
Running Ghost
Interactive Mode
If you just run ghost without any arguments, it starts the interpreter in interactive mode (aka, REPL mode, read-eval-print loop). You can type in a line of code, and immediately execute it. While in this mode, your state is saved until you exit the program. Meaning if you define a variable, you may reference the variable later on.
$ ghost
Ghost (1.0.0-beta.3)
Press Ctrl + C to exit
>> console.log("Hello, world!")
Hello, world!
Ctrl+C aborts the line you are typing; Ctrl+D ends the session. A line that fails is reported in full and the session carries on.
Running a File
Ghost source files use the .gs extension. Pass one to ghost and it is executed, then control returns to your terminal.
ghost example.gs
Anything after the filename is passed through to your script, where os.args() can read it.
Flags
| Flag | Description |
|---|---|
-h | Show help. |
-v | Show the version and exit. |
-t | Report how long the program took to run. |
-i | Run the file, then stay in the REPL with the script's variables intact. |
A file that fails exits with status 1, so a script's success can be tested from a shell or a build.
-i is the one worth knowing about. It runs a file and then hands you the prompt with that script's environment still loaded, so everything it defined is there to poke at — including bindings made before a failure partway through:
ghost -i example.gs
It composes with -t (the timing prints before the prompt appears), and does nothing on its own without a file.
Hello, World
Ready to give Ghost a spin?
console.log("Hello, world!")
console.log() is how a Ghost program writes a line of output.
Importing what you use
Ghost's standard library is import-only. Only two names — console and type — are available without an import; everything else is asked for by name:
import "ghost:math"
console.log(math.sqrt(16)) // >> 4
Individual names can be pulled out instead of the whole module:
import { sqrt } from "ghost:math"
console.log(sqrt(16)) // >> 4
Using a module you haven't imported is an error that names the exact import to add, so this is not something you have to memorise. See Modules.
Three rules worth knowing early
Three of Ghost's rules are deliberate, load-bearing, and easiest to learn before you trip over them:
Types are never converted for you. "count: " + 1 is a type error, not "count: 1". Use a template literal — `count: ${1}` — to build a string out of mixed types. For the same reason, comparing values of different types with == is an error rather than false.
0 and [] are truthy. Only null, false, and the empty string are falsy — see Truthiness.
and and or do not short-circuit. Both sides are evaluated before the operator is applied, so a test on the left cannot guard the expression on the right.
Once you have Ghost setup and installed, you're ready to jump into learning the language.
Building Games
Ghost also has a 2D game engine, Lumen, which gives it a game loop, a renderer, input, audio, and file access — enough that a whole game can be written in Ghost and nothing else.