question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Short-circuit does not work for me in pipe()

See original GitHub issue

Describe the bug Short-circuit does not work for me in pipe(). Maybe i’m using this function in a wrong way. If so, please tell me how it should be.

Thank you.

To Reproduce Execute this code with Expression 2.0.0:

from expression import pipe, effect, Ok
from expression.core.option import Nothing


@effect.result[int, Exception]()
def mulby10(x):
    yield from Ok(x * 10)
 
@effect.option[int]()
def divbyzero(x):
    try:
        yield from Ok(x / 0)
    except Exception as exn:
        yield from Nothing

def main():
    v = 1
    res = pipe(
        v,
        divbyzero,
        mulby10
        )
    print(f"{res=}")

if __name__ == "__main__":
    main()

It executes mulby10 after divbyzero returns Nothing and shows error:

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/Users/davaeron/repos/automation/automation/cli.py", line 18, in main
    res = pipe(
  File "/Users/davaeron/repos/automation/__pypackages__/3.10/lib/expression/core/pipe.py", line 136, in pipe
    return compose(*fns)(value)
  File "/Users/davaeron/repos/automation/__pypackages__/3.10/lib/expression/core/compose.py", line 136, in _compose
    return reduce(lambda acc, f: f(acc), fns, source)
  File "/Users/davaeron/repos/automation/__pypackages__/3.10/lib/expression/core/compose.py", line 136, in <lambda>
    return reduce(lambda acc, f: f(acc), fns, source)
  File "/Users/davaeron/repos/automation/__pypackages__/3.10/lib/expression/core/builder.py", line 96, in wrapper
    result = self._send(gen, done)
  File "/Users/davaeron/repos/automation/__pypackages__/3.10/lib/expression/core/builder.py", line 52, in _send
    yielded = gen.send(value)
  File "/Users/davaeron/repos/automation/automation/cli.py", line 7, in mulby10
    yield from Ok(x * 10)
TypeError: unsupported operand type(s) for *: 'Nothing_' and 'int'

Expected behavior res=Nothing after divbyzero function, mulby10 should be unexecuted

Additional context

  • OS MacOS 12.4
  • Expression version: 2.0.0
  • Python version: 3.10.4

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5

github_iconTop GitHub Comments

1reaction
dbrattlicommented, Jul 8, 2022
from expression import pipe, effect, Ok, Nothing, option


@effect.option[int]()
def mulby10(x: int):
    yield x * 10


@effect.option[int]()
def divbyzero(x: int):
    try:
        yield (x // 0)
    except Exception:
        yield from Nothing


def main():
    v = 1
    res = pipe(
        v,
        divbyzero,
        option.bind(mulby10),
    )
    print(f"{res=}")


if __name__ == "__main__":
    main()
0reactions
pertsevdscommented, Jul 9, 2022
from functools import reduce
from typing import Any
from expression import effect, Error, Ok


class DivisionByZeroError(Error):
    def __init__(self, error="Division by zero"):
        super().__init__(error)
    def bind(self, mapper):
        return self

class OtherError(Error):
    def __init__(self, error="Other error"):
        super().__init__(error)
    def bind(self, mapper):
        return self


@effect.result[int, Exception]()
def mulby10(x: int):
    try:
        yield (x * 10)
    except Exception:
        yield from OtherError()

@effect.result[int, Exception]()
def divbyzero(x: int):
    try:
        yield (x // 0)
    except Exception:
        yield from DivisionByZeroError()


def bound_compose(*fns):
    def _compose(source: Any) -> Any:
        match source:
            case Ok():
                return reduce(lambda acc, f: acc.bind(f), fns, source)
            case Exception():
                return source
            case _:
                return reduce(lambda acc, f: acc.bind(f), fns, Ok(source))
    return _compose

def bound_pipe(__value: Any, *fns) -> Any:
    return bound_compose(*fns)(__value)

def main():
    v = 1
    res = bound_pipe(
        v,
        divbyzero,
        mulby10
    )
    match res:
        case Ok(value):
            print(f"{value=}")
        case DivisionByZeroError(e) | OtherError(e):
            print(e)
        case _:
            print("Not implemented.")


if __name__ == "__main__":
    main()

Something like this? Does this looks reasonable?

Read more comments on GitHub >

github_iconTop Results From Across the Web

Closed, Open, and Short Circuits - Electronics - Dummies.com
This article explains in an easy-to-understand way what open, closed, and short circuits are, using a simple flashlight as an example.
Read more >
What are the conditions for regex (|) pipe operator short ...
The pipe/or ( | ) operator in regex is supposed to short circuit. However, in the examples below, the matches do not seem...
Read more >
Electrical Short Circuit - Types, Causes and Prevention
A short circuit is when there is a low resistance connection between two conductors supplying electrical power to a circuit. This would generate...
Read more >
Problem with short circuit
Resistance is defined as the ratio of voltage across an object (the 'resistor') to current flowing through it. It doesn't matter if other ......
Read more >
Logical OR (||) - JavaScript - MDN Web Docs - Mozilla
Short circuit means that the expr part above is not evaluated, ... effects of doing so do not take effect (e.g., if expr...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found