Danny Yang

Introducing ReScript

Functional Programming for Web Applications

Danny Yang
Mountain View, CA, USA
ISBN 978-1-4842-8887-0e-ISBN 978-1-4842-8888-7
© Danny Yang 2023
This work is subject to copyright. All rights are solely and exclusively licensed by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed.
The use of general descriptive names, registered names, trademarks, service marks, etc. in this publication does not imply, even in the absence of a specific statement, that such names are exempt from the relevant protective laws and regulations and therefore free for general use.
The publisher, the authors, and the editors are safe to assume that the advice and information in this book are believed to be true and accurate at the date of publication. Neither the publisher nor the authors or the editors give a warranty, expressed or implied, with respect to the material contained herein or for any errors or omissions that may have been made. The publisher remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.

This Apress imprint is published by the registered company APress Media, LLC, part of Springer Nature.

The registered company address is: 1 New York Plaza, New York, NY 10004, U.S.A.

Introduction

Why Learn ReScript?

JavaScript is vital to the modern web ecosystem. It’s used in the front end to implement websites and other user interfaces, and used in the back end to implement servers for websites and APIs.

Part of JavaScript’s ubiquity is due to its ease of use. JavaScript is dynamic and flexible, making it easy for people to pick up. However, this strength becomes a weakness when working on large web applications with multiple developers – the only way to know that JavaScript code works correctly is to actually run it, and it’s relatively easy to make mistakes when programming in JavaScript.

What if there was a way to detect bugs in JavaScript before running the code, or prevent many classes of bugs altogether? What if there was a language that was concise and elegant that made it easy for programmers to write complex web applications and hard for programmers to make mistakes?

Enter ReScript.

ReScript is a language designed for writing web applications. It brings a lot to the table: static typechecking, a strong type system, and powerful language features that will change the way you program.

Here’s a glimpse of some of the features that make ReScript a great language:
  • Static typechecking – Catch bugs in your code without having to run it: undefined values, missing cases, incorrect types, and more.

  • Sound type system – ReScript programs that pass typechecking cannot have runtime type errors.

  • Type inference – ReScript automatically infers types based on how variables are used, allowing you to enjoy the benefits of type safety without having to annotate every variable and function.

  • Immutability – Peace of mind while you program with variables and data structures that cannot be unexpectedly modified under your nose.

  • Algebraic data types and pattern matching – Cleanly define and elegantly manipulate complex data.

  • First-class bindings for React – Write React elements and JSX directly inside ReScript files.

There are a number of other languages and tools that offer static typechecking for web applications, but ReScript has several key advantages over its competitors. As an example, let’s look at the benefits ReScript has compared with another popular JavaScript alternative, TypeScript:
  • ReScript is safer – Unlike ReScript’s battle-tested and sound type system, TypeScript’s type system is unsound, so it is still possible to have runtime type errors in a valid TypeScript program.

  • ReScript is faster – ReScript’s compiler is much faster than TypeScript’s compiler, allowing for a smoother development experience when working in large code bases.

  • ReScript is more concise – ReScript’s excellent type inference means that programmers do not have to write as many type annotations in ReScript programs compared to TypeScript programs.

Although ReScript is a relative newcomer to the web ecosystem, it’s actually based on technology that has been battle-tested for years before ReScript even existed. ReScript itself has proven successful as well. Most notably, Facebook used it to build the web interface for Messenger – a product used by hundreds of millions of people – with a code base containing thousands of files.

History of ReScript

The lineage of ReScript can ultimately be traced back to the ML family of languages originating from the 1960s. In particular, ReScript is directly based on OCaml, a general-purpose programming language that was developed in the 1980s and used today for systems programming in academia and industry.

In 2015, Jordan Walke, the creator of the React web framework, developed a toolchain and alternative syntax for OCaml called Reason.

Reason was designed to bridge the gap between the web and OCaml ecosystems – it could be compiled into both native machine code and JavaScript, allowing web developers to take advantage of OCaml’s features. Static typechecking and OCaml’s sound type system eliminated many common bugs in JavaScript code, and OCaml’s immutability and functional style was a great fit for React.

Reason was compiled to JavaScript using a compiler called BuckleScript, which was developed at Bloomberg around the same time Reason was being created at Facebook.

Around 2020, the BuckleScript project created a new language based on Reason that could only be compiled to JavaScript using the BuckleScript compiler, and so ReScript was born.

ReScript has the following key differences from its predecessors:
  • ReScript has different syntax and features. While it looks and feels more like JavaScript, ReScript is still based on the battle-tested compiler and type system as Reason and OCaml, so it has the same type safety benefits as its predecessors.

  • ReScript can only be compiled to JavaScript. By dropping support for native compilation, ReScript has a simpler toolchain and standard library, along with a feature set better suited for web development. This makes ReScript easier for newcomers to learn and allows for smoother integration with other web technologies.

ReScript and the Web Ecosystem

Like some other statically typed languages in the web ecosystem, ReScript code is transpiled to JavaScript. This means that ReScript code doesn’t directly run in the browser or on the server. Instead, the ReScript compiler checks that the code is valid and generates JavaScript files, which can then be imported and used like any handwritten JavaScript file.

Being able to run in any environment that supports JavaScript allows ReScript to be used for full-stack web development, from client-side code that runs in the browser to server-side code that runs in Node.js.

Since ReScript code is exactly the same as JavaScript code when it runs, ReScript programs can easily import and use JavaScript libraries, while JavaScript programs can call ReScript functions as easily as they can call other JavaScript functions.

Why Learn Functional Programming?

Functional programming is a paradigm of programming that focuses on the application and composition of functions.

In functional languages, functions are first class and can be used like any other value (bound to variables, passed as arguments, or returned from other functions). Complex programs are written by composing multiple smaller functions that apply transformations to data. This can be contrasted with the imperative and object-oriented style of many popular languages, where programs look more like a series of commands that read and update memory. It’s important to know that most languages are not purely in one category or the other; many languages fall somewhere in the middle of this spectrum, and features from functional languages are slowly being adopted by other languages. For example, ReScript is more functional but it also has imperative features like loops, while JavaScript is more imperative but it also has first-class functions.

Programming in a functional style has many benefits – programs are cleaner and more concise, and logic is more declarative making it easier to trace the flow of data through a program. The ability to compose functions together and write functions that accept other functions as arguments (higher-order functions) makes functional languages very flexible, and the greater emphasis on immutability and purity makes it easier to understand, write, and test programs.

As a disclaimer, I’m not some functional programming purist here to convince you that functional programming is the best way to solve every problem. Instead, I view functional programming as a useful tool in a programmer’s tool belt, albeit a tool that not enough people know about or know how to use.

Unlike many other functional programming books, the explanations in this book are designed to be accessible to those without a formal background in computer science. I do not expect readers to have experience with statically typed languages or functional programming concepts.

About This Book

This book is written for anyone who is interested in learning ReScript or wants to learn the basics of functional programming using ReScript.

The book is structured as an overview of ReScript’s features, building up from the basics to eventually cover complex data types, pattern matching, modules, and finally writing a minimal web application using ReScript.

Along the way, you will learn functional programming concepts like higher-order functions, immutability, and purity, which will help you think about and write software differently, even when you are not using ReScript.

Here’s what this book will cover:
  • Chapter1 – Language basics: expressions, binding, and control flow

  • Chapter2 – Functions: higher-order programming, recursion, and purity

  • Chapter3 – Composite data types, pattern matching, and error handling

  • Chapter4 – Records and objects

  • Chapter5 – Lists and arrays: map, filter, and reduce

  • Chapter6 – Collections: sets, maps, stacks, and queues

  • Chapter7 – Modular programming: modules and functors

  • Chapter8 – JavaScript integrations: bindings, dealing with JSON, and more

Installing ReScript

ReScript projects are set up just like modern JavaScript projects, except we have an extra development dependency on the rescript package.

Before we begin, make sure you have Node.js v10 or higher, and npm. To check the version of Node.js you have, run node -v in your terminal. If you don’t have Node.js installed, you can find installation instructions at https://nodejs.org.

Once you’ve confirmed that you have the right version of Node.js installed, create a new directory for your project, and run npm install rescript@10 to install v10 of ReScript.

There will be a package.json file with the following contents inside the project’s root directory. Add the following scripts to it:
{
  ...
  "scripts": {
      "build": "rescript",
      "start": "rescript build -w"
  }
}

The scripts we added in package.json are used to run the ReScript compiler to compile our ReScript to JavaScript.

npm run build will compile all the ReScript files in the project.

npm run start will start a process that watches the project and automatically recompiles whenever anything changes.

Next, create a bsconfig.json file inside the same directory, with the following contents:
{
 "name": "your-project-name",
 "sources": [
   {
     "dir": "src",
     "subdirs": true
   }
 ],
 "package-specs": [
   {
     "module": "commonjs",
     "in-source": true
   }
 ],
 "suffix": ".bs.js",
 "bs-dependencies": []
}

The dir field specifies which directory ReScript source files are located, in this case under the folder src. For every ReScript file Foo.res under src, the compiler will output a JavaScript file named Foo.bs.js in the same location as the original source.

Now we’re ready to write some ReScript!

First ReScript Program

Source files in ReScript have the extension .res. We can write a simple Hello World program by creating a file at src/HelloWorld.res with the following contents:
Js.log("hello, world")

ReScript is a compiled language – this means that the ReScript files that we write are not being run directly by the browser or Node.js. The compiler checks to make sure our ReScript code is valid – syntax is correct, function calls and values are the right types, etc. – and then it compiles the ReScript files into JavaScript. The browser or Node.js will run the JavaScript the same way they would for JavaScript we wrote by hand.

Run the compiler using npm run build. You will see the compiled output in src/HelloWorld.bs.js, which will have the following contents:
console.log("hello, world");

You can run the JavaScript file using node src/HelloWorld.bs.js to print “hello, world” to the terminal.

Since ReScript compiles to JavaScript, it can be used for both client and server applications in a variety of environments – your browser, Node.js, etc. For the purposes of this book, we will be executing ReScript programs in Node.js.

As you read through the examples in the book, I encourage you to copy the examples into your code editor or the ReScript playground at https://rescript-lang.org/try so that you can compile and run the programs yourself. As you experiment with ReScript for yourself, make sure to inspect the compiled JavaScript output of your ReScript programs to get a deeper understanding of how ReScript works under the hood. You’ll find that the generated JavaScript code is quite readable!

Table of Contents
About the Author
Danny Yang

is a professional software engineer at Meta working on infrastructure for WhatsApp. He has previously worked on Facebook Messenger, including the web interface which was written in ReScript. His technical interests include functional programming, compilers, and data visualization, which he writes about on his blog at www.yangdanny97.github.io.

 
About the Technical Reviewer
German Gonzalez-Morris

is a software architect/engineer working with C/C++, Java, and different application containers, in particular with WebLogic Server. He has developed various applications using JEE, Spring, and Python. His areas of expertise also include OOP, Java/JEE, Python, design patterns, algorithms, Spring Core/MVC/security, and microservices. German has worked with performance messaging, RESTful API, and transactional systems. For more information about him, visits www.linkedin.com/in/german-gonzalez-morris.

 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset