Skip to content

Commit

Permalink
feat(stdlib)!: Replace Result/Option and/or functions with op…
Browse files Browse the repository at this point in the history
…erators (#1821)
  • Loading branch information
alex-snezhko committed Apr 22, 2023
1 parent 246f894 commit 686de7e
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 81 deletions.
24 changes: 13 additions & 11 deletions compiler/test/stdlib/option.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,19 @@ let mut d = "🌾"
assert Option.peek(x => fail "Shouldn't be called", None) == None
assert d == "🌾"

// Option.or
assert Option.or(Some(1), Some(2)) == Some(1)
assert Option.or(Some(1), None) == Some(1)
assert Option.or(None, Some(2)) == Some(2)
assert Option.or(None, None) == None

// Option.and
assert Option.and(Some(1), Some(2)) == Some(2)
assert Option.and(Some(1), None) == None
assert Option.and(None, Some(2)) == None
assert Option.and(None, None) == None
from Option use { (||), (&&) }

// Option.(||)
assert (Some(1) || Some(2)) == Some(1)
assert (Some(1) || None) == Some(1)
assert (None || Some(2)) == Some(2)
assert (None || None) == None

// Option.(&&)
assert (Some(1) && Some(2)) == Some(2)
assert (Some(1) && None) == None
assert (None && Some(2)) == None
assert (None && None) == None

// Option.toResult
assert Option.toResult("Nope", Some(1)) == Ok(1)
Expand Down
24 changes: 13 additions & 11 deletions compiler/test/stdlib/result.test.gr
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,19 @@ Err("Awesome")
) ==
"7"

// or
assert Result.or(Ok(1), Ok(2)) == Ok(1)
assert Result.or(Ok(1), Err(2)) == Ok(1)
assert Result.or(Err(1), Ok(2)) == Ok(2)
assert Result.or(Err(1), Err(2)) == Err(2)

// and
assert Result.and(Ok(1), Ok(2)) == Ok(2)
assert Result.and(Ok(1), Err(2)) == Err(2)
assert Result.and(Err(1), Ok(2)) == Err(1)
assert Result.and(Err(1), Err(2)) == Err(1)
from Result use { (||), (&&) }

// (||)
assert (Ok(1) || Ok(2)) == Ok(1)
assert (Ok(1) || Err(2)) == Ok(1)
assert (Err(1) || Ok(2)) == Ok(2)
assert (Err(1) || Err(2)) == Err(2)

// (&&)
assert (Ok(1) && Ok(2)) == Ok(2)
assert (Ok(1) && Err(2)) == Err(2)
assert (Err(1) && Ok(2)) == Err(1)
assert (Err(1) && Err(2)) == Err(1)

let mut a = 1
let testMut = f => {
Expand Down
41 changes: 14 additions & 27 deletions stdlib/marshal.gr
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ let validateStack = (value, offset) => {

@unsafe
let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
from Option use { (||) as optOr }

let offsetAsInt32 = toGrain(newInt32(offset)): Int32
Set.add(offsetAsInt32, valuesChecked)

Expand Down Expand Up @@ -500,12 +502,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
if (Set.contains(asInt32, valuesChecked)) {
continue
}
error = Option.or(
error,
validateHeap(buf, bufSize, value, valuesChecked)
)
error = optOr(error, validateHeap(buf, bufSize, value, valuesChecked))
} else {
error = Option.or(error, validateStack(value, offset))
error = optOr(error, validateStack(value, offset))
}
}

Expand All @@ -531,12 +530,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
if (Set.contains(asInt32, valuesChecked)) {
continue
}
error = Option.or(
error,
validateHeap(buf, bufSize, value, valuesChecked)
)
error = optOr(error, validateHeap(buf, bufSize, value, valuesChecked))
} else {
error = Option.or(error, validateStack(value, offset))
error = optOr(error, validateStack(value, offset))
}
}

Expand All @@ -562,12 +558,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
if (Set.contains(asInt32, valuesChecked)) {
continue
}
error = Option.or(
error,
validateHeap(buf, bufSize, value, valuesChecked)
)
error = optOr(error, validateHeap(buf, bufSize, value, valuesChecked))
} else {
error = Option.or(error, validateStack(value, offset))
error = optOr(error, validateStack(value, offset))
}
}

Expand All @@ -593,12 +586,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
if (Set.contains(asInt32, valuesChecked)) {
continue
}
error = Option.or(
error,
validateHeap(buf, bufSize, value, valuesChecked)
)
error = optOr(error, validateHeap(buf, bufSize, value, valuesChecked))
} else {
error = Option.or(error, validateStack(value, offset))
error = optOr(error, validateStack(value, offset))
}
}

Expand All @@ -624,12 +614,9 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
if (Set.contains(asInt32, valuesChecked)) {
continue
}
error = Option.or(
error,
validateHeap(buf, bufSize, value, valuesChecked)
)
error = optOr(error, validateHeap(buf, bufSize, value, valuesChecked))
} else {
error = Option.or(error, validateStack(value, offset))
error = optOr(error, validateStack(value, offset))
}
}

Expand Down Expand Up @@ -675,7 +662,7 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
} else {
let numeratorOffset = load(valuePtr, 8n)
let denominatorOffset = load(valuePtr, 12n)
let error = Option.or(
let error = optOr(
validateHeap(buf, bufSize, numeratorOffset, valuesChecked),
validateHeap(buf, bufSize, denominatorOffset, valuesChecked)
)
Expand Down Expand Up @@ -705,7 +692,7 @@ let rec validateHeap = (buf, bufSize, offset, valuesChecked) => {
} else {
None
}
Option.or(numeratorError, denominatorError)
optOr(numeratorError, denominatorError)
} else {
error
}
Expand Down
10 changes: 6 additions & 4 deletions stdlib/option.gr
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,10 @@ provide let peek = (fn, option) => {
* @param optionB: The second option
* @returns The first Option if it is the `Some` variant or the second Option otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `or`
*/
provide let or = (optionA, optionB) => {
provide let (||) = (optionA, optionB) => {
match (optionA) {
Some(x) => optionA,
None => optionB,
Expand All @@ -349,9 +350,10 @@ provide let or = (optionA, optionB) => {
* @param optionB: The second option
* @returns The second Option if both are the `Some` variant or the first Option otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `and`
*/
provide let and = (optionA, optionB) => {
provide let (&&) = (optionA, optionB) => {
match (optionA) {
Some(_) => optionB,
None => optionA,
Expand Down
38 changes: 26 additions & 12 deletions stdlib/option.md
Original file line number Diff line number Diff line change
Expand Up @@ -539,15 +539,22 @@ Returns:
|----|-----------|
|`Option<a>`|The unmodified option|

### Option.**or**

<details disabled>
<summary tabindex="-1">Added in <code>0.2.0</code></summary>
No other changes yet.
### Option.**(||)**

<details>
<summary>Added in <code>next</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>0.2.0</code></td><td>Originally named `or`</td></tr>
</tbody>
</table>
</details>

```grain
or : (optionA: Option<a>, optionB: Option<a>) -> Option<a>
(||) : (optionA: Option<a>, optionB: Option<a>) -> Option<a>
```

Behaves like a logical OR (`||`) where the first Option is only returned if it is the `Some` variant and falling back to the second Option in all other cases.
Expand All @@ -565,15 +572,22 @@ Returns:
|----|-----------|
|`Option<a>`|The first Option if it is the `Some` variant or the second Option otherwise|

### Option.**and**

<details disabled>
<summary tabindex="-1">Added in <code>0.2.0</code></summary>
No other changes yet.
### Option.**(&&)**

<details>
<summary>Added in <code>next</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>0.2.0</code></td><td>Originally named `and`</td></tr>
</tbody>
</table>
</details>

```grain
and : (optionA: Option<a>, optionB: Option<a>) -> Option<a>
(&&) : (optionA: Option<a>, optionB: Option<a>) -> Option<a>
```

Behaves like a logical AND (`&&`) where the first Option is only returned if it is the `None` variant and falling back to the second Option Result in all other cases.
Expand Down
10 changes: 6 additions & 4 deletions stdlib/result.gr
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,10 @@ provide let mapWithDefaultFn = (fnOk, fnErr, result) => {
* @param result2: The second result
* @returns The first Result if it is the `Ok` variant or the second Result otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `or`
*/
provide let or = (result1, result2) => {
provide let (||) = (result1, result2) => {
match (result1) {
Ok(x) => result1,
_ => result2,
Expand All @@ -178,9 +179,10 @@ provide let or = (result1, result2) => {
* @param result2: The second result
* @returns The second Result if both are the `Ok` variant or the first Result otherwise
*
* @since v0.2.0
* @since v0.6.0
* @history v0.2.0: Originally named `and`
*/
provide let and = (result1, result2) => {
provide let (&&) = (result1, result2) => {
match (result1) {
Ok(_) => result2,
Err(_) => result1,
Expand Down
38 changes: 26 additions & 12 deletions stdlib/result.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,15 +265,22 @@ Returns:
|----|-----------|
|`b`|The value produced by one of the mapping functions|

### Result.**or**

<details disabled>
<summary tabindex="-1">Added in <code>0.2.0</code></summary>
No other changes yet.
### Result.**(||)**

<details>
<summary>Added in <code>next</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>0.2.0</code></td><td>Originally named `or`</td></tr>
</tbody>
</table>
</details>

```grain
or : (result1: Result<a, b>, result2: Result<a, b>) -> Result<a, b>
(||) : (result1: Result<a, b>, result2: Result<a, b>) -> Result<a, b>
```

Behaves like a logical OR (`||`) where the first Result is only returned if it is the `Ok` variant and falling back to the second Result in all other cases.
Expand All @@ -291,15 +298,22 @@ Returns:
|----|-----------|
|`Result<a, b>`|The first Result if it is the `Ok` variant or the second Result otherwise|

### Result.**and**

<details disabled>
<summary tabindex="-1">Added in <code>0.2.0</code></summary>
No other changes yet.
### Result.**(&&)**

<details>
<summary>Added in <code>next</code></summary>
<table>
<thead>
<tr><th>version</th><th>changes</th></tr>
</thead>
<tbody>
<tr><td><code>0.2.0</code></td><td>Originally named `and`</td></tr>
</tbody>
</table>
</details>

```grain
and : (result1: Result<a, b>, result2: Result<a, b>) -> Result<a, b>
(&&) : (result1: Result<a, b>, result2: Result<a, b>) -> Result<a, b>
```

Behaves like a logical AND (`&&`) where the first Result is only returned if it is the `Err` variant and falling back to the second Result in all other cases.
Expand Down

0 comments on commit 686de7e

Please sign in to comment.