Git Product home page Git Product logo

Comments (14)

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024 1

I'm closing this because python's >>= is too syntactically inflexible to be useful.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024

It look to me like it's syntactically not allowed to chain >>=, though I can't quite tell that from https://docs.python.org/3/reference/grammar.html, but I read it in an article somewhere.

from parsy.

spookylukey avatar spookylukey commented on July 18, 2024

Is there any need for this? I personally have never used the bind function once in all my usage of parsy. In addition, the currently defined operators for parsy are based on parallels with things users are likely to already understand (such as | and +), or on things that have good mnemonics for them (such as << and >> which “point to the important one”), rather than on Haskell operators.

So I'm not sure what the value of this would be - but open to being convinced.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024

Maybe I'm going about it wrong, but I'm using bind a lot for a complicated grammar I have, where I'm trying to progressively parse recursive structures. However my impression is this operator can't be implemented anyway, due to the way the python parser works. I guess at this point I'm just looking for someone to say they agree.

You use bind when you want to pass the result of one parser to another parser, with the ensuing applications, though I'm unable to give a clear explanation of this right now.

For further reading, an introduction to monadic parser combinators (i.e. similar to parsy) using a Haskell-like language is https://www.cs.nott.ac.uk/~pszgmh/monparsing.pdf (sidenote; not everything is implementable in Haskell as given in that document).

See mainly section 2.3 for a quick intro to bind :: Parser a -> (a -> Parser b) -> Parser b
as opposed to seq :: Parser a -> Parser b -> Parser (a,b) or (++) :: Parser a -> Parser a -> Parser a (though the latter comes later in the document). I think ++ is the equivalent to alt - at least the type matches: take two parsers of the same type, and return a parser of the same type (one or the other). (One may reflexively ask "but what if the two parsers are a different type?" - you would encode that by using an Either a b - anyway I digress.)

from parsy.

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024

"However my impression is this operator can't be implemented anyway, " - by which I mean you can only use it once like an assignment operator. - or we could abuse some other syntax and drop the syntactic familiarity to haskell. Hm. :P
Anyway bind is pretty fundamental (it's half of a monad, along with join!).

from parsy.

infinisil avatar infinisil commented on July 18, 2024

@deliciouslytyped I kind of doubt python allows chaining of >>= like in Haskell, but ignoring that, can you show a good example of how it improves code? Like comparing the same code with bind and >>=.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024

It's not a big syntactic jump in any direction, one can draw an analogy between a >>= (...) to a.bind(...) quite easily by saying >>= is like .bind, there is no necessity for this to exist, I just thought it would be nice.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024

So, just a sidenote, but I asked and got a good simple example for the necessity of bind!
You need (Edit: well, @generate is a way to do this without explicitly using bind, but that's beside the point) it for parsing context sensitive grammars, and a simple example would be a length-prefixed string.
Exercise left to the reader.

from parsy.

deliciouslytyped avatar deliciouslytyped commented on July 18, 2024

Ok fine, due to prodding from Infinisil (I do dislike left to the reader as much as the next guy - but it really does help if the example is sufficiently easy to do it yourself - but maybe a github issue isn't the right context for that):

(regex("[0-9]+").map(int).bind(lambda n: any_char.times(n).concat())).parse("3lol")

The key thing here is that inside the bind you have a parser parametrized over [part of the result of the parser to the left of the bind], namely the length.

from parsy.

jneen avatar jneen commented on July 18, 2024

This would be fine by me - my only concern is that >>= is an assignment operator in Python, so it might cause problems/break expectations if we were to return a whole new thing. If you can convince me that the precedence and return value semantics are consistent I'm all for it, but I'm concerned they might not be. For example,

a = b >>= f1 >>= f2

from parsy.

jneen avatar jneen commented on July 18, 2024

Though I do take @spookylukey's side here - if you're doing complicated chains like that you may just consider using @generate, which gives you a lot of flexibility. For the above example:

@generate
def a():
    res = yield b
    res = yield f1(res)
    return f2(res)

from parsy.

spookylukey avatar spookylukey commented on July 18, 2024

@jneen thanks for adding the explanation I should have written at first - the existence of generate is why I never use bind directly. The "length prefixed string" example is in fact in the docs already - https://parsy.readthedocs.io/en/latest/ref/generating.html#using-values-already-parsed . The verbosity and limitations of lambdas in Python make this a much more attractive option IMO.

from parsy.

jneen avatar jneen commented on July 18, 2024

Agreed! Those docs are beautiful by the way.

from parsy.

Profpatsch avatar Profpatsch commented on July 18, 2024

bind makes a parser context sensitive, too. Something to keep in mind, so maybe it’s good to not make it too easy to use bind.

from parsy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.