Open
Description
I decided to take a bit to sketch out an alternative strawman, to see what I could do. Key takeaways:
- Coming up with a concise, well-defined syntax and semantics set is hard. As if that wasn't already obvious, though... 😄
- I had to create an additional implicit context channel to avoid
this
conflicting issues. It was much better than introducing this footgun:forEach(array) do (item) { this.consume(item) }
. - I had to figure out a better system to solve the scoping issue, and I decided to settle on no sigil on top-level DSLs,
@
for dependent DSLs, and tentatively::
for top-level control flow DSLs and:
for dependent control flow DSLs. I know the former could conflict with decorators and the latter with labels, but I made mention of how to address it (as in, decorators and labels come first, respectively). - Managing control flow is incredibly hard, even at the conceptual level. It's bad enough to just incorporate synchronous, immediate values into the mix, but add the ability to suspend the context, and I quickly had to jump to coroutines, just to have a sane execution model for the DSLs themselves.
- Managing completions without reifying them is pretty difficult to come up with solutions for. It wasn't exactly a simple thought process to go from reified completions to just using syntax. I used
try
/catch
as a base because they already deal with abrupt completions. - I tried dealing with the exact completions in the spec when modeling the control flow DSLs, but I found a few complications and glitches with that reasoning (and why I opted to model my "inline completions" based on outside behavior instead):
break
could mean the DSL itself, or it could mean an outer loop.continue
is really just a glorified block-levelreturn
, so there's little point in discerning them.return
breaks out of the loop and triggers the same exit sequence asbreak
does.throw
can work a lot likereturn
, but it can also just be an error handleable by the DSL itself.- Sometimes, you want to short-circuit and return a value for the DSL's callee, like in the
select
example here in this repo's README. This can't be modeled with a completion in terms of the current spec.
Here's a few other features specific to my rendition:
- The implicit scope is accessible, and I do make it possible to read from and write to members of the context, to make it much more transparent and user-friendly.
- I also took into account the possibility of computed properties, and tried to support that use case.
- I found it easier to treat control flow arguments as thunks, and similarly, I made the syntactic variant use call-by-name, rather than call-by-value.
/cc @samuelgoto @rwaldron
Metadata
Metadata
Assignees
Labels
No labels