Re: Hints Towards Writing a Module with New Operators
by moritz (Cardinal) on Dec 19, 2009 at 22:48 UTC
|
use v6;
multi sub infix:<.EQV.>($x, $y) { $x == $y };
say 1 .EQV. 1;
say 1 .EQV. 2;
When you run this with Rakudo, it prints
1
0
| [reply] [d/l] [select] |
Re: Hints Towards Writing a Module with New Operators
by JadeNB (Chaplain) on Dec 20, 2009 at 00:37 UTC
|
The little Fortran documentation that I can find by Googling suggests that, as moritz (implicitly) points out, .EQV. is just == on Booleans. If this is correct, are you just looking to bring to Perl the syntactic beauty of Fortran :-)—or is it that you want something that does the Boolean conversion for you, so that you can write $a .EQV. $b ** as the equivalent of $a ? $b ? 1 : 0 : $b ? 0 : 1 *?
Either way, as moritz says, for adding new syntax to Perl-as-it-now-is, I think that the only options are syntax filters (struck out as I write it so that you don't even think about it) or Devel::Declare (which worries adamk).
* Or ($a && $b) || !($a || $b), I suppose. UPDATE: Ha, and maybe I'd like to write my own routines for addition while I'm at it. Thanks, JavaFan. :-)
UPDATE: ** Note that this precise syntax conflicts with string concatenation, but we shouldn't be using barewords anyway.
| [reply] [d/l] [select] |
|
!($a xor $b)
| [reply] [d/l] |
|
Or
- .NEQV. ~= $a ^ $b
- .EQV. ~= !($a ^ $b)
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
|
|
!$a == !$b
but that relies on the fact than the true and false values returned by Perl ops are 1) always the same, and 2) numeric*. xor is definitely the way to go.
* — They're also strings, but that's not relevant here.
| [reply] [d/l] [select] |
|
Considering .EQV. as == for booleans is more or less correct: a .eqv. b is true if a and b are either both true or both false, and it would result in false otherwise. Most modern Fortran compilers will squawk if either a or b isn't a boolean (Fortran logical), so a fragment like
logical boole
integer int
int = 42
boole = .TRUE.
write(*,*) 'is int .eqv. boole true?', int .eqv. boole
will cause a compile-time error, which is, on the whole, probably a good thing.
As I said in my original post, I've been programming Fortran for quite a few years and never found a use for .eqv. or .neqv.. As an aside, Fortran is insensitive to case; I tend to use uppercase for Fortran keywords and lowercase for everything else.
Information about American English usage here and here. Floating point issues? Please read this before posting. — emc
| [reply] [d/l] |
Re: Hints Towards Writing a Module with New Operators
by duelafn (Parson) on Dec 20, 2009 at 16:58 UTC
|
# IHeartFortran.pm
package IHeartFortran;
use strict; use warnings;
require Exporter;
our @ISA = qw( Exporter );
our @EXPORT = qw/ EQV NEQV /;
use overload '.' => \&_do_op;
sub _do_op {
my ($self, $y, $reverse) = @_;
$$self{ $reverse ? 'left' : 'right' } = $y;
if (exists($$self{left}) and exists($$self{right})) {
return $$self{op}->(@$self{qw/ left right /});
}
return $self;
}
sub new {
my ($class, $op) = @_;
bless { op => $op }, $class;
}
sub EQV() { __PACKAGE__->new( sub { $_[0] == $_[1] ? 1 : 0 } ) }
sub NEQV() { __PACKAGE__->new( sub { $_[0] != $_[1] ? 1 : 0 } ) }
Then to use it:
#!/usr/bin/perl
use strict; use warnings; use 5.010;
use IHeartFortran;
say 1 .EQV. 1;
say 1 .EQV. 2;
say 1 .NEQV. 1;
say 1 .NEQV. 2;
This doesn't exactly create a .EQV. operator (for instance, spaces would be allowed: 1 . EQV . 2), but it looks good enough.
update: Actually, I think FORTRAN's whitespace rules would allow extra spaces anyway, so perhaps this is a somewhat faithful recreation anyway. Case flexibility on the other hand...
| [reply] [d/l] [select] |
Re: Hints Towards Writing a Module with New Operators
by Anonymous Monk on Dec 20, 2009 at 01:20 UTC
|
I thought of overload but after having gone through writing a demonstration, I discovered what appears to be a fact that logical operators like .EQV. and .NEQV. which are non-Perl can not be overloaded and that there are restrictions on what can be overloaded within Perl itself -if I understood that well- because of the degeneracy of operators and that overloading all in all can cause certain operators to lose their magical properties (ex, x=, .=) ... seeking enlightenment on this Monks.. | [reply] |
|
I discovered what appears to be a fact that logical operators like .EQV. and .NEQV. which are non-Perl can not be overloaded and that there are restrictions on what can be overloaded within Perl itself
This is basically correct, although the wording is strange. Overloading is something applied to objects, not operators; it changes how an object behaves when an operator is applied to it, without changing the default behaviour of that operator.
UPDATE: Perhaps the confusion comes from the term ‘operators’? Unlike some languages, the only kind of ‘operators’ that can be defined in Perl are prefix, and their names must be alphanumeric (or else invoked by &{...}-style trickery); there is no provision in Perl (or, rather, in the parser for Perl) for a user-defined infix or postfix operator—that's the price we pay for the syntactic flexibility that's already available.
the degeneracy of operators
I don't know what this means.
cause certain operators to lose their magical properties (ex, x=, .=)
Perhaps what you mean is that one can overload, say, x and x= separately, and that the overloaded behaviours need have nothing to do with one another? This is true, but not necessary: It's perfectly possible to overload, say, just x, and let Perl figure out for you how to perform x=.
| [reply] [d/l] [select] |
|
"Overloading is something applied to objects, not operators"
There's a concept called "Operator Overloading" that allows you to provide your own versions of operators to perform operations on class objects such as addition and subtraction of these objects lest Perl would treat these objects as strings that describe the class, a "string" here represents implementation and memory address (aka, references). If an operator is not overloaded and you called say + or - to add or subtract two objects (e.g defined data types) Perl would add/subtract on something like "Date=HASH(0x80f11fc)" ergo the need for Operator overloading which is described as:
"When you overload one of Perl's built-in operators, you define how it behaves when it's applied to objects of a particular class", from Programming Perl.
However, it seems that with overloading, there's a mixed statement because others describe it as:
"The module overload.pm is a standard part of the Perl distribution. It allows your objects to define how they will react to a number of Perl's operators. " from Perl.com
"the only kind of ‘operators’ that can be defined in Perl are prefix, and their names must be alphanumeric"
You can define addition and subtraction operators, built-in functions, prefix and post fix operators and around 50 other functions out there...
I think the entire concept is full of hassles that can be circumvented otherways around, but this is a SWAG for I don't have such information...and this discussion is amazing and informative... keep it going....
| [reply] |