Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Perl: porters

Custom infix operators (was: feature request: string-or)

 

 

Perl porters RSS feed   Index | Next | Previous | View Threaded


petercmartini at gmail

Aug 4, 2013, 8:33 AM

Post #1 of 8 (56 views)
Permalink
Custom infix operators (was: feature request: string-or)

On Sun, Aug 4, 2013 at 1:40 AM, Father Chrysostomos <sprout [at] cpan> wrote:
> Felipe Gasper asked:
>> Where can I find documentation on implementing custom operators in Perl?
>
> Perl currently has no mechanism for custom infix operators. It has
> been discussed a few times, but no serious volunteers have stepped up
> to the challenge. Peter Martini submitted a demo patch (just a toy),
> but it was barely sufficient, only allowing two precedence levels
> (<https://github.com/PeterMartini/perl/tree/peter/infix>).
>

Of the potential issues with the patch, I hadn't though an
insufficient number of precedence levels would be one of them, the
distinction being, conceptually, like 'and' or like '&&'. Can you
give more details on what other precedence levels could be offered?

I didn't push any further with the patch mainly because (as far as I
know) the custom operators we have already were designed by Zefram,
and he's not happy with how its currently done, so pushing further
seemed unwise without proper insight into what the problems are.


sprout at cpan

Aug 4, 2013, 11:01 AM

Post #2 of 8 (52 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

Peter Martini asked:
> Can you
> give more details on what other precedence levels could be offered?

Why not offer all of them? (Caveat: I may be misreading your patch.
I do not know yacc in depth.)


petercmartini at gmail

Aug 4, 2013, 12:04 PM

Post #3 of 8 (52 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

On Sun, Aug 4, 2013 at 2:01 PM, Father Chrysostomos <sprout [at] cpan> wrote:
> Peter Martini asked:
>> Can you
>> give more details on what other precedence levels could be offered?
>
> Why not offer all of them? (Caveat: I may be misreading your patch.
> I do not know yacc in depth.)
>

Nevermind, you're completely on point. As far as a reason to not
offer all of them - that could get very messy. Putting this on my
list of things to chew on...


eda at waniasset

Aug 6, 2013, 3:08 AM

Post #4 of 8 (40 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

Adding custom infix operators would make it easier to get rid of smartmatch.

--
Ed Avis <eda [at] waniasset>


davidnicol at gmail

Aug 7, 2013, 1:43 PM

Post #5 of 8 (32 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

On Tue, Aug 6, 2013 at 5:08 AM, Ed Avis <eda [at] waniasset> wrote:

> Adding custom infix operators would make it easier to get rid of
> smartmatch.
>

yes, but how? Without breaking indirect method invocation? Would there be a
readily identifiable set of tokens that are reserved as infix operators? An
"insub" keyword? A
special prototype that means "infix binary" with variations indicating
precedence? And how would this interoperate to the yacc-generated parsing?

If wishes were bicycles...


aaron at priven

Aug 7, 2013, 3:55 PM

Post #6 of 8 (31 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

On Aug 7, 2013, at 1:43 PM, David Nicol <davidnicol [at] gmail> wrote:
> On Tue, Aug 6, 2013 at 5:08 AM, Ed Avis <eda [at] waniasset> wrote:
> Adding custom infix operators would make it easier to get rid of smartmatch.
>
> yes, but how? Without breaking indirect method invocation?

Um, that might be OK.

I'm the first to admit I have no idea how to solve the other issues though.

> Would there be a readily identifiable set of tokens that are reserved as infix operators? An "insub" keyword? A
> special prototype that means "infix binary" with variations indicating precedence? And how would this interoperate to the yacc-generated parsing?


--
Aaron Priven, aaron [at] priven, www.priven.com/aaron


latk at gmx

Aug 9, 2013, 3:45 AM

Post #7 of 8 (21 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

Am 07.08.2013 22:43, schrieb David Nicol:
>
>
> On Tue, Aug 6, 2013 at 5:08 AM, Ed Avis <eda [at] waniasset
> <mailto:eda [at] waniasset>> wrote:
>
> Adding custom infix operators would make it easier to get rid of
> smartmatch.
>
>
> yes, but how? Without breaking indirect method invocation? Would there
> be a readily identifiable set of tokens that are reserved as infix
> operators? An "insub" keyword? A
> special prototype that means "infix binary" with variations indicating
> precedence? And how would this interoperate to the yacc-generated parsing?
>
> If wishes were bicycles...

There are various sane ways how custom binops could be added. A brainstorm:

0. Ignore custom operators, as autoboxing and operator overloading
provide sufficient chances for syntactic mayhem.

1.1 Have a special binop operator. E.g. in Haskell, you can write "x
`foo` y" which is syntactic sugar for "foo(x, y)". Perl would need
another character. Interesting candidates are:

- Some already-used symbols (the code would already have a meaning,
but spacing could be used to disambiguate): "$x :myop: $y", "$x ?myop?
$y", "$x !myop! $y", "$x |myop| $y", "$x ^myop^ $y", "$x ~myop~ $y", "$x
%myop% $y", ...
As e.g. "^" isn't used that much, this might not be so bad after
all. Only one such character should be chosen. The Sub::Infix module
implements this is a very inefficient way.

- Non-ASCII characters. "$x 〈myop〉 $y", "$x ★myop★ $y", "$x «myop»
$y". This is probably a bad idea, as this would require "utf8", and
opens Pandora's Box for other Unicode syntax. OTOH, this is very orthogonal.

If any such solution is chosen, precedence and context have to be fixed.
Custom operators should be non-associative to impose minimum assumptions
on user operators. The precedence level should be roughly as low as
other operators with word characters. Choosing the precedence of the
"eq" or "cmp" operator would feel nice.

It would be sensible to ignore any prototypes of the "myop" sub, and
impose semantics like the (+) or ($) prototype on each operand.

1.2 Allow existing operators to enclose a sub name. This custom
operator would then take on precedence and associativity etc. of the
enclosing operator. This makes sufficient sense for the operators "* / %
+ - . << >> < > <= >= == != ~~ & | ^ ..". Silly example:
my $matrix = [1..3] *x* [-1..1];
# my $matrix = &x([1..3], [-1..1]);
Maybe more complex stuff could be enclosed on curlies, so that "+foo+"
is equivalent to "+{\&foo}+". Then:
say for 3 ..{range_step(2)}.. 19;
# say for range_step(2)->(3, 19);
The above points about ambiguity still hold. I am not that fond of this
idea, because having an operator contain both symbols and word
characters could be a bit confusing: "foo() if $x <<a_lot_less<< $y".

2. Pick a few Unicode blocks and let those symbols be used as binops
(save for those that look too similar to existing operators). This would
require an "operators" pragma (or feature providing declaration syntax)
to map symbols to subs. Major disadvantage is the difficulty of typing
these characters. But a "$x ∈ %hash" would be cool (∈ could cover half
of the smartmatch cases). I do not like this, because the next logical
step would be custom circumfix operators, and parsing *that* in a sane
way is unrealistic for Perl5.

3. Using prototypes to declare binops is unrealistic in my opinion.
This is a lot of action at a distance, and renders the use of stacking
subs like "foo bar baz $x" utterly incomprehensible for a human reader.

Incidentally, these ideas are sorted in estimated difficulty of
implementation.

-- Lukas Atkinson / amon


fraserbn at gmail

Aug 10, 2013, 11:04 PM

Post #8 of 8 (20 views)
Permalink
Re: Custom infix operators (was: feature request: string-or) [In reply to]

On Fri, Aug 9, 2013 at 7:45 AM, Lukas Atkinson (amon) <latk [at] gmx> wrote:

> Am 07.08.2013 22:43, schrieb David Nicol:
> >
> >
> > On Tue, Aug 6, 2013 at 5:08 AM, Ed Avis <eda [at] waniasset
> > <mailto:eda [at] waniasset>> wrote:
> >
> > Adding custom infix operators would make it easier to get rid of
> > smartmatch.
> >
> >
> > yes, but how? Without breaking indirect method invocation? Would there
> > be a readily identifiable set of tokens that are reserved as infix
> > operators? An "insub" keyword? A
> > special prototype that means "infix binary" with variations indicating
> > precedence? And how would this interoperate to the yacc-generated
> parsing?
> >
> > If wishes were bicycles...
>
> There are various sane ways how custom binops could be added. A brainstorm:
>
> 0. Ignore custom operators, as autoboxing and operator overloading
> provide sufficient chances for syntactic mayhem.
>
> 1.1 Have a special binop operator. E.g. in Haskell, you can write "x
> `foo` y" which is syntactic sugar for "foo(x, y)". Perl would need
> another character. Interesting candidates are:
>
> - Some already-used symbols (the code would already have a meaning,
> but spacing could be used to disambiguate): "$x :myop: $y", "$x ?myop?
> $y", "$x !myop! $y", "$x |myop| $y", "$x ^myop^ $y", "$x ~myop~ $y", "$x
> %myop% $y", ...
> As e.g. "^" isn't used that much, this might not be so bad after
> all. Only one such character should be chosen. The Sub::Infix module
> implements this is a very inefficient way.
>
> - Non-ASCII characters. "$x 〈myop〉 $y", "$x ★myop★ $y", "$x «myop»
> $y". This is probably a bad idea, as this would require "utf8", and
> opens Pandora's Box for other Unicode syntax. OTOH, this is very
> orthogonal.
>
> If any such solution is chosen, precedence and context have to be fixed.
> Custom operators should be non-associative to impose minimum assumptions
> on user operators. The precedence level should be roughly as low as
> other operators with word characters. Choosing the precedence of the
> "eq" or "cmp" operator would feel nice.
>
> It would be sensible to ignore any prototypes of the "myop" sub, and
> impose semantics like the (+) or ($) prototype on each operand.
>
> 1.2 Allow existing operators to enclose a sub name. This custom
> operator would then take on precedence and associativity etc. of the
> enclosing operator. This makes sufficient sense for the operators "* / %
> + - . << >> < > <= >= == != ~~ & | ^ ..". Silly example:
> my $matrix = [1..3] *x* [-1..1];
> # my $matrix = &x([1..3], [-1..1]);
> Maybe more complex stuff could be enclosed on curlies, so that "+foo+"
> is equivalent to "+{\&foo}+". Then:
> say for 3 ..{range_step(2)}.. 19;
> # say for range_step(2)->(3, 19);
> The above points about ambiguity still hold. I am not that fond of this
> idea, because having an operator contain both symbols and word
> characters could be a bit confusing: "foo() if $x <<a_lot_less<< $y".
>
> 2. Pick a few Unicode blocks and let those symbols be used as binops
> (save for those that look too similar to existing operators). This would
> require an "operators" pragma (or feature providing declaration syntax)
> to map symbols to subs. Major disadvantage is the difficulty of typing
> these characters. But a "$x ∈ %hash" would be cool (∈ could cover half
> of the smartmatch cases). I do not like this, because the next logical
> step would be custom circumfix operators, and parsing *that* in a sane
> way is unrealistic for Perl5.
>
> 3. Using prototypes to declare binops is unrealistic in my opinion.
> This is a lot of action at a distance, and renders the use of stacking
> subs like "foo bar baz $x" utterly incomprehensible for a human reader.
>
> Incidentally, these ideas are sorted in estimated difficulty of
> implementation.
>

Having already implemented a subset of 2 and 3[*], I can safely say those
are easier to implement than 1.1 and 1.2, not even taking into account that
overloading current operators even more would just cause headaches and edge
cases. 1.1 + Unicode would be doable but seems needlessly restrictive; I'd
rather have 2, then use D::CP to attach a custom parser to search for the
next symbol.

That being said, I don't think that "this has the potential to be written
in a confusing way" is a valid argument. You can write all sorts of
"incomprehensible" code right now (e.g. foo bar baz quux, or foo + bar, or
the example you provided, which has several meanings right now), and our
reactions generally aren't to wish that we didn't have prototypes/indirect
object syntax[**], but instead to modify the code to be sensical, like by
adding parenthesis, or explicit method calls, or abstracting to a sub. Perl
mostly gives you rope, and it's up to the programmer to decide how to use
it.

Implementation-wise, I believe that there's two big roadblocks for infix
operators:
First, there's currently no easy way to pick a given level of precedence
without adding a huge chunk of code to perly.y. Mind you, I'm barely
knowledgable in yacc/bison, so maybe there's a super easy way to do this? I
would be more than glad to be corrected here. This is because, taking
and/or as an example, a user might want a precedence levels that is "higher
than and/or", "same as and/or", or "lower than and/or," and then each of
those has three extra versions, one for non associative, and two for
left/right associative -- which nets you nine new entries to the precedence
table in perly.y, just for one existing level. Peter settled for adding two
levels for starters -- since I was implementing infix subs, I only needed
to add one.
Second, we don't have lazy arguments yet, so some cool uses of infix
operators go right out of the window. Self-plug here, because I'm working
on this :D [***]


[*] Well, implemented 3, then wrote a quick hack for "use operators" and
set ∈ to an infix sub.
[**] Er, not all of us.
[***] https://github.com/Hugmeir/Params-Lazy

Perl porters RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.