Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: For discussion: operator attributes - associativity, chainity and ability to short-circuit

by Don Coyote (Hermit)
on Jan 29, 2021 at 20:57 UTC ( [id://11127661]=note: print w/replies, xml ) Need Help??


in reply to For discussion: operator attributes - associativity, chainity and ability to short-circuit

Hello again rsFalse. You got me to thinking.

Having had another look, I think I see what is happening. Basically, if I am percieving correctly, you are taking return values from different events to be different things.

However, the nature of this update has also caught my intruige. So informally I've been looking at this in this way.

Work In Progress as at Fri 29 Jan 2021 pls be patient.

The return value of the comparison operator is a boolean 1 or 0. Although I would need to check the zero return may be undef which then transforms to 0 used as a string or number. But in practice, it can be considered as evaluating in the perl boolean sense. This means that it tseted for truthiness.

before we consider what this means for chainified operations lets take a quick look at a typical comparison operator usage. Lets take a constant and compare it to a variable that increases from being lesser to being greater than the constant. That is $kappa starts at 0 and increases through to 3. And $mu which remains constant at 2. We print a list that tells us whether the comparison returns true or false.

#!perl -T -w use strict; #use wtf8; my ($kappa,$mu) = (0,2); print "Is $kappa lesser than $mu ?:\n"; printf "%8s%s%-4s%s\n",'$kappa',' < ','$mu','-> boolean context'; my $bool = $kappa < $mu; printf "%8d%s%-4d%s%d\n","$kappa",' < ',"$mu",'-> ', $bool; while( ++$kappa ){ # prefix increment $bool = $kappa < $mu; printf "%8d%s%-4d%s%d\n",$kappa,' < ',$mu, '-> ',$bool; last if $kappa == 3; } __END__ #OUTPUT $kappa < $mu -> boolean context 0 < 2 -> 1 1 < 2 -> 1 2 < 2 -> 0 3 < 2 -> 0

So what is happening is that the operator returns truthiness. However, perl still needs to access the variables $kappa and $mu to make the comparison during each loop. So during each loop, perl accesses, (looks at) the scalar variables then makes the comparison using our chosen comparison operator. Then returns whether the comparison equates to being true or false, 1 or 0 respectively. This is known as boolean context, which is a sub-context of scalar context in perl.

Context is one of the fundamental concepts within perl 5, and its fairly straightforward once you understand it. Most of the time you are using context without realising. Let me quickly describe how context is working using the while loop I have introduced here. Now to make the while loop work as I desired I needed to understand that the while condition evaluates in scalar context. Basically While loops continue running while the condition is true, which in perl means the return value is neither numerically 0 nor undefined. So I had to make sure that the first time the loop evalutes $kappa it did not evaluate to the number 0 or undefined. This is why you will often see constructs such as while(my $v = defined( shift( @array ) ) ){ print $v; }. So, without getting too complicated, I make sure $kappa returns 1 in the while condition and then exit the loop from within, by using the last statement on the condition that $kappa reaches 3.

Otherwise this does not work, the while condition evaluates false on first run and so skips running the while code block.

($kappa,$mu) = (0,2); print "Is $kappa lesser than $mu ?:\n"; printf "%8s%s%-4s%s\n",'$kappa',' < ','$mu','-> boolean context'; $bool = $kappa < $mu; printf "%8d%s%-4d%s%2d\n",$kappa,' < ',$mu, '-> ',$bool; while( $kappa++ ){ # postfix increment $bool = $kappa < $mu; printf "%8d%s%-4d%s%2d\n",$kappa,' < ',$mu, '-> ',$bool; last if $kappa == 3; } printf "Where is my table?\n"; __END__ #OUTPUT Is 0 lesser than 2 ?: $kappa < $mu -> boolean context 0 < 2 -> 1 Where is my table?

The comparison operator does not return the value. If we want to get the value for comparison we are evaluating we have to do this in two steps. That is just how this operator works, other operators return scalar values, or lists, or booleans, which is documented in the relevant documentation for that operation. So to get the value we use the boolean return value to split the branch to return the value we want using for example an if condition.

Like While, if evaluates in scalar context, but just the once, and then returns the relevant code block. Perl accessing the variable to carry out the comparison is not the same thing as returning a value once the comparison has been evaluated. And it is this accessng the variable to carry out the operation which is being explained in the documentation for how chained comparison operators are evaluated. The return value is still boolean, just on a chain of boolean comparison operators rather than on a single boolean comparison operator.

To return a value we use two steps; Evaluate the comparison for truthiness, then return a value ourselves dependant on that truthiness.

($kappa,$mu) = (0,2); printf "%s\n",'$kappa < $mu -> boolean -> value we ask perl to return' +; $bool = $kappa < $mu; my $ret_value; if( $kappa < $mu ){ # if( $bool ) $ret_value = sprintf "%-8s%d", '$kappa: ',$kappa; }else{ $ret_value = sprintf "%-8s%d", '$mu: ',$mu; } printf "%8d%s%-4d%s%-11d%s%s\n",$kappa,' < ',$mu,' -> ',$bool,'-> ',$r +et_value; while( ++$kappa ){ $bool = $kappa < $mu; if( $kappa < $mu ){ # if( $bool ) $ret_value = sprintf "%-8s%d", '$kappa: ',$kappa; }else{ $ret_value = sprintf "%-8s%d", '$mu: ',$mu; } printf "%8d%s%-4d%s%-11d%s%s\n",$kappa,' < ',$mu,' -> ',$bool,'-> ',$ +ret_value; last if $kappa == 3; } __END__ $kappa < $mu -> boolean -> value we ask perl to return 0 < 2 -> 1 -> $kappa: 0 1 < 2 -> 1 -> $kappa: 1 2 < 2 -> 0 -> $mu: 2 3 < 2 -> 0 -> $mu: 2

To evaluate a chainified comparison perl needs to access some of the variables more than once before making the camparison. What the documentation in perlop describes is how perl does this in the two differing cases of when there is a simple scalar variable and when there is an expression to evaluate. So the idea of short circuiting would only work in specific cases such as when all the comparison operators in the chain are the same. Then when one of the sub evaluations returns false, the whole statement can be considered false. But this would not work generally, as you suggest, on a chain of operations that involves multiple different comparison operators. In general, that is not to say certain variations of operators chained would not reduce to an ability to shortcut depending on whether it was truly boolean of course.

Revise SectionEssentially what chaining of operators now allows us to do is to write.

while( $kappa < $mu ){ $ret_value = $kappa }

Revise Section end

perhaps I dont really want to create a huge table with all the possibilities laid out. Maybe I just want to test the conditions when the comparison is true.

print qq{\n}; ($kappa,$mu) = (0,15); $bool = $kappa < $mu; if( $kappa < $mu ){ # if( $bool ) $ret_value = sprintf "%-8s%d", '$kappa: ',$kappa; }else{ $ret_value = sprintf "%-8s%d", '$mu: ',$mu; } printf "%8d%s%-4d%s%-11d%s%s\n",$kappa,' < ',$mu,' -> ',$bool,'-> ',$r +et_value; __END__ $kappa < $mu -> boolean -> value we ask perl to return 0 < 15 -> 1 -> $kappa: 0

On my first comparison i know the comparison returns true. however I just want to show wat happens when the statement is false. I could just reverse the operator or the operands, but for whatever reason I am unable to do that. So I use the anti operation of While, Until, to increment my variable to a value that suits the condition. And then run my evaluating program on my required value.

print qq{\n}; $kappa++ until( $kappa > $mu ); $bool = $kappa < $mu; if( $kappa < $mu ){ # if( $bool ) $ret_value = sprintf "%-8s%d", '$kappa: ',$kappa; }else{ $ret_value = sprintf "%-8s%d", '$mu: ',$mu; } printf "%8d%s%-4d%s%-11d%s%s\n",$kappa,' < ',$mu,' -> ',$bool,'-> ',$r +et_value; __END__ $kappa < $mu -> boolean -> value we ask perl to return 16 < 15 -> 0 -> $mu: 15

This time I know the reverse is true, and my table only has the values for which I am interested in, rather than for all of the intervening values. Prior to chaining if I wanted to do this with more values I would have needed to use the relevant logical operators for my specification.

So one place this might come in handy is evaluating relations. Here is a simple contrived example that evaluates two permutations from six of a relation between addition of two numbers ad which of those numbers is larger. The point is that prior to chaining we will need to use the logical operators between the comparison operators. In theory chaining will now allow us to just enter the comparison relation in the until. However as oyu can see form this simple example, you will still need to calculate all the logic that you wish your program to convey.

# An approach to coding the proof for Distribution rule # for Summation and Union over the Natural Realm # re MF:C:155 my($nu,$lhs,$rhs); ($kappa,$mu,$nu) = (3,4,5); if( $kappa < $mu and $mu < $nu ){ print "Evaluating relation when \$kappa:$kappa < \$mu:$mu < \$nu:$nu +\n"; $lhs = $kappa + ( $mu < $nu ? $nu : $mu ); $rhs = ( $kappa + $mu ) < ( $kappa + $nu ) ? $kappa + $nu : $kappa + + $mu ; print "\$lhs:$lhs = \$kappa:$kappa + \$nu:$nu\n"; print "\$rhs:$rhs = \$kappa:$kappa + \$nu:$nu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'faile +d'; print qq{\n}; } until( $kappa > $mu and $mu > $nu ){ $mu *= $mu unless $mu > $nu; $kappa *= $kappa unless $kappa > $mu; # print "\$kappa:$kappa \$mu:$mu \$nu:$nu\n"; } #print "\$kappa:$kappa > \$mu:$mu > \$nu:$mu" #now we have interchanged the values not the operators if( $nu < $mu and $mu < $kappa ){ print "Evaluating relation when \$nu:$nu < \$mu:$mu < \$kappa:$kappa +\n"; $lhs = $nu + ( $mu > $kappa ? $mu : $kappa ); # $rhs = ( $nu > $mu ? $nu : $mu ) + ( $nu < $kappa ? $nu : $kappa ) +; $rhs = ( $nu + $mu ) > ( $nu + $kappa ) ? $nu + $mu : $nu + $kappa + ; print "\$lhs:$lhs = \$kappa:$kappa + \$mu:$mu\n"; print "\$rhs:$rhs = \$kappa:$kappa + \$mu:$mu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'faile +d'; print qq{\n}; } __END__ Evaluating relation when $kappa:3 < $mu:4 < $nu:5 $lhs:8 = $kappa:3 + $nu:5 $rhs:8 = $kappa:3 + $nu:5 Evaluation of relation succeeded Evaluating relation when $nu:5 < $mu:16 < $kappa:81 $lhs:86 = $kappa:81 + $mu:16 $rhs:86 = $kappa:81 + $mu:16 Evaluation of relation succeeded

Actually those if statements dont really need to be there, and by wrap the until in a subroutine, we may be able to do all the permutation logic programmatically...

this example is a work in progress, as I would like to develop the full relation proof. However there is enough here to satisfy the explanation of chaining, so it is published in its present format as wip (est. a week or less providing logic is sound.), along with a chaining example for the bleaders. And to make sure I have understood chaining properly, and that it is implemented as suggested.

What should be noted here is that while we are essentially hardcoding the relations as we expect them to turn out, we are programmatically altering the values to fit each subsequent permutation, which we could of course hardcode too, but wheres the fun in that?

So lets do the six permutations and then see if we can reduce them into a permutating program of a couple of subroutines.

REVISE SECTION: SOMETHINGS NOT QUITE RIGHT HERE

Apparantley all lhs and rhs cases should be of the form ( k + m ) or ( k + n ). ANd it would appear I have fixed the permutations to produce symmetrical output, rather than testing the same relation on each permutation.To Fix

An approach to the proof of the Distribution Rule for Summation and Union over the Natural Realm wrt MF(C):155 Prof.NJW

print qq{\nAn approach to the proof of the Distribution Rule for\n}; print qq{Summation and Union over the Natural Realm wrt MF(C):155 P.NJ +W\n}; # An approach to coding the proof for Distribution rule # for Summation and Union over the Natural Realm # re MF:C:155 #my($nu,$lhs,$rhs); ($kappa,$mu,$nu) = (3,4,5); until( $kappa < $mu and $mu < $nu ){ # skips this, already satisfied $mu *= $mu unless $mu > $nu; $kappa *= $kappa unless $kappa > $mu; print "\$kappa:$kappa \$mu:$mu \$nu:$nu\n"; } print "\nEvaluating relation (P1) when \$kappa:$kappa < \$mu:$mu < \$n +u:$nu\n"; $lhs = $kappa + ( $mu < $nu ? $nu : $mu ); $rhs = ( $kappa + $mu ) < ( $kappa + $nu ) ? $kappa + $nu : $kappa + + $mu ; print "\$lhs:$lhs = \$kappa:$kappa + \$nu:$nu\n"; print "\$rhs:$rhs = \$kappa:$kappa + \$nu:$nu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'failed' +; print qq{\n}; until( $kappa < $nu and $nu < $mu ){ $mu *= $mu unless $mu > $nu; $nu *= $nu unless $nu > $kappa; # print "\$kappa:$kappa \$nu:$nu \$mu:$mu\n"; } print "\nEvaluating relation when (P2) \$kappa:$kappa < \$nu:$nu < \$m +u:$mu\n"; $lhs = $kappa + ( $mu < $nu ? $nu : $mu ); $rhs = ( $kappa + $mu ) < ( $kappa + $nu ) ? $kappa + $nu : $kappa + + $mu ; print "\$lhs:$lhs = \$kappa:$kappa + \$mu:$mu\n"; print "\$rhs:$rhs = \$kappa:$kappa + \$mu:$mu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'failed' +; print qq{\n}; until( $mu < $kappa and $kappa < $nu ){ $nu *= $nu unless $nu > $kappa; $kappa *= $kappa unless $kappa > $mu; # print "\$mu:$mu \$kappa:$kappa \$nu:$nu\n"; } print "\nEvaluating relation (P3) when \$mu:$mu < \$kappa:$kappa < \$n +u:$nu\n"; $lhs = $mu + ( $kappa < $nu ? $nu : $kappa ); $rhs = ( $mu + $kappa ) < ( $mu + $nu ) ? $mu + $nu : $mu + $kappa ; print "\$lhs:$lhs = \$mu:$mu + \$nu:$nu\n"; print "\$rhs:$rhs = \$mu:$mu + \$nu:$nu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'failed' +; print qq{\n}; until( $mu < $nu and $nu < $kappa ){ $kappa *= $kappa unless $kappa > $nu; $nu *= $nu unless $nu > $mu; # print "\$mu:$mu \$nu:$nu \$kappa:$kappa\n"; } print "\nEvaluating relation (P4) when \$mu:$mu < \$nu:$nu < \$kappa:$ +kappa\n"; $lhs = $mu + ( $kappa < $nu ? $nu : $kappa ); $rhs = ( $mu + $kappa ) < ( $mu + $nu ) ? $mu + $nu : $mu + $kappa ; print "\$lhs:$lhs = \$mu:$mu + \$nu:$nu\n"; print "\$rhs:$rhs = \$mu:$mu + \$nu:$nu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'failed' +; print qq{\n}; until( $nu < $kappa and $kappa < $mu ){ $mu *= $mu unless $mu > $kappa; $kappa *= $kappa unless $kappa > $nu; # print "\$nu:$nu \$kappa:$kappa \$mu:$mu\n"; } print "\nEvaluating relation (P5) when \$nu:$nu < \$kappa:$kappa < \$m +u:$mu\n"; $lhs = $nu + ( $mu > $kappa ? $mu : $kappa ); $rhs = ( $nu + $mu ) > ( $nu + $kappa ) ? $nu + $mu : $nu + $kappa ; print "\$lhs:$lhs = \$kappa:$kappa + \$mu:$mu\n"; print "\$rhs:$rhs = \$kappa:$kappa + \$mu:$mu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'failed' +; print qq{\n}; until( $nu < $mu and $mu < $kappa ){ $kappa *= $kappa unless $kappa > $mu; $mu *= $mu unless $mu > $nu; # print "\$nu:$nu \$mu:$mu \$kappa:$kappa\n"; } print "\nEvaluating relation (P6) when \$nu:$nu < \$mu:$mu < \$kappa:$ +kappa\n"; $lhs = $nu + ( $mu > $kappa ? $mu : $kappa ); $rhs = ( $nu + $mu ) > ( $nu + $kappa ) ? $nu + $mu : $nu + $kappa ; print "\$lhs:$lhs = \$kappa:$kappa + \$mu:$mu\n"; print "\$rhs:$rhs = \$kappa:$kappa + \$mu:$mu\n"; print "Evaluation of relation ", $lhs == $rhs ? 'succeeded' : 'failed' +; print qq{\n\n};

output

An approach to the proof of the Distribution Rule for Summation and Union over the Natural Realm wrt MF(C):155 P.NJW Evaluating relation (P1) when $kappa:3 < $mu:4 < $nu:5 $lhs:8 = $kappa:3 + $nu:5 $rhs:8 = $kappa:3 + $nu:5 Evaluation of relation succeeded Evaluating relation when (P2) $kappa:3 < $nu:5 < $mu:16 $lhs:19 = $kappa:3 + $mu:16 $rhs:19 = $kappa:3 + $mu:16 Evaluation of relation succeeded Evaluating relation (P3) when $mu:16 < $kappa:81 < $nu:625 $lhs:641 = $mu:16 + $nu:625 $rhs:641 = $mu:16 + $nu:625 Evaluation of relation succeeded Evaluating relation (P4) when $mu:16 < $nu:625 < $kappa:6561 $lhs:6577 = $mu:16 + $nu:625 $rhs:6577 = $mu:16 + $nu:625 Evaluation of relation succeeded Evaluating relation (P5) when $nu:625 < $kappa:6561 < $mu:65536 $lhs:66161 = $kappa:6561 + $mu:65536 $rhs:66161 = $kappa:6561 + $mu:65536 Evaluation of relation succeeded Evaluating relation (P6) when $nu:625 < $mu:65536 < $kappa:43046721 $lhs:43047346 = $kappa:43046721 + $mu:65536 $rhs:43047346 = $kappa:43046721 + $mu:65536 Evaluation of relation succeeded

REVISE SECTION END: SOMETHINGS NOT QUITE RIGHT HERE All the relations have not succeeded!!

All relations succeeded (hopefully) and so we can see the Distribution Rule for Summation and Union over the Natural Realm holds, at least for all permutations of ordering three distinct values.

ToDo put the repeated code into subroutines. Evaluate when values are also equal, as this only evaluates at strictly distinct values. Also need to update the comparison subroutine to evaluate using the new chaining ability of operators with a bleading edge version of perl. Lets hope it does what we think it does.

  • Comment on Re: For discussion: operator attributes - associativity, chainity and ability to short-circuit
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: For discussion: operator attributes - associativity, chainity and ability to short-circuit
by rsFalse (Chaplain) on Jan 30, 2021 at 19:56 UTC
    Hello. Thank you for interesting read with mathematics included!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11127661]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (3)
As of 2024-04-25 09:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found