Re: more hyper-operators: reduce, thank-you! :) Of course, it'd still be
better as a hyper-operator instead of a function (so that it works on
operators too).
I wrote:
> (speaking of which, I'd like a uniq function to be part of perlfunc).
Damian wrote:
> uniq - remove duplicates without reordering
I now write "Sorry!"
Btw, even a complete list of built-in functions would be nice as a
synopsis; it would prevent ill-informed posts like most of my previous one;
Damian's one is a great start :).
:)
---------------------------------------------------------------------
| Name: Tim Nelson | Because the Creator is, |
| E-mail: way...@smartchat.net.au | I am |
---------------------------------------------------------------------
----BEGIN GEEK CODE BLOCK----
Version 3.12
GCS d+ s:- a- C++>++++$ U++ P++ L++ E- W+++ N+ w>--- V- Y+>++
PGP->++ R !tv b++ DI++++ D+ G e++>++++ h! y-
-----END GEEK CODE BLOCK-----
Incidentally, is there any chance we'll have more than one official
hyper-operator in Perl6? According to the S3, there's only one, "the"
hyper-operator, >><<. If I understand, hyper-operators are just operators
which operate on functions (including operators). We effectively already have
three more hyper-operators, "sort", "map" and "grep", all of which are
operators which take one function and one array. But I can also see uses for
some of the other ones from APL (where they call hyper-operators operators).
Maybe if we could work out some way to take the current perl
hyper-operator, and have it optionally f-Reduce (see APL) rather than
expanding arrays. Then we could do something better than:
----------------------------------------
@array = qw(1 2 3 4 5 6 7 8);
foreach(@array) { $total += @array; }
eg.
$total +=<<< @array;
----------------------------------------
For f-Reduce:
http://www.info.univ-angers.fr/pub/gh/wAides/sax6_userdoc.pdf
Look under Language Guide/Operators.
Yes, I suspect we really can't use <<<; maybe we could use some
unicode thing.
New comparison operator
-----------------------
It'd be nice to have a subset operator. If one operand is an array,
it says whether the other operand is a subset of it. If both operands are
scalar, it returns the position of one as a substring in the other.
Override comparison function
----------------------------
We have two set of operators for comparison, one for numeric, and one
for string. There are a variety of other comparisons possible, for example
case insensitive, soundex, Wagner-Fischer (cf. Text::WagnerFischer, agrep,
etc). I know that the first two can be simulated by running both operands
through a conversion function first, but this is a pain in eg. sort.
I was thinking that this also could be resolved with hyper-operators.
Imagine two hyper-operators, which I will call <s> (string), and <o> (other)
(these are not suggested syntax, but placeholders in this discussion). Then
we could do:
$a == $b
$a ==<s> $b
$a ==<o> $b
The first would be a numeric comparison, as always. The second would
be a string comparison. The third would be another comparison, and could be
redefined with eg. "use Text::WagnerFischer" or "use Text::Soundex".
It'd also be cool if we could do:
@a = sort<=><s> @b
(sort would default to sort <=>, but the above would do a string
comparison).
Or, as an alternate syntax (I don't mind the syntax, I just want the
functionality), we could have an internal function called eg. scalar_compare,
which points to scalar_compare_string. We'd keep all the current operators,
but when someone did "use Text::WagnerFischer qw(override_compare)", it would
repoint scalar_compare at scalar_compare_WagnerFischer, and all string
comparison functions (eg. eq, ne, sort) would automatically use the new
function.
Note both ways achieve what I want, but the first would have overrides
on a per-operator basis, whereas the second would make it the default for all
comparison functions. There are various middle ways, but I think the whole
thing could be easier this way.
Array operators (functions?)
---------------
It'd be nice to have awway union and intersection operators. I'm
assuming that all arrays in the following example have unique elements
(speaking of which, I'd like a uniq function to be part of perlfunc).
Union: Easily simulated with (@a, @b) ==> uniq ==> @c
Intersection: this one's harder:
foreach $avar (@a) { push @c, grep { /$avar/ } @b; }
-or-
@c = map { $avar = $_; grep { /$avar/ } @b } @a;
-or-
@a ==> map { $avar = $_; @b ==> grep { /$avar/ } } ==> @c;
...none of which are neat. Assuming we don't get an extra magic
variable (ie. $_ = this, $!!! = $that), it'd be nice to have something that
does this.
getfiledir function
-------------------
I don't see anything that talks about a perlfunc rewrite, so I thought
I'd comment on the one function I use in nearly *every* perl program I write.
Here it is:
sub getfiledir {
my($file) = @_;
my(@lines);
if(-d $file) { return(glob($file)) }
else {
open(FILE, $file) or die "Error: Can't open file '$file': $!";
@lines = <FILE>;
close(FILE) or die "Error: Can't close file '$file': $!";
}
}
That also lets me pass in command pipes ending in |.
-------------------------------------------------------------------
Anyway, hopefully someone will point out an easy way to do one or two
of the above with existing features, and the other(s) will be useful to the
community.
Just to straighten around our terminology here, we're reserving
the term "hyper operator" to refer only to explicitly parallelized
operators. (We tried briefly to call them "vector operators", but
that confused the mathmaticians.) Anyway, I think the term you're
looking for here is "higher-order function", if you're referring to
the semantics, or "meta-operator", if you're referring to the syntax.
Of course, these terms are all arbitrary, but that's how we're using
them currently.
: We effectively already have
: three more hyper-operators, "sort", "map" and "grep", all of which are
: operators which take one function and one array. But I can also see uses for
: some of the other ones from APL (where they call hyper-operators operators).
Well, in Perl 6 any operator that takes a closure as an argument is
essentially a higher-order function, which leads me to suspecty you're
mostly just asking for syntactic relief in the form of a meta-operator
that happens to implement a higher-order function.
: Maybe if we could work out some way to take the current perl
: hyper-operator, and have it optionally f-Reduce (see APL) rather than
: expanding arrays. Then we could do something better than:
: ----------------------------------------
: @array = qw(1 2 3 4 5 6 7 8);
: foreach(@array) { $total += @array; }
:
: eg.
:
: $total +=<<< @array;
: ----------------------------------------
:
: For f-Reduce:
: http://www.info.univ-angers.fr/pub/gh/wAides/sax6_userdoc.pdf
: Look under Language Guide/Operators.
:
: Yes, I suspect we really can't use <<<; maybe we could use some
: unicode thing.
I've explicitly made Unicode available for such purposes--though, to be
sure, you'll have to justify your use of esoteric operators to your own
audience. For Perl 6 itself we're intentionally restricting ourselves
to Latin-1.
: New comparison operator
: -----------------------
: It'd be nice to have a subset operator. If one operand is an array,
: it says whether the other operand is a subset of it. If both operands are
: scalar, it returns the position of one as a substring in the other.
This seems like a confusing spec. You don't seem to care about
the ordering of the array, but you do care about the ordering of
the string. That's not terribly consistent, especially to people
who view a string as essentially an array of characters. Or were
you thinking of the array's "subset" as a "subsequence"? (To me,
subsets aren't ordered because sets aren't ordered.)
: Override comparison function
: ----------------------------
:
: We have two set of operators for comparison, one for numeric, and one
: for string. There are a variety of other comparisons possible, for example
: case insensitive, soundex, Wagner-Fischer (cf. Text::WagnerFischer, agrep,
: etc). I know that the first two can be simulated by running both operands
: through a conversion function first, but this is a pain in eg. sort.
:
: I was thinking that this also could be resolved with hyper-operators.
: Imagine two hyper-operators, which I will call <s> (string), and <o> (other)
: (these are not suggested syntax, but placeholders in this discussion). Then
: we could do:
:
: $a == $b
: $a ==<s> $b
: $a ==<o> $b
:
: The first would be a numeric comparison, as always. The second would
: be a string comparison. The third would be another comparison, and could be
: redefined with eg. "use Text::WagnerFischer" or "use Text::Soundex".
:
: It'd also be cool if we could do:
: @a = sort<=><s> @b
:
: (sort would default to sort <=>, but the above would do a string
: comparison).
We have room in the grammar engine for defining various metasyntaxes
surrounding operators, so that >>+<< and += are just specific
examples of more generic operator transformations. However, we'll
try to discourage profligate use of such metasyntax as leading to
gobbledygook. Basically, you shouldn't be coining new verb forms
too frequently if there's another way to modify an existing verb.
And natural language provides just such a way with adverbs.
So instead, we're trying to encourage people to modify their operators
using an adverbial syntax. The prototypical example is the range operator:
for 1..100 :by(2) {...}
This is not exactly a higher-order function, though. There has to be
at least one range operator that understands the "by" option. We'll
eventually be relying on multiple dispatch to find that operator. Using
a higher-order function for this would be overkill.
: Or, as an alternate syntax (I don't mind the syntax, I just want the
: functionality), we could have an internal function called eg. scalar_compare,
: which points to scalar_compare_string. We'd keep all the current operators,
: but when someone did "use Text::WagnerFischer qw(override_compare)", it would
: repoint scalar_compare at scalar_compare_WagnerFischer, and all string
: comparison functions (eg. eq, ne, sort) would automatically use the new
: function.
A pragma can do anything it likes to the interpreation of the
subsequent lexical scope. But you have to be aware that you're
essentially creating a new language every time you do that, which
means you're potentially making liars of people who say on their
resume that they know Perl. :-)
Nevertheless, Perl 6 is designed around the notion that it is not a
single language, but rather a clade of related langauges.
: Note both ways achieve what I want, but the first would have overrides
: on a per-operator basis, whereas the second would make it the default for all
: comparison functions. There are various middle ways, but I think the whole
: thing could be easier this way.
Whether it's easier or not depends on which "whole thing" you're
talking about...
: Array operators (functions?)
: ---------------
: It'd be nice to have awway union and intersection operators. I'm
: assuming that all arrays in the following example have unique elements
: (speaking of which, I'd like a uniq function to be part of perlfunc).
:
: Union: Easily simulated with (@a, @b) ==> uniq ==> @c
: Intersection: this one's harder:
: foreach $avar (@a) { push @c, grep { /$avar/ } @b; }
: -or-
: @c = map { $avar = $_; grep { /$avar/ } @b } @a;
: -or-
: @a ==> map { $avar = $_; @b ==> grep { /$avar/ } } ==> @c;
:
: ...none of which are neat. Assuming we don't get an extra magic
: variable (ie. $_ = this, $!!! = $that), it'd be nice to have something that
: does this.
Hmm,
@c = (my %foo = (@a,@b)).keys;
might possibly be made to do an intersection. But I'm leary of such
shenanigans ever since seeing seeing Fortran code doing integerization
like this:
I = X
X = I
: getfiledir function
: -------------------
: I don't see anything that talks about a perlfunc rewrite, so I thought
: I'd comment on the one function I use in nearly *every* perl program I write.
: Here it is:
:
: sub getfiledir {
: my($file) = @_;
: my(@lines);
:
: if(-d $file) { return(glob($file)) }
: else {
: open(FILE, $file) or die "Error: Can't open file '$file': $!";
: @lines = <FILE>;
: close(FILE) or die "Error: Can't close file '$file': $!";
: }
: }
:
: That also lets me pass in command pipes ending in |.
Well, hey, we'll have to leave some of the programming up to you. :-)
Larry
> On Sat, Feb 12, 2005 at 05:55:48PM +1100, Timothy S. Nelson wrote:
> : More hyper-operators
> : --------------------
> :
> : Incidentally, is there any chance we'll have more than one official
> : hyper-operator in Perl6? According to the S3, there's only one, "the"
> : hyper-operator, >><<. If I understand, hyper-operators are just operators
> : which operate on functions (including operators).
> Just to straighten around our terminology here, we're reserving
> the term "hyper operator" to refer only to explicitly parallelized
> operators. (We tried briefly to call them "vector operators", but
> that confused the mathmaticians.) Anyway, I think the term you're
"foreaching operators?" :) "mapping operators"? I'm happy with it as
it is, though :).
> looking for here is "higher-order function", if you're referring to
> the semantics, or "meta-operator", if you're referring to the syntax.
> Of course, these terms are all arbitrary, but that's how we're using
> them currently.
:). I'd always called the things I'm talking about "meta-operators",
but was clearly mistaken in my assumption that hyper-operator was the Perl6
synonym. So yes, meta-operators is what I meant.
> : We effectively already have
> : three more hyper-operators, "sort", "map" and "grep", all of which are
> : operators which take one function and one array. But I can also see uses for
> : some of the other ones from APL (where they call hyper-operators operators).
>
> Well, in Perl 6 any operator that takes a closure as an argument is
> essentially a higher-order function, which leads me to suspecty you're
> mostly just asking for syntactic relief in the form of a meta-operator
> that happens to implement a higher-order function.
I guess :). Hmm. I think I was making a false distinction here:
sort, map, grep, et. al: take only a function as an operand
meta-operators: take a function *or an operator* as an operand
But presumably I could use operators as operands to sort et. al. by
invoking the function version of the operator (ie. &infix:<+> or whatever).
> : Maybe if we could work out some way to take the current perl
> : hyper-operator, and have it optionally f-Reduce (see APL) rather than
> : expanding arrays. Then we could do something better than:
> : ----------------------------------------
> : @array = qw(1 2 3 4 5 6 7 8);
> : foreach(@array) { $total += @array; }
> :
> : eg.
> :
> : $total +=<<< @array;
> : ----------------------------------------
> :
> : For f-Reduce:
> : http://www.info.univ-angers.fr/pub/gh/wAides/sax6_userdoc.pdf
> : Look under Language Guide/Operators.
> :
> : Yes, I suspect we really can't use <<<; maybe we could use some
> : unicode thing.
>
> I've explicitly made Unicode available for such purposes--though, to be
> sure, you'll have to justify your use of esoteric operators to your own
> audience. For Perl 6 itself we're intentionally restricting ourselves
> to Latin-1.
I'll make do with the reduce builtin which I only discovered (from an
e-mail of Damian) after writing my original e-mail.
> : New comparison operator
> : -----------------------
> : It'd be nice to have a subset operator. If one operand is an array,
> : it says whether the other operand is a subset of it. If both operands are
> : scalar, it returns the position of one as a substring in the other.
>
> This seems like a confusing spec. You don't seem to care about
> the ordering of the array, but you do care about the ordering of
> the string. That's not terribly consistent, especially to people
> who view a string as essentially an array of characters. Or were
> you thinking of the array's "subset" as a "subsequence"? (To me,
> subsets aren't ordered because sets aren't ordered.)
:). Ok, two new operators :). I guess I was just thinking of what
people would often use, and putting them both on the same operator. But
assuming that we still have index and substr from perlfunc, the subsequence
probably isn't important enough to make a separate operator. And the subset
one could be simulated pretty easily with my suggested union op below, eg.
if(@a >>==<< (@a union @b)) {...
> : Override comparison function
> : ----------------------------
> :
> : We have two set of operators for comparison, one for numeric, and one
> : for string. There are a variety of other comparisons possible, for example
> : case insensitive, soundex, Wagner-Fischer (cf. Text::WagnerFischer, agrep,
> : etc). I know that the first two can be simulated by running both operands
> : through a conversion function first, but this is a pain in eg. sort.
> :
> : I was thinking that this also could be resolved with hyper-operators.
> : Imagine two hyper-operators, which I will call <s> (string), and <o> (other)
> : (these are not suggested syntax, but placeholders in this discussion). Then
> : we could do:
> :
> : $a == $b
> : $a ==<s> $b
> : $a ==<o> $b
> :
> : The first would be a numeric comparison, as always. The second would
> : be a string comparison. The third would be another comparison, and could be
> : redefined with eg. "use Text::WagnerFischer" or "use Text::Soundex".
> :
> : It'd also be cool if we could do:
> : @a = sort<=><s> @b
> :
> : (sort would default to sort <=>, but the above would do a string
> : comparison).
>
> We have room in the grammar engine for defining various metasyntaxes
> surrounding operators, so that >>+<< and += are just specific
> examples of more generic operator transformations. However, we'll
Great! :). Do all the comparison ops point to the same base?
> try to discourage profligate use of such metasyntax as leading to
> gobbledygook. Basically, you shouldn't be coining new verb forms
> too frequently if there's another way to modify an existing verb.
> And natural language provides just such a way with adverbs.
Hmm, sounds like a COBOL vs. APL argument :} (<--evil grin). Now I'm
wondering what they do with adverbs in mathematics :).
...so I asked my dad, who is a physicist/engineer. He couldn't think
of any particularly striking examples. But the examples he did manage to
think of, people had to figure stuff out from context (as in natural language,
but not as in COBOL :) ).
Here's an even better idea; we could (and this is for modules written
after, not part of the language design) overload the with operator, so that,
in addition to having a pascal-like "with" operator for objects, with could be
overloaded so that you could say:
use Text::WagnerFischer;
with override(WagnerFischer) {
$a == $b;
}
I guess the idea here is that override is a function (again, not
necessarily built-in, but hopefully part of the standard distribution) where
we could pass in a child of Override (an object), in this case WagnerFischer,
which would have methods "override" and "un_override", and basically the first
gets called at the start of the block, and the second gets called at the end.
Ok, sorry for rambling, but I've worked out a good way to achieve what
I wanted, so I'm happy :).
> So instead, we're trying to encourage people to modify their operators
> using an adverbial syntax. The prototypical example is the range operator:
>
> for 1..100 :by(2) {...}
>
> This is not exactly a higher-order function, though. There has to be
> at least one range operator that understands the "by" option. We'll
> eventually be relying on multiple dispatch to find that operator. Using
> a higher-order function for this would be overkill.
Good :). This gets to the point where I'd prefer a two-dimensional
medium, rather than the single dimension of program code, so we could have:
by(2)
V
for 1..100 {...}
Yeah, silly for this, I know, but then, I am kinda silly. Or even
edgescritps? (whatever those things around the sigma and integral signs in
mathematics are). We can't do those either. Still, no point complaining
about the medium when that's what we've got :).
> : Or, as an alternate syntax (I don't mind the syntax, I just want the
> : functionality), we could have an internal function called eg. scalar_compare,
> : which points to scalar_compare_string. We'd keep all the current operators,
> : but when someone did "use Text::WagnerFischer qw(override_compare)", it would
> : repoint scalar_compare at scalar_compare_WagnerFischer, and all string
> : comparison functions (eg. eq, ne, sort) would automatically use the new
> : function.
>
> A pragma can do anything it likes to the interpreation of the
> subsequent lexical scope. But you have to be aware that you're
> essentially creating a new language every time you do that, which
> means you're potentially making liars of people who say on their
> resume that they know Perl. :-)
Guess I'll have to start looking for resumes with EvilPerl(TM) (that
would be the modified version) :).
> Nevertheless, Perl 6 is designed around the notion that it is not a
> single language, but rather a clade of related langauges.
:). My new word for the day (clade). I hope that's what you're
aiming for, because I like Unicode operators :). But I think I'll need a
keyboard redesign :).
> : Note both ways achieve what I want, but the first would have overrides
> : on a per-operator basis, whereas the second would make it the default for all
> : comparison functions. There are various middle ways, but I think the whole
> : thing could be easier this way.
>
> Whether it's easier or not depends on which "whole thing" you're
> talking about...
"Whole thing" being changing the comparison operators :).
> : Array operators (functions?)
> : ---------------
> : It'd be nice to have awway union and intersection operators. I'm
> : assuming that all arrays in the following example have unique elements
> : (speaking of which, I'd like a uniq function to be part of perlfunc).
> :
> : Union: Easily simulated with (@a, @b) ==> uniq ==> @c
> : Intersection: this one's harder:
> : foreach $avar (@a) { push @c, grep { /$avar/ } @b; }
> : -or-
> : @c = map { $avar = $_; grep { /$avar/ } @b } @a;
> : -or-
> : @a ==> map { $avar = $_; @b ==> grep { /$avar/ } } ==> @c;
> :
> : ...none of which are neat. Assuming we don't get an extra magic
> : variable (ie. $_ = this, $!!! = $that), it'd be nice to have something that
> : does this.
>
> Hmm,
>
> @c = (my %foo = (@a,@b)).keys;
>
> might possibly be made to do an intersection. But I'm leary of such
Leary? http://www.google.com.au/search?hl=en&q=define%3Aleary Very
appropriate, although I thought maybe you actually meant leery.
http://www.google.com.au/search?hl=en&q=define%3Aleery&meta=
> shenanigans ever since seeing seeing Fortran code doing integerization
> like this:
>
> I = X
> X = I
:). Well, I must admit, I can understand the ForTran more easily that
the Perl example you gave above. To me, the intuitive sense of your perl code
would be a union. And using your example, my example under subset would then
be *really* awful.
> : getfiledir function
> : -------------------
> : I don't see anything that talks about a perlfunc rewrite, so I thought
> : I'd comment on the one function I use in nearly *every* perl program I write.
> : Here it is:
> :
> : sub getfiledir {
> : my($file) = @_;
> : my(@lines);
> :
> : if(-d $file) { return(glob($file)) }
> : else {
> : open(FILE, $file) or die "Error: Can't open file '$file': $!";
> : @lines = <FILE>;
> : close(FILE) or die "Error: Can't close file '$file': $!";
> : }
> : }
> :
> : That also lets me pass in command pipes ending in |.
>
> Well, hey, we'll have to leave some of the programming up to you. :-)
Sorry, I've just worked out that, while I'm not sure I understand your
comments on RFC 051 in A2, it looks like there'll be a function where I pass
it a filename and it returns the contents, and that's what I want; I presume
this closes it after.
Thanks, and btw, since I haven't said this yet, Perl6 looks great so
far, especially sub flexibility and grammars+rules :).
>
> Sorry, I've just worked out that, while I'm not sure I understand your
> comments on RFC 051 in A2, it looks like there'll be a function where I pass
> it a filename and it returns the contents, and that's what I want; I presume
> this closes it after.
Yes. The function is called C<slurp>. See:
http://search.cpan.org/~dconway/Perl6-Slurp-0.03/Slurp.pm
Damian