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.

Think about typed do-notation

See original GitHub issue

I have removed @pipeline in 0.14 release. It had lots of problems:

  1. It was not working properly with Failure types: #90
  2. It had problems with unwrapping complex values like IOResult and FutureResult
  3. It had problems unwrapping containers of different types (you were not allowed to unwrap both Maybe and Result in the same @pipeline
  4. It was encouraging imperative code in a functional codebase

I would love to have some solution instead! But, no ideas about how it should work or look like. So, any ideas are welcome.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:18 (10 by maintainers)

github_iconTop GitHub Comments

4reactions
bgroundscommented, Jul 14, 2021

Currently I am thinking about this API:

assert do(
   x + y
   for x in wrap(Some(1))
   for y in wrap(Success(2))
) == 3

But, this API still does not work properly with IO values. How can we unwrap IO in this comprehension safely? It does mean that for z in wrap(IO(1)) should return raw 1 value, but the result of do(...) would have IO type on top of it.

Ideas?! 💯

A couple of thoughts here:

  • I don’t believe you can typically mix different types of monads in the same do block (in pure functional languages that enforce strong static types). This is the problem that monad transformers solve. In this particular case, you’d probably just convert your Maybe value into a Result value and use 2 Result values in the do block.
  • I think the result of do(...) should be wrapped in IO. 3 is a pure value, but x + y happens in the impure IO context. Once you enter IO, you cannot get back; you just have to keep working in IO.
  • what is wrap? Is it just a way to turn a monadic type into a generator? I wonder if there’s a way to bake generator functionality into the monadic types themselves so you could avoid the wrap function…
  • I think using generator expressions for do notation is a really cool idea. I don’t know if they’re equally powerful, but this reminds me of LINQ in C#. Language-Ext is a comprehensive C# library that uses LINQ for do notation, which could be a handy reference for this work.
1reaction
papavercommented, Aug 27, 2020

@sobolevn i ended up going the generator route as it resulted in the cleanest code while still looking like python. all the other implementations i ran into were fairly gross looking and convoluted to force the code to do something it wasn’t meant for (like the decorator with dozens of yields). the for comprehension was was able to do a form of ‘lifting’ for free, cleanly.

i actually use that pattern in code all the time now. most people just don’t understand the power of the for comprehension.

    # run validator on cut data, convert errors into issues as well
    def tryValidation(validator, cutData):
        idx, cut, take, shot = cutData
        def toIssue(e):
            return {
                'issue'     : 'ValidationIssue',
                'cut_idx'   : idx,
                'shot'      : shot and shot.code or None,
                'take'      : take and take.code or None,
                'validator' : validator.__name__,
                'error'     : repr(e) }
        return Try(validator, cutData).recover(toIssue)

    # keep track of all the issues found
    issues = []
    def validateCutlist(cutlist, validators):
        [issues.append(issue)
         for validator in validators
         for cutData in cutlist
         for issue in tryValidation(validator, cutData)
             if is_some(issue)]

personally i think typed python is a step backwards so i haven’t messed with it. python is extremely powerful functionally without types.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Connotation and Denotation
Denotation is when you mean what you say, literally. Connotation is created when you mean something else, something that might be initially hidden....
Read more >
What Is Denotation? Definition of Denotation, With Examples ...
Denotation is the objective meaning of a word. The term comes from the Latin word “denotationem,” meaning “indication.” The denotation of a ...
Read more >
Denotation & Connotation in Type - Study.com
Denotation in Type​​ The first step is determining what your message will actually say, the definition of the words. Often, this will come...
Read more >
Denotation Examples and Meaning | YourDictionary
Learning about denotation starts by understanding its meaning. Find the definition along with several examples across literature and even zodiac signs here.
Read more >
connotation vs. denotation : Choose Your Words
Denotation means the literal meaning of a word or name. Although Paris might make you think of romance, its denotation is simply "the...
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