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

Allomorphic numerics should probably be accepted as literals in signatures #1828

Closed
zoffixznet opened this issue May 14, 2018 · 10 comments
Closed

Comments

@zoffixznet
Copy link
Contributor

zoffixznet commented May 14, 2018

We have some funky rules regarding when angle brackets produce a numeric literal vs. when they produce a numeric allomorph, so it could be hard for a beginner to figure out which makes what.

We currently accept numeric literals in signatures, however, allomorphic numerics produce a rather LTA error. IMO we should accept RatStr and other allomorphic numerics just as we accept plain numeric literals.

$ perl6 -e '-> <1/2> {say "in"}(<1/2>)'
in

$ perl6 -e '-> < 1/2> {say "in"}(< 1/2>)'
===SORRY!=== Error while compiling -e
Missing block
at -e:1
------> ->⏏ < 1/2> {say "in"}(< 1/2>)
    expecting any of:
        formal parameter

$ perl6 -v
This is Rakudo version 2018.04-20-g7847768 built on MoarVM version 2018.04-34-g25f165a
implementing Perl 6.c.
@lizmat
Copy link
Contributor

lizmat commented May 14, 2018 via email

@zoffixznet
Copy link
Contributor Author

That would lose the information on whether it's supposed to be an allomorph or a plain numeric, wouldn't it? <1/2> is a Rat, < 1/2> is a RatStr. If you .trim, both will be passed to the routine as a plain Rat.

@zoffixznet
Copy link
Contributor Author

If you .trim, both will be passed to the routine as a plain Rat.

Err. It'd be passed fine, but typing will be wrong. :( < 1/2> ) supposed to accept RatStr objects, but if you trim, it'd accept plain Rats too.

@zoffixznet
Copy link
Contributor Author

zoffixznet commented May 14, 2018

Actually, I'm gonna self-close this. Changed my mind.

If < 1/2> is accepted, then the question becomes why can't <1 2> be accepted too, and if that's accepted, it becomes why not accept qw/ / and %( ) too.

The alternative (RatStr where < 1/2>) is not too long to type.

YAGNI.

@lizmat
Copy link
Contributor

lizmat commented May 14, 2018

FWIW, I thought that <1/2> would also be a RatStr rather than a Rat. So I think that that is the real issue here. The handling of <1/2> is inconsistent with handling of say <42>, <42e0> and <42i> (which are all allomorphs without any space).

@lizmat lizmat reopened this May 14, 2018
@zoffixznet
Copy link
Contributor Author

The current rule (modulo some bugs) is if it's an expression without spaces then you get a numeric literal, otherwise you get an allomorph. So <1/2> is a Rat literal, because there's an operator involved, but <42> is an IntStr, because there's no operator and there's no point in using the angle brackets to get a plain Int (since you can get it without 'em, but the same isn't true with 1/2).

If you make all of them allomorphs, then there'd be no way to specify, for example, a Rat literal in fractional form, e.g. here:

-> <1/42> { say "you gave me a Rat literal" }(1/42)

@zoffixznet
Copy link
Contributor Author

The current rule

Did a bit of digging. It's been documented for a year. IIRC I wrote it down when bdfoy was doing research for the LP6 book so it might be documented in that book too.

And it was TimToady who told me about it, stating the reasoning for it was pragmatism.

@lizmat
Copy link
Contributor

lizmat commented May 14, 2018

Aha, ok, get it now: we're in fact abusing the < > syntax for specifying literal Rats.

So you're saying that 1/2 is not a literal Rat? If so, why is that? Isn't that something that could be either codegenned differently, or be handled by the static optimizer?

@zoffixznet
Copy link
Contributor Author

zoffixznet commented May 14, 2018

Aha, ok, get it now: we're in fact abusing the < > syntax for specifying literal Rats.

Pretty much. Complex too.

So you're saying that 1/2 is not a literal Rat?

Right, before static optimizer constant folds it, it's just an infix / call:

# --target=ast
- QAST::Op(call &infix:</>) <wanted> /
    - QAST::Want <wanted> 1
      - QAST::WVal(Int) 
      - Ii
      - QAST::IVal(1)  1
    - QAST::Want <wanted> 2
      - QAST::WVal(Int) 
      - Ii
      - QAST::IVal(2)  2

# --target=optimize
- QAST::WVal(Rat)

Isn't that something that could be either codegenned differently, or be handled by the static optimizer?

Not an expert on this, but wouldn't both of those happen after the decision about whether 1/2 is a term, operator, term or a numeric literal? As in, if 1/2 is a Rat literal, then what about constant foo = 1; constant bar = 2; foo/bar? Because both variants get constant folded by static optimizer to the same thing. and if those are the rules for writing numeric literals, then it follows I can write this, or even more complex expressions, to declare numeric literals in, say, signatures:

constant foo = 1;
constant bar = 2;

sub (foo/foo+foo+foo+foo-bar) {}

And I'd say such rules a lot more complex to understand than the current < > abuse.

@lizmat
Copy link
Contributor

lizmat commented May 15, 2018

Thanks for the enlightening answer! Closing again now

@lizmat lizmat closed this as completed May 15, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants