glom
glom copied to clipboard
STOP/SKIP raise StopGlom(), ContinueGlom()?
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
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?
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
(Note that, for the moment, it's possible for BadSpec to come at runtime. glompilation may change that, but BadSpec may remain a combination runtime/compiletime thing.)
On Tue, Jun 30, 2020 at 12:59 PM Kurt Rose [email protected] wrote:
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
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/mahmoud/glom/issues/156#issuecomment-652011818, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA7ZEKT55BPWARAJKJQTNLRZI725ANCNFSM4OKIJGMQ .
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
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
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