官术网_书友最值得收藏!

File modules

It turns out we've already made some modules! Reason treats the .re source files as modules, so our src/Ch01/Ch01_Demo.re and src/Ch02/Ch02_Demo.re files are automatically available as modules, with the names Ch01_Demo and Ch02_Demo, respectively. In the Reason world, these are called implementation files. We will informally refer to them as file modules.

Reason names file modules purely from their file names, ignoring their directory nesting. It makes every module automatically available from every other module, regardless of where they are physically in the project. This is why we were careful to name our modules with chapter prefixes; otherwise, files from different chapters but with the same names would confuse the compiler.

Let's take advantage of Reason's automatic module resolution, by creating a new (file) module that refers to something in an existing module:

/* src/Ch03/Ch03_Greet.re */
let greet(person: Ch02_Demo.person) = /* (1), (2), (3) */
"Hello, " ++ /* (4), (5) */
person.name ++
" with ID " ++
string_of_int(person.id) ++ /* (6) */
"!";

Here we're defining a function that knows how to greet people with a name and an ID. There are a few things happening in this example (marked by the numbered comments):

  1. We assign a type to the person function parameter by appending a colon followed by the type. You can read this as "person has type c h 0 2 demo dot person". We can assign types to any function parameters in Reason; they are almost always optional though, because of type inference. In this case, we wanted to be explicit because of a subtle issue: there are actually two different record types (person and company) with the name and id fields in the Ch02_Demo module, and we need to distinguish between them.
  2. Function definitions have a body consisting of a single expression; this can also be a compound expression delimited by brackets (we'll see examples later).
  3. We can have a person value and a person type–they don't clash because Reason stores them separately, in the static and dynamic environments.
  4. Reason is whitespace-insensitive; you can lay out your code any way you want, as long as you separate bindings with a semicolon. For most codebases, you would actually just use the Reason formatter tool, refmt, which would automatically take care of all formatting.
  5. The ++ operator in Reason concatenates two strings (and nothing else!) together.
  6. person.id is an int, so we can't concatenate it with its surrounding stringsunless we convert it to a string with the built-in string_of_int function. Reason has strict, strong typing, and doesn't implicitly convert between types (not even between int and float variables).

To understand what Reason is doing for us, let's look at the relevant part of the output JavaScript:

// src/Ch03/Ch03_Greet.bs.js
function greet(person) {
return "Hello, "
+ person[1]
+ " with ID "
+ String(person[0])
+ "!";
}
I've cleaned and rearranged the JavaScript output somewhat, without changing its meaning.

As usual, we see the types are completely erased, and the output is concerned only with values. Based on the types, though, the Reason compiler knew to access the person's name at array index 1 and ID at index 0. Also, it knows to ensure that person[0] gets converted into a string by using the JavaScript string constructor.

In the JavaScript world, we'd say that such a conversion is unnecessary. But in the statically typed Reason world, the compiler keeps a tally of the types of all values and ensures they interact only according to the rules of their types. Thus we ensure that a number can't accidentally be added to a series of strings.

On a larger scale, notice that the fact that Reason files are modules is not directly visible in the JavaScript output codeexcept that the Reason files are directly compiled, with a one-to-one relationship, to JavaScript modules.

主站蜘蛛池模板: 福清市| 汨罗市| 南江县| 贵溪市| 丹巴县| 习水县| 惠水县| 博爱县| 静海县| 麻栗坡县| 宁乡县| 西乡县| 容城县| 丰城市| 班戈县| 静安区| 灵宝市| 顺昌县| 重庆市| 兴和县| 天门市| 张家川| 洮南市| 柘荣县| 黄浦区| 巩留县| 电白县| 东乌珠穆沁旗| 达孜县| 喀喇沁旗| 霍林郭勒市| 沙河市| 水城县| 新营市| 惠安县| 雷波县| 二手房| 大悟县| 若尔盖县| 昌吉市| 鄂尔多斯市|