XTCLANG GUIDES
How to write your first ‘’Hello World’’ and get started with the Ecstasy Language.
xtclang
xdk
install
hello world
Authored by: Abby Sassel, Cameron Purdy
Last edited: @January 11, 2024
About this guide
Learn how to install the Ecstasy language development kit (XDK) and to write and run a simple ‘Hello World’ example in the Ecstasy language.
Topics:
- Install the Ecstasy language development kit (XDK).
- Write, and run a simple "Hello World" example.
- Understand the benefits of Ecstasy language compared to others in the C family.
Target Audience
If you would like to learn how to write and run a simple “Hello World” example in the Ecstasy Language, this guide is for you!
It is helpful to have an understanding of Ecstasy’s syntax, structure and execution model prior to using this guide. For a primer, please refer to earlier guides here.
Installing Ecstasy
Go to https://github.com/xtclang/xvm#installation and follow the appropriate steps for your system.
To verify the installation, run the xec
and xcc
commands in your terminal with no arguments. Both should display documentation and options for the respective command.
Our first Ecstasy application
Let's write our first Ecstasy application that prints some text to the console.
In a new directory, create a HelloWorld.x
file, with the contents:
module HelloWorld {
@Inject Console console;
void run() {
console.print("Hello World!");
}
}
Navigate to the project directory in the terminal, and compile the module using the following command:
xcc HelloWorld
The xcc
command will compile the HelloWorld.x
source file to the HelloWorld.xtc
compiled module file in the same directory.
To run the resulting HelloWorld.xtc
file, use this command:
xec HelloWorld
Which should print out:
Hello World!
Executing the xcc
or xec
commands with the full filenames is also valid:
-
xcc HelloWorld.x
, including the.x
source file extension, will compile it. -
xec HelloWorld.xtc
, including the.xtc
compiled module file extension, will run it.
And the xec
command will automatically compile the source file if the compiled module is missing or out-of-date.
Code walkthrough
Congratulations on your first Ecstasy program! Let's review what's happening in the code:
Modules
module HelloWorld {
// module definition
}
Every module in the Ecstasy language must start with a module declaration. The convention is that the module name is the same as the file name; in this example, HelloWorld.x
contains module HelloWorld
.
Injection
@Inject Console console;
@Inject Console console
declares a property on the module. The property's name is console
, its type is Console
, and the @Inject
annotation indicates that the property value is injected by the parent container of the container in which this code is loaded.
In other words, the @Inject
annotation indicates: "This property will magically have a value at runtime, and that value will be a Console
object".
Methods
void run() {
// method definition
}
void run()
is a method on the HelloWorld
class. If you're familiar with C, it may look like a function definition, but here it’s an instance method on the module itself. By convention, this method signature is the default entry point on a module when the module is executed from the command line.
console.print("Hello World!");
Finally, we get to that one remaining line of code in the module that calls console.print
, which is fairly self-explanatory: It prints out the String "Hello World!", using the Console
capability that was injected into the console
property.
Benefits of the Ecstasy language
Boilerplate-free Module
interface
Using the module
keyword in Ecstasy is conceptually similar to writing something like this in a language such as Java, C# or C++:
// `HelloWorld` is a class because, in Ecstasy, modules are classes
static class HelloWorld implements immutable Module {
// every module contains the "ecstasy" package
package ecstasy import ecstasy.xtclang.org;
// paste in a lot of code here that implements the Module interface
// ...
// and here are the few lines of code for doing "Hello World!"
@Inject Console console;
void run() {
console.print("Hello World!");
}
}
Instead of writing all of that (including the code implied by the "..."), we can use the keyword module
and let the compiler verify all of the rules around what a module
can and cannot do.
Then, the linker automatically provides an implementation of the Module
interface for us. In other words, just by using the module
keyword, we get an entire Module
implementation, but that implementation is not generated at compile-time and stuffed into the .xtc
compiled module file.
This is a fairly typical approach in Ecstasy: You shouldn't have to hard-code and/or cut & paste lines of code, and the compiler shouldn't be doing that work for you, either. So if you compile a module and look inside its structure, it won't contain any code for the Module
interface. There are lots of reasons why -- from security, to versioning, to evolution of the language and runtime -- but regardless, this is the approach that we chose for the language.
Secure container model
Compared to other languages in the C family, Ecstasy's container model is secure by design thanks to its more defensive approach to injection.
Consider the axiom: "No native code can exist inside of an Ecstasy container". If it were impossible to inject a console into a container, then it would be impossible to print "Hello World!"
, or anything else, to the screen. Furthermore, it would not be possible to create a socket, read or write a file, access a database, or anything else that would require talking to the operating system or other native code.
In Ecstasy, any software or hardware capability must be injected in order to access its functionality within a container.
In an equivalent HelloWorld.c
, the C program has access to:
- The C runtime library;
- Whatever other libraries the program is linked to;
- Whatever other libraries (
.so
or.dll
) the program can load and link to dynamically; - Everything on the hard drive and any other OS storage that isn't explicitly protected from the user who started the process;
- All of the local hardware that isn't explicitly protected from the user who started the process;
- Its own memory, including its own running code, which it may be able to alter on the fly unless specific protections are explicitly put in place to prevent that; and
- All of the computer's memory that isn't explicitly protected from the user who started the process.
While the Ecstasy HelloWorld.x
module has access to:
- A
Console
.
And that's it.
EXPLORE & LEARN
Ready to learn more?
Check out our latest guides, blogs and tutorials!