Closed rhdunn closed 1 year ago
For the sake of completeness, I’m adding the link to the original suggestion from @dirkk… https://www.w3.org/Bugs/Public/show_bug.cgi?id=29393
…and the link to the xpath-ng proposal: https://github.com/expath/xpath-ng/pull/5
Thanks for the references, and for the reminder of my comment:
("a", "b", "c") => for-each(uppercase#1)
which I suggested again in today's call.
The current example
"The cat sat on the mat" => tokenize() -> concat(".") -> upper-case() => string-join(" ")
then becomes
"The cat sat on the mat" => tokenize() => for-each( concat(?, ".") => upper-case() ) => string-join(" "))
which is longer, but seems to have more clarity; it certainly introduces fewer new concepts.
Correction. I got that wrong. The 2nd argument to for-each must be a function, and concat(?, ".") => upper-case()
is not a function. Rather, it throws a type error saying that upper-case()
cannot be applied to a function. Perhaps influenced by Dimitre's remarks today, I was thinking here of =>
as being an operator that composes two functions into a single function, which it is not.
What we have to write instead is something like => for-each(->( (.||".") => upper-case())
After today's discussion, I think I'm leaning towards dropping the thin-arrow operator completely (not just the "inlined function" variant of it)
It would be worth adding that example using for-each as it is a useful demonstration of how to do this with the existing arrow operator.
If the thin arrow is kept, I recommend starting with a much simpler example that makes the difference in behavior clear, repeated for each operator, e.g.:
(1, 2) => sum()
returns 3
(1, 2) -> sum()
returns (1, 2)
I'd like to put forward a more radical set of reforms. Each of the following changes could technically be made on its own, but taken together, they are designed to reduce the amount of new syntax that needs to be mastered (and explained) while retaining or increasing its expressive power.
->{.+1}
)->
as a synonym for function
(as in ->($a, $b){$a + $b}
){$1 + $2}
$x -> f()
)$x => {$1 * 2}()
~>
, so that if F1 and F2 are expressions returning functions, then F1 ~> F2 returns a function F3 with the same signature as F1, with the effect that F3(args) delivers the same result as F2(F1(args)). Example 1: sort($input, key:=normalize-space#1~>upper-case#1)
. Notes:
filter($in, ->{. gt 2})
becomes filter($in, {$1 gt 2})
, while sort(//emp, (), ->{@salary})
becomes sort(//emp, (), {$1/@salary})
.->($a, $b){$a + $b}
becomes more compact: {$1 + $2}
. The zero-arity function ->{EXPR}
becomes simply {EXPR}
. Note that the arity is inferred from the highest argument number in a contained parameter reference.{EXPR}
, but we could avoid closing up our future options by adding some syntactic marker, for example ${EXPR}
or \{EXPR}
or f{EXPR}
.EXPR -> f()
, use EXPR => for-each(f)
. As a replacement for EXPR -> f() -> g()
, use perhaps EXPR => for-each(f ~> g)
. To take an example from the spec, (1 to 5) -> xs:double() -> math:sqrt() -> {.+1} => sum()
becomes (1 to 5) => for-each(xs:double ~> math:sqrt ~> {$1+1}) => sum()
Michael, thanks for the revised proposal.
->
as a synonym for function
. We had preliminarily added the new syntax in BaseX, and it has already caused confusion that the arrow appears before and not after the arguments, as known from other languages (I know there have been good syntactical reasons not to follow the syntax of other languages). Next, arrows are known to be used when functions are chained, so we are indeed using a similar syntax for different concepts. Personally, I have some sympathy for adding fn
as an alias for the function
keyword, as most people know the fn:
prefix for standard functions."The cat sat on the mat"
=> tokenize()
-> concat(".")
-> upper-case()
=> string-join(" ")
I don’t think there’s anything close as elegant and readable with the existing language. Examples:
let $string := "The cat sat on the mat"
let $tokens := (
for $token in tokenize($string)
return $token => concat(".") => upper-case()
)
return string-join($tokens, " ")
string-join(
let $string := "The cat sat on the mat"
for $token in tokenize($string)
return upper-case(concat($token, ".")),
" "
)
"The cat sat on the mat"
=> tokenize()
=> for-each(concat(?, '.'))
=> for-each(upper-case#1)
=> string-join(" ")
$1
shortcuts are not very intuitive, and they may restrict us in the middle term, now that we introduce keyword arguments. Same for named functions, such as a function like local:wrap($data, $prefix, $suffix)
, which would need to be addressed with local:wrap#3
: It would be much nicer if we could use real variable names. That being said, I’d first need to find out what would be a good alternative…With respect to
"The cat sat on the mat"
=> tokenize()
-> concat(".")
-> upper-case()
=> string-join(" ")
Am I correct that it would be the same if you wrote "The cat sat on the mat" -> tokenize() ...
? Since there's only one argument before the first arrow operator, either would work? Or maybe I haven't groked some subtle aspect of the difference.
At a glance, the mixture of arrows seems awfully subtle. I can see how it's concise, but I find the syntactic variation of using !
easier to read:
('The cat sat on the mat' => tokenize())
! concat(., '.')
! upper-case(.)
=> string-join()
The parentheses around the first expression are perhaps a little annoying, but like MSM, I tend to use parentheses liberally. Do I remember that 3 * 4 + 2
is 14
? Yeah, probably, but I'd always write (3 * 4) + 2
anyway.
I, being the sort who prefers things to be explicit rather than implicit, actually like ! concat(., '.')
better than -> concat('.')
though I wouldn't be surprised if I'm in the minority on that point.
My concern with item 3 (quick inline functions) is how that syntax mixes with existing EnclosedExpr
usage. -- For example, what does if (true()) { $1 + $1 }
parse as, given the new EnclosedExpr
form for if expressions?
We currently don't have any expression, or any construct that can appear in the same context as an expression, that starts with a left open brace. There's a valid argument that we should avoid introducing such an expression in order to keep some of the syntactic space unused -- unused syntactic space preserves options for later enhancements, and tends to allow more accurate diagnosis of syntax errors.
So in your example, the construct if (true()) { $1 + $1 }
is an error, but it might be tricky to give a good error message. The open brace is will get the parser thinking it's a braced conditional expression, it will then find the $1 which is allowed only in a "quick inline function", so the likely error message is "numeric parameter reference not allowed outside a quick inline function" (or whatever we decide to call the thing).
Am I correct that it would be the same if you wrote
"The cat sat on the mat" -> tokenize() ...
?
Exactly: If there’s one argument, the arrows are interchangeable. It’s comparable to for
and let
, both do the same if a single item is bound.
At a glance, the mixture of arrows seems awfully subtle. I can see how it's concise, but I find the syntactic variation of using
!
easier to read:
The syntax and the formatting gets tricky once you have intermixed occurrences of single and multiple items: Imagine you have item iterations followed by sequence operations followed by item iterations…
What I really like about the arrow approach is that you don’t have to reformat your code once a single operation is added. Instead, you simply move it in between. Currently, with the given syntax, we rewrite arrow chains back to FLWOR expressions in such cases, or we decide not to use the arrow operator at all because of the given restrictions.
An alternative to
"The cat sat on the mat"
=> tokenize()
=> for-each(concat(?, '.'))
=> for-each(upper-case#1)
=> string-join(" ")
under the proposal is to write
"The cat sat on the mat"
=> tokenize()
=> for-each(concat(?, '.') ~> upper-case#1)
=> string-join(" ")
or if you prefer
"The cat sat on the mat"
=> tokenize()
=> for-each({($1 || '.') => upper-case()})
=> string-join(" ")
My thinking is that the function composition operator (which I'm writing as ~>
) is more versatile and powerful than the current single-arrow operator, though it might not always be simpler. Of course, I wouldn't want to have both. But I think that flagging the point at which the pipeline splits into item-by-item processing with the visible "for-each" call improves readability for those who're not 100% familiar with the subtle distinctions.
Just for the record, my comment from Slack (in which the latest proposals haven’t been considered yet):
In 2014, there was a suggestion from @LeoWoerteler to extend the arrow operator for function items: https://www.w3.org/Bugs/Public/show_bug.cgi?id=26889. If it had been adopted, we could do things like:
$text => file:write-text('data.txt, ?)
$payloads => http:send-request($request, $uri, ?)
Back then, I favored that design choice, which got rejected, and our impression was that the fat arrow operator was designed to be intuitive for occasional and intermediate users of the languages.
The good thing about the decision was that the fat arrow is widely used today, and I think we should follow the popularity/simplicity argument for the thin arrow operator as well. Constructs such as…
$seq => ! op("+")(?, 1)
$seq => for-each(function($x) { $x + 1 })
…are certainly more flexible, and we could add or motivate those in addition, but I’m not sure if we should try to introduce or present them to inexperienced users as a default solution. Recommending standard FLWOR expressions would probably be a better choice for most users.
From Slack, using the proposed squashing operator:
"The cat sat on the mat"
=> tokenize()
~> concat(?, ".")
~> upper-case#1
=> string-join(" ")
And the same starting from a single array, containing the words:
["The", "cat", "sat", "on", "the", "mat"]
~> concat(?, ".")
~> upper-case#1
=> string-join(" ")
It’s due to the 3.1 grammar that an arrow expression can yield either the result of function call or a partially applied function:
(1 to 5) => sum(0) (: yields the result of the function call :)
(1 to 5) => sum(?) (: yields a function item :)
The behavior is consistent, as it’s a basic property of argument lists that they contain expressions and argument placeholders:
ArrowExpr ::= UnaryExpr ("=>" ArrowFunctionSpecifier ArgumentList)*
ArrowFunctionSpecifier ::= EQName | VarRef | ParenthesizedExpr
ArgumentList ::= "(" (Argument ("," Argument)*)? ")"
Argument ::= ExprSingle | ArgumentPlaceholder
ArgumentPlaceholder ::= "?"
Perhaps we can avoid new intricacies by sticking to a simple grammar representation. If we want to have a unified syntax for function calls, and if we want to support the two arrow operators, we could simplify the current 4.0 grammar and instead slightly enhance the 3.1 grammar as follows:
ArrowExpr ::= UnaryExpr (("=>" | "->") ArrowFunctionSpecifier ArgumentList)*
ArrowFunctionSpecifier ::= EQName | VarRef | InlineFunctionExpr | ParenthesizedExpr
Examples for legal expressions:
(: processing of sequences; analogous to the let clause :)
$seq => sum()
$seq => $process-sequence()
$seq => function($x) { count($x) }()
$seq => (if($sum) then sum#1 else avg#1)()
(: processing of items; analogous to the for clause :)
$seq -> string()
$seq -> $process-item()
$seq -> function($x) { $x + 1 }()
$seq -> (if($short) then xs:short#1 else xs:byte#1)()
In a second step (see #53), the InlineFunctionExpr
rule can be further tweaked (provided that the alternative syntax creates no ambiguities with the ArrowFunctionSpecifier
RHS rules).
PS: In addition to InlineFunctionExpr
, we could add NamedFunctionRef
, but as count()
and count#1()
return the same result, it would probably have no added value within the scope of my proposed rules.
Alternative syntax proposals for the item arrow (see https://github.com/qt4cg/qtspecs/issues/53#issuecomment-1513297753):
A =!> B
(added , see https://github.com/qt4cg/qtspecs/pull/447A !=> B
A !> B
A -> B
A ~> B
Once a user understands what !
does and what =>
does, !=>
should be an intuitive compound. The other options, not so much.
!=>
makes me think of 8======D
!=>
makes me think of8======D
(: fits the language :)
the current example
"The cat sat on the mat" => tokenize() -> concat(".") -> upper-case() => string-join(" ")
then becomes
"The cat sat on the mat" => tokenize() => for-each( concat(?, ".") => upper-case() ) => string-join(" "))
which is longer, but seems to have more clarity; it certainly introduces fewer new concepts.
Correction. I got that wrong. The 2nd argument to for-each must be a function, and
concat(?, ".") => upper-case()
is not a function. Rather, it throws a type error saying thatupper-case()
cannot be applied to a function. Perhaps influenced by Dimitre's remarks today, I was thinking here of=>
as being an operator that composes two functions into a single function, which it is not.What we have to write instead is something like
=> for-each(->( (.||".") => upper-case())
After today's discussion, I think I'm leaning towards dropping the thin-arrow operator completely (not just the "inlined function" variant of it)
Actually no new constructs like "lambda expressions" or "thin arrows" are necessary. The following is a correct XPath 3.1 expression that produces the wanted result and demonstrates chaining:
"The cat sat on the mat" => tokenize() => for-each( concat(?, ".")) => for-each( upper-case#1 ) => string-join(" ")
With BaseX:
and with Saxon (Oxygen):
Excuse me for still failing to understand why we should be inventing new, complicated and confusing syntax , when we already can write such expressions. 😢
P.S. I still wouldn't be writing such expressions for anyone to look at, and would be afraid that in one month from now I myself wouldn't be confident that I understand what I have written ...
But for anyone wanting powerful shiny new toys: stay relaxed, as this example already shows, we have them at present 😄 If you haven't mastered even what we already have, why want even new such toys?
Is this indicative of too much "parental care", or lack of it?
. . . 7. Introduce a function composition operator, spelt perhaps
~>
, so that if F1 and F2 are expressions returning functions, then F1 ~> F2 returns a function F3 with the same signature as F1, with the effect that F3(args) delivers the same result as F2(F1(args)). Example 1:sort($input, key:=normalize-space#1~>upper-case#1)
.Notes: . . .
- The function composition operator (suggested to me by Dimitre's remarks during yesterday's meeting) seems to have a lot of potential which I haven't yet fully explored. The suggested spelling is just a first-cut idea, alternatives are welcome. This would be better explored as a separate proposal, but I include it here because I think it's part of justification that says we can drop the thin arrow expression without losing anything. I feel it's more poweful than the thin arrow in its current form because it's a pure binary operator that can take arbitrary expressions as its operands (subject to type and precedence rules of course), and it can be used anywhere that a function item is expected, including a "fat arrow" pipeline.
Yes, multiple-composition is really powerful.
But please note the following:
F ^ G (x) is F(G(x))
not:
G(F(x))
Maybe to avoid confusion we should call the latter with a different name, why not "left-to-right composition"
.
, though just $ could be used.Multiple composition is defined as a right fold over the list of functions to be composed, with step-function the apply operator $
and the "zero" accumulator - the value on which the multiple composition is to be applied.
We can express the same in XPath:
let $apply := function($f, $x) {$f($x)},
$multiCompose := function($funs as function(*)*, $x as item()*) {fold-right($funs,$x, $apply)}
return
$multiCompose( (op('+')(?, 1), op('*')(?, 2)), ?) (2)
And this correctly produces:
5
,
that is : *`1 + (22)`**
With BaseX:
And with Saxon (Oxygen):
I could certainly live without the "mapping arrow". I think that if we make it easier to write inline functions, use of things like for-each
and filter
will start to become more normal and natural, and reduce the need for more complex constructs.
Actually no new constructs like "lambda expressions" or "thin arrows" are necessary.
@dnovatchev You’re obviously right. The assumption is that the mapping arrow (as coined by Michael in #447) improves the readability of code that can be chained, in particular for novice and intermediate users, and this assumption is based on the wide acceptance of =>
.
It’s completely fair to question new syntax in general. In retrospect, your objection is also valid for the 3.0/3.1 operators (!
, ?
, =>
), and it applies to any 4.0 operators that still being discussed. You are right that the abstracted version of the sitting-cat example…
$input => A() =!> B(".") =!> C() => D(" ")
…can already be written as:
$input => A() => for-each( B(?, ".") ) => for-each( C#1 ) => D(" ")
My experience is that partial function applications – B(?, ".")
– and named function references – C#1
– are rare encounters, whereas $input => A()
is used a lot today. Instead of using these constructs, I would rather expect most users to throw all 3.0 constructs overboard and use FLWOR expressions instead (provided you use XQuery):
let $a := $input
for $b in A($a)
for $c in B($b, " ")
let $d := C($c)
return $D($d, " ")
I think that if we make it easier to write inline functions, use of things like for-each and filter will start to become more normal and natural, and reduce the need for more complex constructs.
That is so bad
The great thing about XPath was that you could do for-each with /
and filter with []
The XPath way of cat sitting would be
("The cat sat on the mat" => tokenize()) ! concat(., ".") ! upper-case(.) => string-join(" ")
! concat(., ".")
is shorter than => for-each( concat(?, "."))
and easier to read.
@michaelhkay , @ChristianGruen
Yes, we all agree that the newly-proposed syntax is just another way of writing an XPath expression, that we can already write today.
Sometimes inventing "yet another way" to do the same thing and including it in the language makes it difficult to choose which of the available writing facilities to choose, and on reading, why exactly this way of writing was chosen and not that one, again leading to confusion trying to distinguish the differences between this form and that form.
I believe that at present we already have too-many ways to say the same thing, that inventing and adding to the language yet other ways to express the same thing already becomes counter-productive. And most of us shared that the newly-proposed writing additions would benefit and be used just by 5% of the user audience. Thus, introducing this will be devisive and not uniting the users of XPath.
It seems to me that here we are doing the opposite of what Antoine de Saint-Exupéry “Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”
It seems to me that here we are doing the opposite of what Antoine de Saint-Exupéry “Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.”
It’s certainly a good principle to literature. Kafka also felt that way, he didn’t believe his work was perfect enough to be kept alive. Still, Max Brod refused to destroy his legacy. Hardly anyone thinks it was a bad decision.
Maybe it was a bad design to add =>
, !
and ?
to the language, even though it could be taken away. Maybe we should never have introduced higher-order features, which 95% don’t use in practice. – I still believe the decisions made development of complex applications much more comfortable.
@dnovatchev Having an existing way of doing something shouldn't mean that a feature/syntax is rejected, otherwise we would not add anything new. [1] The test should be:
Note that these tests need to be applied to different types of user -- i.e. not everyone uses the same coding style, or features. I understand that there are users who want/write simple XSLT transforms, while others are more familiar with higher order functions, etc.
[1] That would apply to many of the proposed and accepted features -- simple mapping operator, exists/every, named keywords, arrays (XPath/XQuery had sequences), sequences (XPath/XQuery had nodes), etc. It would even apply to other languages and features such as procedural languages vs assembly; while/for given the presence of if and goto; classes; etc.
It's very much my experience that the small things are often the ones that are most popular with users: things like the separator
attribute of xsl:value-of
. I remember there was an argument for minimalism in the Algol68 working group, and someone pointed out that you didn't actually need a "+" operator because "--" did the job perfectly well. It's all about finding the right balance, not about following philosophical design principles blindly.
I bet that most of the folks in our CG can program in more than one language. I'll further bet that for every one of us, and every language, there are features of the language that we have never used or only very rarely use. I would be very surprised if the features we don't use are all the same! But I bet few of us regularly scorn the languages we use because they have features we don't use.
Language design has a scientific component: determining what can actually be achieved, what is intentionally not possible, what is accidentally not possible, and even what is possible but we didn't know it[¹]. It's also part art. Sometimes having redundancy makes a task easier, or easier to do correctly. Sometimes it makes the language more confusing to some users.
I think the working group is largely of the opinion that we need some new syntax to make inline functions easier to use in some circumstances and some new variant of the existing fat arrow operator. At this point, I think everyone recognizes that there are ways to use functions that satisfy the "can it be achieved" requirements. If arguments of the form "you don't need this because..." were going to be persuasive, I think they would already have been so. Conversely, I don't think arguments of the form "by that logic, we don't need [some feature we already have]" are likely to be persuasive (though if the completion of that argument is actually "therefore we should remove it", please open an issue specifically about that).
I think what's left to do is work out what syntax choices are the most agreeable, offer the least element of surprise, and introduce the smallest practical amount of confusion. I encourage everyone to approach the questions in that spirit.
[¹] I love this story, even though I expect it's apocryphal. The story goes that back in the 70's or thereabouts, a team of engineeers was challenged to add a stop watch function to some HP scientific calculator. This is back in the days of 8 digit glowing red LED displays and chunky collections of physical buttons that clicked when you pushed on them. So the team gets out the schematics, big hardcopy print outs of the circuit design, spreads them out over a table in a conference room, and begins the difficult process of working out where and how they can fit the new circuits into the calculator. They've been going at it for a while when one of the engineers looks up from the table: "hang on a minute. If you pressed that button and that button," he says, pointing at places several feet apart on the diagrams, "and that button, wouldn't that make the circuit?" So someone gets out the calculator and pushes the three buttons and the little LED display starts running a stopwatch.
It's very much my experience that the small things are often the ones that are most popular with users: […]
I once asked developers what’s the coolest 3.0 feature, and the answer was: ||
, the operator for concatenating strings!
Hey folks,
I wouldn't be raising my concerns if the proposed new syntax wasn't so confusing.
Just take my feedback (2¢) and let the resulting (hopefully not) monstrosity weigh on your conscience.
I do understand the reasons and justification to strive for expressiveness, but my gut feeling is that the currently proposed new syntax crosses a line that we probably should not.
Also, please, ask yourselves these questions:
Where should we put the focus and emphasis in our future work:
Imagine that the "End of the world" is just in 3 years. 😄 Would you then be happy to be working on this feature? If not, what feature you would have chosen to be working on?
I think the working group is largely of the opinion that we need some new syntax to make inline functions easier to use in some circumstances and some new variant of the existing fat arrow operator. At this point, I think everyone recognizes that there are ways to use functions that satisfy the "can it be achieved" requirements. If arguments of the form "you don't need this because..." were going to be persuasive, I think they would already have been so. Conversely, I don't think arguments of the form "by that logic, we don't need [some feature we already have]" are likely to be persuasive (though if the completion of that argument is actually "therefore we should remove it", please open an issue specifically about that).
I think what's left to do is work out what syntax choices are the most agreeable, offer the least element of surprise, and introduce the smallest practical amount of confusion. I encourage everyone to approach the questions in that spirit.
As for the working group being " largely of the opinion that ...", this definitely doesn't seem so definite. The last and only time there was an attempt at voting, exactly 50% of the voters did not support the proposal. Taking into account that some valued people were not present due to health and other reasons (could it not be because they were not feeling satisfied and confident with the current state and subject-matter of work?) , it wouldn't be too-surprising at all if this proposal turns out to be not too-popular even amongst the so called 5%.
If we really do care about "diversity", why not ask for the opinion of more users whenever approaching an obviously controversial decision?
The last and only time there was an attempt at voting, exactly 50% of the voters did not support the proposal. Taking into account that some valued people were not present due to health and other reasons (could it not be because they were not feeling satisfied and confident with the current state and subject-matter of work?) , it wouldn't be too-surprising at all if this proposal turns out to be not too-popular even amongst the so called 5%.
@dnovatchev Statements like this are simply biased and misleading. The result was that no one objected. 5 favored the proposal, 5 were undecided, no one objected (including you). Only 3 persons were not present in the meeting (https://qt4cg.org/meeting/minutes/2023/04-11.html).
The result of this vote was a new proposal: #447. I’m not even sure if you are still commenting on the old status quo or the recently proposed adjustments. Originally, this issue (#435) was about the “removal of the inlined function expression variant of the thin arrow operator“; we shouldn’t overstretch it and try to focus again to make progress.
- Is this the most important and most urgent new feature that we should be working on at present?
I’m sorry I have to mention that no one at the meeting strongly opposed the proposal except you. If we want to be able to focus on other features soon, it’s time to get constructive, accept others’ opinions that may contrast with the personal ones, and look at the overall picture again. Without compromises, we wouldn’t have added a single feature to the spec yet.
Next, note that the feature had already been included in the spec for a longer time; even users of us discovered it on their own. It would have been easy to comment on it at an earlier stage.
If we really do care about "diversity", why not ask for the opinion of more users whenever approaching an obviously controversial decision?
I regularly mention we do things like that. We are in regular contact with our users (both novice and advanced) via trainings and assisted coding sessions. I can safely confirm that a) there’s a need for a compacter lambda syntax and b) that an arrow for requesting single items has been repeatedly asked for, not only by our own team members. I can also confirm that users have been happy to see the thin arrow included in our latest minor versions (but we remind everyone that none of these features are to be included in productive code, which is also the reason we don’t document any preliminary 4.0 features before they haven’t been added to the spec).
I don’t understand why you aren’t bringing this into the equation when demanding diversity. Please don’t hesitate to share your experiences with users. I have shared some quantitative evaluations on code bases on Slack. I would be happy to see more of such results, as I believe they can help us to at least assess the acceptance of already added features.
@ChristianGruen
The last and only time there was an attempt at voting, exactly 50% of the voters did not support the proposal. Taking into account that some valued people were not present due to health and other reasons (could it not be because they were not feeling satisfied and confident with the current state and subject-matter of work?) , it wouldn't be too-surprising at all if this proposal turns out to be not too-popular even amongst the so called 5%.
@dnovatchev Statements like this are simply biased and misleading. The result was that no one objected. 5 favored the proposal, 5 were undecided, no one objected (including you).
I am tired of people either ignoring facts pointed out or twisting statements made by me.
What I clearly said (quoted and bolded above) was that "exactly 50% of the voters did not support the proposal" not that they voted "against". The fact is that they didn't vote "for" this proposal.
Only 3 persons were not present in the meeting (https://qt4cg.org/meeting/minutes/2023/04-11.html).
As for "Only 3 persons were not present in the meeting" this is only 😄 30% of the people that were present. 😄😄
Reading about the history of mathematical symbols here, it once again seems that being too-eager to add new such symbols is most likely going to pollute this nice space.
Will any of the proposed new XPath operators be known 100 years from now?
As #447 was merged, I’m closing this issue, as well as #53 and #436. In #503, an alternative compact syntax for anonymous functions with single arguments is discussed.
This proposal is to remove the third bullet/variant from the thin arrow operator so that the new inline function syntax (
-> { ... }
) cannot be used within the arrow expressions.This makes the thin/fat arrows consistent in behaviour with each other, with the exception of how they pass the value to the expressions:
Changes
Update the syntax:
Remove the text for the inline function variant:
Remove/update the associated examples, e.g. to use
let $f := function ($x) { $x + 1 } return $x -> f() -> $f()
.