Getting started with MojiScript: FizzBuzz (part 1)
Tags: functional, javascript, mojiscript
Published: 2018-09-27 17:13:05

---
title: Getting started with MojiScript: FizzBuzz (part 1)
published: true
description: 
tags: functional, javascript, mojiscript
---

[![4 people looking at laptop](https://thepracticaldev.s3.amazonaws.com/i/f91nbmjbcbiofo5mr1c1.jpg)](https://unsplash.com/photos/vdXMSiX-n6M)

# What is MojiScript

[MojiScript](https://github.com/joelnet/MojiScript) is an async-first, opinionated, and functional language designed to have 100% compatibility with JavaScript engines.

Because MojiScript is written async-first, asynchronous tasks not only become trivial, but become a pleasure to use. Read this article for more on async in MojiScript: [Why async code is so damn confusing (and a how to make it easy)](https://dev.to/joelnet/why-async-code-is-so-damn-confusing-and-a-how-to-make-it-easy-3441).

MojiScript is also JavaScript engine compatible, meaning **it runs in node.js and browsers without the need to transpile!**

Even though it runs in any JavaScript engine, you will notice significant differences between MojiScript and JavaScript.

# Significant differences you say?

Well, JavaScript as you know it will not run. But other than that...

![screenshot of JavaScript errors](https://thepracticaldev.s3.amazonaws.com/i/h7waopmb48icskst1kwd.png)

It's best to forget everything you know about JavaScript when learning MojiScript.

But don't worry, **there are easy ways to interop with JavaScript**. We won't be convering JavaScript iterop in this article though.

# FizzBuzz

You should already be familiar with FizzBuzz. If not, the game is simple:

> Write a program that prints the numbers from 1 to 100. But for multiples of three print "Fizz" instead of the number and for the multiples of five print "Buzz". For numbers which are multiples of both three and five print "FizzBuzz". -- [FizzBuzz Test](http://wiki.c2.com/?FizzBuzzTest)

# Start

We'll be writing a node application, so I am assuming you already have node and git installed.

Make sure you have node `v10.9.0`+

Install the `mojiscript-starter-app`

```
git clone https://github.com/joelnet/mojiscript-starter-app.git
cd mojiscript-starter-app
```

Make sure it builds and runs.

```
npm ci
npm run build
npm start --silent
```

If everything went well you should see:

```
Hello World
```

# Format on Save

Visual Studio Code is highly recommended as your editor. It adds some nice features like **Format on Save**.

If there's another IDE you love that doesn't **Format on Save**, then you can just run this command:

```
npm run watch
```

This is important because your app will not `build` if your formatting is off.

You can also run this command to fix your formatting.

```
npm run build -- --fix
```

It's little things like this that make MojiScript such a joy to code in!

# Files

There are two files that are important:

`src/index.mjs` - Load dependencies and start app.
`src/main.mjs` - Your app without dependencies makes it easy to test.

note: We are using the `.mjs` file extension so that we can use `node --experimental-modules` which gives us the ability to `import` and `export` without transpiling.

Open up `src/main.mjs` That is where we will start.

It should look like this:

```javascript
import pipe from 'mojiscript/core/pipe'

const main = ({ log }) => pipe ([
  'Hello World',
  log
])

export default main
```

# Let's write some code!

First let's create a loop from 1 to 100.

Import these two functions:

- `range` - Creates an Iterable from `start` to `end`.
- `map` - Maps over an Iterable.

```javascript
import range from 'mojiscript/list/range'
import map from 'mojiscript/list/map'
```

Modify your main to look like this:

```javascript
const main = ({ log }) => pipe ([
  () => range (1) (101),
  map (log)
])
```

run your app and you should see the console output numbers 1 to 100.

Next, I'd like to get rid of those "magic numbers" `1` and `100`. You shouldn't be hard-coding values directly into your source, at least not in `src/main.mjs`. You can however put those values in `src/index.mjs` since it's responsibility is to load and inject dependencies and add configuration.

So open up `src/index.mjs` add those numbers to a new value `state`.

```javascript
const state = {
  start: 1,
  end: 100
}
```

Add the state to the `run` command

```javascript
run ({ dependencies, state, main })
```

Now `src/index.mjs` should look like this:

```javascript
import log from 'mojiscript/console/log'
import run from 'mojiscript/core/run'
import main from './main'

const dependencies = {
  log
}

const state = {
  start: 1,
  end: 100
}

run ({ dependencies, state, main })
```

Go back to `src/main.mjs` and modify `main` to use `start` and `end`.

```javascript
const main = ({ log }) => pipe ([
  ({ start, end }) => range (start) (end + 1),
  map (log)
])
```

run `npm start` again to make sure it works.


# Let's break to talk about Pipes

I would like to talk a little bit about `pipe` and how it works. Imagine data moving through the `pipe` and being transformed (or Morphed) at each step of the way.

With this pipe, if we were to pass a `4` through  it, it will be morphed into a `9`, then an `18`. `log` performs a side effect and doesn't morph the value at all so the `18` would be returned from the pipe.

```javascript
const main = pipe ([
  //         |
  //         | 4
  //         ▼ 
  /*-------------------*/
  /**/  x => x + 5,  /**/
  /*-------------------*/
  //         |
  //         | 9
  //         ▼
  /*-------------------*/
  /**/  x => x * 2,  /**/
  /*-------------------*/
  //         |
  //         | 18
  //         ▼
  /*-------------------*/
  /**/      log,     /**/
  /*-------------------*/
  //         |
  //         | 18
  //         ▼
])
```

So in our FizzBuzz example, we start with `{ start: 1, end: 100 }` morph that into an `Iterable` of `1` to `100` and then `log` each value. The pipe would return an array of `1` to `100`.

# Back to FizzBuzz

So far all we have done is create an array. We still have to calculate the Fizziness of each number.

```javascript
import allPass from 'mojiscript/logic/allPass'
import cond from 'mojiscript/logic/cond'

const isFizz = num => num % 3 === 0
const isBuzz = num => num % 5 === 0
const isFizzBuzz = allPass ([ isFizz, isBuzz ])

const fizziness = cond ([
  [ isFizzBuzz, 'FizzBuzz' ],
  [ isFizz, 'Fizz' ],
  [ isBuzz, 'Buzz' ],
  [ () => true, x => x ]
])
```

`isFizzBuzz` is `true` if both `isFizz` and `isBuzz` are true.

`cond` is similar to JavaScript's `switch`. It compares either a function or a value and then will execute a function or a value. The last condition `[ () => true, x => x ]` will always return `true` and then will return the value passed into `fizziness`. This is the default case.

Finally, add the `fizziness` morphism to your `main`

```javascript
const main = ({ log }) => pipe ([
  ({ start, end }) => range (start) (end + 1),
  map (fizziness),
  map (log)
])
```

# Function Compostion

You may have noticed `map` being called twice. We are looping through `1` to `100` twice. It's not a big deal here because 100 iterations is microscopic. But other applications this might be important.

We can compose `fizziness` and `log` together using a `pipe` and modify our `main` to use our new `logFizziness` function.

```javascript
// logFizziness :: Function -> Number -> Number
const logFizziness = log => pipe ([
  fizziness,
  log
])

const main = ({ log }) => pipe ([
  ({ start, end }) => range (start) (end + 1),
  map (logFizziness (log))
])
```

Now we are iterating through the iterator only once.

Our final `src/main.mjs` should look like this:

```javascript
import cond from 'mojiscript/logic/cond'
import pipe from 'mojiscript/core/pipe'
import map from 'mojiscript/list/map'
import range from 'mojiscript/list/range'
import allPass from 'mojiscript/logic/allPass'

const isFizz = num => num % 3 === 0
const isBuzz = num => num % 5 === 0
const isFizzBuzz = allPass ([ isFizz, isBuzz ])

const fizziness = cond ([
  [ isFizzBuzz, 'FizzBuzz' ],
  [ isFizz, 'Fizz' ],
  [ isBuzz, 'Buzz' ],
  [ () => true, x => x ]
])

const logFizziness = log => pipe ([
  fizziness,
  log
])

const main = ({ log }) => pipe ([
  ({ start, end }) => range (start) (end + 1),
  map (logFizziness (log))
])

export default main
```

# Part 2

In part 2 I'm going to go over asynchronous mapping, `Infinity`, `reduce`, unit testing and more! This is where MojiScript really starts to get fun!

Follow me here, or on Twitter [@joelnet](https://twitter.com/joelnet) so you do not miss **Part 2**!

# End

Did you notice you just learned currying, partial application, function composition, functors, and category theory? Gasp! Of course not. That's because we were having too much fun!

If you thought MojiScript was fun, give it a star https://github.com/joelnet/MojiScript! If you have questions, put em in the comments!

Do not miss **Part 2** where I reveal the mysteries of life!

**Read my other articles:**

[Why async code is so damn confusing (and a how to make it easy)](https://dev.to/joelnet/why-async-code-is-so-damn-confusing-and-a-how-to-make-it-easy-3441)

[How I rediscovered my love for JavaScript after throwing 90% of it in the trash](https://hackernoon.com/how-i-rediscovered-my-love-for-javascript-after-throwing-90-of-it-in-the-trash-f1baed075d1b)

![Cheers!](https://thepracticaldev.s3.amazonaws.com/i/6jsy3a866frzp3u5oda0.jpg)