Deku logo

Introduction

Hello world

Let's teach Deku to say hello.

Hello world in Deku is a one-liner... after imports, and type declarations, and newlines… But even with all of that stuff, it's a ten-liner. And oh what lines! Let's see them in action.


Saying hello

This section, like many that will come after it, first presents some code and then presents the result of the code rendered in a blockquote. In some cases, we may present code without rendering or vice versa. But for the most part, we’ll try to always pair up code with a working example.

The code

Here it is, the moment you've all been waiting for. Let's say hello to the world!

View on GithubVITE_START=HelloWorldCode pnpm example
module Examples.HelloWorldCode where

import Prelude
import Deku.Toplevel (runInBody)
import Effect (Effect)
import ExampleAssitant (ExampleSignature)
import Deku.Control (text_)
import Deku.Toplevel (runInBody)

main :: Effect Unit
main = void $ runInBody (text_ "Hello world")

The result

As promised, here's the result.

Hello world
You gotta start somewhere!

Code snippets

The code snippets in this documentation aren't just there to be purty. Dig in! You can run the command above the snippet (you can click on the clipboard to copy it) from the documentation project's root directory after having cloned it from Github viagit clone https://github.com/mikesol/deku-documentation. After cloning, make sure to run pnpm install to get all the dependencies.


The anatomy of hello

There are a few things going on in our Hello world that we’ll see over and over again. Soon, we’ll start collapsing some bits like import statements in the interest of saving space, so it's best we get acquainted with them now!

Module declaration

module Main where

All PureScript files must start with a module declaration, and it's customary to call this module Main in a file called Main.purs.

Imports

import Prelude

import Deku.Control (text, text_)
import Deku.Toplevel (runInBody)
import Effect (Effect)

PureScript, like Java and Haskell, has a pretty tiny core language. That means that, to get most things done, you’ll need to import a few types and terms from various libraries.

The convention in PureScript is to import the language's Prelude in an unqualified format, meaning that everything from the Prelude winds up getting imported. This is because the Prelude's content is a veritable Greatest Hits of Functional Programming and you’ll likely need much of it to get stuff done.

Prelude etiquette

Try not to define something using a word that's already used in the Prelude. For example, the word map has such a strong connotation in PureScript's Prelude that it's usually a good idea to avoid defining something with that name, even if the language technically allows you.

After this, there are three more imports, all of which will be crucial in any Deku app of repute.

  • text: A way to write a text string to the DOM.
  • runInBody: Takes the current Deku program and inserts it into the body of a webpage.
  • Effect: The monad that a Deku program runs in. If you don't know what a monad is, you can think of it as a computational context. Effect is a context that accounts for various side effects like changing the dom and/or JavaScript errors arising, which is a danger in most web apps. I personally have never written any code with errors before, but some of my friends have, and they tell me it's not that bad.

Lastly, Effect Unit means that the computational context of Effect returns a dummy value of Unit if and when the program stops executing.

The main function

main :: Effect Unit
main = ...

In most PureScript programs (and most programs), a function or context called main is where the main action happens. If you take a peek in the Deku starter app you created in the Getting started section, you’ll see that main is called from index.js, which in turn is imported into index.html.

Running in the body

runInBody (...)

The most common way to run a Deku app is to embed it in the body of a webpage. You can also embed a Deku app in an arbitrary element. For now, we’ll stick to presenting our app in a webpage's body.

Filling up the DOM

text ("Hello world")

Last, and arguably least, we say "Hello world". To do so, we use the text function which takes a string and turns it into an abstract representation of a text node. runInBody interprets this instruction as something that should be rendered on a webpage.