𝛿₀ - The DeltaZero Language

// Functions are everywhere, and in this language, they are very flexible.

// This is an introduction to the basics of how functions are made and used.

// First, we need to understand what exactly a function is.

// The most basic function returns the same thing every time.

// This function just returns the number 5:

myFunction = fn: 5;

// To call this function, we can do this:

myFunction();

// Now for something more useful...

// We can use parameters to make our function work for us.

// This is a function that returns whatever you give it:

doNothing = fn x: x;

doNothing(5); // Returns the number 5

// We can also use several parameters.

// This function adds the two numbers you give it:

add = fn (a, b): a + b;

add(1, 2); // Returns 3

// What if you don't want to put in all of the parameters?

// Use the `?` character as a placeholder:

add(1, ?);

// This is called partial application, and it can be very useful.

addOne = add(1, ?); // Returns fn b: 1 + b

addOne(2); // Returns 3

// You can put the placeholder anywhere:

otherAddOne = add(?, 1); // Returns fn a: a + 1

// Note how the functions addOne and otherAddOne are different,

// even though they behave the same way mathematically.

// The placeholder simply ignores the parameter it is placed on.

// There is also one more thing to know,

// instead of putting placeholders last, you can ignore the parameters:

addOne = add(1); // Returns fn b: 1 + b

// That's all fine and dandy, but what can you actually use it for?

// Let's make a function that doubles every item in an array of numbers:

double = fn n: 2*n;

doubleArray = map(double); // Or map(double, ?)

doubleArray([1, 2, 3]); // Returns [2, 4, 6]

// Now for something a little more complicated.

// This finds the sum of all the multiples of 3 or 5 below 1000:

multiples = fn n: (n % 3 == 0) || (n % 5 == 0);

reduce(add, 0, filter(multiples, [0..999]));

// That kinda sucks, you can barely tell what's happening...

// How can we call these functions in a way that makes more sense?

[0..999] ->

 filter(multiples) ->

 reduce(add, 0);

// So now we can see the flow of data easily,

// the flow arrow, `->`, puts the value to the left of it into

// the function to the right of it. This is the alternative way of calling functions.

// Asynchronicity is just a bit different from javascript

// These four expressions will simply evaluate in order, as if synchronous

res = fetchSomeJSON;

res -> console.log;

res -> process -> postJSON;

res -> doSomethingElse;

// We can call any function asynchronously by prefixing with the `go` keyword.

// This will call the functions in the same order as before,

// but there will be no waiting for the functions to return before moving on.

go doWhatever();

go doThisToo();

// Asynchronous behavior is designed to be almost invisible.

// This essentially means that `await` is always implied when you access

// an asynchronous return value. You will never have to interact with a promise.

/* JS:

async function http(url) {

 const res = await fetch(url);  return res.json(); }

// You can only use `await` within an async function

async wrapperFunction() {  const json = await http(apiURL); }

*/

// DeltaZero equivalent:

http = fn url: fetch(url).json();

json = apiURL -> http;

// The one quirk is that if and match are special,

// We can write them like functions, but they are more

// accurately language constructs.

// This is the most basic use of if:

if { thisIsTrue: doThis(); };

// There is no need to say `then`, `else if`, or `else`:

if {

 thisIsTrue: doThis();

 elseIfThisIsTrue: thenThis();

 defaultToThis();

};

// Nesting works just what you would expect:

if {

 maybe: if {

   false: this;

   true: that;

 };

 this: that;

 that;

};

// This is what `match` looks like:

match thisValue withThis: doThis();

// Here's an more extended example:

price = match fruit {

 "Oranges": 0.59;

 "Apples": 0.32;

 "Bananas": 0.48;

 "Cherries": 3;

 "Mangoes", "Papayas": 2.79;

 `Sorry, we are out of ${fruit}.` -> fail;

};

// Now realize that `if` is equivalent to `match true`.

// Could this also apply to functions?

// Of course, check out this factorial function:

factorial = fn: match args {

 0: 1;

 n: n * factorial(n-1);

};

// Or more usefully:

factorial = fn {

 0: 1;

 n: n * factorial(n-1);

};

// Function guards automatically match and assign to parameters.

// This computes the greatest common denominator using Euclid's algorithm.

gcd = fn {

 (a, 0): a;

 (a, b): gcd(b, a%b);

};

// Normal Strings

"Normal, single line string surrounded by double quotes";

'Normal, single line string surrounded by single quotes';

// Template Strings

`2 + 2 = ${2 + 2}`;

`This is a

multi-line

string`;