Feature #20404
closed`2pi`
Description
I propose a new Float literal: 2pi
.
p 2pi #=> 6.283185307179586 == 2 * Math::PI
I am not proposing 1pi
, 3pi
or 4pi
. I do only 2pi
. Because in most cases, all you need is 2pi
. Any other multiple of pi is rarely needed.
I've got the statistics. GitHub code search revealed that more than 80% of the occurrences of n * Math::PI
and Math::PI * n
had n = 2. [1]
n | n * Math::PI |
Math::PI * n |
sum | % |
---|---|---|---|---|
0 | 48 | 1 | 49 | 1.4% |
1 | 58 | 3 | 61 | 1.7% |
2 | 2300 | 534 | 2834 | 80.4% |
3 | 218 | 17 | 235 | 6.7% |
4 | 200 | 23 | 223 | 6.3% |
5 | 24 | 2 | 26 | 0.7% |
6 | 41 | 3 | 44 | 1.2% |
7 | 14 | 0 | 14 | 0.4% |
8 | 6 | 2 | 8 | 0.2% |
9 | 8 | 0 | 8 | 0.2% |
10 | 17 | 0 | 17 | 0.5% |
11 | 2 | 0 | 2 | 0.1% |
12 | 2 | 0 | 2 | 0.1% |
Here is the PIe chart
I know that a new constant name "Tau" is proposed (#4897, #17496). But notice: "2pi" and "Tau" have the same number of characters. Then, it is obvious that familiarity is better. In fact, 2 * Math::PI
is 4 times more than Math::PI * 2
, indicating that all programmers are copying "2pi" in their textbook.
The idea of 2pi came up regularly in chats among committers. The discussion quickly shifted to its generalization: should we treat 3e
as 3 * Math::E
, or even 42foo
as 42 * foo
? However, I noticed such a generalization is unnecessary because all we need is 2pi. Unneeded generalization is evil.
Here is a patch.
diff --git a/parse.y b/parse.y
index 55619273b8..93b16a16ac 100644
--- a/parse.y
+++ b/parse.y
@@ -10208,6 +10208,13 @@ parse_numeric(struct parser_params *p, int c)
return set_number_literal(p, tINTEGER, suffix, 10, 0);
}
}
+ else if (c == '2' && peek(p, 'p') && peek_n(p, 'i', 1)) {
+ tokadd(p, c);
+ tokadd(p, nextc(p));
+ tokadd(p, nextc(p));
+ tokfix(p);
+ return set_number_literal(p, tFLOAT, 0, 0, 0);
+ }
for (;;) {
switch (c) {
diff --git a/ruby_parser.c b/ruby_parser.c
index 6d85a72c5b..3a6e0b5704 100644
--- a/ruby_parser.c
+++ b/ruby_parser.c
@@ -936,6 +936,9 @@ VALUE
rb_node_float_literal_val(const NODE *n)
{
const rb_node_float_t *node = RNODE_FLOAT(n);
+ if (strcmp(node->val, "2pi") == 0) {
+ return DBL2NUM(2 * M_PI);
+ }
double d = strtod(node->val, 0);
if (node->minus) {
d = -d;
P I
Happy a r l fool
[1] I used these queries: /[^.]\b2 ?\* ?Math::PI/ language:Ruby
and /Math::PI *\* *2\b *[^.\/]/ language:Ruby