Re: junctions and parenthesis
It seems to me that arbitrarily changing the precedence of a function would produce a horrible maintenance nightmare. It would mean recognising what had been done, interpreting the first example found in a different way than any other code, then tracking down any other place the trick had been used. (Or determining that none of the other programs in the system used the same technique.)
Re: junctions and parenthesis
You're quite correct Brad, so maybe I mis-stated my observation: > any( eq any()) any(any(False, False)) > eq any() any(False, False) > Would the first line of code above code (wrapping an 'eq' call inside an any-junction, along with another any-junction) be written by a Raku programmer? If so, what would his/her objective be? Doesn't the second line of code suffice? In Joseph's/Patrick's code, the external 'any' seems to only resolve to a taking a single (internal, nested) any-junction argument, while in your example, the external 'any' takes three internal, nested any-junction arguments. Best, Bill. On Wed, Jun 24, 2020 at 5:57 PM Brad Gilbert wrote: > > It does actually make sense to call any on any > > say (1, 2, 3).any + (4, 5, 6).any > # any(any(5, 6, 7), any(6, 7, 8), any(7, 8, 9)) > > On Wed, Jun 24, 2020 at 6:22 PM William Michels via perl6-users > wrote: >> >> I evaluated Joe's code using Patrick's explanation of parentheses-less >> parsing (in the REPL): >> >> > say(so(any( eq any(; >> False >> > say any( eq any()); >> any(any(False, False)) >> > >> >> Q1. Does it make any sense to call "any" on "any" (i.e. nested "any" >> calls)? Could this anti-pattern be used to generate a warning, i.e. >> 'Useless use of nested any-junctions, did you mean...' or something >> similar? >> >> > say any( eq any()); >> any(any(False, False)) >> > say any( eq any()); >> any(any(False, False, False)) >> > >> >> Q2. Swapping the first argument to the binary infix operator >> 'eq' with the second argument results in two different code >> evaluations (above). Can this be used to alert the user to a potential >> violation of the commutative property of equality? Again, maybe useful >> for generating a warning (at least in the REPL), " Warning: >> Commutativity--code without parentheses evaluates differently based on >> LHS vs RHS ordering of arguments to "eq" operator... ." >> >> (note, the second suggestion won't help if each argument to the "any" >> calls surrounding 'eq' are an equivalent number of elements). >> >> HTH, Bill. >> >> >> >> On Sun, Jun 21, 2020 at 8:12 PM Patrick R. Michaud >> wrote: >> > >> > The "any" function is just like any other function taking an arbitrary >> > list of arguments (including user-defined functions). As such it parses >> > with lower precedence than comparison operators -- so "eq" binds more >> > tightly than "any". >> > >> > Thus >> > >> >say so any eq any ; >> > >> > parses like >> > >> >say(so(any( eq any(; >> > >> > which is indeed False. >> > >> > I'm not exactly sure what sort of warning should go here, or how it'd be >> > detected. But perhaps others have ideas. >> > >> > Pm >> > >> > >> > On Sun, Jun 21, 2020 at 07:00:23PM -0700, Joseph Brenner wrote: >> > > I was just playing around with junctions a bit today, and I >> > > noticed that if you weren't religious about using parenthesis >> > > with them you could get quietly tripped up: >> > > >> > > say so any() eq any(); # True (as expected) >> > > say so any() eq any(); # False (as expected) >> > > say so any eq any ; # False(something's wrong) >> > > >> > > Basically, you need the parens on that first use of any. >> > > >> > > Is there a reason you don't at least get a warning if you don't?
Re: junctions and parenthesis
It does actually make sense to call any on any say (1, 2, 3).any + (4, 5, 6).any # any(any(5, 6, 7), any(6, 7, 8), any(7, 8, 9)) On Wed, Jun 24, 2020 at 6:22 PM William Michels via perl6-users < perl6-us...@perl.org> wrote: > I evaluated Joe's code using Patrick's explanation of parentheses-less > parsing (in the REPL): > > > say(so(any( eq any(; > False > > say any( eq any()); > any(any(False, False)) > > > > Q1. Does it make any sense to call "any" on "any" (i.e. nested "any" > calls)? Could this anti-pattern be used to generate a warning, i.e. > 'Useless use of nested any-junctions, did you mean...' or something > similar? > > > say any( eq any()); > any(any(False, False)) > > say any( eq any()); > any(any(False, False, False)) > > > > Q2. Swapping the first argument to the binary infix operator > 'eq' with the second argument results in two different code > evaluations (above). Can this be used to alert the user to a potential > violation of the commutative property of equality? Again, maybe useful > for generating a warning (at least in the REPL), " Warning: > Commutativity--code without parentheses evaluates differently based on > LHS vs RHS ordering of arguments to "eq" operator... ." > > (note, the second suggestion won't help if each argument to the "any" > calls surrounding 'eq' are an equivalent number of elements). > > HTH, Bill. > > > > On Sun, Jun 21, 2020 at 8:12 PM Patrick R. Michaud > wrote: > > > > The "any" function is just like any other function taking an arbitrary > list of arguments (including user-defined functions). As such it parses > with lower precedence than comparison operators -- so "eq" binds more > tightly than "any". > > > > Thus > > > >say so any eq any ; > > > > parses like > > > >say(so(any( eq any(; > > > > which is indeed False. > > > > I'm not exactly sure what sort of warning should go here, or how it'd be > detected. But perhaps others have ideas. > > > > Pm > > > > > > On Sun, Jun 21, 2020 at 07:00:23PM -0700, Joseph Brenner wrote: > > > I was just playing around with junctions a bit today, and I > > > noticed that if you weren't religious about using parenthesis > > > with them you could get quietly tripped up: > > > > > > say so any() eq any(); # True (as expected) > > > say so any() eq any(); # False (as expected) > > > say so any eq any ; # False(something's wrong) > > > > > > Basically, you need the parens on that first use of any. > > > > > > Is there a reason you don't at least get a warning if you don't? >
Re: junctions and parenthesis
I evaluated Joe's code using Patrick's explanation of parentheses-less parsing (in the REPL): > say(so(any( eq any(; False > say any( eq any()); any(any(False, False)) > Q1. Does it make any sense to call "any" on "any" (i.e. nested "any" calls)? Could this anti-pattern be used to generate a warning, i.e. 'Useless use of nested any-junctions, did you mean...' or something similar? > say any( eq any()); any(any(False, False)) > say any( eq any()); any(any(False, False, False)) > Q2. Swapping the first argument to the binary infix operator 'eq' with the second argument results in two different code evaluations (above). Can this be used to alert the user to a potential violation of the commutative property of equality? Again, maybe useful for generating a warning (at least in the REPL), " Warning: Commutativity--code without parentheses evaluates differently based on LHS vs RHS ordering of arguments to "eq" operator... ." (note, the second suggestion won't help if each argument to the "any" calls surrounding 'eq' are an equivalent number of elements). HTH, Bill. On Sun, Jun 21, 2020 at 8:12 PM Patrick R. Michaud wrote: > > The "any" function is just like any other function taking an arbitrary list > of arguments (including user-defined functions). As such it parses with > lower precedence than comparison operators -- so "eq" binds more tightly than > "any". > > Thus > >say so any eq any ; > > parses like > >say(so(any( eq any(; > > which is indeed False. > > I'm not exactly sure what sort of warning should go here, or how it'd be > detected. But perhaps others have ideas. > > Pm > > > On Sun, Jun 21, 2020 at 07:00:23PM -0700, Joseph Brenner wrote: > > I was just playing around with junctions a bit today, and I > > noticed that if you weren't religious about using parenthesis > > with them you could get quietly tripped up: > > > > say so any() eq any(); # True (as expected) > > say so any() eq any(); # False (as expected) > > say so any eq any ; # False(something's wrong) > > > > Basically, you need the parens on that first use of any. > > > > Is there a reason you don't at least get a warning if you don't?
Re: junctions and parenthesis
> I would suggest calling .any on the list, that gives you just the tight > preference you want; even if there were no .any method available on the > object you've got, or you want a different function, you can . That's a good thought. The code wouldn't read as nicely, though (the syntax is less like English): say so .any eq .any; My solution would be just to always use parens on the junction functions: say so any() eq any(); On 6/24/20, Timo Paulssen wrote: > On 22/06/2020 20:12, Joseph Brenner wrote: >> > Speculating wildly: could there be a need for a different type of > > function with different precedence? > I would suggest calling .any on the list, that gives you just the tight > preference you want; even if there were no .any method available on the > object you've got, or you want a different function, you can . > > LMKWYT > - Timo > > >
Re: junctions and parenthesis
On 22/06/2020 20:12, Joseph Brenner wrote: > > Speculating wildly: could there be a need for a different type of > function with different precedence? I would suggest calling .any on the list, that gives you just the tight preference you want; even if there were no .any method available on the object you've got, or you want a different function, you can . LMKWYT - Timo
Re: junctions and parenthesis
On Mon, 22 Jun 2020, Elizabeth Mattijsen wrote: > BEGIN trait_mod:(, :tighter(:<*>)); > > comes to mind, but that doesn't seem to do the trick. > My guess: tighter and looser are only consulted by the parser in contexts where 'any' was recognized as an *operator*.
Re: junctions and parenthesis
BEGIN trait_mod:(, :tighter(:<*>)); comes to mind, but that doesn't seem to do the trick. > On 22 Jun 2020, at 21:11, Tobias Boege wrote: > > On Mon, 22 Jun 2020, Joseph Brenner wrote: >> Patrick R. Michaud wrote: >> >>> The "any" function is just like any other function taking an arbitrary list >>> of arguments (including user-defined functions). As such it parses with >>> lower precedence than comparison operators -- so "eq" binds more tightly >>> than "any". >> >> Thanks, makes sense. >> >>> I'm not exactly sure what sort of warning should go here, or how it'd be >>> detected. >> >> Yes, exactly. From one point of view it's working as designed-- to me >> it felt pretty weird, though. >> >> Speculating wildly: could there be a need for a different type of >> function with different precedence? >> > > You can achieve this today by redefining to be a prefix operator > and provide it with tight enough precedence. In this example, I pick > infix multiplication as the argument stopper, which is in particular > tighter than the relevant eq operator; your mileage may vary: > > sub old-any (|c) { CORE::{''}.(|c) } > > multi prefix: (|c) is tighter(:<*>) { > old-any |c > } > > say so any eq any ;# True (fixed) > say so old-any() eq old-any(); # True > say so old-any eq old-any ; # False > > Now I'd be interested to see how someone would turn this into a > frugal-sub declarator or an `is frugal` trait. > > Regards, > Tobias > > -- > "There's an old saying: Don't change anything... ever!" -- Mr. Monk
Re: junctions and parenthesis
On Mon, 22 Jun 2020, Joseph Brenner wrote: > Patrick R. Michaud wrote: > > > The "any" function is just like any other function taking an arbitrary list > > of arguments (including user-defined functions). As such it parses with > > lower precedence than comparison operators -- so "eq" binds more tightly > > than "any". > > Thanks, makes sense. > > > I'm not exactly sure what sort of warning should go here, or how it'd be > > detected. > > Yes, exactly. From one point of view it's working as designed-- to me > it felt pretty weird, though. > > Speculating wildly: could there be a need for a different type of > function with different precedence? > You can achieve this today by redefining to be a prefix operator and provide it with tight enough precedence. In this example, I pick infix multiplication as the argument stopper, which is in particular tighter than the relevant eq operator; your mileage may vary: sub old-any (|c) { CORE::{''}.(|c) } multi prefix: (|c) is tighter(:<*>) { old-any |c } say so any eq any ;# True (fixed) say so old-any() eq old-any(); # True say so old-any eq old-any ; # False Now I'd be interested to see how someone would turn this into a frugal-sub declarator or an `is frugal` trait. Regards, Tobias -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk
Re: junctions and parenthesis
Patrick R. Michaud wrote: > The "any" function is just like any other function taking an arbitrary list > of arguments (including user-defined functions). As such it parses with > lower precedence than comparison operators -- so "eq" binds more tightly > than "any". Thanks, makes sense. > I'm not exactly sure what sort of warning should go here, or how it'd be > detected. Yes, exactly. From one point of view it's working as designed-- to me it felt pretty weird, though. Speculating wildly: could there be a need for a different type of function with different precedence? On 6/21/20, Patrick R. Michaud wrote: > The "any" function is just like any other function taking an arbitrary list > of arguments (including user-defined functions). As such it parses with > lower precedence than comparison operators -- so "eq" binds more tightly > than "any". > > Thus > >say so any eq any ; > > parses like > >say(so(any( eq any(; > > which is indeed False. > > I'm not exactly sure what sort of warning should go here, or how it'd be > detected. But perhaps others have ideas. > > Pm > > > On Sun, Jun 21, 2020 at 07:00:23PM -0700, Joseph Brenner wrote: >> I was just playing around with junctions a bit today, and I >> noticed that if you weren't religious about using parenthesis >> with them you could get quietly tripped up: >> >> say so any() eq any(); # True (as expected) >> say so any() eq any(); # False (as expected) >> say so any eq any ; # False(something's wrong) >> >> Basically, you need the parens on that first use of any. >> >> Is there a reason you don't at least get a warning if you don't? >
Re: junctions and parenthesis
The "any" function is just like any other function taking an arbitrary list of arguments (including user-defined functions). As such it parses with lower precedence than comparison operators -- so "eq" binds more tightly than "any". Thus say so any eq any ; parses like say(so(any( eq any(; which is indeed False. I'm not exactly sure what sort of warning should go here, or how it'd be detected. But perhaps others have ideas. Pm On Sun, Jun 21, 2020 at 07:00:23PM -0700, Joseph Brenner wrote: > I was just playing around with junctions a bit today, and I > noticed that if you weren't religious about using parenthesis > with them you could get quietly tripped up: > > say so any() eq any(); # True (as expected) > say so any() eq any(); # False (as expected) > say so any eq any ; # False(something's wrong) > > Basically, you need the parens on that first use of any. > > Is there a reason you don't at least get a warning if you don't?
junctions and parenthesis
I was just playing around with junctions a bit today, and I noticed that if you weren't religious about using parenthesis with them you could get quietly tripped up: say so any() eq any(); # True (as expected) say so any() eq any(); # False (as expected) say so any eq any ; # False(something's wrong) Basically, you need the parens on that first use of any. Is there a reason you don't at least get a warning if you don't?