BuckleScript

BuckleScript

  • Docs
  • Try
  • API
  • Community
  • Blog
  • Languages iconEnglish
    • 日本語
    • Español
    • Français
    • 한국어
    • Português (Brasil)
    • Русский
    • 中文
    • 繁體中文
    • Help Translate
  • GitHub

›Interop

Intro

  • What & Why
  • Installation
  • New Project
  • Try
  • Concepts Overview
  • Upgrade Guide to v7

Interop

  • Overview
  • Cheatsheet
  • Embed Raw JavaScript
  • Common Data Types
  • Intro to External
  • Bind to Global Values
  • Null, Undefined & Option
  • Object
  • Object 2
  • Class
  • Function
  • Property access
  • Return value wrapping
  • Import & Export
  • Regular Expression
  • Exceptions
  • JSON
  • Pipe First
  • Generate Converters & Helpers
  • Better Data Structures Printing (Debug Mode)
  • NodeJS Special Variables
  • Miscellaneous
  • Browser Support & Polyfills

Build System

  • Overview
  • Configuration
  • Automatic Interface Generation
  • Interop with Other Build System
  • Performance
  • Advanced

Standard Library

  • Overview

Advanced

  • Conditional Compilation
  • Extended Compiler Options
  • Use Existing OCaml Libraries
  • Difference from Native OCaml
  • Compiler Architecture & Principles
  • Comparison to Js_of_ocaml
Edit

Pipe First

BuckleScript has a special |. (or -> for Reason) pipe syntax for dealing with various situations. This operator has many uses.

Pipelining

The pipe takes the item on the left and put it as the first argument of the item on the right. Great for building pipelines of data processing:

a
|. foo b
|. bar
a
->foo(b)
->bar

is equal to

bar(foo a b)
bar(foo(a, b))

JS Method Chaining

JavaScript's APIs are often attached to objects, and often chainable, like so:

const result = [1, 2, 3].map(a => a + 1).filter(a => a % 2 === 0);

asyncRequest().setWaitDuration(4000).send();

Assuming we don't need the chaining behavior above, we'd bind to each case this using bs.send from the previous section:

external map : 'a array -> ('a -> 'b) -> 'b array = "map" [@@bs.send]
external filter : 'a array -> ('a -> 'b) -> 'b array = "filter" [@@bs.send]

type request
external asyncRequest: unit -> request = "asyncRequest"
external setWaitDuration: request -> int -> request = "setWaitDuration" [@@bs.send]
external send: request -> unit = "send" [@@bs.send]
[@bs.send] external map : (array('a), 'a => 'b) => array('b) = "map";
[@bs.send] external filter : (array('a), 'a => 'b) => array('b) = "filter";

type request;
external asyncRequest: unit => request = "asyncRequest";
[@bs.send] external setWaitDuration: (request, int) => request = "setWaitDuration";
[@bs.send] external send: request => unit = "send";

You'd use them like this:

let result = filter (map [|1; 2; 3|] (fun a -> a + 1)) (fun a -> a mod 2 = 0)

let () = send(setWaitDuration (asyncRequest()) 4000)
let result = filter(map([|1, 2, 3|], a => a + 1), a => a mod 2 == 0);

send(setWaitDuration(asyncRequest(), 4000));

This looks much worse than the JS counterpart! Now we need to read the actual logic "inside-out". We also cannot use the |> operator here, since the object comes first in the binding. But |. and -> work!

let result = [|1; 2; 3|]
  |. map(fun a -> a + 1)
  |. filter(fun a -> a mod 2 == 0)

let () = asyncRequest () |. setWaitDuration 400 |. send
let result = [|1, 2, 3|]
  ->map(a => a + 1)
  ->filter(a => a mod 2 === 0);

asyncRequest()->setWaitDuration(400)->send;

Pipe Into Variants

This works:

let result = name |. preprocess |. Some
let result = name->preprocess->Some

We turn this into:

let result = Some(preprocess(name))
let result = Some(preprocess(name))
Last updated on 4/13/2020
← JSONGenerate Converters & Helpers →
  • Pipelining
  • JS Method Chaining
  • Pipe Into Variants