[ruby-core:117390] [Ruby master Feature#20404] `2pi`

Issue #20404 has been reported by mame (Yusuke Endoh). ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404 * Author: mame (Yusuke Endoh) * Status: Open ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by duerst (Martin Dürst). I really like this proposal. But I think for most of the world, it was a few hours too early. A time around 2024-04-01 12:00:00 UTC may have been easier to understand for most of the world. ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107553 * Author: mame (Yusuke Endoh) * Status: Open ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by byroot (Jean Boussier). Now that Ruby has been unicode aware for over a decade, it's probably better to use actual pi letter: `2π` ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107557 * Author: mame (Yusuke Endoh) * Status: Open ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by shan (Shannon Skipper). The Tau Manifesto (https://tauday.com/) was introduced by Michael Hartl, a Rubyist, and handily `𝜏 == 2π` so it might be worth also considering the tau letter: 𝜏 ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107559 * Author: mame (Yusuke Endoh) * Status: Open ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by jzakiya (Jabari Zakiya). This has been brought up before to add the constant `tau` https://bugs.ruby-lang.org/issues/17496 ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107560 * Author: mame (Yusuke Endoh) * Status: Open ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by mame (Yusuke Endoh). Status changed from Open to Rejected April Fools' Day is over. Closing. This proposal is half joke, half serious. I can think of some reasons why we should introduce `2pi`. ### There are some languages that provide not only `pi` but also commonly used values. @ko1 and @shyouhei told me that Gauche and C (POSIX) defines the following constants. It seem reasonable to provide frequently used values, even if they can be easily computed from other values. * Gauche (Scheme): `pi`, `2pi`, `pi/2`, `pi/4`, `pi/180`, `1/pi`, and `180/pi` * C (POSIX): `pi`, `pi/2`, `pi/4`, `1/pi`, `2/pi`, and `2/sqrt(pi)` (but not `2pi`, why?) https://practical-scheme.net/gauche/man/gauche-refe/Mathematical-constants.h... https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/math.h.html ### There is no good alternative constant name. We cannot define `Math::2PI` unfortunately. `Math::PI2` and `Math::PI_2` are in unnatural word order, and also ambiguous as pi^2 or pi/2. `Math::TWO_PI` does not look so good. I mentioned Tau in the original proposal, and seriously, I don't believe that `Math::Tau` is the way to go at the present. As long as most textbooks use 2pi, programmers will have to replace it with `2pi` in their mind every time they see `Math::Tau`, which is too inconvenient. We should consider this when most textbooks start using Tau. (If I had a time machine, I would try to convince the ancient Greeks to consider the ratio of circumference to radius instead of diameter.) ### `Math::PI` is often the only used one in Math module. Because Ruby has Complex, it is often not necessary to use `Math.sin` and `cos` directly. When dealing with 2D graphics, we typically use only Complex multiplication and `Math::PI`. ### `Math::PI` leads to a bit cryptic code. For example, to find the coordinates of the vertices of a hexagon, one would write `Complex.polar(1, 2 * Math::PI / 6 * n)`. However, many people may be bothered by the redundant multiplication and rewrite it as `Complex.polar(1, Math::PI / 3 * n)`. Then the original intent of the hexagon disappears from the code. Since math code tends to be originally cryptic, I think it is better if the intent remains as straightforward as possible. With `2pi`, we could write `Complex.polar(1, 2pi / 6 * n)`. ... Well, but I wonder if a new literal is impossible? ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107582 * Author: mame (Yusuke Endoh) * Status: Rejected ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by zverok (Victor Shepelev).
This proposal is half joke, half serious.
There are several interesting things to unpack here (though I don’t see any actionable proposals). When writing/reading in Ruby some math, there are several different irky things: 1. `Math::` prefix (honestly, I never felt it totally justified, like `sin` or `cos` is obvious without any prefixes, why should we have it?..)—but at least can be mitigated by `include Math` 2. `PI` in all-caps. I understand it corresponds to the constant rules of Ruby, yet in a complicated formula, it really catches your eye as ”something I’d like to read in a less screaming manner” (in some cases, I even introduced a local variable `π` to write some cumbersome formula) 3. The math intuition of `2<variable>` to mean `2 * <variable>`, and in some formulae, perceived as an atomic part of it (3) in some languages (can’t remember which ones from the top of my head, but I definitely saw it) is addressed by treating `<number><identifier>` as `<number> * <identifier>`. IDK, maybe this is the way?.. Currently, `2x` is a syntax error, so there should be no conflicts. And also... Can it be possible to introduce `Math::pi` and `Math::e` (which, by the logic of naming, should be methods, yet maybe can be treated by parser or optimizer as constants)?.. Just thoughts. ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107797 * Author: mame (Yusuke Endoh) * Status: Rejected ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by duerst (Martin Dürst). zverok (Victor Shepelev) wrote in #note-7:
When writing/reading in Ruby some math, there are several different irky things:
One thing that irks me about Math::sin and friends is that these are not available as methods (on Float and so on). It's annoying, and doesn't feel like Ruby, to have to write `array.map { |x| Math.sin x }` instead of just `array.map(&:sin)`. I understand why in some places, you want `sin` in prefix position so that it looks like it does in a Mathematical formula, but in Ruby, there are often multiple ways to write things, so it shoulsd also be possible to write `x.sin`. ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107798 * Author: mame (Yusuke Endoh) * Status: Rejected ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/

Issue #20404 has been updated by nobu (Nobuyoshi Nakada). zverok (Victor Shepelev) wrote in #note-7:
(3) in some languages (can’t remember which ones from the top of my head, but I definitely saw it) is addressed by treating `<number><identifier>` as `<number> * <identifier>`. IDK, maybe this is the way?.. Currently, `2x` is a syntax error, so there should be no conflicts.
Already we have `2i`, `2r` and `2ri`. ---------------------------------------- Feature #20404: `2pi` https://bugs.ruby-lang.org/issues/20404#change-107857 * Author: mame (Yusuke Endoh) * Status: Rejected ---------------------------------------- I propose a new Float literal: `2pi`. ```ruby 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 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`](https://github.com/search?type=code&q=%2F%5B%5E.%5D%5Cb2+%3F%5C*+%3FMath%3A%3API%2F+language%3ARuby) and [`/Math::PI *\* *2\b *[^.\/]/ language:Ruby`](https://github.com/search?type=code&q=%2FMath%3A%3API+*%5C*+*2%5Cb+*%5B%5E.%5C%2F%5D%2F+language%3ARuby) -- https://bugs.ruby-lang.org/
participants (7)
-
byroot (Jean Boussier)
-
duerst
-
jzakiya (Jabari Zakiya)
-
mame (Yusuke Endoh)
-
nobu (Nobuyoshi Nakada)
-
shan (Shannon Skipper)
-
zverok (Victor Shepelev)