Leading plus sign on integers


#1

I just noticed this:

fn main() {
    assert_eq!("-42".parse::<i32>(), Ok(-42));
    assert_eq!("+42".parse::<i32>(), Ok( 42));
}

… fails with Err(ParseIntError { kind: InvalidDigit }) on the second line, because of the + obviously.

Is it on purpose? Is it documented somewhere? Is there another function to parse an integer that does not choke on an explicit plus sign?

There is the same problem in the language itself:

    assert_eq!("+42".parse::<i32>(), Ok(+42));

does not compile due to the + in the 42 constant. This is not very important, but for symmetry, I like being able to write something like that:

    Left  => -1,
    Right => +1,

(Amusingly, TikZ has the same problem, but when writing a parser in TeX, limitations must be tolerated.)


#2

No. There is no need for a unary plus operator that would be a no-op anyway, it would just complicate the parser for very little gain.


#3

Ok. But in that case, I suggest to put in big fiery blinking letters “WARNING: UNLIKE ALMOST ALL OTHER LANGUAGE IN THE WORLD, RUST DOES NOT CONSIDER THAT +1 IS A NUMBER.”

This is especially important for the standard library functions, because there is no compiler to point to the exact character causing the error, just a terse error return.


#4

Python allows unary +, Lisps should, too. Lua, Java and PHP don’t. Forth and any other cannot do so by design.

I’m on mobile, so I didn’t check other languages, but it already appears that unary plus isn’t half as ubiquitous as you claim.


#5

Let me check…

Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> a = "+5"; print(a + 8);
13
> a = "/5"; print(a + 8);
stdin:1: attempt to perform arithmetic on global 'a' (a string value)
stack traceback:
        stdin:1: in main chunk
        [C]: ?
public class example {
    public static void main(String[] args) {
        System.out.println("+5 = " + Integer.parseInt("+5"));
        System.out.println("/5 = " + Integer.parseInt("/5"));
    }
}
$ java example
+5 = 5
Exception in thread "main" java.lang.NumberFormatException: For input string: "/5"

```null
$ php <<\EOF
<?php
$a = "+5"; $b = $a + 8; print "b = $b\n";
$a = "/5"; $b = $a + 8; print "b = $b\n";
?> 
EOF
b = 13
b = 8

That makes your first three examples wrong. Are you sure you correctly understood the issue?


#6

You are right, I misunderstood the issue – I thought it was about the Rust parser accepting unary +. Now, I’ve yet to find a place where I would have needed this, but in the meantime, you can just build it yourself with:

fn parse_int(s: &str) -> i32 { 
    s.trim_left_matches('+').parse()
}

#7

I think you found a bug and should file an issue for the parse::<i32>() case! I tried to look for existing issues but couldn’t find anything exactly. These looked somewhat related:

Here’s a link to a minimal reproduction of the issue on playpen, the expected behavior being a successful compilation and run: http://is.gd/MS2sYy

As far as the language itself, which you said is not very important, this behavior is sort of documented by the lack of + under unary operators in the reference.


#8

Thanks for the feedback. This is now issue #27580.