Skip to content

Commit

Permalink
Add Try.@return (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkf authored Apr 24, 2022
1 parent 50d6d40 commit f6f9faa
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/Try.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ end

macro and_return end
function var"@?" end
function var"@return" end

function and_then end
function or_else end
Expand Down
12 changes: 12 additions & 0 deletions src/branch.jl
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ macro and_return(ex)
end
end

const var"@_return" = Try.var"@return"
macro _return(ex)
quote
br = branch($(esc(ex)))
if br isa Continue
return valueof(br)
else
valueof(br)
end
end
end

function Try.and_then(f, result)
br = branch(result)
if br isa Continue
Expand Down
49 changes: 49 additions & 0 deletions src/docs/@return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
Try.@and_return result -> result′

Evaluate `f(value)` if `result` is a "success" wrapping a `value`; otherwise, a "failure"
`value` as-is.

| Invocation | Equivalent code |
|:--- |:--- |
| `@and_return Ok(value)` | `value` |
| `@and_return err::Err` | `return err` |
| `@and_return Some(value)` | `value` |
| `@and_return nothing` | `return nothing` |

See also: [`@?`](@ref) [`and_then`](@ref), [`or_else`](@ref).

# Extended help

## Examples

Let's define a function `nitems` that works like `length` but falls back to iteration-based
counting:

```julia
using Try, TryExperimental

function trygetnitems(xs)
Try.@and_return trygetlength(xs)
Ok(count(Returns(true), xs))
end

nitems(xs) = Try.unwrap(trygetnitems(xs))

nitems(1:3)

# output
3
```

`nitems` works with arbitrary iterator, including the ones that does not have `length`:

```julia
ch = foldl(push!, 1:3; init = Channel{Int}(3))
close(ch)

nitems(ch)

# output
3
```

10 changes: 9 additions & 1 deletion test/TryTests/src/test_tools.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ function nitems(xs)
end |> Try.unwrap
end

function nitems2(xs)
Try.@return trygetlength(xs)
count(Returns(true), xs)
end

function test_and_return()
@test Try.unwrap(trygetnitems(1:3)) == 3

Expand All @@ -30,14 +35,17 @@ function test_and_return()
@test Try.unwrap(trygetnitems(ch)) == 3
end

function test_or_else()
function check_nitems(nitems)
@test nitems(1:3) == 3

ch = foldl(push!, 1:3; init = Channel{Int}(3))
close(ch)
@test nitems(ch) == 3
end

test_or_else() = check_nitems(nitems)
test_return() = check_nitems(nitems2)

try_map_prealloc(f, xs) =
Try.and_then(trygetlength(xs)) do n
Try.and_then(trygeteltype(xs)) do T
Expand Down

0 comments on commit f6f9faa

Please sign in to comment.