I’m thinking that translates as:
No. Go fix the documentation.
I’m thinking that translates as:
No. Go fix the documentation.
It could be “Yes, and” ![]()
Which acceptance of the PEP would make easier. It’s “a feature” of the number theoretic functions that their results are defined to infinite precision, and that the implementations deliver those exact results on all platforms and all implementations of the language, across eternity. The latter is rarely true of functions involving floats.
Useful (clear and succinct and precise) docs can exploit these fundamental differences, in ways that can at best be obscured and prone to misreading if we try to smash every function “that feels kinda like math stuff” into the same section of the docs.
The math docs could be profitably split into distinct sub-pages “as if” math had been split into conceptually distinct modules, but, e.g., IDE auto-completers have no knowledge of the conceptual split. When I’m working with ints, I never want to see, e.g, even math.floor or math.ceil suggested, despite that they now return (ill-defined) ints (but “should” still return floats, as the libm functions of the same names do, and Python used to do).
We have a long history of not designing specifically for 3rd party tools, and instead letting 3rd party tools manage their own features. If they want to encode a “smart” ordering/grouping for functions in math, they can do it whenever they like. If they have the type information handy, they can even filter automatically.
Insisting that we have to split up our modules for the sakes of the (mostly) large, for-profit companies who build these tools[1] sounds like the real desire is for architectural purity[2] but the IDEs are just a more acceptable excuse that the SC might fall for.
You can just say that you want to refactor the modules because it looks nice in the source code ![]()
IDLE has long been part of the std CPython distribution, and the newer std REPL loop for interactive shells also offers auto-complete now. Those are, in fact, the only “IDEs” I ever use for Python, so there’s nothing hypothetical or “3rd party” about my personal experience here. I’m already annoyed by what comes out of the box ![]()
It would, but that’s not what’s driving this. It also has consequences: it takes a very different mindset to work on exact code than code that has to fight with floating-point vagaries. It’s decidedly unhelpful to have both kinds of code mixed up in a single file. Which could be addressed by splitting the code into multiple .c files internally. And then the source code structure would become that much harder for “non-math developers” to understand. “One module, one file” has practical benefits too. There are no pure wins.
I don’t know how much weight a “me too” comment will have at this point, but I agree that this is an important point, and a good reason for separating the “exact” (integer) functions from the “inexact” (floating point) ones.
The work I do with maths functions is almost exclusively with integer values, or exact values derived from integers (fractions, or odds in a probability context), and having the relevant functions in their own module would be helpful for me. It gives a better overview of what’s available, ensures that like things are together, etc. Yes, this could be done with documentation, but I’d argue that to do it properly, you’d need to split the math module documentation into two separate parts, one for integer functions and the other for floating point functions. At which point it would effectively look like two separate modules, and it would be more confusing to find that they are actually all in the same module…
Of course, the biggest problem with making this something to fix with documentation is that it’s unlikely that we’d actually do such a radical rewrite. If we split the module, splitting the docs is natural and relatively mechanical. Once that’s done, incremental improvements to the presentation of the material, emphasising the (now) common aspects of functions in each individual module, can be completed over time. Conversely, if we don’t split the module, splitting the docs into two “virtual” modules, while making it clear that they are actually both simply sections of the same physical module, will be a fairly significant overhaul of the documentation, precisely because we don’t have the natural sectioning of having two modules. In reality, I suspect that “fix the issue with documentation” will end up being rather close to “do very little, and live with the status quo”.
Yours should carry more weight than it will get
- you actually use these functions. While all opinions are welcome, I confess I give more weight to people directly affected, and more so the more heavily they use the gimmicks under discussions. And I agree with all you said.
Past is prelude. @skirpichev may have an appetite for trying to make the current docs more coherent about the current structure. l don’t. The older I get, the more I have to take “scratch your own itches” as potentially life-preserving counsel
.
About the documentation, it could of course be improved but I find that the distinction between the different kinds of functions in math is already explicit. Someone (disclaimer: it was me) even added a table to quickly grasp the content of the module. In conclusion, I’m not sure that the documentation needs “fixes”, but rather incremental improvement.
Sure, “mildly favorable” could be also “mildly unfavorable” ![]()
Exactly. Docstrings (lets not forget that part of documentation!) — also have no knowledge on tables we group functions in sphinx docs.
+1 (Though, I still prefer IPython console “IDE” to builtin REPL’s.)
Sorry, no
In my reply to SC I mentioned, that this is probably doable. Champions are welcome (from the beginning of this thread), please show how exactly it’s possible!
You forgot about docstrings.
What we should do here? Assume some prior knowledge of users, coming from reading “tables” in sphinx docs? Explicitly describe details of interfaces and behavior? Should we do this only for “special” functions in the module (i.e. for integer-related) — or for all?
All that information might be communicated to end users even in case when module is just a bag for unrelated functions. But separate namespaces make things much more simple.
Docstrings should be written assuming someone has just opened the repl and typed help(the_function) without any other context, but guessing that they want a reminder of how to use it/what it’s for rather than its entire life story (for which they can go to the actual reference docs).
If that means they are a bit repetitive, it doesn’t matter - nobody is sitting and reading all the docstrings in one sitting, they’re going directly to the single one they care about. “argument x will be interpreted as a float and the result will be a float” can be written 100 times over 100 functions and most docstring users will never notice.
And if it makes sense to include “if you are using ints, you want other_func instead” then it can be included. I really don’t see why we’re trying to complicate this so much.
Personally, I don’t think we are trying to complicate it. All we’re trying to say is that to people who use these functions, the existing documentation isn’t ideal. I don’t personally care that much about the docstrings - they could certainly be improved (for example, the docstring for math.factorial doesn’t explain that it provides an exact integer result, and this is not obvious for a function in the math module), but I don’t use them so I don’t care personally.
What I do care about is the manual. And there, the problem is structural. I want the integer functions separated from the floating point ones, precisely because I tend to only use one or the other type in any given application. Yes, this can be done by rewriting, but that’s a big change, and goes against the “one page per module” structure of the library documentation. I fully expect that anyone trying to do such a rewrite would get pushback from people who like the documentation to have a uniform structure. The net effect is that I expect we’ll get at best a minor improvement, but not the structural change that those of us who actually find the status quo to be a problem would like.
Conversely, if we create a new (sub-) module, reorganising the docs is simply a part of that work, and becomes a non-event.
All I’m trying to do here is to address the SC’s statement “we wonder whether most of the problems described by this PEP actually could be fixed with documentation”. In theory, maybe they could, but in practice, it’s extremely likely that this won’t happen - so the choice isn’t “reorganise the namespace or the documentation”, it’s “reorganise the namespace, or do some minor but ultimately ineffective tidying up of the docs”.
All IMO, of course, but that’s my opinion as a semi-regular user of the integer functions in the math module. Are the people who think we could do this as a doc change also regular users of those functions? I don’t know.
Eh, if people start pushing back, make them read this thread to catch up on the motivation for the rewrite. We had the asyncio docs completely redone at one point and I don’t recall anyone pushing back on that (and you could argue that should’ve been a full restructure of the asyncio modules to put ABCs in one place rather than merely documenting them in a logical order, but clearly anyone arguing that lost then, and I think would lose again).
It’s a straw man argument, unless someone wants to come along and put their name to it (specifically, we shouldn’t group functions in the math docs the same way that they’re grouped in the os module, the io module, the datetime module, the threading module, and no doubt many more that group functions logically rather than directly following the source code).
Many of our docs pages are too long and I think we should restructure them. This would also help SEO which is pretty bad right now.
See also Restructuring the stdlib docs and the linked topics.
So that says to me that if PEP 791 is rejected in favour of “just improve the docs”, then any substantial docs improvement will get sucked into the bigger “improve the docs” project, which is absolutely a worthwhile thing to do in the long term, but offers no immediate benefit[1].
Personally, I remain in favour of a new (sub-)module, and I don’t think “just improve the documentation” is an adequate alternative. I don’t know if the discussion here will have helped convince the SC of that, but if nothing else I hope it’s at least established that improving the docs is a bigger exercise than simply adding a bit of extra text.
It’s also worth noting that we have no-one volunteering to improve the docs, whereas we do have volunteers to restructure the code - so it’s very plausible that rejection of the PEP in favour of improving the docs will mean that nothing changes ↩︎
I’m inclined to share the same concern about this sort of incremental improvement getting bundled under a “let’s do it all at once” concept that’s never going to actually happen (unless done, well, as this kind of incremental improvement).
But let’s not forget that PEP 791 is about adding a set of new functions (or rather, an almost-empty-for-now module where new functions can go), and the SC has a preference for a submodule math.integer.
All that’s being rejected is the use of “the docs are always structured alphabetically”[1] as a rationale for “therefore we must create a new namespace”. The namespace itself is being endorsed, though the PEP isn’t yet accepted.
My mildly-hyperbolic paraphrase of the discussion, not just the PEP text. ↩︎
Honestly the docstring stuff can be fixed regardless. If someone types help(math.factorial) they should just see “returns exact integer” or whatever. Thats not hard to add, even if it bit repetitive.
I think the real problem is people trying to solve too many things at once here. The PEP should just be “hey we want math.integer for these functions” and thats it. All this documentation restructuring debate is kind of separate issue that gonna happen or not happen regardless of this PEP.
I’m not going to argue that there wouldn’t be benefits; I agree with many of the things others in favor have stated, including that the implementation is significantly different for dealing with floats and ints and that there are maintainability improvements here too.
I’m in favor of either new modules or reorganizing the math module into submodules while reexporting in the main namespace to keep existing code valid.
With that said, there is a lighter-weight option that could be done first that would, for users at least, provide these groupings.
Rather than submodules per domain with reexports, just create simplenamespace (or something less mutable with similar behavior if you want to avoid accidents) objects for a handful of function groups by domain in the math module. document them in such a way that the actual type of these containers isn’t guranteed right now, and if we later want submodules, it’s a simple switch in terms of public API.
I fully agree with you both, and the plan would be to do it in small pieces, not all at once (exactly because “all at once” will never happen): Restructuring the stdlib docs - #7 by encukou
Docstrings should be written assuming someone has just opened the repl and typed
help(the_function)without any other context, but guessing that they want a reminder of how to use it/what it’s for rather than its entire life story (for which they can go to the actual reference docs).
Well, it’s not really clear what the “entire life story” means in this context. For example, we could group some module functions in the sphinx docs (we already did) into a separate section and add a specific description (about arguments and exactness). Will be this such “story”?
As an example, recently added isnormal/issubnormal. In context of floating-point math library, it’s natural that docstrings don’t define what’s subnormal number is (sphinx docs do). But in context of “catch all” module for “some math functions” — I’m not sure if this is a right approach.
But let’s not forget that PEP 791 is about adding a set of new functions
No, at all. As a matter of fact: there is a bunch of useful extensions for existing set of integer-related function and past history tells us, that probably some will be added, regardless on fate of this PEP. It’s all about a separate namespace for some set of functions.
That also should simplify documentation (e.g. we could assume context for new namespace in docstrings) — but it’s an additional bonus.
I don’t know if the discussion here will have helped convince the SC of that
Keep in mind, it’s a monumental task for anyone to keep up with a single discussion thread, as @pablogsal laments over in the PEP 810 thread, let alone every PEP thread. There’s just no humanly way possible, even if none of us had jobs and outside lives
. I certainly try, but there’s a prodigious amount of suggestions and feedback and it’s very easy to miss an important point, or lose track of what needs to be decided. I’m sure @pf_moore can relate as a packaging delegate.
All of which is ironic because the original motivation for the entire PEP thing was to help @guido navigate proposals where the discussions (on mailing lists at the time) was overwhelming. PEPs were envisioned as a way to consolidate the proposal, giving succinct pros and cons, and representing the sentiment of the community in a way that he could more easily digest to make a decision.
I can’t say I have any great answers, and I personally willingly take on the extra work by serving on the SC, so I’m trying not to have this come off as a complaint. I know it’s tough for PEP authors too, but I really want PEPs to stand on their own. It should be possible to make a decision based on what’s in the PEP and not have to imperfectly slog through megathreads on DPO.