# Introduction

![](https://github.com/luna/luna-studio/raw/master/resources/logo.ico)

## The Luna Book

Welcome to the Luna book. Although it is far from being a proper book, the name refers to what we want it to evolve into – an intuitive, easy to follow, yet complete Luna introduction. We strongly believe that tutorials are easier to read and understand than formal documents, therefore the style used is a fusion of both, often relying on examples and intuitive explanations.

This book is aimed at people who work with data processing on a daily basis. It includes both software developers and domain experts, like data scientists, architects or even procedural graphic designers. Even if you have a significant programming experience and you are a functional programming guru, you should find lots of interesting information here.

Writing a good manual is hard. Anybody who has ever tried, knows how insanely time consuming and exhausting it is to create a clear, usable and concise document. If you feel that it could be improved in any way, don't hesitate to [edit it](https://github.com/luna/luna-book) or [talk with us about your suggestions](https://discuss.luna-lang.org).

### Quick start!

We strongly encourage you to [download Luna Studio](http://luna-lang.org) and play with interactive tutorials and demo scenes before reading the book. Gaining feelings of how Luna works is as important as gaining technical knowledge.

### Join us!

Your feedback is very important to us. Join the Luna community, ask questions and share your ideas. It is also the ultimate way to dispel any doubts while reading the book:

* [Chat](http://chat.luna-lang.org) – use it to quickly discuss ideas and get help on the fly while using Luna.
* [Mail](mailto:contact@luna-lang.org) – write to us if you want to say "hi!", or you want to collaborate with us. Please do not use mail to report problems or get help with Luna usage – using chat is always a better idea.
* [GUI bugtracker](https://github.com/luna/luna-studio/issues) and [Compiler bugtracker](https://github.com/luna/luna/issues) – if you are sure you are facing a bug, please report it to us. Be as precise as possible. Screenshots and logs are always more than welcome! Please do not use the bug tracker to express improvement ideas – use chat instead. Chat is a much better place to discuss them before formulating an official task for developers.


# Preface

![](https://github.com/luna/luna-studio/raw/master/resources/logo.ico)

## The Luna Book

Welcome to the Luna book. Although it is far from being a proper book, the name refers to what we want it to evolve into – an intuitive, easy to follow, yet complete Luna introduction. We strongly believe that tutorials are easier to read and understand than formal documents, therefore the style used is a fusion of both, often relying on examples and intuitive explanations.

This book is aimed at people who work with data processing on a daily basis. It includes both software developers and domain experts, like data scientists, architects or even procedural graphic designers. Even if you have a significant programming experience and you are a functional programming guru, you should find lots of interesting information here.

Writing a good manual is hard. Anybody who has ever tried, knows how insanely time consuming and exhausting it is to create a clear, usable and concise document. If you feel that it could be improved in any way, don't hesitate to [edit it](https://github.com/luna/luna-book) or [talk with us about your suggestions](https://discuss.luna-lang.org).

### Quick start!

We strongly encourage you to [download Luna Studio](http://luna-lang.org) and play with interactive tutorials and demo scenes before reading the book. Gaining feelings of how Luna works is as important as gaining technical knowledge.

### Join us!

Your feedback is very important to us. Join the Luna community, ask questions and share your ideas. It is also the ultimate way to dispel any doubts while reading the book:

* [Chat](http://chat.luna-lang.org) – use it to quickly discuss ideas and get help on the fly while using Luna.
* [Mail](mailto:contact@luna-lang.org) – write to us if you want to say "hi!", or you want to collaborate with us. Please do not use mail to report problems or get help with Luna usage – using chat is always a better idea.
* [GUI bugtracker](https://github.com/luna/luna-studio/issues) and [Compiler bugtracker](https://github.com/luna/luna/issues) – if you are sure you are facing a bug, please report it to us. Be as precise as possible. Screenshots and logs are always more than welcome! Please do not use the bug tracker to express improvement ideas – use chat instead. Chat is a much better place to discuss them before formulating an official task for developers.


# Starting Out

Luna is available as a stand-alone application for Mac OS, Linux and Windows, named Luna Studio. Its graphical interface is completely based on web technologies, so it is possible to run them in a web browser instead. However, Luna Studio desktop distribution was tightly integrated with [GitHub's Atom](https://atom.io) in order to provide decent code editing capabilities. Currently only the desktop distribution is supported.

## Luna Manager

The Luna Manager is a tool for managing your Luna environment. It allows installing and uninstalling different Luna versions side by side, switching between them, managing the development environment, building Luna packages and much more. It is bundled with a simple graphical interface for everyday use, like installing or updating Luna.

For your convenience we distribute it as a binary, so you can download it and literally "double click" to start the installation process. You can download it from our [website](http://luna-lang.org) or build it from [source](https://github.com/luna/luna-manager).

![](/files/-LdNvxUUHnhI9VFh0NuT)

After the successful installation you should be able to execute Luna Studio using your system application manager (Mac OS Spotlight, or Windows Start menu) or run the `luna-studio` binary manually from the installation path (`$HOME/.luna/bin`).


# What you need to dive in

Luna is available as a stand-alone application for Mac OS, Linux and Windows, named Luna Studio. Its graphical interface is completely based on web technologies, so it is possible to run them in a web browser instead. However, Luna Studio desktop distribution was tightly integrated with [GitHub's Atom](https://atom.io) in order to provide decent code editing capabilities. Currently only the desktop distribution is supported.

## Luna Manager

The Luna Manager is a tool for managing your Luna environment. It allows installing and uninstalling different Luna versions side by side, switching between them, managing the development environment, building Luna packages and much more. It is bundled with a simple graphical interface for everyday use, like installing or updating Luna.

For your convenience we distribute it as a binary, so you can download it and literally "double click" to start the installation process. You can download it from our [website](http://luna-lang.org) or build it from [source](https://github.com/luna/luna-manager).

![](/files/-LdNvxUUHnhI9VFh0NuT)

After the successful installation you should be able to execute Luna Studio using your system application manager (Mac OS Spotlight, or Windows Start menu) or run the `luna-studio` binary manually from the installation path (`$HOME/.luna/bin`).


# Learning the interface

We are ready to get started! If you're the kind of person who just skips introductions, you might want to read it anyway because it explains what you need to follow this chapter.

## Dashboard

![](/files/-LdNvwxtVP8d96kW3wnu)

Alright, you've got Luna Studio installed and running on your computer. After launch you will be greeted with the Dashboard. Think about it like about a mix of a "hello screen" and a place gathering all common quick start actions. You can always access the dashboard simply by pressing the Luna logo on the left toolbar.

Dashboard allows you to:

* access the community channels (chat);
* load one of example projects or tutorials;
* create new local project;&#x20;
* open your recent projects;
* load one of community projects;
* create a new community project.&#x20;

## Workspace

![](/files/-LdNvwxvCUj5zznxi4CW)

Luna is like a toolbox. The Workspace is a way to arrange the tools for your convenience. The Workspace is divided into panels containing tabs. Each panel is a separate tool from the toolbox. The most important tools are described below.

### Luna toolbar

This pane contains the most common actions concerning Luna Studio, like:

* 1 accessing the dashboard;
* 2 creating new modules;
* 3 searching the modules in the current project.

### Luna Visual Editor

Luna Visual Editor 4 delivers a whiteboard-like interface for editing data flow graphs. Moreover, it seamlessly integrates other tools from the toolbox. For example, the Visual Editor is able to display interactive results visualizations next to nodes, giving you instant feedback right where you are processing the data.

### Code Editor

Code Editor 5 is a powerful text editor. It allows you to edit the textual Luna representation and source code of other languages. It is integrated with the Visual Editor – whenever you modify the code, the data flow graph updates. It works the other way around too – every graph modification updates the code.

### Project view

Project View 6 is a list of modules in current Luna project.

### Status bar

Status bar has two important properties:

* Controlling the graph evaluation engine 7. By default Luna tries to evaluate every node as soon as possible. There are sometimes situations, however, when you want to disable this behavior and refresh the scene on demand. The pause button allows stopping and resuming the interactive graph evaluation. The refresh button tells Luna to re-compute every value from scratch.
* Current status information 8 displays information about what is currently computed and guides you when using tools. Currently, however, the information is very limited.


# Explorer

The Luna Explorer is a sophisticated fuzzy search engine integrated with an expression editor. It allows you to search for components, create them and browse their documentation. The Explorer is context-aware, which means that it tries to predict your intention and adjust the search results accordingly.

### Accessing the Luna Explorer

In order to access the Explorer place your mouse over the data flow editor and press the tab key. You can close the Explorer by pressing either the escape key or the tab key again, however the latter is allowed only if no input was provided so far.

The Explorer consists of three panels – expression editor, suggestions list and documentation view. The expression editor is always active and listens for your input, so you can start typing as soon as the explorer appears on your screen.

The circle below the Explorer is called a node. It is a preview of the component you are going to create. You will learn more about nodes in the following chapter.

![](/files/-LdNvwt8ckbn8LOLdcTw)

## Using the Explorer

The Explorer will search Luna libraries for components that match your query. The provided query does not need to be precise – it is usually sufficient to provide only a part or several parts of the name you are looking for.

The Explorer will provide suggestions on the fly while you are typing. The best match will be displayed on the bottom of the list and will be selected by default. You can move the selection by using the up up arrow and down arrow keys. To confirm your choice and create the selected component, press the enter key. To accept the hint and continue typing after that, prass tab.

However, there are sometimes situations when you want to create components that are not available on the suggestion list. A good example is when you want to refer to a component that does not yet exist and you are going to create it soon. Another possibility is that Luna didn't get enough information to provide you with the complete components list, which could happen when you are working on polymorphic data. You will learn more about polymorphism later, for now just remember, that you can use the down arrow key to move the selection from the suggestions list onto the expression editor and press the enter key to create component named exactly what you have typed.


# Syntax

Luna is a data processing language and like every language it provides a syntax. However, in contrast to majority of languages Luna has more than one syntax representation – visual and textual. In order to use Luna efficiently you should learn both of them – the visual representation uses the textual one to define component's expressions. This chapter describes the former – visual data flow graph.

While designing the visual representation we've put an enormous emphasis on productivity and ergonomics. Every element and every action was carefully designed to allow you express your thoughts easily, understand the results rapidly and clearly see all the data transformations. You have to learn how to "speak this language", however it's worth doing, as even hardcore coders much prefer using Luna for building high-level data processing workflows than writing code. We are on a mission to constantly improve how you work with Luna, so your feedback and suggestions are very important to us. If you have any ideas related to how the visual representation works, [tell us about it](https://discuss.luna-lang.org)!

## Navigation

Luna Visual Editor is a canvas allowing you for fluid navigation so you can always focus on what is important at the moment. You can:

* **pan** the view using two fingers drag gesture or the middle mouse button;
* **zoom** the view using pinch gesture or the right mouse button;
* **select nodes** by clicking them or using left mouse button to draw selection area starting from the background;
* **dive into nodes** by double clicking them;
* **view parent nodes** by double clicking on the background or using the breadcrumb controls on top of the Visual Editor.

## Nodes

Nodes are the most primitive entities in the visual representation, which, together with other nodes, form the data flow graph.

### Value nodes

Value nodes are the most common node types. They represent any valid Luna value, including data processing functions. From the high perspective, a value node can generate data, modify it or pass to it some external service like a web service or a database. Value nodes consist of several visual elements:

#### Node expression 1

The node expression is any valid Luna code, in particular a function name. For example, a node adding two objects is named `+`.

#### Node name 2

The node name is a name you give to it to describe its role in the graph. Any other node referencing this one uses this name.

#### Input ports 3 and output ports 4

Ports are the node's communication gates. Data flows into input ports on the left side, is processed according to the node expression and the result flows out from the output ports on the right side. Port colors indicate what type of data flows through them. You will learn more about data types in the [Types 101](/luna-user-guide/types) chapter.

#### Self port 5

Luna is an object oriented language. It means that every piece of data that flows between nodes is not just information, it can also respond to your commands. You can for example tell a car to stop, a dog to bark, a number to increase or a list to sort its items. If data is connected to self port, then the node's expression tells it what to do. A rule of thumb is that if you want to process a piece of data, connect it to the self port. You will learn in detail about it in the [Making our own type](broken://pages/-LdNvwJUokiHNYUzfFcW) chapter.

![](/files/-LdNvwe-caotpAbg_bCh)

### Reference nodes

Sometimes you don't want to process data, you want to inspect and deconstruct it instead. Nodes that do not affect the data, but allow you to look into it are called reference nodes. Their usage is covered in detail in the [Pattern matching](/luna-user-guide/classes/constructors) chapter. They contain a special target port 1 which accepts data that you want to inspect.

![](/files/-LdNvwe1ZkjUeaPVq3FF)

## Creating nodes

Nodes are always created with the help of [Luna Explorer](/luna-user-guide/explorer), however, there are several options to launch it and guide towards our intentions:

* press the tab key to search across all available components;
* select a node and then press the tab key to guide the Explorer to look for functions capable of processing its results.

## Connecting and disconnecting nodes

To establish a new flow of data, you have to create a connection between an output port and an input port (including self port). There is no a single best way to do it, it depends on your preferences, graph complexity, zoom level and much more. Luna provides you with several alternative ways to connect and disconnect nodes, so you can choose the one which suits you most in a given situation.

#### Connecting nodes

* **By drag**\
  Press an output port, drag and drop it over desired input or self port. Alternatively you can press the input port, drag and drop it over desired output port. You cannot, however, start the connection by pressing the self port – pressing the node body selects the whole node instead. Drop over the background to cancel. ![](/files/-LdNvwe3roRsmX6-2yE8)
* **By click**\
  Click (press and release) an output port, the connection will follow your mouse until you click again. Click on the desired input port or self port to create new connection or click on the background to cancel. You can alternatively click first on the input port and then on the output port. Click on the background to cancel. ![](/files/-LdNvwe5Kv5iDHjgiHXB)
* **Using connection pen** Press and drag on the stage while holding the ctrl key to use the connection pen in connecting mode. A green stroke will follow your pointer and will connect all nodes on its way. Currently, if a connection pen connects two nodes, the results from the first one will be connected to the self port of the second node. This behavior will be enhanced soon and Luna will try to create connection between ports with matching types. ![](/files/-LdNvwe7reHe3SFxr6XL)
* **On creation** Select a node before opening Explorer to guide it to search for functions associated with the node's results and automatically connect them to the self port of a newely created node. ![](/files/-LdNvwe9aR66ySqLk2om)

#### Disconnecting and reconnecting nodes

* **By drag** Press one of connection's ends to disconnect it and enter "connecting by drag" mode. You can drag and drop it over other port to reconnect or drop on the background to remove the connection. ![](/files/-LdNvweBik32GhJe6-uy)
* **By click** Click one of connection's ends to disconnect it and enter "connecting by click" mode. You can click on other port to reconnect or click on the background to remove the connection. ![](/files/-LdNvweDdCYF9Jf4fCym)
* **By connecting to an occupied port** Create a new connection using any above method to an input (or self) port which is already connected to replace the old connection with the new one.
* **Using connection pen** Press and drag on the stage while holding both ctrl and shift keys to draw a stroke, which will disconnect every connection it crosses. ![](/files/-LdNvweFlXJczZ86jIk0)

## Node's details view

Luna allows you to display a node in either of two views – a compact, as seen above, or in a detailed one. The detailed view takes more screen space, however, it also provides widgets to interactively control the node's input values. To switch between the views, select the desired nodes and press the enter.

#### Parameters widgets

Every input to a node is called a parameter. A parameter can either be delivered by a connection or set manually using widgets.

![](/files/-LdNvweH05gY7R4YXEzQ)

## Results visualisations

Every node is able to visualize its results. To open the visualization press the eye icon above the node. If you press and hold the space bar, the visualization will enter full-screen mode. You can also press space + ctrl to lock the visualization in full-screen mode (press esc to exit this view). You can choose which visualization to use from the drop-down visualizations menu available to the left of visualization.

> **\[info] Changes ahead!**
>
> Currently, result visualisations are only available inside no–argument nodes. If there are any arguments on the left–hand–side bar of your workspace, this means that the results would depend on those arguments and we are not computing them. This will be changed soon, so you will be able to inspect the results with given input arguments. You can learn more more about functions and arguments in the [Functions chapter](/luna-user-guide/calling_functions/defining_functions).

Many visualizations provide interactive controls. In order to access them you have to focus the visualization by clicking on it. When you focus a visualization, the graph gets dimmed and you cannot control it until you exit the focus by pressing the escape key or pressing on the dimmed background.


# Visual representation

Luna is a data processing language and like every language it provides a syntax. However, in contrast to majority of languages Luna has more than one syntax representation – visual and textual. In order to use Luna efficiently you should learn both of them – the visual representation uses the textual one to define component's expressions. This chapter describes the former – visual data flow graph.

While designing the visual representation we've put an enormous emphasis on productivity and ergonomics. Every element and every action was carefully designed to allow you express your thoughts easily, understand the results rapidly and clearly see all the data transformations. You have to learn how to "speak this language", however it's worth doing, as even hardcore coders much prefer using Luna for building high-level data processing workflows than writing code. We are on a mission to constantly improve how you work with Luna, so your feedback and suggestions are very important to us. If you have any ideas related to how the visual representation works, [tell us about it](https://discuss.luna-lang.org)!

## Navigation

Luna Visual Editor is a canvas allowing you for fluid navigation so you can always focus on what is important at the moment. You can:

* **pan** the view using two fingers drag gesture or the middle mouse button;
* **zoom** the view using pinch gesture or the right mouse button;
* **select nodes** by clicking them or using left mouse button to draw selection area starting from the background;
* **dive into nodes** by double clicking them;
* **view parent nodes** by double clicking on the background or using the breadcrumb controls on top of the Visual Editor.

## Nodes

Nodes are the most primitive entities in the visual representation, which, together with other nodes, form the data flow graph.

### Value nodes

Value nodes are the most common node types. They represent any valid Luna value, including data processing functions. From the high perspective, a value node can generate data, modify it or pass to it some external service like a web service or a database. Value nodes consist of several visual elements:

#### Node expression 1

The node expression is any valid Luna code, in particular a function name. For example, a node adding two objects is named `+`.

#### Node name 2

The node name is a name you give to it to describe its role in the graph. Any other node referencing this one uses this name.

#### Input ports 3 and output ports 4

Ports are the node's communication gates. Data flows into input ports on the left side, is processed according to the node expression and the result flows out from the output ports on the right side. Port colors indicate what type of data flows through them. You will learn more about data types in the [Types 101](/luna-user-guide/types) chapter.

#### Self port 5

Luna is an object oriented language. It means that every piece of data that flows between nodes is not just information, it can also respond to your commands. You can for example tell a car to stop, a dog to bark, a number to increase or a list to sort its items. If data is connected to self port, then the node's expression tells it what to do. A rule of thumb is that if you want to process a piece of data, connect it to the self port. You will learn in detail about it in the [Making our own type](/luna-user-guide/classes/classes) chapter.

![](/files/-LdNvwe-caotpAbg_bCh)

### Reference nodes

Sometimes you don't want to process data, you want to inspect and deconstruct it instead. Nodes that do not affect the data, but allow you to look into it are called reference nodes. Their usage is covered in detail in the [Pattern matching](/luna-user-guide/classes/constructors) chapter. They contain a special target port 1 which accepts data that you want to inspect.

![](/files/-LdNvwe1ZkjUeaPVq3FF)

## Creating nodes

Nodes are always created with the help of [Luna Explorer](/luna-user-guide/explorer), however, there are several options to launch it and guide towards our intentions:

* press the tab key to search across all available components;
* select a node and then press the tab key to guide the Explorer to look for functions capable of processing its results.

## Connecting and disconnecting nodes

To establish a new flow of data, you have to create a connection between an output port and an input port (including self port). There is no a single best way to do it, it depends on your preferences, graph complexity, zoom level and much more. Luna provides you with several alternative ways to connect and disconnect nodes, so you can choose the one which suits you most in a given situation.

#### Connecting nodes

* **By drag**\
  Press an output port, drag and drop it over desired input or self port. Alternatively you can press the input port, drag and drop it over desired output port. You cannot, however, start the connection by pressing the self port – pressing the node body selects the whole node instead. Drop over the background to cancel. ![](/files/-LdNvwe5Kv5iDHjgiHXB)
* **By click**\
  Click (press and release) an output port, the connection will follow your mouse until you click again. Click on the desired input port or self port to create new connection or click on the background to cancel. You can alternatively click first on the input port and then on the output port. Click on the background to cancel. ![](/files/-LdNvwe5Kv5iDHjgiHXB)
* **Using connection pen** Press and drag on the stage while holding the ctrl key to use the connection pen in connecting mode. A green stroke will follow your pointer and will connect all nodes on its way. Currently, if a connection pen connects two nodes, the results from the first one will be connected to the self port of the second node. This behavior will be enhanced soon and Luna will try to create connection between ports with matching types. ![](/files/-LdNvwe7reHe3SFxr6XL)
* **On creation** Select a node before opening Explorer to guide it to search for functions associated with the node's results and automatically connect them to the self port of a newely created node. ![](/files/-LdNvwe9aR66ySqLk2om)

#### Disconnecting and reconnecting nodes

* **By drag** Press one of connection's ends to disconnect it and enter "connecting by drag" mode. You can drag and drop it over other port to reconnect or drop on the background to remove the connection. ![](/files/-LdNvweDdCYF9Jf4fCym)
* **By click** Click one of connection's ends to disconnect it and enter "connecting by click" mode. You can click on other port to reconnect or click on the background to remove the connection. ![](/files/-LdNvweDdCYF9Jf4fCym)
* **By connecting to an occupied port** Create a new connection using any above method to an input (or self) port which is already connected to replace the old connection with the new one.
* **Using connection pen** Press and drag on the stage while holding both ctrl and shift keys to draw a stroke, which will disconnect every connection it crosses. ![](/files/-LdNvweFlXJczZ86jIk0)

## Node's details view

Luna allows you to display a node in either of two views – a compact, as seen above, or in a detailed one. The detailed view takes more screen space, however, it also provides widgets to interactively control the node's input values. To switch between the views, select the desired nodes and press the enter.

#### Parameters widgets

Every input to a node is called a parameter. A parameter can either be delivered by a connection or set manually using widgets.

![](/files/-LdNvweH05gY7R4YXEzQ)

## Results visualisations

Every node is able to visualize its results. To open the visualization press the eye icon above the node. If you press and hold the space bar, the visualization will enter full-screen mode. You can also press space + ctrl to lock the visualization in full-screen mode (press esc to exit this view). You can choose which visualization to use from the drop-down visualizations menu available to the left of visualization.

> **\[info] Changes ahead!**
>
> Currently, result visualisations are only available inside no–argument nodes. If there are any arguments on the left–hand–side bar of your workspace, this means that the results would depend on those arguments and we are not computing them. This will be changed soon, so you will be able to inspect the results with given input arguments. You can learn more more about functions and arguments in the [Functions chapter](/luna-user-guide/calling_functions/defining_functions).

Many visualizations provide interactive controls. In order to access them you have to focus the visualization by clicking on it. When you focus a visualization, the graph gets dimmed and you cannot control it until you exit the focus by pressing the escape key or pressing on the dimmed background.


# Textual representation

Luna is a data processing language and like every language it provides a syntax. However, in contrast to majority of languages Luna has more than one syntax representation – visual and textual. This chapter describes the later – the code. In order to use Luna efficiently you should learn both of them – the visual representation uses the textual one to define component's expressions.

Luna was designed to be a highly readable language. While designing its textual representation the main focus was creating a clean, concise and expressive syntax.

## Code layout

Luna code is indentation sensitive, which means that logically nested expressions are also visually nested in code. The layout was designed to maximally increase code readability and layout flexibility. There are three rules describing how it works:

1. Each block can start in current or a new line. The block's indentation level is the same as it's first expression's indentation;
2. Each nested code block should have bigger indentation level than the parent's one.
3. Expressions can span over multiple lines, but all the spanned lines have to be indented more than the expression itself.

Luna does not allow mixing the use of tabs and spaces, only spaces are allowed for making code indentations. Almost every block starts with the colon `:` operator. Here are some examples of different usages of indentation layout. You do not have to understand the code yet, it's important however to feel how the layout works.

```ruby
# inline expression
def sum a b: a + b

# standard function declaration with indented code block
def main:
    v = Vector 1 2 3
    print $ checkVector v
```

The following example is **invalid**:

```ruby
# ERROR: Indentation level does not match the first expression's one
def main: v = Vector 1 2 3
    print $ checkVector v
```

## Scoping

Scopes define when a particular name is accessible in a program. Each code block creates a distinct name scope, inheriting the names from the parent one. All the names of entities defined in a scope cannot escape its boundaries, in particular they cannot be accessed from the parent scope.


# Switching between representations

Luna delivers a mechanism for the two way translation between visual and textual representations. It allows you to switch the representation on demand and even work on both of them at the same time. The implementation details are beyond the scope of this book, however, from the high perspective the translation is a straightforward process.

In the most common case, each Luna node corresponds to a line of code. For example:

![](/files/-LdNvwoUk6TxE1hwxcSU)

```python
a = 1
b = 2
c = a + b
c.succ
```

Let's break this graph down:

1. The two leftmost nodes correspond to the lines `a = 1` and `b = 2`. The variable names `a` and `b` become names of their corresponding nodes, and the numbers `1` and `2` are their definitions. They have no input ports and one output port each.
2. The node in the middle corresponds to the line `c = a + b`. It has the `a` and `b` nodes connected to its inputs. Thanks to this, you can clearly see where does the input data come from.
3. The rightmost node corresponds to the line `c.succ`. The node has no name, as the corresponding line does not define any variables. It has the node `c` connected to its `self` port. This port denotes the target of method call.


# Types 101

## What are types and why do they matter?

Luna can process any kind of data. It can compute a car's velocity, reply to a user's questions via a chat-like interface or process all photos from your last trip to San Francisco.

Some operations, however, only make sense with very specific kinds of data. You can multiply numbers, however it's hard to imagine what the result of a cake multiplication would be. Other operations allow some degree of freedom. Reversing, for example, works with any list with no regard to what its individual elements are. Yet other operations provide more complex constraints. Summing a list will work with any non-empty list containing arithmetic elements only, but we don't really care about the exact structure of these elements. They may be integers, fractions or even matrices; the only requirement is having an addition operation defined.

In this chapter we introduce the type system, a way Luna handles such constraints. You will learn how types are defined, how to check a type of a given value and what happens when the constraints could not be resolved. The philosophy behind the type system is to provide as much safety and useful hints as possible without restricting your expressive powers.

## How do I see types?

The type system in Luna is fundamentally different from any other type system used in programming languages nowadays. It was designed from scratch to be invisible until you need it, yet fully aware of the structure of the data being processed. You will never *need* to manually specify the types in Luna. The type inference engine computes every single type behind the scenes automatically for you. This computation ensures that every operation will be performed safely, without any contradictory properties arising.

Since the types are usually not expressed in code, we need a way to show them to you. You have probably already noticed that the nodes in our visual editor come in different, seemingly random, colors. Those colors are just one of the ways the visual editor communicates types. Each of the ports on the node is assigned a color corresponding to its type. All the connections are also colored; the colors correspond to the type of data "being sent" via this connection.

![](/files/-LdNvxmsNk-pJhK5pdvy)

Colors provide a quick visual cue to tell if two values have the same or different types, but they are not enough. Just imagine referring to them like "the text `"hello world!"` has type `magenta`". That's why the colors serve only as visual aids, but the real types have a text representation. If you hover above a node, the real types are revealed. Each of the node inputs and outputs displays its corresponding type.

![](/files/-LdNvxmu1P7zq1qJiWMu)

In the above image you can see the actual type names and thus understand the behavior of the node:

1. The nodes `number2` and `number3` don't have inputs – they are both constants of type `Real`,
2. The node `sum3` has two `Real` inputs and a `Real` output – it transforms two `Real` numbers into another `Real` number,
3. The node `just2` has a `Real` input and a `Maybe Real` output – it transforms a `Real` number into a `Maybe Real` value.

Oh, and the type of `"hello world!"` is not `magenta`. It's `Text`.

## What happens when I mess up?

Besides providing a better understanding of program behavior, types have an even more important role to play: they make sure everything will work smoothly and safely. They are crucial in preventing many errors that may accidentally arise during development. So what happens when you make a mistake?

Let's try doing something clearly nonsensical: adding a text and a number. This is how Luna reacts:

![](/files/-LdNvxmwmaCb9IjkU-aO)

Luna's typechecker has found out about our mistake. The `+` function works only with arguments of the same type, so it complained that `Real` and `Text` are not the same and we cannot safely proceed.


# Basic data types

In this section will go through the basic data types available in Luna. You'll encounter some of these in every Luna program.

## Literal values

Luna supports three kinds of literals – expressions of special form, denoting primitive types of data. Those types are `Text`, `Real` and `Int`. Creating literal nodes is as simple as opening the Explorer and typing in the desired value. `Int`s are just numbers without a decimal point, `Real`s are those numbers that do contain a decimal point. `Text`s are arbitrary series of characters, delimited by quotes.

![](/files/-LdNvyPiNwpDB-rvTwZm)

Remember that you can always press tab with a node of a specific type selected, to bring up the explorer and get a list of all operations supported by the type, together with their documentation.

![](/files/-LdNvyPko0gGfjfCr4vC)

## Numeric types

The basic numeric types in Luna are `Int`, representing integers of arbitrary size and `Real`, for floating point numbers.

> **\[info] Changes ahead!**
>
> Currently, the type of a numeric literal is decided based on the presence of decimal point. This means, that `1` has the type `Int`, while `1.0` has the type `Real`. In the future releases of Luna, the numeric literals will be polymorphic, allowing to write expressions like `1.7 + 2`.

They support basic arithmetic operators and mathematical functions.

## Text

The basic type for text processing in Luna is, unsurprisingly, `Text`. Luna supports two kinds of text literals: interpreted and uninterpreted. The interpreted texts are wrapped in single quotes. They provide the capabilities to insert escaped character sequences such as `\n` etc. The uninterpreted strings are wrapped in double quotes and do not provide any such facilities. The only character that can be escaped in an uninterpreted text is `\"` itself. It is usually sufficient and more handy to use single–quoted (interpreted) texts by default, unless you need to type in a text containing many special characters.

> **\[info] Changes ahead!**
>
> In the future releases of Luna the interpreted texts will also allow to insert arbitrary expressions, results of which will be then inserted into the resulting text. For example ``'Adding 2 and 2 gives `2 + 2` in result'`` will be evaluated to `'Adding 2 and 2 gives 4 in result'`.

## Booleans

Logical values are represented using the `Bool` class. It has two constructors: `True` and `False`. They support basic logical combinators such as `&&`, `||` or `not`.

The most common function used for conditional branching in Luna is `if_then_else`. It can be used in this form (i.e. `if_then_else condition valueWhenTrue valueWhenFalse`) or, more elegantly, in its *mixfix* form:

```ruby
if condition then valueWhenTrue else valueWhenFalse
```

There is nothing special about this function, all the arguments are standard values and it returns a value just like any other function would:

```ruby
def reportRelationshipToSeven x:
    relation = if x > 7 then "greater than" else "less than or equal to"
    print (x.toText + " is " + relation + " seven")
```

## Lists & Tuples

The most basic container types in Luna are tuples and lists.

Lists are arbitrary–length containers for same-type values. Some examples are `[3, 4, 5]` of type `List Int` or `['first', 'second', 'third']` of type `List Text`. There are also some interesting functions and methods in the standard library, that return lists of desired shape – make sure to go through the available methods using the Explorer. Some examples are:

```ruby
1.upto 5                       # => [1, 2, 3, 4, 5]
3.times "hello"                # => ["hello", "hello", "hello"]
[True, False] . cycle . take 5 # => [True, False, True, False, True]
```

Tuples are like lists, but they can store elements of different types and they have statically defined lengths. Some examples are:

```ruby
(1, "hello", False) :: (Int, Text, Bool)
("hi", 3.0)         :: (Text, Real)
```

> **\[info] Changes ahead!**
>
> In the future versions of Luna, lists and tuples will be merged into one type – a list which fully understands its structure and allows to encode information about its length and different element types on type level. Thus you may expect code like `["Hello", 32, False]` to be valid Luna soon.

## Maybe

Luna, much like other functional languages, does not have a `null` value. That means, if you have a value of type `Int`, there will always be a number, there is no way to have an "invalid" number. If there is a possibility of a value not being there, it needs to be encoded in a type-safe manner. This is where `Maybe` enters the stage. A value of class `Maybe` can either be `Just value` or `None`. You can check which of the possibilities happened using pattern matching. Suppose you have a value `myNumber` of type `Maybe Int`. You can use it like so:

```
reportedValue = case myNumber of
    Just v -> 'Got a number ' + v.toText + '.'
    Nothing -> 'Did not get a number.'
print reportedValue
```

There is also a bunch of useful methods like `getWithDefault`, which are handy to replace the pattern match in most cases. Consult Explorer for more details.


# Functions

Functions are the basic units of reusable logic. A function is a piece of logic that takes any number of arguments, performs some operations and returns a result of these operations. Functions in Luna are also ordinary values, so you can pass them around freely. Most nodes you have used so far are actually functions. In this chapter you'll learn how to use functions and how to define them.

## Calling functions

Calling functions in text is accomplished by passing space–separated arguments. In the visual graph it corresponds to setting the values of respective input ports on a node – either by connecting other values to them or setting the values in the expression or by using port controls such as sliders.

```
a = 1
b = 2
c = add a b
d = add 53 2
```

![](/files/-LdNvwzMO946k5CCf_Dx)

## First class functions

Functions in Luna are first class citizens. It means that you can treat them like any other value. You can assign them to variables, pass as arguments to other functions or even store them in other data structures, like lists or maps. Many classes and libraries in Luna define functions or methods which expect other functions as their arguments. Most common examples are `List` methods `each` and `fold`. The former takes a single argument function and calls it on each element of the list, while the latter takes a two-argument function which is used to combine all the elements:

```
f = x: x + 2
myList = [1, 2, 3]
myList.each f # => [3, 4, 5]
myList.fold 0 add # => 6
```

![](/files/-LdNvwzO7fEjH7fVAcPK)

## Type of functions

Since functions are ordinary values, they need to have a type (all values in Luna are typed, remember?). The type of function taking an argument `A` and returning a `B` is `A -> B`. It's easy to remember when you think about the arrow as representing a transformation from type `A` to type `B`.

Multi–argument functions are typed using more arrows – for example a function taking a `Real`, an `Int` and returning a `Text` would be typed as `Real -> Int -> Text`. The last part of such an arrow chain is the return value, while all the parts before are consecutive arguments.

## Currying

Luna supports currying. This means, that you may provide fewer arguments than the function expects. This fixes some of the function arguments, allowing to pass the rest later on. This is particularly useful when passing functions as arguments. Using currying, we can rewrite the example from previous section as:

```
myList = [1, 2, 3]
myList.each (+ 2)
```

It is also important to understand how currying works when using nodes. Whenever you don't set a port's value, this argument is automatically curried. This is shown by the changing type of the node's output. Note how the output type changes depending on the number of ports connected, showing the different curried variants of a function:

![](/files/-LdNvwzQbKmg_mqaL5pR)

1. The `add1` node does not set any arguments, thus the output type is `Int -> Int -> Int`,
2. The `add2` node has the second argument connected, so the output type is `Int -> Int`. Note the `_` in it's expression. This underscore introduces explicit currying for this argument – `add _ number1` means "set the second argument and leave the first one unapplied",
3. The `add3` node applies the first argument and leaves the second one. There is no need for the `_` in this case, since the applied argument precedes the unapplied. The type is the same as that of `add2`, since both arguments have the same type.
4. The `add4` node is fully applied, so the return type is just `Int`.


# Basics

Functions are the basic units of reusable logic. A function is a piece of logic that takes any number of arguments, performs some operations and returns a result of these operations. Functions in Luna are also ordinary values, so you can pass them around freely. Most nodes you have used so far are actually functions. In this chapter you'll learn how to use functions and how to define them.

## Calling functions

Calling functions in text is accomplished by passing space–separated arguments. In the visual graph it corresponds to setting the values of respective input ports on a node – either by connecting other values to them or setting the values in the expression or by using port controls such as sliders.

```
a = 1
b = 2
c = add a b
d = add 53 2
```

![](/files/-LdNvwzMO946k5CCf_Dx)

## First class functions

Functions in Luna are first class citizens. It means that you can treat them like any other value. You can assign them to variables, pass as arguments to other functions or even store them in other data structures, like lists or maps. Many classes and libraries in Luna define functions or methods which expect other functions as their arguments. Most common examples are `List` methods `each` and `fold`. The former takes a single argument function and calls it on each element of the list, while the latter takes a two-argument function which is used to combine all the elements:

```
f = x: x + 2
myList = [1, 2, 3]
myList.each f # => [3, 4, 5]
myList.fold 0 add # => 6
```

![](/files/-LdNvwzO7fEjH7fVAcPK)

## Type of functions

Since functions are ordinary values, they need to have a type (all values in Luna are typed, remember?). The type of function taking an argument `A` and returning a `B` is `A -> B`. It's easy to remember when you think about the arrow as representing a transformation from type `A` to type `B`.

Multi–argument functions are typed using more arrows – for example a function taking a `Real`, an `Int` and returning a `Text` would be typed as `Real -> Int -> Text`. The last part of such an arrow chain is the return value, while all the parts before are consecutive arguments.

## Currying

Luna supports currying. This means, that you may provide fewer arguments than the function expects. This fixes some of the function arguments, allowing to pass the rest later on. This is particularly useful when passing functions as arguments. Using currying, we can rewrite the example from previous section as:

```
myList = [1, 2, 3]
myList.each (+ 2)
```

It is also important to understand how currying works when using nodes. Whenever you don't set a port's value, this argument is automatically curried. This is shown by the changing type of the node's output. Note how the output type changes depending on the number of ports connected, showing the different curried variants of a function:

![](/files/-LdNvwzQbKmg_mqaL5pR)

1. The `add1` node does not set any arguments, thus the output type is `Int -> Int -> Int`,
2. The `add2` node has the second argument connected, so the output type is `Int -> Int`. Note the `_` in it's expression. This underscore introduces explicit currying for this argument – `add _ number1` means "set the second argument and leave the first one unapplied",
3. The `add3` node applies the first argument and leaves the second one. There is no need for the `_` in this case, since the applied argument precedes the unapplied. The type is the same as that of `add2`, since both arguments have the same type.
4. The `add4` node is fully applied, so the return type is just `Int`.


# Defining functions

## Lambdas

A lambda is a simple, annonymous function. They are defined with the `:` operator. The part before `:` is the lambda argument, while the part after it is the returned value. Thanks to currying it's also possible to define multi-argument lambdas – all you need to do is return another lambda, e.g. `x: y: x + y`.

```
id = x: x
const = x: y: x
myLambda = x: y: z: (x + y) * z
```

Simple lambdas can often be shortened even more by using the `_` idiom, which we have first seen in the section on currying. All occurrences of `_` inside a parenthesized expression are replaced with consecutive lambda arguments. This allows to simplify some constructions like this:

```
_.succ # same as (x: x.succ)
_.toText + _.toText # same as (x: y: x.toText + y.toText)
```

Note that each pair of parentheses creates a new lambda context, so `(_ + 2) + _` is interpreted as `x: (y: y + 2) + x`, not `x: y: (x + 2) + y`.

## Module view

So far we were always concerned about the body of a particular function. However, there is also a view containing all functions defined in the given module. You will need it to build more complex pieces of logic in Luna. To access this view, simply double click on the workspace background or select it on the breadcrumb in the top left corner of visual editor.

In this view, you can see all the functions defined in a file, displayed as nodes like this:

![](/files/-LdNvweJq70rbGaJRXuu)

To enter any of these functions, double click the node. If there is a function called `main`, the visual editor will automatically enter this function when opening the file.

## Function definitions

Defining module-level or complex functions is best accomplished with the `def` keyword. Any functions defined this way on the module toplevel are visible by any modules importing it (and of course throughout the defining module itself). To define a function named `foo` in the visual editor just type in `def foo` in the explorer and press enter. This will create an empty function that you can then enter and complete the logic definition. The arguments are ports on the left hand side bar, and the returned value is connected to the right hand side.

![](/files/-LdNvweLVo8u8g7WpGva)

```
def move shape tx ty:
translation = translationTrans tx ty
transformed = shape.transform translation
transformed
```

There is also a way to create functions out of existing pieces of logic – just select any number of nodes and press f. The nodes will get folded into a function, with any external input connection becoming an argument, and any external output connection being returned from the function. This workflow is very handy when prototyping solutions and playing around with different ways of solving particular problems. For example the following graph:

![](/files/-LdNvweWZeQXH6mbx--7)

after collapsing the selected nodes becomes:

![](/files/-LdNvweYJMYnXdiNCJ06)

and the newly created `func1` function looks like this on the inside:

![](/files/-LdNvwe_Mysj-nwfGq_e)


# Creating custom data types

Objects are the basic blocks for bundling data and behaviors together. Luna's approach combines the approach known from Object Oriented languages with purely functional techniques, such as Algebraic Data Types.

## Introduction

Luna's notion of a class differs from what is known in most languages. If you are familiar with objects from Java or Python, you're in for a surprise.

First of all, Luna objects, besides having multiple fields, can also come in multiple, distinguishable flavors. This is known in functional programming as Algebraic Data Types and basically means that an object can be built using one of many available constructors and each of the constructors defines a different structure.

Using this technique we can say that any `Shape` is either a `Circle` or a `Rectangle`. Given an object of type `Shape` you are always sure it's one of those but you need to use [pattern matching](/luna-user-guide/classes/constructors) to discover which one was it.

However, thanks to methods, you can call some behaviors regardless of the constructor used. This means, given a `Shape` value, you may always use its `area` method, even though you may not know what was the real constructor used.

Another important property of objects in Luna is immutability. You may be used to mutable objects and expressions like `counter.count += 1` in other languages. In Luna every object is immutable – once it's created in a given way, it will never change. If you write `foo = Circle 15.0`, `foo` will always remain a `Circle` with the same radius, no matter how it is used. Any method that may seem to mutate the object, actually returns its changed version. So if you have a list and call its `sort` method, the original list remains unsorted – the sorted list is returned from the method instead and you need to assign this value to another variable if you want to use the sorted version later on.

## Class definition

> **\[info] Changes ahead!**
>
> Currently, there is no way to define classes and methods using the visual editor. All the mechanisms described in these sections are text-only, the support for visual workflow is coming soon.

Classes in Luna are defined with the `class` keyword. It is followed by definitions of constructors and methods. Let's consider this definition of the `Shape` class to better understand its different parts.

```haskell
class Shape:
    Circle:
        radius :: Real
    Rectangle:
        width  :: Real
        height :: Real

    def perimeter: case self of
        Circle r: 2.0 * pi * r
        Rectangle w h: 2.0 * w + 2.0 * h

    def area: case self of
        Circle r: pi * r * r
        Rectangle w h: w * h
```

The first section in this code snippet defines constructors. Constructors are different variants of a given object. So the first part of the definition says "a Shape is either a Circle or a Rectangle". Then we define some methods. Methods are just like functions, but they have one implicit argument – `self`. They are called using the `.` operator and the object before `.` becomes the `self` inside method definition.

Both methods defined in the above snippet use pattern matching – the `case` construction, that allows to change the behavior based on the constructor of some object.

We can use our newly defined `Circle` class as follows:

`Circle 2.0 . area`

## Constructors

Most classes in Luna have at least one constructor. They are used to create instances of the class and to pattern match on the objects. The basic way to define them is as follows:

```haskell
class Shape:
    Circle:
        center :: Point
        radius :: Real
    Rectangle:
        topLeft     :: Point
        bottomRight :: Point
```

This snippet defines a `Shape` class with two constructors: `Circle` and `Rectangle`. Each of the constructors stores information essential for a given kind of shape.

You may also omit the field names, resulting in code like this:

```haskell
class Shape:
    Circle    Point Real
    Rectangle Point Point
```

While this code is much more concise, it has some drawbacks. First of all it isn't clear from the definition what the fields are really representing. Moreover, you lose the ability to access the fields by name.

> **\[info] Changes ahead!**
>
> Currently Luna allows accessing fields by name only when there is exactly one constructor present. This behavior will be extended in the near future, providing great capabilities for multi-constructor classes.

Finally, when there is only one constructor present, you may skip its name. In this case Luna will create a constructor with the same name as the class name:

```haskell
class Vector:
    x y z :: Real
```


# Algebraic classes

Objects are the basic blocks for bundling data and behaviors together. Luna's approach combines the approach known from Object Oriented languages with purely functional techniques, such as Algebraic Data Types.

## Introduction

Luna's notion of a class differs from what is known in most languages. If you are familiar with objects from Java or Python, you're in for a surprise.

First of all, Luna objects, besides having multiple fields, can also come in multiple, distinguishable flavors. This is known in functional programming as Algebraic Data Types and basically means that an object can be built using one of many available constructors and each of the constructors defines a different structure.

Using this technique we can say that any `Shape` is either a `Circle` or a `Rectangle`. Given an object of type `Shape` you are always sure it's one of those but you need to use [pattern matching](/luna-user-guide/classes/constructors) to discover which one was it.

However, thanks to methods, you can call some behaviors regardless of the constructor used. This means, given a `Shape` value, you may always use its `area` method, even though you may not know what was the real constructor used.

Another important property of objects in Luna is immutability. You may be used to mutable objects and expressions like `counter.count += 1` in other languages. In Luna every object is immutable – once it's created in a given way, it will never change. If you write `foo = Circle 15.0`, `foo` will always remain a `Circle` with the same radius, no matter how it is used. Any method that may seem to mutate the object, actually returns its changed version. So if you have a list and call its `sort` method, the original list remains unsorted – the sorted list is returned from the method instead and you need to assign this value to another variable if you want to use the sorted version later on.

## Class definition

> **\[info] Changes ahead!**
>
> Currently, there is no way to define classes and methods using the visual editor. All the mechanisms described in these sections are text-only, the support for visual workflow is coming soon.

Classes in Luna are defined with the `class` keyword. It is followed by definitions of constructors and methods. Let's consider this definition of the `Shape` class to better understand its different parts.

```haskell
class Shape:
    Circle:
        radius :: Real
    Rectangle:
        width  :: Real
        height :: Real

    def perimeter: case self of
        Circle r: 2.0 * pi * r
        Rectangle w h: 2.0 * w + 2.0 * h

    def area: case self of
        Circle r: pi * r * r
        Rectangle w h: w * h
```

The first section in this code snippet defines constructors. Constructors are different variants of a given object. So the first part of the definition says "a Shape is either a Circle or a Rectangle". Then we define some methods. Methods are just like functions, but they have one implicit argument – `self`. They are called using the `.` operator and the object before `.` becomes the `self` inside method definition.

Both methods defined in the above snippet use pattern matching – the `case` construction, that allows to change the behavior based on the constructor of some object.

We can use our newly defined `Circle` class as follows:

`Circle 2.0 . area`

## Constructors

Most classes in Luna have at least one constructor. They are used to create instances of the class and to pattern match on the objects. The basic way to define them is as follows:

```haskell
class Shape:
    Circle:
        center :: Point
        radius :: Real
    Rectangle:
        topLeft     :: Point
        bottomRight :: Point
```

This snippet defines a `Shape` class with two constructors: `Circle` and `Rectangle`. Each of the constructors stores information essential for a given kind of shape.

You may also omit the field names, resulting in code like this:

```haskell
class Shape:
    Circle    Point Real
    Rectangle Point Point
```

While this code is much more concise, it has some drawbacks. First of all it isn't clear from the definition what the fields are really representing. Moreover, you lose the ability to access the fields by name.

> **\[info] Changes ahead!**
>
> Currently Luna allows accessing fields by name only when there is exactly one constructor present. This behavior will be extended in the near future, providing great capabilities for multi-constructor classes.

Finally, when there is only one constructor present, you may skip its name. In this case Luna will create a constructor with the same name as the class name:

```haskell
class Vector:
    x y z :: Real
```


# Constructors and pattern matching

Constructors associated with classes have two important roles. First, they provide a way to create objects of a given class. Second, they are used as patterns, allowing to discover what constructor was used to create a given object and to access its fields.

## Object construction

Constructors can be used as ordinary functions. They take as their arguments values for the fields (in order of declaration) and return an object of the given class. For example, the definition for `Maybe` class:

```
class Maybe a:
    Just a
    Nothing
```

gives rise to two such values:

```
Just :: a -> Maybe a
Nothing :: Maybe a
```

![](/files/-LdNvy7X4egDCrtWqy5x)

Note that since the `Nothing` constructor has no fields, it is not a function, it's a constant, that can assume the type `Maybe a` for any choice of `a`.

## Pattern matching

The other use of constructors is for pattern matching. This allows to unpack an object into it's constituent fields, assuming the constructor used in pattern match is the same as the one assigned to the object. First of all, you may use patterns on the left-hand-side of assignment operator. This assigns the values of fields to the variables mentioned in the pattern. Let's see how this can be used with the `Vector` class defined like so:

```
class Vector:
    x y z :: Real
```

```
myVec = Vector 1.0 2.0 3.0
Vector a b c = myVec
bTimesOne = b * 1.0
```

![](/files/-LdNvy7ZSDIF_3rMYyH1)

You need to be careful with this construction though! It assumes that you have picked the right constructor and a mismatch will result in a runtime error. As a rule of thumb, you should use this form of pattern matching only on classes that have one constructor (thus making sure there is no possibility for an error).

## Case expression

The case expression is the most general way to handle pattern matching. It is also generally the safest and when in doubt you should always resort to this form of pattern matching. It's a mechanism allowing to discover which particular constructor was used to create a given object and to provide a different value for each of the possibilities.

Let's get back to the `Shape` example once again. Suppose we have facilities for rendering circles and rectangles and we need to render general `Shape`s. This can be accomplished with a simple case expression:

```
def render shape:
    case shape of
        Circle c r: drawCircle c r
        Rectangle tl br: drawRectangle tl br
```

The structure is pretty straightforward: first, between the `case ... of` we need to provide the object which identity we need to discover and then we provide a series of clauses, each providing a return value to use in the case of the particular constructor.


# Type polymorphism

## Type parameters

Classes in Luna can also take type parameters, making them polymorphic in some values. For an example, consider the previous definition of `Vector`:

```haskell
class Vector:
    x y z :: Real
```

What if we needed a `Vector` of `Int`s? In the current approach, it would require us to create another class just for this purpose. We can, however, add a type parameter to the `Vector` class:

```haskell
class Vector a:
    x y z :: a
```

Equipped with this definition, we can create vectors containing elements of any type, such as `Real`s, `Int`s, `Bool`s etc.

```haskell
Vector "hello" "world" "!" :: Vector Text
Vector 1 2 3 :: Vector Int
Vector 1.0 2.0 3.0 :: Vector Real
```

![](/files/-LdNvwkfjEzjrRWkqERi)

## Constrained methods

It is also possible to implement methods that assume some additional properties of the type `a` (such as supporting arithmetic operations, or having defined some other methods). Once you use such properties, Luna typechecker automatically keeps track of them and checks whether they are satisfied. For example:

```haskell
class Vector a:
    x y z :: a
    def dotProduct that:
        self.x * that.x + self.y * that.y + self.z * that.z
```

The `dotProduct` method will work with any elements supporting addition and multiplication, so using it with `Int`s or `Real`s is fine, while using it with `Text` results in a type error.

```
Vector 1 2 3 . dotProduct (Vector 4 5 6) # returns 32 :: Int
Vector 1.0 2.0 3.0 . dotProduct (Vector 4.0 5.0 6.0) # returns 32.0 :: Real
Vector "hello" "world" "!" . dotProduct (Vector "foo" "bar" "baz") # does not compile
```

![](/files/-LdNvwkhdc6FXcIYFbC4)


# Advanced types

## Methods

To achieve maximum levels of freedom and expressiveness, Luna allows calling methods on polymorphic arguments. Of course it's not always possible to infer what is the result type, so in this case we leave this unsolved until the real type is really needed. If you're familiar with the "duck typing" technique from dynamic languages, it's exactly the same in Luna, except when it's not really possible to call the function, you still get a compile-time error. Consider the following function:

```
def callSucc a: a.succ
```

What is its type? Since we haven't defined what is the type of `a`, we are assigning it a type parameter `b`. Now, what is the type of method `succ` on a type `b`? We can never know, as it depends on the implementation of a particular class that will be used. Hence, the type of `callSucc` is simply `b -> b.succ`. You can read it as "a function that takes an argument of type `b` and returns whatever the method `succ` of class `b` returns". We can now write `callSucc 1`, since the `succ` method is defined for `Int`s, but `callSucc "hello"` will result in a compile error.

## Type assumptions and the process of typechecking

Luna's typechecker stores some additional assumptions about type parameters, that need to be met by the types substituted for the variables. Those usually arise from manually typed functions and using methods on polymorphic values. Let's start with a simple example. The `+` operator is defined in Luna standard library as:

```python
def + :: a -> a -> a
def + x y = x.+ y
```

This definition allows us to write expressions like `5 + 7` or `"foo" + "bar"`, but will reject `"foo" + 5` (because arguments' types are different) or `Just 5 + Just 7` (because the `+` method is not defined for the `Maybe` class). So what is really going on here?

First of all, the user-specified type indicates that both the arguments and the return type need to be of the same type. Second, the use of the method `+` indicates that the type `a` needs to have this method defined. Moreover, this method needs to take a single argument of type `a` and return a result also of type `a`. All this allows us to describe the type of function `+` as:

```
+ :: a -> a -> a
```

for any `a` such that `a.+ = a -> a`

All this is handled by the Luna compiler under the hood, so that you don't need to think about all the assumptions present.

Let's consider another example:

`def foo x: x.succ + 1`

What is the type of this function? First of all, we can see that the result of `x.succ` is added to an `Int`, so (from the definition of `+` above) we know that `x.succ :: Int` and that the result of this function is also an `Int`. So the final type with the underlying assumptions is:

```
foo :: a -> Int
```

for any `a` such that `a.succ = Int`

All those assumptions can grow with more complex, multiline functions. That's why Luna tracks them under the hood, revealing them only when some of them can't be satisfied.


# Libraries

> **\[info] Changes ahead!**
>
> This describes the simplest way to share libraries, introduced in Luna Studio 1.3 beta. A proper package manager is currently being designed and coded and will be available soon.

## What is a library?

Library is a set of modules shared by others for reuse in other projects. This is the base way to share code between different projects – every functionality such as a database driver, a set of image processing functions or an awesome data science toolkit constitutes a library.

## How to create a library?

On the technical level library does not differ at all from an ordinary Luna project. It has the same structure as any other project. Maybe even some of the projects you've already created deserve to become publicly available libraries?

From the design perspective, there are some things you need take into account when creating a library. In order for others to enjoy using it, put some thought into the basic usage patterns – what set of functionalities is really needed and how do the functionalities compose? Think about the classes you define – do they encompass well the usage you intend for the library? If yes – congratulations, your project is a library! Publish it and encourage others to use it. Also, let us know, we love to learn about awesome things happening in the community!

## How to use a library?

The basic flow (before proper package management comes to Luna) is just to put it in the `local_libs` directory in your Luna project. After that, it will be available for other modules to import. Note that the name of the library is the first part of module name. It's probably best to explain it with an example. Suppose you have the following directory structure:

```
MyProject/
  MyProject.lunaproject
  src/
    Main.luna
  local_libs/
    MyLib/
      MyLib.lunaproject
      src/
        Foo.luna
        Bar.luna
```

And `Bar.luna` file is just:

```
def barify t: 'bar ' + t.toText + ' bar'
```

Then, you can import the `MyLib.Bar` module inside `Main.luna` (also inside `Foo.luna` – any module is available throughout the library defining it). So now your `Main.luna` file may look like this:

```
import Std.Time
import MyLib.Bar

def main:
    barify Time.now
```


# Calling C Functions

Starting from the 1.3 beta version, Luna comes equipped with the ability to call foreign C functions from object files. This document describes how to use this system to create C based libraries.

## Object files

Object files contain compiled code that can be dynamically loaded and used by other programs. The most common types are `.so` files on Linux, `.dylib` files on macOS and `.dll` on Windows. Luna is able to work with object files coming from two sources: 1. System-wide available dynamic libraries. If a library is installed on your machine, Luna will be able to use it. Unfortunately, this requires all the users of your library to have the dynamic library installed in their systems. For most libraries this is not a good solution, it will, however, work fine for bindings to the most popular libraries and for quick prototyping. 2. Object files inside the project tree. You can drop any shared object file into the `native_libs/PLATFORM` directory inside your project (`PLATFORM` is `macos`, `linux` or `windows`) and use it from Luna. This is a great solution for making sure users are able to use your library without any external dependencies. It's also the only way to include your own C extension or wrapper.

## Using a shared library

> **\[info] Changes ahead!**
>
> This describes the bare-bones way of interacting with foreign objects. There are some syntactic changes coming soon to cut down on boilerplate. The basic concepts, however, will remain unchanged.

OK, so you have your shared library in place, how to actually use it from Luna? For this example, we'll assume that we're working with the following directory structure:

```
MyProject/
  MyProject.lunaproject
  src/
    Main.luna
  native_libs/
    macos/
      libawesome.dylib
    linux/
      libawesome.so
    windows/
      libawesome.dll
```

The object files in this example contain just a single function, with the following C signature:

```
int awesomeFunction(int);
```

How do we use it?

### Resolving the symbol

The workhorse of our FFI (Foreign Function Interface) is the `lookupSymbol` function from `Std.Foreign` module. It takes a shared object file name and a name of the symbol to lookup, and returns a `FunPtr` object. The library resolution takes into account the most common naming conventions, so that it is possible to use the same call with a file named `awesome.dylib` as well as `libawesome.4.so`. So, in our example, you can just write:

```
def awesomeFunction i:
    funPtr = lookupSymbol "awesome" "awesomeFunction"
```

### Calling the FunPtr

Now that we've obtained the function pointer, it's time to call the function. This is what the `call` method of `FunPtr` does. It takes two arguments – a representation for the output type and a list of objects of type `CArg`, representing the function arguments. Note that not every type can be represented as a C argument. The types that can (numeric types, pointers and a few more) are converted using their `toCArg` method. So, back to our example. The `awesomeFunction` expects and `int` and returns an `int`. Note that Luna's `Int`s are different from C's, so the latter are represented by the class `CInt`. This is what our function call looks like:

```
def awesomeFunction i:
    funPtr = lookupSymbol "awesome" "awesomeFunction"
    result = funPtr . call CInt [i.toCArg]
```

### Translating between C and Luna data types

We have successfully called a C function. It is not very usable for most Luna code though – it requires us to use the C types throughout the program. We'll fix that with a few conversion methods. First of all, the function argument needs to be a `CInt`. Most Luna programs, however, use standard `Int`s and these cannot easily be represented in C. This can be fixed with the help of `CInt.fromInt` function, which converts an ordinary `Int` object into a `CInt`. It also returns a `CInt`, which again is not very handy. This can be fixed with the help of `toInt` method of `CInt`. The final version of our wrapper, which operates on `Int`s and from the outside is nearly indistinguishable from pure Luna code looks like this:

```
def awesomeFunction i:
    iArg = CInt.fromInt i
    funPtr = lookupSymbol "awesome" "awesomeFunction"
    result = funPtr . call CInt [iArg.toCArg]
    result.toInt
```

## Basic C Types

Luna defines counterparts of the standard C types in the `Std.Foreign.C.Value` module. This section is a short overview of all of them.

### Integer types

There is a counterpart for integral types commonly used throughout C codebases. All these wrappers have a common API – they define the `fromInt` and `toInt` methods, support comparison and basic arithmetic operators. The following table shows the C types and their Luna counterparts.

| C Type        | Luna Class |
| ------------- | ---------- |
| (signed) char | CChar      |
| unsigned char | CUChar     |
| wchar\_t      | CWChar     |
| (signed) int  | CInt       |
| unsigned int  | CUInt      |
| (signed) long | CLong      |
| unsigned long | CULong     |
| int8\_t       | CInt8      |
| uint8\_t      | CUInt8     |
| int16\_t      | CInt16     |
| uint16\_t     | CUInt16    |
| int32\_t      | CInt32     |
| uint32\_t     | CUInt32    |
| int64\_t      | CInt64     |
| uint64\_t     | CUInt64    |
| size\_t       | CSize      |

### Floating point numbers

Luna defines the `CDouble` and `CFloat` classes as counterparts of C's `double` and `float`, respectively. Both classes define `fromReal` and `toReal` methods for conversion between them and Luna's `Real`. They also support basic arithmetic and comparison operators.

## Pointers

The basic pointer type is just `Pointer`. It takes a single argument denoting the type of its content. So, for example, `Pointer CInt` corresponds to `int*` in C, while `Pointer (Pointer None)` is `void**`.

### Creating and freeing pointers

To create a pointer able to hold a single value of type `X` use the `malloc` method on pointer class:

```
ptr = Pointer X . malloc
```

For this to work, the `X` object must define a `byteSize` method, returning the size in bytes of the structure. You can also use `mallocElems` to create arrays like so:

```
arr = Pointer CInt . mallocElems 40
```

Any pointer can be freed using its `free` method – if you're done with your `ptr` just call `ptr.free`.

### Reading and writing

Reading a pointer can be accomplished by its `read` method. It works on a `Ptr X` and returns a value of type `X`. Keep in mind that in order for this to work, the `X` type must define a `readPtr` method that takes a bare pointer and plucks the fields one by one.

Similarly, to write a value to `ptr` of type `Pointer X`, call `ptr.write x`. Again, this requires the type `X` to define `writePtr` method.

For the basic C types, the required methods are already defined in the standard library.

### Pointer arithmetic

Any pointer can be moved by a specified number of bytes using the `ptr.moveBytes i` method – it returns a new pointer, resulting from adding `i` bytes to `ptr`. There is also a `moveElems` method, that will move the pointer by the specified number of elements (i.e. by `number of elements * element.byteSize` bytes).

## Managed Pointers

With standard pointers we need to think about freeing unused memory, or it will clutter up our RAM. We can fix that issue with managed pointers – pointers that can be automatically garbage collected when no longer needed. Since managed pointers are available the regular pointers should not be used any more. To create managed pointer for single value of `X` type call, like for pointer, `malloc` method just on the managed pointer class:

```
ptr = ManagedPointer X . malloc
```

Allocating multiple elements with `mallocElems` works just like for regular poinetrs. To create array with managed pointer use:

```
arr = ManagedPointer CInt . mallocElems 40
```

It is also possible to create managed pointer from existing pointer `ptr`. For this finalizer function `fin` is required. Finalizer will be run when the pointer will be garbage collected:

```
ptr = ManagedPointer X . fromPtr fin ptr
```

Methods like `read`, `write`, `moveElems` works the same way for managed pointers like for regular pointers.

## Real life example

Now that we've covered all the basics, let's dive into a more involved example – using the `SHA1` function from `openssl`. It takes an input buffer of type `unsigned char*`, a `size_t` denoting the length of input and an output buffer of type `unsigned char*` and length 20. Suppose you have a list of Luna `Int`s and want to compute the SHA1 digest of this list, as another list of `Int`s. This is how this can be done with Luna's FFI:

```
import Std.Foreign
import Std.Foreign.C.Value

def sha1Digest inputList:
    # Inputs preparation
    inputLength = inputList . length
    inBuf  = ManagedPointer CUChar . mallocElems inputLength      # Allocate the input buffer.
    inSize = CSize.fromInt inputLength                            # Convert the length to a CSize.
    outBuf = ManagedPointer CUChar . mallocElems 20               # Allocate the output buffer.
    indexed = 0 . upto inputLength . zip inputList
    indexed . each (ix, elem):
        inBuf . moveElems ix . write (CUChar.fromInt elem) # Write each element to the buffer at correct position.

    # Calling the foreign function
    sha1FunPtr = lookupSymbol "openssl" "SHA1"                          # Get the function from dynamic library.
    sha1FunPtr . call None [inBuf.toCArg, inSize.toCArg, outBuf.toCArg] # Call the function passing all the arguments
                                                                        # and specifying the return type as None

    # Getting the final results                                                                    
    result = 0 . upto 19 . each i:
        outBuf . moveElems i . read . toInt    # Read from the output buffer at consecutive positions
                                               # and convert the values back to Ints.

    result
```


# FAQ

**Q:** Why doesn't the Luna Studio installer do anything after I run it?

**A:** The installer is having trouble working on particular OS's, however, the known issues are only with the GUI. If the GUI installer for your system doesn't work, try the command line installer (you will need to run as root/administrator). Note that using the command line installer does not mean you need to use Luna on the command line. If you encounter issues with the command line installer, please inform us of your bug.

**Q:** How do I run programs in Luna?

**A:** In Luna Studio all code is being continuously executed. If you have the code open, it has already begun execution. If you would like to use Luna on the command line, you can find information on how to do so [here](https://github.com/luna/luna).

**Q:** How do I use type signatures in Luna?

**A:** We are working on finalizing some of the details of the type system. We want whatever syntax we decide on to be finalized before we release it to you so that your code will be compatible between versions.

**Q:** Can Luna/Luna Studio run in browser?

**A:** Luna Studio could be configured to run in a browser, and much of how the UI was implemented was done specifically with the intent to make the possible to do in the future. However, the core Luna team is not actively working on implementing Luna in browser at the moment.


