Comments (14)
I'm closing this because python's >>=
is too syntactically inflexible to be useful.
from parsy.
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.
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.
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.
"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.
@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.
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.
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.
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.
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.
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.
@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.
Agreed! Those docs are beautiful by the way.
from parsy.
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)
- Missing documentation for eof parser? HOT 1
- Improve debugging: peek show next data in errors HOT 5
- Recompute line number for ParseError passed up from .bind
- Improve debugging ergonomics HOT 3
- Inline (explicit) and implicit tracing
- Missing seq import statement in tutorial HOT 1
- Help with parsing that "hangs" HOT 3
- Bug with backtracking and generate? HOT 4
- Parsy 1.3.0 fails to support 'group' keyword of `regex` function HOT 1
- async/await support in generate() HOT 6
- Release HOT 2
- Interested in a version of parsy with type annotations? HOT 3
- Allow providing a default to optional() HOT 2
- maintaining state while parsing HOT 3
- combine fails when nothing is produced by many HOT 2
- [bug] Parser.desc() causes loss of error information, simple fix HOT 2
- alt doesn't use fallback parsers when initial parser has .many()/.sep_by() HOT 1
- Processing list of tokens HOT 1
- Seeking Guidance on Implementing Parser Autocomplete HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from parsy.