Declaring the Point
class
⚠️ DADA DOESN'T REALLY EXIST. ⚠️
See the About page for more information. Also, you have to pretend that all the code examples are editable and runnable, with live IDE tooltips and so forth. =)
The main data structures in Dada are classes. The full class syntax has various bells and whistles, but let's start off with the simplest form. We'll define a class Point
for storing (x, y)
values. It will have two fields, x
and y
:
class Point(our x, our y)
# ^^^^^ ^^^ ^
# | | |
# | | Field name
# | Permission
# Class name
The our
permission
You can see that the fields are declared with an permission -- our
in this case. There are several permissions (my
, our
, leased
, and shleased
); these permissions are a key part of how Dada works, and we'll be covering them throughout this tutorial. For now, it's enough to say that an our
field stores an object that may be referenced by other fields or variables as well (it belongs to everyone, hence our
). For points, we are expecting to store integers like 22
and 44
, so this is a good fit.
Constructor functions
The class Point(..)
syntax also creates a constructor function that creates an instance of Point
when called. Try executing the following code:
class Point(our x, our y)
# This function is declared as `async` because it
# awaits the result of print.
async fn print_point(p) {
print("The point is: {p}").await
}
# This function is not declared as `async` because it
# doesn't await anything. The `->` indicates that it
# returns a value.
fn compute_new_value() -> {
33
}
my p = Point(22, 44)
print_point(p).await
p.x := compute_new_value()
p.x += 1
print_point(p).await
# prints:
# The point is: Point(x: 22, y: 44)
# The point is: Point(x: 34, y: 44)
Some things to note here:
- Comments are written
#
, like Python or Ruby, not//
like JavaScript or Rust. - The
my p = ...
statement declares a local variablep
using another permission,my
.my
declares a variable that has unique access to its object: in this case, we just created thePoint
, so nobody else could possibly be referencing it, so that makes sense. If that doesn't make sense yet, don't worry, we're going to talk all aboutmy
in the next section.
- You create a class by invoking its constructor function
Point(22, 44)
. - Strings can embed expressions with
{}
, and they get "stringified", so"The point is {p}"
embedsp
into the string.- The default stringifier prints the values of each field.
- You write
:=
to reassign variables or fields (just=
is for declaring a new variable).- You can also use the
+=
,-=
,*=
,/=
,%=
operators you may be familiar with from other languages.
- You can also use the
- Declaring a function with
async fn
means that it can await thunks, like the one from callingprint
. - Declaring a function with
->
means that it returns a value; as in Rust, the final expression in the function is its return value.- In this case,
compute_new_value()
returns33
.
- In this case,
Summary and key differences
So far, everything hopefully feels fairly familiar, except for the permissions, which we'll cover next. Some highlights:
- Declaring a class like
class Point(x, y)
also gives a constructor functionPoint
that can be called (e.g.,Point(22, 44)
) to create an instance of the class. - You can use
"{p}"
in strings to print the values of things. - Use
=
to declare a new variable and:=
or+=
to update an existing one. - Dada is based on async-await:
- When you
print
something (or do any I/O), you mustawait
the result for it to take effect (print("Hi").await
). - You can only
await
things from inside anasync
fn.
- When you