Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STOP/SKIP raise StopGlom(), ContinueGlom()? #156

Open
kurtbrose opened this issue Jun 28, 2020 · 6 comments
Open

STOP/SKIP raise StopGlom(), ContinueGlom()? #156

kurtbrose opened this issue Jun 28, 2020 · 6 comments

Comments

@kurtbrose
Copy link
Collaborator

rather than scanning one level for STOP and SKIP literals, should instead STOP and SKIP have a glomit() which raises StopGlom() and ContinueGlom()?

then, specs for which these make sense can do try/except (StopGlom) within their own glomit()

this gives similar behavior to break and continue keywords in python that they rise to the closest enclosing loop, and it is an error if there is no enclosing loop

@mahmoud
Copy link
Owner

mahmoud commented Jun 30, 2020

I think the names'd be like _GlomStop and _GlomContinue, but also, they're basically never going to be raised, right? I imagine that those internal exceptions (as they start to appear) might at most be converted to BadSpec at the top?

@kurtbrose
Copy link
Collaborator Author

yup, 100%

these should have the same semantics as BadSpec -- if they are uncaught that is like having a break outside of a loop in python; syntax error

@mahmoud
Copy link
Owner

mahmoud commented Jun 30, 2020 via email

@kurtbrose
Copy link
Collaborator Author

kurtbrose commented Jul 6, 2020

this may also dovetail into "breadcrumbs" / branching

if we want SKIP and STOP to be handled more centrally by _glom dispatching rather than manually one-by-one in each spec, that might mean having a way to externalize "I'm an iterator; here is my state, here is my current position"

so you could imagine:

def _glom(spec, target, scope):
    result = spec.glomit(target, scope)
    if iterable(result):
        def result_stream():
            while 1:  # assuming underlying StopIteration just bubbles up
                try:
                    yield result.next()
                except GlomContinue:
                    pass
        state = spec.blank()
        try:
            for item in result_stream():
                spec.add(state, item)
        except GlomBreak:
               pass
        return state

@kurtbrose
Copy link
Collaborator Author

or maybe it could just be a helper function for iterable-specs; basically catch Continue "inside the loop", catch Break "outside the loop"

that code pattern is worth abstracting, and by re-using it all over the place we can get broadly compatible / similar behaviors

@kurtbrose
Copy link
Collaborator Author

the most useful pattern of "SKIP as value" is things like Check(..., default=SKIP) or Coalesce(..., default=SKIP)

one alternative to this would be if default used a new ArgSpec, which basically left all atomic values alone, but iterated on list, tuple, dict, set, etc

basically ArgSpec = Fill except it doesn't even call functions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants