Skip to content

Commit

Permalink
Merge pull request #620 from tweag/task/rename-stdlib-modules-2
Browse files Browse the repository at this point in the history
Rename stdlib modules (remove trailing `s`)
  • Loading branch information
yannham committed Feb 25, 2022
2 parents 417ad5f + 9753deb commit c21cf28
Show file tree
Hide file tree
Showing 54 changed files with 280 additions and 282 deletions.
23 changes: 13 additions & 10 deletions benches/functions/church.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,19 @@
id = fun x => x,

run = fun n =>
let orig = generate id n in
let encoded = lists.map encode orig in
let base = generate id n in

let listChurch = lists.map (fun nChurch =>
add (mult (encode 3) nChurch) (encode 5))
encoded in
let sumChurch = lists.fold (fun accChurch nChurch => add accChurch nChurch)
(encode 0) listChurch in
let encoded =
base
|> list.map encode
|> list.map (fun nChurch =>
add (mult (encode 3) nChurch) (encode 5))
|> list.fold add (encode 0) in

let list = lists.map (fun n => 3*n + 5) orig in
let sum = lists.foldl (fun acc n => acc + n) 0 list in
decode sumChurch == sum,
let decoded =
base
|> list.map (fun n => 3*n + 5)
|> list.foldl (fun acc n => acc + n) 0 in

decode encoded == decoded,
}
16 changes: 8 additions & 8 deletions benches/lists/fold.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,29 @@ let letter | strings.CharLiteral -> strings.CharLiteral = fun n => strings.charF
right = {
strings = {
run = fun n =>
lists.fold (fun x y => x ++ "a") (lists.generate n (fun n => letter n))
list.fold (fun x y => x ++ "a") (list.generate n (fun n => letter n))
},
nums = {
run = fun n =>
lists.fold (fun x y => x*y + (x - y)) (lists.generate n (fun n => n/2))
list.fold (fun x y => x*y + (x - y)) (list.generate n (fun n => n/2))
},
lists_ = {
list_ = {
run = fun n =>
lists.fold (fun x acc => [x] ++ acc) (lists.generate n (fun n => [n]))
list.fold (fun x acc => [x] ++ acc) (list.generate n (fun n => [n]))
},
},
left = {
strings = {
run = fun n =>
lists.foldl (fun x y => x ++ "a") (lists.generate n (fun n => letter n))
list.foldl (fun x y => x ++ "a") (list.generate n (fun n => letter n))
},
nums = {
run = fun n =>
lists.foldl (fun x y => x*y + (x - y)) (lists.generate n (fun n => n/2))
list.foldl (fun x y => x*y + (x - y)) (list.generate n (fun n => n/2))
},
lists_ = {
list_ = {
run = fun n =>
lists.foldl (fun x acc => [x] ++ acc) (lists.generate n (fun n => [n]))
list.foldl (fun x acc => [x] ++ acc) (list.generate n (fun n => [n]))
},
}
}
2 changes: 1 addition & 1 deletion benches/lists/map.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let f = { f = fun x => if (x == 0) then 0 else f (x - 1) }.f in
{
run = fun n =>
lists.map f (lists.generate functions.id n)
list.map f (list.generate function.id n)
}
10 changes: 5 additions & 5 deletions benches/lists/pipe.ncl
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
run = fun n =>
let l = lists.generate (fun n => n*n) n in
let l = lists.filter (fun n => n % 2 == 0) l in
let l = lists.map (fun n => [n, n+1]) l in
let l = lists.flatten l in
lists.partition (fun n => n % 2 == 0) l
let l = list.generate (fun n => n*n) n in
let l = list.filter (fun n => n % 2 == 0) l in
let l = list.map (fun n => [n, n+1]) l in
let l = list.flatten l in
list.partition (fun n => n % 2 == 0) l
}
2 changes: 1 addition & 1 deletion benches/lists/sort.ncl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
let nums = [3288, 2438, 1462, 437, 17, 1929, 2595, 2702, 831, 3685, 1906, 420, 2646, 1906, 2539, 184, 299, 3455, 2320, 1471, 1812, 3837, 1000, 2097, 945, 1973, 1090, 2285, 2272, 1045, 848, 3194, 2113, 537, 1953, 561, 2082, 2416, 3182, 3660, 3379, 1458, 39, 2720, 2469, 811, 837, 548, 3021, 2961, 2860, 2092, 942, 2511, 1769, 168, 130, 2755, 2552, 1057, 2619, 1848, 2373, 2012, 2339, 2521, 3593, 2784, 3094, 2260, 1994, 690, 828, 1298, 3434, 2929, 2188, 1285, 3783, 3635, 971, 3334, 87, 1578, 1363, 533, 3634, 1874, 830, 3976, 1140, 789, 1483, 1966, 1626, 3552, 2968, 3301, 749, 2576] in
let ascending = fun x y => if x < y then `Less else if (x == y) then `Equal else `Greater in
{
run = fun n => lists.sort ascending nums
run = fun n => list.sort ascending nums
}
8 changes: 4 additions & 4 deletions benches/numeric/reduce.ncl
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
sum = {
run = fun n =>
let numbers = lists.generate functions.id n in
lists.foldl (fun acc x => acc + x) 0 numbers
let numbers = list.generate function.id n in
list.foldl (fun acc x => acc + x) 0 numbers
},

product = {
run = fun n =>
let numbers = lists.generate functions.id n in
lists.foldl (fun acc x => acc * x) 1 numbers
let numbers = list.generate function.id n in
list.foldl (fun acc x => acc * x) 1 numbers
},
}
10 changes: 5 additions & 5 deletions benches/numeric/scalar.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
if l1 == [] || l2 == [] then
[]
else
[f (lists.head l1) (lists.head l2)]
@ map2 f (lists.tail l1) (lists.tail l2),
[f (list.head l1) (list.head l2)]
@ map2 f (list.tail l1) (list.tail l2),

run = fun n =>
let left = lists.generate functions.id n in
let right = lists.generate (fun n => n*n/2) n in
let left = list.generate function.id n in
let right = list.generate (fun n => n*n/2) n in
let prod = map2 (fun x y => x * y) left right in
lists.foldl (fun x y => x + y) 0 prod
list.foldl (fun x y => x + y) 0 prod
}
4 changes: 2 additions & 2 deletions benches/records/countLetters.ncl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
run = fun s =>
let updateDict = fun dict char =>
if records.has_field char dict then
if record.has_field char dict then
dict -$ char & {"#{char}" = dict."#{char}" + 1}
else
dict & {"#{char}" = 1} in
lists.foldl updateDict {} (strings.chars s)
list.foldl updateDict {} (string.chars s)
}
16 changes: 8 additions & 8 deletions benches/records/merge.ncl
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
{
run = fun n m =>
let prefix = fun n =>
let l = lists.generate (fun _n => "a") n in
lists.foldl (fun x y => x ++ y) "" l in
let l = list.generate (fun _n => "a") n in
list.foldl (fun x y => x ++ y) "" l in
let makeRecStep = fun state k =>
let name = state.prevName ++ (strings.from_num k) in
let name = state.prevName ++ (string.from_num k) in
{
value = state.value & {"#{name}" = {}},
prevName = name,
} in
let topList = lists.generate functions.id m in
let topList = list.generate function.id m in
let makeRec = fun m =>
let l = lists.generate functions.id n in
let result = lists.foldl makeRecStep {value = {}, prevName = prefix m} l in
let l = list.generate function.id n in
let result = list.foldl makeRecStep {value = {}, prevName = prefix m} l in
result.value in
let l = lists.map makeRec topList in
lists.foldl (fun r1 r2 => r1 & r2) {} l
let l = list.map makeRec topList in
list.foldl (fun r1 r2 => r1 & r2) {} l
}
2 changes: 1 addition & 1 deletion benches/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn round_trip(c: &mut Criterion) {
path.push("benches/serialization/input.json");

let content = format!(
"builtins.serialize `Json (import \"{}\")",
"builtin.serialize `Json (import \"{}\")",
path.to_string_lossy(),
);

Expand Down
80 changes: 40 additions & 40 deletions doc/manual/contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,25 @@ properties. Let us see how to define our very own contract. We start the REPL

```nickel
let IsFoo = fun label value =>
if builtins.is_str value then
if builtin.is_str value then
if value == "foo" then
value
else
contracts.blame_with "not equal to \"foo\"" label
contract.blame_with "not equal to \"foo\"" label
else
contracts.blame_with "not a string" label
contract.blame_with "not a string" label
```

A custom contract is a function of two arguments:

- A `label`. Provided by the interpreter, the label contains tracking information
for error reporting. Its main usage is to be passed to `contracts.blame` or
`contracts.blame_with` when the contract isn't satisfied.
for error reporting. Its main usage is to be passed to `contract.blame` or
`contract.blame_with` when the contract isn't satisfied.
- The value being checked.

Upon success, the contract must return the original value. We will see the reason why
in the [laziness](#laziness) section. To signal failure, we use
`contracts.blame` or its variant `contracts.blame_with` that takes an additional
`contract.blame` or its variant `contract.blame_with` that takes an additional
error message as a parameter. `blame` immediately aborts the execution and
reports a contract violation error.

Expand Down Expand Up @@ -103,10 +103,10 @@ error, as well as various other data) is enough to understand the error. In this
case, we can write our contract more succinctly as:

```nickel
let IsFoo = contracts.from_predicate ((==) "foo")
let IsFoo = contract.from_predicate ((==) "foo")
```

`contracts.from_predicate` takes a predicate (a function of one argument that
`contract.from_predicate` takes a predicate (a function of one argument that
returns a boolean) and converts it to a contract. The syntax `(==)` turns the
equality operator `==` into a function, and is a shorthand for
`fun x y => x == y`. The partial application to `(==) "foo"` is then the function
Expand All @@ -117,9 +117,9 @@ the contract is simple enough to not require custom error message.
Here is an example of a port number contract:

```nickel
let Port = contracts.from_predicate (fun value =>
builtins.is_num value &&
nums.is_int value &&
let Port = contract.from_predicate (fun value =>
builtin.is_num value &&
num.is_int value &&
value >= 0 &&
value <= 65535)
```
Expand All @@ -129,8 +129,8 @@ let Port = contracts.from_predicate (fun value =>
Let us consider a contract for bound checking:

```nickel
let Between5And10 = contracts.from_predicate (fun value =>
builtins.is_num value &&
let Between5And10 = contract.from_predicate (fun value =>
builtin.is_num value &&
value >= 5 &&
value <= 10) in
let MyConfig = {
Expand All @@ -141,12 +141,12 @@ let MyConfig = {
Now, we add a new field to our schema, that must be between `0` and `1`:

```nickel
let Between5And10 = contracts.from_predicate (fun value =>
builtins.is_num value &&
let Between5And10 = contract.from_predicate (fun value =>
builtin.is_num value &&
value >= 5 &&
value <= 10) in
let Between0And1 = contracts.from_predicate (fun value =>
builtins.is_num value &&
let Between0And1 = contract.from_predicate (fun value =>
builtin.is_num value &&
value >= 0 &&
value <= 1) in
let MyConfig = {
Expand All @@ -162,17 +162,17 @@ parameters must appear first, before the `label` and `value` arguments:

```nickel
let Between = fun min max =>
contracts.from_predicate (fun value =>
contract.from_predicate (fun value =>
value >= min &&
value <= max) in
// alternative without from_predicate
let BetweenAlt = fun min max label value =>
if builtins.is_num value &&
if builtin.is_num value &&
value >= min &&
value <= max then
value
else
contracts.blame label in
contract.blame label in
let MyConfig = {
level | Between 5 10,
strength | Between 0 1,
Expand All @@ -186,8 +186,8 @@ parametrized contracts, but note that although contracts can be functions, we
will see soon that they can be different objects as well. Even with functions,
contract application behaves slightly differently than bare function
application. Thus, when manually handling a contract `contract`, do not apply it
as a function `contract label value`, but use `contracts.apply`:
`contracts.apply contract label value`. One example of such a contract is a
as a function `contract label value`, but use `contract.apply`:
`contract.apply contract label value`. One example of such a contract is a
`Nullable` contract, that accepts a value that is either null or of some other
given format:

Expand All @@ -196,7 +196,7 @@ let Nullable = fun contract label value =>
if value == null then
value
else
contracts.apply contract label value in
contract.apply contract label value in
// succeeds
null | Nullable Num
// succeeds too
Expand Down Expand Up @@ -307,7 +307,7 @@ nickel>let MyConfig = {
bar | Num,
}
nickel>let config | MyConfig = {bar = 2}
nickel> builtins.serialize `Json config
nickel> builtin.serialize `Json config
"{
"bar": 2,
"foo": "foo"
Expand Down Expand Up @@ -352,7 +352,7 @@ nickel>let Secure = {
must_be_very_secure | Bool = true,
data | Str,
}
nickel>builtins.serialize `Json ({data = ""} | Secure)
nickel>builtin.serialize `Json ({data = ""} | Secure)
"{
"data": "",
"must_be_very_secure": true
Expand Down Expand Up @@ -416,8 +416,8 @@ A list contract checks that the value is a list and applies the parameter
contract to each element:

```
nickel>let VeryBig = contracts.from_predicate (fun value =>
builtins.is_num value
nickel>let VeryBig = contract.from_predicate (fun value =>
builtin.is_num value
&& value >= 1000)
nickel>[1000, 10001, 2] | List VeryBig
error: contract broken by a value.
Expand Down Expand Up @@ -578,24 +578,24 @@ is the rationale behind contracts returning a value. Let us see:

```
let NumBoolDict = fun label value =>
if builtins.is_record value then
if builtin.is_record value then
let check_fields = value
|> records.fields
|> lists.foldl (fun acc field_name =>
if strings.is_match "^\\d+$" field_name then
|> record.fields
|> list.foldl (fun acc field_name =>
if string.is_match "^\\d+$" field_name then
acc // unused and always null through iteration
else
contracts.blame_with "field name `#{field_name}` is not a number" label
contract.blame_with "field name `#{field_name}` is not a number" label
) null in
value
|> records.map (fun name value =>
|> record.map (fun name value =>
let label_with_msg =
contracts.tag "field `#{name}` is not a boolean" label in
contracts.apply Bool label_with_msg value)
|> builtins.seq check_fields
contract.tag "field `#{name}` is not a boolean" label in
contract.apply Bool label_with_msg value)
|> builtin.seq check_fields
else
contracts.blame_with "not a record" label
contract.blame_with "not a record" label
```

There is a lot to unwrap here. Please refer to the [syntax](./syntax.md) section
Expand All @@ -609,9 +609,9 @@ For laziness, the interesting bit happens here:

```
value
|> records.map (fun _name value =>
contracts.apply Bool label value)
|> builtins.seq check_fields
|> record.map (fun _name value =>
contract.apply Bool label value)
|> builtin.seq check_fields
```

This is the final return value of the contract (at least when `value` is a
Expand Down

0 comments on commit c21cf28

Please sign in to comment.