From: "mame (Yusuke Endoh) via ruby-core" Date: 2024-04-03T01:16:52+00:00 Subject: [ruby-core:117409] [Ruby master Feature#20404] `2pi` 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.html 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 ![](https://gist.github.com/assets/21557/1c077af3-f753-4ee1-bc75-5b38a3bd6487) 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/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/