Open QuentinOchem opened 3 years ago
match filter (it, p_base_types ().foreach (), many (AdaNode (), 2))
weave standard.out (@ & it & " has an ascendance depth of at least two\n");
For me there are still at least two really strange bits here:
p_base_types ().foreach ()
is an expression, with a property call and a foreach
. You expect that to be called exactly once when the filter is evaluated. Here it's not the case. In some way you could say that it's much more akin to a lambda. I would like to read either of the following:# Property ref version
match filter (it, p_base_types, ...)
# Lambda version
match filter (it, node => node.p_base_types().foreach(), ...)
Also ideally (as discussed before) the foreach would not be needed, and node => node.p_base_types()
and p_base_type
would be equivalent.
child()
as the traversal function and every match accumulated in an or
. So let's imagine instead:# many version
match
query it
through p_base_types
match many (AdaNode (), 2)
# / version
match
query it
through p_base_types
match AdaNode() / AdaNode()
You could imagine that in a regular child
based filter, you can omit the through
, so it could look like
query it
match many (AdaNode(), 2)
I decided to name filter
query
above. Not sure either is perfect. traverse
could be a better choice, and we could still have fold
with a similar syntax I guess.
Aside: I had a big discussion with Romain yesterday about DSLs and how to make them intuitive. For me, after a big chunk of experience, a key principle is to start with a minimal but complete general purpose language, with functions, expressions, etc (you can often omit side effects in a DSL), and then, make the DSLish bit easily understandable in the context of that general purpose language. Else you very quickly end up with something that is very hard to understand for outsiders.
The current implementation of generator suffixes such as fold () and filter () is currently confusing and has annoying limitations. E.g. in an expression like
a.b
denotes an initialit
value,c ()
is the generator to test in the filter. From live discussion, this experimental syntax proves unsuccessful. This RFC proposes two potential reorganization while retaining current semantics.We need to consider two pieces: (1) the function to call in the filter (2) the initial value of
it
For (1), we move that to a parameter. This is still a "magic" lambda in this case, I suggest to discuss lambda in general separately.
For (2) we either keep this (a) as the prefix (which provides more compact code by default) or (b) add another parameter.
The above would be written either (a):
or (b):
The
p_base_types
test can now be written without the use of an intermediate function, showing below the version with and without many, either (a):Or (b):
Note that composing filters is still possible. Something that would have been written:
Can now be written (a):
or (b):
fold
will follow the exact same changes.In terms of implementation, either change is trivial, they're just about modifying where to find the various pieces in the code handling fold and filter.