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

[EXPERIMENT] any() and all() list-processing operators #22794

Open
leonerd opened this issue Nov 28, 2024 · 3 comments
Open

[EXPERIMENT] any() and all() list-processing operators #22794

leonerd opened this issue Nov 28, 2024 · 3 comments
Labels
experiment ticket tracking an active experiment

Comments

@leonerd
Copy link
Contributor

leonerd commented Nov 28, 2024

PPC0027 introduced any() and all() as list-processing operators, inspired by the ones in List::Util.

This issue tracks its progress toward the end of its experimental phase.

@leonerd leonerd added the experiment ticket tracking an active experiment label Nov 28, 2024
@wchristian
Copy link
Contributor

As per comments by @leonerd the deferred-expression form of any EXPR, LIST is as of yet not implemented primarily in order to prevent collisions with the implementation of any my $var { BLOCK } LIST. Implementing parsing identical to how map/grep do it would very effectively block this. There are likely to be language designs that would allow having the deferred-expression form without such blockage. Following is a chat log with @leonerd @mauke and me that discusses the matter with one possible proposal, that can be summarized as:

"if the first significant thing after the operator is my or {, parse it as a block and throw errors if things don't make sense, otherwise parse as deferred block"

18:16 <Mithaldu> is there documented consideration of an xor approach where you can have named vars if you choose to use a block, but can choose deferred without named vars?
18:17 <LeoNerd> I'm not entirely sure I follow the question
18:18 <Mithaldu> also in general having the history of a decision available is always good for the future
18:18 <Mithaldu> which part do you not follow?
18:18 <LeoNerd> But also you don't need to guess around it. I think it's widely known I /really/ hate the deferred expression syntax. It's a weird special-case quirk of map and grep that complicates *everything* surrounding them
18:18 <LeoNerd> It exists purely because of history of having been implemented first, before the block form was even thought up. It wouldn't even be suggested now
18:19 <mauke> is it xor? I mean, it looks syntactically unambiguous to me, but maybe the look-ahead required is too annoying to implement?
18:19 <LeoNerd> mauke: it's the lookahead
18:19 <LeoNerd> grep my $x, qw( list of things here )   is of course a valid, albeit useless, expression
18:19 <LeoNerd> Having to look forward to find out what's going on requires an arbitrary amount of tokens to be eaten. The parser doesn't like that
18:19 <mauke> yeah, you need to look at the token after the variable name
18:19 <mauke> why arbitrary?
18:20 <LeoNerd> grep my $x :readonly :const :Title("here's a long and winding story thatI've put into an attribute attactyed to a lexical..")
18:20 <mauke> ah, attributes
18:20 <mauke> just don't allow them
18:20 <LeoNerd> grep my IntegerBetween(-10, 10) $x ....  <== value constraints?
18:21 <mauke> I thought that was a syntax error atm
18:21 <LeoNerd> Probably is currently, yes
18:22 <Mithaldu> right, but keeping in mind the stuff you said earlier, even if we had answers to all of those, you'd still oppose it
18:22 <Mithaldu> correct?
18:23 <LeoNerd> I'm not sure what you mean "answers to" - these aren't open questions
18:23 <LeoNerd> These are "X gets in the way of Y1, Y2, Y3, ...." and I've given a whole bunch of Ys that would be nice to have in future
18:25 <mauke> the problem is that map(length, @words) looks good, but map({ length } @words) looks bizarre
18:25 <Mithaldu> "answers to" being short for: implementations that involve restrictions that make the decision between the two paths parseable without demanding arbitrary length lookahead
18:25 <LeoNerd> mauke: right, but it *works* totally differently to  zap(length, @words)
18:26 <LeoNerd> Also don't put the parens on it ;)
18:26 <mauke> LeoNerd: don't care, map is yellow, zap isn't :-)
18:26 <Mithaldu> for example an extremely crude restriction that would solve all of this would be "if the first word after the operator is my, only a var declaration and a block can follow it
18:27 <mauke> Mithaldu: needs some consideration of any(my $x { ... } @y) vs. any((my $x), @y), but basically yes
18:28 <LeoNerd> I wouldn't like to try to write that into tree-sitter-perl.. or PPI.. ;)
18:28 <Mithaldu> i mean, i can prototype it into ppi if you like
18:28 <mauke> easier than the existing heuristics around map/grep or in regexes
18:28 <LeoNerd> *ideally* grep and map wouldn't do this either, but we are in a situation where that exists. So we already have two special cases.
18:29 <Mithaldu> mauke: also yeah, good clarification
18:29 <LeoNerd> I'd rather stick to that number being 2, rather than 2 + N for some N that depends on the perl version in question
18:29 <mauke> LeoNerd: ideally map BLOCK and grep BLOCK wouldn't exist
18:29 <mauke> they're redundant with the EXPR form
18:30 <Mithaldu> LeoNerd: so what problems do you foresee with having an implementation that decides "if the first significant thing after the operator is my or {, parse it as a block and throw errors if things don't make sense, otherwise parse as deferred block"?
18:30 <Mithaldu> why do you think that would be hard in ppi?
18:30 <Mithaldu> (as far as i can tell that completely removes lookahead)
18:31 <Mithaldu> heck, that might even be an improvement to map/grep, enablable via a feature
18:31 <LeoNerd> Well already that isn't the behaviour. There's already quite a complex thing that looks into the contents of  map { ...   to decide if this might actually still look like an anonymous hashref construction
18:31 <Mithaldu> it is not for any/all
18:32 <Mithaldu> and yes, that complex thing is bad, right?
18:32 <Mithaldu> so, replace it with a more simple thing that is a little less flexible but allows more options on the bigger scale?
18:32 <mauke> we're already incompatible with map { ... by not having the hashref constructor heuristics

@leonerd
Copy link
Contributor Author

leonerd commented Dec 4, 2024

@wchristian - Reminder of the last time you pasted a big conversation chunk directly from an IRC log without first getting permission from those you quoted. Ironically also on a discussion about deferred-expression syntax.

@wchristian
Copy link
Contributor

Noted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
experiment ticket tracking an active experiment
Projects
None yet
Development

No branches or pull requests

2 participants