Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

toggle operator missing reset: proposal #12632

Closed
p5pRT opened this issue Dec 8, 2012 · 15 comments
Closed

toggle operator missing reset: proposal #12632

p5pRT opened this issue Dec 8, 2012 · 15 comments

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented Dec 8, 2012

Migrated from rt.perl.org#116020 (status was 'rejected')

Searchable as RT116020$

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 8, 2012

From tlhackque@yahoo.com

Created by tlhackque@yahoo.com

This is a bug report for perl from tlhackque@​yahoo.com,
generated with the help of perlbug 1.39 running under perl 5.14.3.

-----------------------------------------------------------------
As others have noted, the perl toggle (a.k.a. range) operator
has the odd property that it has global state, which can't be reset.

This makes its use difficult where the input is external.

Consider the case where we want to extract lines from a file
between marker --a and --b. We code something like (reduced)​:
sub extract {
  my $out = '';
  while( <F> ) {
  $out .= $_ if /^--a$/ ... /^--b/;
  }
  return $out;
}
print extract("filea"), extract("second");

This is great, until we encounter a filea that is missing the (last) --b marker.
When we call extract with the second file, the ... operator is looking for --b, so
the first block of the second file isn't included.

Various work-arounds have been used; typically arranging for an "extra" end marker to be
passed through the toggle. This is awkward, since it has to be the same operator in the same
line of code. So we end up reading a file into an array of lines, or putting the test in a subroutine
or ...

My proposal​:
  Since we can label any statement (now), why not have the reset operator take a label argument?
  Then reset can act on the toggle(s) in that statement.

  So the minimum implemention would permit​:
sub extract {
  my $out = '';
  reset TOGGLE;
  while( <F> ) {
TOGGLE​:
  $out .= $_ if /^--a$/ ... /^--b/;
  }
  return $out;
}

  Here, reset will initialize every toggle operator in the labeled statement.

  Extra credit​:

  if the label is indexed, initialize the n'th toggle. E.g. The LABEL has the semantics of
  an array of the operators in the following statement.

  A somewhat contrived example​:

  reset TOGGLES[0,2];

TOGGLES​:
  $x = /^--a/ ... /^--b/ || /^--c/ ... /^--d/ || /^--e/ ... /^--f/;

  initializes the first and third toggles, but doesn't touch the second.

This seems useful, consistent with Perl syntax and yet new syntax that won't break any existing code.

I think it would solve this long-standing divot in Perl's semantics.

Perl Info

Flags:
    category=core
    severity=wishlist

This perlbug was built using Perl 5.14.3 in the Fedora build system.
It is being executed now by Perl 5.14.3 - Thu Oct 18 13:30:29 UTC 2012.

Site configuration information for perl 5.14.3:

Configured by Red Hat, Inc. at Thu Oct 18 13:30:29 UTC 2012.

Summary of my perl5 (revision 5 version 14 subversion 3) configuration:
   
  Platform:
    osname=linux, osvers=2.6.32-279.9.1.el6.x86_64, archname=x86_64-linux-thread-multi
    uname='linux buildvm-03.phx2.fedoraproject.org 2.6.32-279.9.1.el6.x86_64 #1 smp fri aug 31 09:04:24 edt 2012 x86_64 x86_64 x86_64 gnulinux '
    config_args='-des -Doptimize=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4  -m64 -mtune=generic -Dccdlflags=-Wl,--enable-new-dtags -Dlddlflags=-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4  -m64 -mtune=generic -Wl,-z,relro  -DDEBUGGING=-g -Dversion=5.14.3 -Dmyhostname=localhost -Dperladmin=root@localhost -Dcc=gcc -Dcf_by=Red Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl5 -Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5 -Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5 -Dvendorarch=/usr/lib64/perl5/vendor_perl -Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Duseshrplib -Dusethreads -Duseithreads -Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbin!
 perl=n -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto -Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto -Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.7.2 20120921 (Red Hat 4.7.2-2)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='gcc', ldflags =' -fstack-protector'
    libpth=/usr/local/lib64 /lib64 /usr/lib64
    libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc -lgdbm_compat
    perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.15'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wl,-z,relro '

Locally applied patches:
    


@INC for perl 5.14.3:
    /usr/local/lib64/perl5
    /usr/local/share/perl5
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5
    .


Environment for perl 5.14.3:
    HOME=/root
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2012

From @iabyn

On Sat, Dec 08, 2012 at 03​:56​:33AM -0800, via RT wrote​:

Since we can label any statement (now), why not have the reset operator take a label argument?
Then reset can act on the toggle(s) in that statement.

So the minimum implemention would permit​:
sub extract {
my $out = '';
reset TOGGLE;

but C<reset TOGGLE> currently means the same as C<reset "TOGGLE">
(which means the same as C<reset "EGLOT">).

--
The crew of the Enterprise encounter an alien life form which is
surprisingly neither humanoid nor made from pure energy.
  -- Things That Never Happen in "Star Trek" #22

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2012

The RT System itself - Status changed from 'new' to 'open'

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 10, 2012

From tlhackque@yahoo.com

Fair observation.

Other syntax would work - pehaps "reset [label]" ?

Surely an arrayref is currently a nonsensical argument to reset...which
is what this would look like to current Perl. To make it easy to
parse, we could even say reset ['label'] - so no special handling in
the []s.

I'm not a Perl internals person, so certainly other ideas will come to
more internals-savvy folks.

I'm just hoping that some variant of this will take someone's fancy who
can implement it and remove this long-standing restriction in the
language.

On Mon Dec 10 07​:51​:43 2012, davem wrote​:

On Sat, Dec 08, 2012 at 03​:56​:33AM -0800, via RT wrote​:

Since we can label any statement (now), why not have the reset
operator take a label argument?
Then reset can act on the toggle(s) in that statement.

So the minimum implemention would permit​:
sub extract {
my $out = '';
reset TOGGLE;

but C<reset TOGGLE> currently means the same as C<reset "TOGGLE">
(which means the same as C<reset "EGLOT">).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 28, 2013

From zefram@fysh.org

via RT wrote​:

My proposal​:
Since we can label any statement (now), why not have the reset operator take a label argument?

I think the toggle operator is a wart that we should lean towards
removing, not something to encourage wider use of. The context-dependent
behaviour is particularly nasty to handle internally, compared to other
context-dependent operators.

If you like the toggle behaviour, I suggest that you should implement
a cleaner version of it (certainly including explicit operations on
named toggles) on CPAN.

-zefram

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 29, 2013

From @cpansprout

On Wed Aug 28 13​:20​:25 2013, zefram@​fysh.org wrote​:

via RT wrote​:

My proposal​:
Since we can label any statement (now), why not have the reset
operator take a label argument?

I think the toggle operator is a wart that we should lean towards
removing, not something to encourage wider use of. The context-
dependent
behaviour is particularly nasty to handle internally, compared to
other
context-dependent operators.

If you like the toggle behaviour, I suggest that you should implement
a cleaner version of it (certainly including explicit operations on
named toggles) on CPAN.

I think I agree here. Shall I close it? What do others think?

--

Father Chrysostomos

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 29, 2013

From zefram@fysh.org

tlhackque wrote​:

One might imagine a toggle object as a middle ground -- e.g.
$toggle = Toggle​::new( '...', sub {/^--a$/} , sub {/^--b$/}); #

Can be done much more neatly by a call-checker plugin and custom ops.
I'm thinking of it looking something like

  $out .= $_ if toggle /^--a$/, /^--b$/;

Named toggles just need a slight extension to put their state somewhere
visible. As the hiddenness of a toggle's state is a nasty aspect of
the core feature, I'd be inclined to make these toggles use an explicit
variable, whose lifetime can be controlled in the usual ways​:

  my $tog;
  reset_toggle $tog;
  $out .= $_ if toggle $tog, /^--a$/, /^--b$/;

such as

 reset \['label'\]; or reset\( \['label'\]\, 2 \);

If a toggle reset feature is added to the core, it should not further
overload an existing core operator, especially one that is presently
unrelated.

-zefram

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 29, 2013

From tlhackque@yahoo.com

On 28-Aug-13 16​:20, Zefram via RT wrote​:

via RT wrote​:

My proposal​:
Since we can label any statement (now), why not have the reset operator take a label argument?
I think the toggle operator is a wart that we should lean towards
removing, not something to encourage wider use of. The context-dependent
behaviour is particularly nasty to handle internally, compared to other
context-dependent operators.

If you like the toggle behaviour, I suggest that you should implement
a cleaner version of it (certainly including explicit operations on
named toggles) on CPAN.

-zefram

Although it certainly isn't the most elegant of Perl's operators and
could have been done differently/better at the beginning of time, it
exists. It is used, and it's more than a wart - no matter how ugly the
internals. It provides a very concise way to deal with the common issue
of processing data within brackets. (e.g. certificate operations on PEM
files such as BEGIN X509 (CERTIFICATE/CRL...) / DATA / END X509)

The suggestion for a cleaner version in CPAN is interesting; although
exactly how to go about that without a heavy dependency on
version-specific Perl internals is not obvious. I suspect that it's
really too closely coupled to Perl internals (for which I don't claim
expertise) to take this approach and end up with syntax as clean as the
current operator.

One might imagine a toggle object as a middle ground -- e.g.
  $toggle = Toggle​::new( '...', sub {/^--a$/} , sub {/^--b$/}); #
booleans have to be a coderef for short-circuit semantics
  .......
  sub use_function{
  $toggle->reset if ($. <= 1);
  while (<>) {
  $out .= $_ if $toggle->test > 1;
  }
}
- which could be made to work, but is hardly concise or as clear as the
existing syntax, especially when one considers that the object approach
also has scoping/initialization issues that the existing operator
hides. $toggle would have to be some file scope variable, so it would
often end up far from the point of use. And if the boolean inputs are
more interesting (e.g. /^--$a$/, where $a is a MY variable in the
use_function scope) things go downhill rapidly.

Note also that the range (a.k.a toggle) operator can not be overloaded.
(http​://perldoc.perl.org/overload.html#BUGS-AND-PITFALLS final bullet),
so we can't use it for precedence or syntactic sugar.

And so we end up with my original suggestion as the least inelegant
solution​: provide a mechanism for reseting the existing operator, such as

  reset ['label']; or reset( ['label'], 2 );

Or any other syntax that expresses the semantics but is easier to deal
with in the internals.

--
This communication may not represent my employer's views,
if any, on the matters discussed.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 29, 2013

From tlhackque@yahoo.com

On 29-Aug-13 03​:15, Father Chrysostomos via RT wrote​:

On Wed Aug 28 13​:20​:25 2013, zefram@​fysh.org wrote​:

via RT wrote​:

My proposal​:
Since we can label any statement (now), why not have the reset
operator take a label argument?

I think the toggle operator is a wart that we should lean towards
removing, not something to encourage wider use of. The context-
dependent
behaviour is particularly nasty to handle internally, compared to
other
context-dependent operators.

If you like the toggle behaviour, I suggest that you should implement
a cleaner version of it (certainly including explicit operations on
named toggles) on CPAN.
I think I agree here. Shall I close it? What do others think?

I responded yesterday, but it didn't seem to get posted. Short form​: if
ugly internals were the criterion, there's a lot of Perl that could be
removed...

The range operator is part of the language, and is undeniably useful
(and used) in real-world situations. My suggestion would make it more
usable - and I think the criterion for deciding what to do should be
based primarily on what benefits users of the language, not on the
ugliness of the Perl internals.

I would strongly oppose removing the range operator. And given that it
stays, making it easier to use seems worthwhile.

I don't see how CPAN distribution makes the problem simpler​: code to
identify and manipulate the internals of flip-flops would be at least as
ugly as the current implementation - with the added issues of version
dependency and users not being able to rely on its presence. I don't
think it's a good idea to patch basic operators of the language with
CPAN add-ons.

As I noted yesterday (quoted below), re-implementing a 'cleaner' version
as an object has issues as well.

The range [flip-flop] operator isn't pretty - but it is expressive and
hard to replace efficiently with some external device.

I don't see a deprecation effort being successful - and it's almost
certainly more work (for someone who knows Perl internals) than
extending reset (or introducing some other device to identify and clear
the bit.)

Please focus on what's good for the language's users rather than the
elegance of the internals...

Although it certainly isn't the most elegant of Perl's operators and
could have been done differently/better at the beginning of time, it
exists. It is used, and it's more than a wart - no matter how ugly
the internals. It provides a very concise way to deal with the common
issue of processing data within brackets. (e.g. certificate operations
on PEM files such as BEGIN X509 (CERTIFICATE/CRL...) / DATA / END X509)

The suggestion for a cleaner version in CPAN is interesting; although
exactly how to go about that without a heavy dependency on
version-specific Perl internals is not obvious. I suspect that it's
really too closely coupled to Perl internals (for which I don't claim
expertise) to take this approach and end up with syntax as clean as
the current operator.

One might imagine a toggle object as a middle ground -- e.g.
$toggle = Toggle​::new( '...', sub {/^--a$/} , sub {/^--b$/}); #
booleans have to be a coderef for short-circuit semantics
.......
sub use_function{
$toggle->reset if ($. <= 1);
while (<>) {
$out .= $_ if $toggle->test > 1;
}
}
- which could be made to work, but is hardly concise or as clear as
the existing syntax, especially when one considers that the object
approach also has scoping/initialization issues that the existing
operator hides. $toggle would have to be some file scope variable, so
it would often end up far from the point of use. And if the boolean
inputs are more interesting (e.g. /^--$a$/, where $a is a MY variable
in the use_function scope) things go downhill rapidly.

Note also that the range (a.k.a toggle) operator can not be
overloaded. (http​://perldoc.perl.org/overload.html#BUGS-AND-PITFALLS
final bullet), so we can't use it for precedence or syntactic sugar.

And so we end up with my original suggestion as the least inelegant
solution​: provide a mechanism for reseting the existing operator, such as

  reset \['label'\]; or reset\( \['label'\]\, 2 \);

Or any other syntax that expresses the semantics but is easier to deal
with in the internals.

--
This communication may not represent my employer's views,
if any, on the matters discussed.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 29, 2013

From @Hugmeir

On Thu, Aug 29, 2013 at 12​:48 PM, Zefram <zefram@​fysh.org> wrote​:

tlhackque wrote​:

One might imagine a toggle object as a middle ground -- e.g.
$toggle = Toggle​::new( '...', sub {/^--a$/} , sub {/^--b$/}); #

Can be done much more neatly by a call-checker plugin and custom ops.
I'm thinking of it looking something like

    $out \.= $\_ if toggle /^\-\-a$/\, /^\-\-b$/;

Heh. I was about to do a bit of shameless advertisement by saying that "you
can do that with Params​::Lazy right now!", but turn out, you can't without
some silly workarounds, at least until I push this new version to CPAN :P
But well, this works on the dev version​:

sub toggle;
use Params​::Lazy toggle => q(^^);

my $toggle_state = '';
sub toggle {
  my ($begin, $end) = @​_;

  if ( !$toggle_state ) {
  $toggle_state = 1 if force $begin;
  }
  else {
  if ( force $end ) {
  $toggle_state = '';
  return "1E0";
  }
  else {
  $toggle_state++;
  }
  }

  return $toggle_state;
}

my $out;
for (qw(no1 no2 --a first second third --b no3)) {
  $out .= "<$_>" if toggle /^--a$/, /^--b$/;
}

say $out;

Named toggles just need a slight extension to put their state somewhere
visible. As the hiddenness of a toggle's state is a nasty aspect of
the core feature, I'd be inclined to make these toggles use an explicit
variable, whose lifetime can be controlled in the usual ways​:

    my $tog;
    reset\_toggle $tog;
    $out \.= $\_ if toggle $tog\, /^\-\-a$/\, /^\-\-b$/;

I believe this would "just" require extending the code above to also use
the * prototype.

such as

 reset \['label'\]; or reset\( \['label'\]\, 2 \);

If a toggle reset feature is added to the core, it should not further
overload an existing core operator, especially one that is presently
unrelated.

+1

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 5, 2013

From tlhackque@yahoo.com

On 29-Aug-13 11​:49, Zefram via RT wrote​:

tlhackque wrote​:

One might imagine a toggle object as a middle ground -- e.g.
$toggle = Toggle​::new( '...', sub {/^--a$/} , sub {/^--b$/}); #
Can be done much more neatly by a call-checker plugin and custom ops.
I'm thinking of it looking something like

$out \.= $\_ if toggle /^\-\-a$/\, /^\-\-b$/;

Named toggles just need a slight extension to put their state somewhere
visible. As the hiddenness of a toggle's state is a nasty aspect of
the core feature, I'd be inclined to make these toggles use an explicit
variable, whose lifetime can be controlled in the usual ways​:

my $tog;
reset\_toggle $tog;
$out \.= $\_ if toggle $tog\, /^\-\-a$/\, /^\-\-b$/;

call-checker plugin?

The problem with an explicit variable is that having a lifetime with the
right semantics is not intuitively trivial.

The current (core) feature is associated with a line of code, not a
recursion level, block scope or closure. Once could put a variable at
file scope, but as previously noted, that's likely to be many lines of
code distant from the point of use.

Without an explicit variable, how do you have instance state? You have
to label the statement (and deal with more than one in a statement -
e.g. toggle1 || toggle2) in order to have a reset operator/function.
Then do you hook the state onto the label? Can a function in the
compiled code find its caller's label?

To me, this seems a lot harder than making the current toggle's state
visible and addressable - and adding a means to reset it. Plus, the
function/object approach ends up with TWO (well, four if you count the
../... variants) operators in the language​: the original ops that aren't
resetable, and the new function/objectish ones that have different
semantics (and precedence), but are resetable. So harder doesn't get an
externally pleasing result...even if you make this work.

But I'm not a Perl internals person. From a consumer's point of view,
the current implementation has defined the scope, precedence, behavior
of the operators and has a place where the state lives. All that's
necessary is a way to name that existing state, and a way to apply a
reset operation to that name.

I thought that since any statement can be labeled, a label would be a
good way to name the state - or more precisely, the states since a
statement can have more than one toggle operator. It doesn't require
novel syntax.

But I suppose there are other approaches. condition1 ..('name')
condition2 comes to mind...That allows labeling each operator (even
allowing 'Package​::name' to refer to it) rather than hooking on to the
statement label. This might be neater, but I assumed that novel syntax
was the greater barrier.

such as

  reset \['label'\]; or reset\( \['label'\]\, 2 \);

If a toggle reset feature is added to the core, it should not further
overload an existing core operator, especially one that is presently
unrelated.
I don't care how the reset function/operator is spelled - the word seems
to have the right sense, and using it avoids adding a new reserved word
to the language. But if it were spelled "/Snuffleupagus/('name')" & had
the desired semantics I'd be happy!
-zefram

--
This communication may not represent my employer's views,
if any, on the matters discussed.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 5, 2013

From zefram@fysh.org

tlhackque wrote​:

call-checker plugin?

See L<perlapi/cv_set_call_checker>. It's a mechanism that allows an
XS module to completely transform the op tree resulting from parsing a
subroutine call. The "toggle $tog, /^--a$/, /^--b$/" expression parses
as a call to the toggle() sub, provided there is such a sub in scope.
A call checker attached to the sub can then replace the sub call with
an op tree that uses the argument ops in a different way.

The problem with an explicit variable is that having a lifetime with
the right semantics is not intuitively trivial.

A "state" variable gives you the whole-program lifetime that you get for
the state of a built-in toggle. That's only rarely the best scope to
use, but it's there if you want it. It looks like you want this scoping
(or think you want it) just because it's what the built-in feature does.
Most of your cases for resetting toggles would probably be better handled
by having a separate instance of the state variable per invocation of
some function, which you could get with a "my" variable.

Without an explicit variable, how do you have instance state?

A call checker can introduce implicit variables if it wants to.
If they're "state" variables, they'll act exactly like the implicit
state of built-in toggles.

have to label the statement (and deal with more than one in a
statement - e.g. toggle1 || toggle2)

That's a good reason why the labels on statements are not a good approach
to linking reset operations to toggle expressions. Another good reason
is that statement labels are designed to be resolved at runtime, whereas
this feature makes more sense with compile-time resolution. Some of the
other issues you list are also problems that only arise if you attempt
to use statement labels for this. The great thing about using ordinary
variables to hold state is that the whole mechanism already exists,
with sensible semantics and a lot of flexibility.

To me, this seems a lot harder than making the current toggle's state
visible and addressable

The problems with using statement labels would apply regardless of
whether it's a new module implementation or a modification of the
built-in toggles.

                 This might be neater\, but I assumed that novel

syntax was the greater barrier.

Novel syntax (both here and for the reset operator) is less of a problem
than using a semantic feature for a purpose for which it is not suitable.
But overall there's some resistance to adding *any* substantive feature
to the core that could be implemented as a module.

-zefram

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 6, 2013

From @ikegami

On Wed, Aug 28, 2013 at 4​:19 PM, Zefram <zefram@​fysh.org> wrote​:

via RT wrote​:

My proposal​:
Since we can label any statement (now), why not have the reset operator
take a label argument?

I think the toggle operator is a wart that we should lean towards
removing, not something to encourage wider use of.

Use of global vars/states keeps getting us into trouble.

This would be easy to implement using Devel​::CallParser​:

my $toggle;
while (...) {
  if (flipflop($toggle, EXPR1, EXPR2)) {
  ...
  }
}

It's not much more complicated than the existing syntax, and it could allow
C<next> and such to work (unlike a sub(&) approach).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 12, 2017

From zefram@fysh.org

There's a consensus against adding anything to the core here. This ticket
should be closed.

-zefram

@p5pRT p5pRT closed this Dec 12, 2017
@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 12, 2017

@cpansprout - Status changed from 'open' to 'rejected'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.