Coding with Shards¶
In this chapter, we will be learning how to code with Shards so that you can write your very own program!
A shard in its most basic code form consists of its name surrounded by parentheses.
The above example consists of 3 different predefined shards.
Shards are named to make their purpose rather intuitive.
(Msg) is the Message shard that prints a message to the console, while
Math.Add is a Mathematics shard that add numbers together.
It is a good practice to name your code based on their purpose. This allows others to easily understand what your code achieves without getting too technical.
For example, the code
(Msg "Hello World!") can be easily understood to be sending the message "Hello World" to the console. You do not need to delve into how
(Msg) was coded to understand what it can do.
A shard can take in an input, process that input, and produce an output. Shards also have parameters which behave as user-defined settings.
Math.Add has the parameter
Operand which is defined by the user. It determines the value that will be added to the input. The final result is then produced as the output.
In code form, parameters are defined by the user within the parentheses of the shard itself, after the shard's name. The above examples will appear as
5 (Math.Add 1) and
5 (Math.Add 3) in code.
Some shards have multiple parameters. When specifying values for multiple parameters, you will have to prepend your values with the parameter they are for if some parameters are skipped.
Let us take a look at the
Repeat shard which has four parameters:
We can utilize the
Repeat shard with its different parameters as shown:
- When no parameters are specified, parameters are treated as implied and are resolved in order. In this case,
Actionis the implied parameter for
Repeatand we set
(Msg "Hello World")to it.
- Since the other parameters are not defined, they will assume their default values. In this case, the
Repeatshard will not run at all as
Timeshas a default value of 0.
1 2 3
- The parameters are fully declared for clarity.
- Repeats the
- Both parameters can be implied since they are resolved in order. In this case,
Actionis the first implied parameter, and
Timesis the second implied parameter.
1 2 3
- You can still implicitly declare the first parameter, while fully declaring the other parameters. Note that it does not work vice versa. You cannot implicitly declare parameters if the parameter before it has been fully declared.
1 2 3
- This will not work as you cannot implicitly declare the second parameter if the first has been fully declared.
1 2 3 4 5
Timesparameter is skipped and
Foreveris declared instead. Since we are skipping a parameter, we must fully declare the parameters that come after it.
Untiltakes a shard that returns
Repeatwill loop forever until the shard specified in
When using shards for a parameter (e.g.,
Action), you must always place
-> before the first shard.
-> is a shard container used to group multiple shards together. We will see how to eliminate the use of
-> later in the segment for
To find out more about the input/output/parameter of a shard, you can search for the shard in the search bar above and check out its documentation page.
Give it a try!
Type "Msg" in the search bar above and select the first result that appears. It should lead you to the page for
From there, you can learn more about:
The purpose of the shard
The input type it can receive
The output it will produce
How to utilize the shard by looking at the examples given
A shard can take in data, process it, and output the results.
There are many different types of data in the Shards language, and each shard will have specific data types that it can work with.
For example, the
Math.Add shard can only work with numeric data types, while the
Log shard that prints information to the console can work with
Any data type.
Here are some of the data types found in Shards:
||Any data type.|
||No data type.|
||Evaluates to either
||A numerical value with a decimal point.||
||A numerical value with no decimals. Read as "integer".||
||A collection of values.||
||Characters enclosed by double quotes.||"A string!"|
||A sequence of shards.|
A shard can have multiple data types as its input and output. For example, the shard
Math.Add can have its input and output as an
Int, or it can have its input and output as a
For the full list of data types and more in-depth reading, check out the
Types documentation page here.
To better work with data across your code, we can assign them to data containers known as variables.
Imagine a scenario where you have a float
3.141592653589793 that you need to reuse in code multiple times. Instead of typing the entire float out each time, you could assign it to a variable called
.pi-value and simply use that variable whenever its needed.
- 3.141592653589793 is assigned to the variable
.pi-value. We'll learn more about assigning variables in a bit!
Variable names always start with a
Some example of variable names:
How you assign data to variables depends on the variable type. The main differences between variables are as follows:
Constant vs Mutable
Constant: The variable's value cannot be changed once defined.
Mutable: The variable's value can be changed.
Local vs Global
Local: The variable is only known within the Wire it originated from.
Global: The variable is known throughout the entire Mesh.
Local vs Global
We will learn more about this later in the section about Scope in Shards.
Here are the variable types and the symbols used to create and assign to them:
||Creates a local constant variable.|
||Creates a local mutable variable.|
||Creates a global mutable variable.|
||Updates a mutable variable.|
=to create constant variables.
>=to create local variables, or
>==to make them global.
>to update variable values.
Some shards have an alias to reduce your code's verbosity. They can represent shards with defined settings, as you will see in
When defining variables in your program, you can use
Setup to ensure that variables defined within it will only ever be defined once within a program.
1 2 3
- Code within a
Setupwill only be run once. As such, you can prevent variables defined in a loop from being reset each time.
Setup is an alias of the shard
Once, with its
Every parameter set to 1 to ensure that code defined in it's
Action parameter will only be run once.
defshards allows you to group multiple shards together to form a new shard, thereby eliminating the use of
->. It is useful for organizing your code and improving readability.
defshards has a syntax as such:
1 2 3
The square brackets
 is where you can define parameters. For example:
1 2 3
When used in code:
Let us now take a look at how we can utilize
defshards in a code snippet that counts from 1 to 5 multiple times.
1 2 3 4 5 6 7 8
We can eliminate the use of
-> and make the code more readable by defining a new shard named
1 2 3 4 5 6
defshards inherently behaves as a shards container, thereby removing the need to use
-> for parameters that takes in shards.
1 2 3
The parameter will still require a
-> if it contains multiple shards.
1 2 3 4 5
A Wire is made up of a sequence of shards, queued for execution from left to right, top to bottom.
To create a Wire, we use
1 2 3
The syntax for
defwire is different from
defshards as you cannot define parameters. Square brackets
 are not used.
defshards which groups shards up for organization,
defwire groups shards up to fulfill a purpose. As Wires are created with a purpose in mind, they should be appropriately named to reflect it.
A Wire's lifetime ends once the final shard within it has been executed. To keep a Wire alive even after it has reached its end, we can set it to be loopable. This is called a Looped Wire.
A Looped Wire will continue running until its exit conditions have been met.
You will learn more about the entering and exiting of Looped Wires in the next chapter!
To create a Looped Wire, we use
1 2 3
Wires are queued for execution within a Mesh, from left to right, top to bottom.
To queue a Wire on a Mesh, we use
We will learn more about controlling the flow of Shards with Wires and Meshes in the following chapter.
In order to actually get Shards running, a specific hierarchy and sequence must be followed. Your shards are first queued into Wires, which are then queued onto a Mesh.
When the Mesh is run, the Wires are executed in sequence and your program is started. This is done using the aptly named command
run can take in two optional values:
The interval between each iteration of the Mesh.
The maximum number of iterations, typically used for Debugging purposes.
If your program has animations, we recommend that you set the first value to
(/ 1.0 60.0) which emulates 60 frames per second (60 FPS).
Let us now take a look at how a basic Shards program will look like!
Writing a sample program¶
Do you recall the
hungry-cat loop from the previous chapter? Let us try to implement a simpler modified version of it using the concepts learned in this chapter.
In this example, the "cat" starts off with 0 hunger. At the end of each loop, we increase the hunger by 1. Once the value of hunger is greater than 0, the cat starts to make cat noises.
defshards and defwire¶
Let us first define the
1 2 3 4 5
We can employ the
Repeat shard we saw earlier to make our code more efficient.
1 2 3 4 5 6 7 8 9 10 11 12 13
Going a step further, we can better organize our code by creating new shards with
defshards. Look at how much neater it is now!
1 2 3 4 5 6 7 8 9 10 11 12
make-cat-noises Wire done, let us now look at creating the full
hungry-cat program loop.
We want to first create a variable to track the cat's hunger level. Create the
.hunger variable and assign the value of 0 to it. Remember to create it within a
Setup to prevent the variable from being reassigned every loop.
1 2 3
- Code within a
Setupwill only be run once in a program.
Next, use the
Math.Inc shard to increase the value of
.hunger every time the Wire loops.
1 2 3 4
A conditional can be used to check if
.hunger is greater than 0. When the cat's hunger level has risen above 0, we want the cat to start making cat noises. Some conditional shards that you can use are:
When allows you to specify what happens if a condition is met. The syntax reads as:
When a condition is met,
Then a specified action happens.
If is similar to
When, but it has an additional parameter
Else that allows it to have a syntax that reads as:
If a condition is met,
Then a specified action occurs,
Else another action is executed instead.
For this example, using
When would suffice as we only need
make-cat-noises to run
IsMore than 0.
1 2 3 4 5 6 7
What if you wanted to check the value of
.hunger in each loop iteration?
We can employ a shard that is useful when you wish to debug your code - the
Debugging is the process of attempting to find the cause of an error or undesirable behavior in your program. When attempting to debug your code, functions or tools that allow you to check the value of variables at various points in your code can be useful in helping you narrow down where the errors could be originating from.
Log is useful as it can be placed at any point of your code to check the value passing through it. In this example, we will use
Log to verify the value of
.hunger before the conditional check with
When occurs. Upon running the code, you will see that when the value of
.hunger becomes 1, the cat starts to make noises.
Readying the Mesh¶
Before our program can run, do not forget to:
Define the Mesh.
schedulethe Wire on the Mesh.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
- We set the Mesh to only run 3 iterations. This means that the
hungry-catloop will only occur 3 times.
[hungry-cat] Hunger Level: 0 [hungry-cat] Hunger Level: 1 [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Mew [make-cat-noises] Mew [make-cat-noises] Mew [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Mew [make-cat-noises] Mew [make-cat-noises] Mew [hungry-cat] Hunger Level: 2 [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Mew [make-cat-noises] Mew [make-cat-noises] Mew [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Meow [make-cat-noises] Mew [make-cat-noises] Mew [make-cat-noises] Mew
Congratulations! You have now learned the fundamentals of writing a Shards program.
We will next look at how you can manipulate the flow of Shards to give you better control of how your program utilizes different Wires.