Closed robrix closed 8 years ago
This doesn’t work due to what I currently believe to be a Swift bug.
I think I’ll go to +
instead of ++
for starters.
:anguished: +
has the same precedence as |
!
%(a, b, c, d, e) --> { … }
would be very nice indeed! As would be $3
and alike. ++
Going to have to hunt down the Swift bugs preventing %(a, b, c, d, e)
from working presently and file some radars.
let concatenated1 = %(a, b, c, d, e) // fails
let concatenated2 = (%)((a, b, c, d, e)) // succeeds
Should we call it "swisp" or "lift"?
I wish I could star comments on here; I’ll pretend I can anyway: :star:
The other problem with %(a, b, c, d, e)
(or, equally, concatenate(a, b, c, d, e)
) is ()
. Currently ()
is used to ignore a term, dropping it from the parse tree. The ignore
operator maps its argument to ()
, and concatenation, alternation, and repetition all treat it appropriately:
a ++ ignore(b) ++ c // => (A, C)
a | ignore(b) // => A?
ignore(a)* // => ()
Seeing as actually dropping the void parse trees occurs in the ++
, |
, and *
(etc) operators, we’ve actually got to have four different definitions of ++
:
A
and B
()
and A
A
and ()
()
and ()
(because otherwise ()
and ()
is ambiguous between the above two)It’s bad having to write a different concatenate operator for each arity (2-concatenate, 3-concatenate, etc); it’s really bad having to write 2ⁿ + 2ⁿ⁻¹ + … different ones. In order to support up to 5-tuples, we’d need ~60 functions.
On the other hand, using ()
to drop terms from the parse forest was mostly a way to avoid having to deal with the right-associative tuple tree problem sooner. Maybe it will be acceptable to do --> { a, _, c in … }
…but it is very nice not having to account for whitespace at all.
This issue is actually tracking two different (tho intersecting) issues:
++
is syntactically loud relative to the parsers it’s combining, and(a, (b, (c, (d, e))))
is a horrible parse tree to to deal with in Swift.Using an infix operator allows us to retain the piecewise handling of ()
parsers, eliding them. Maybe we can resolve the second issue orthogonally: by adding an nth
operator for the parse trees:
nth
per tree-arity.…but we can’t implement nth
because we don’t know what its type will be :tired_face:
We can implement at0
, at1
, etc., however.
(I am so very much reminded of the C preprocessor.)
We end up needing two at
n definitions for each arity. I’ll take 2n over 2ⁿ + 2ⁿ⁻¹ + … tho.
Having done that, I can’t recommend anyone ever use it, because Swift’s got some crazy O(_n_²) stuff going on or something and the typechecker caused my laptop to burn my leg.
is the concatenation of three parsers but you as much of the concatenation as the parsers.
is a bit better, and
+
already basically means concatenation forSequenceType
.We could also add overloads for arrays/various arities of tuples:
would be an overload of
-->
applying to 3-tuples of parsers. This would, sadly, need a lot of overloads, but it would also be kind of nice because it would avoid the problem that++
has (as would other infix operators) where you get a right-associative list of pairs instead of an n-tuple. That is,results in a parse tree that looks like
which is really obnoxious to unpack:
d
is$0.1.1.1.0
instead of, say,$3
.Since we probably don’t want to have overrides for every combination of operator, side, and tuple-arity, we could instead do something similar to #15 and use an operator: