I suspect the thread I saw got locked because people might not want to discuss the docs. Clearly a lot of work has been put into them, and I do think they're pretty broad. The documentation feels sufficient in most areas for grey beards coming from C like myself; I picked up the language less than 2 months ago, and am quite enamored with it.
Still, I do believe the docs are objectively "good", I do not believe they are sufficient for the level adoption that I think Nim should have, even within the stated target niche (specifically, more seasoned programmers). Given I want to see Nim take over the world, I thought it was worth sharing my perspective, which I personally feel is objective, and not cluttered with a long history with the language.
For me, occasionally the docs aren't going to be sufficient no matter what, but I'll ask around, and I'll go read the code. But if most people are going to invest in a new language, even the top tier engineers will want to minimize the amount of times they have to rely on those options. If it seems like it'd be a frequent occasion, then most of them will self-select out quickly.
I'd say I had to ask around and go look at the implementation a bit more than I wanted, but it was fine for me. Still, I have a much higher tolerance for this than most people, especially since I think Nim hits absolutely everything I want in a language.
So I look at it from the perspective of how well is the documentation serving other people new to the language. There, I have two sets of data points, one from the chat room, and one from co-workers.
I've sat in the chatroom for the last month or so, and seen plenty of people already who seem likely to have given up quickly on Nim because it's not always clear enough how to do fairly simple things for expert developers, without digging into implementations. That hasn't just been programming beginners coming from Python; it's included, just as a single example, multiple people who understand generics and interfaces in other languages, but don't find the docs on concepts sufficient.
First, people coming at from languages like Go who are expecting more of an 'interface replacement' don't understand that they're not concrete types. They want to declare arrays of their concepts and then mix adding in ints, objects and strings to some seq[] and don't understand why they can't have a seq of their concept.
Second, people who have a more deep understanding of parametric polymorphism, might not have that issue, but have definitely seen people not understand enough when you need multiple variables defined on the concept line, and why you'd want to have them be modified there (e.g. with var or ref). The documentation that does exist gives plenty of examples of declaring concepts, but, to my recollection, NO examples of actually instantiating and using them in the ways people are likely to want to use them.
I've seen similar problems with, for example, the OpenSSL integration. Having written a book on OpenSSL myself, I know that library sucks big time, and their documentation, while extensive, is still garbage. But beyond the actual wrapping of a socket, the nim-level documentation of the API isn't really there, and it probably should be, because a bunch of people come in wanting to use cryptography in some way; I just got done fielding one issue in the chat room, where the person was using an INCREDIBLY crappy 3rd party library to do basic AES encryption that should be available any time -d:ssl is on. Unfortunately, these are the kinds of things that will cause even GOOD experienced developers to bounce.
Otherwise, I do generally agree that the standard library docs in particular are decent enough, though it'd occasionally would be great to have more depth. For instance, the first time I had to use os.getAppFileName(), the fact that the documentation was right under os.getAppDir() let me to assume that os.getAppFileName() would be just the file name, not the full path (i.e., that I would need to do joinPath() on the two. It wasn't a lot of friction to find out I was wrong and fix it, but those are pretty basic semantics that should be in the docs that aren't. Enough little paper cuts like that will drive away many people from the target audience.
Still, in general, I do agree that the documentation (while perhaps being adequate for people who are excited to learn the language) is not adequate for most people coming to the language. I've got several people at work who, on paper should like the language, and are smart, senior engineers, who love the concepts. But they have been turned off by the docs, and are not willing to put in the effort to switch from Go or what have you.
All in all, two months in, Nim's my favorite language of all time (and over the last 25 years I've taught both programming languages and compilers plenty of times). I do feel like it should be a lot more popular than it is.
You can attribute some of that to the fact that a lot of the languages to take off in the past decade have had big money put behind it from big tech companies, and that's a limiting factor. But I don't think that would be an issue; I think far more people would be reaching for Nim than, say, Rust if the docs were more mature, and if the tooling ecosystem were more mature and better documented.
For instance, one member of my team tried to get the VSCode integration working, installed one of the major lldb integrations, and yet for whatever reason, none of his set breakpoints would ever fire. He couldn't find any FAQ or README to help quickly, and that was the final straw, he went back to Go. Maybe he was just doing something wrong, but he knows how to use a debugger w/ VSCode (whereas I'm just a unix grey beard using emacs as my IDE).
Anyway, getting new people in the ecosystem might not be the largest priority right now, so I'm not saying this is a 'problem' that definitely needs to be fixed. The docs are certainly good enough for me and, I'm not going to bounce out to something else easily. But I do think, even as comprehensive as they are, that's not comprehensive enough for MOST people to make the jump to a language, especially with a relatively small ecosystem when compared to the languages they already use.
If the ecosystem were bigger, maybe the docs would be sufficient. But I believe the ecosystem can't grow fast enough for that, unless the docs are even better than they already are, by a lot.
doc complainers dont understand that until someone who wants to "improve" them comes and actually does the thing the docs will stay as they are. certainly you wouldnt expect araq to improve the docs for new users. you need someone who understands what the hell new users want in every concrete situation to improve docs. docs will not improve just because tens of people think that "there needs to be a change".
here, you thought that` getAppFileName` is confusing without explanation. who the hell is gonna fix that? not me, for me getAppFileName is perfectly reasonable. guess its gonna stay that way. sure hope araq and miran just write shitton of docs, yep.
but tooling could be improved, yes.
I'm not suggesting anyone improve anything. I'm just trying to point out that, if there are doc complainers, it is because there is an actual barrier, and that barrier is almost certainly keeping people out of the tent that you want in the tent.
I don't think the doc for getAppFileName is confusing per se, it just doesn't have sufficient detail on semantics to be sure what the output is going to be before trying it out. So it leads to surprises. Not a big one, but if there are a lot of little things like that, you end up with people feeling "death by 1000 paper cuts".
Personally, I don't need any more docs, and I'm cut from very similar cloth that I don't want to spend an undue amount of time writing excessive amounts of documentation. But I think if there are adoption goals, then it's good to think about what the barriers to adoption really are, and try to figure out how it might get resourced. Seems like if someone's got a good vision for what would be helpful, there are people who might contribute if encouraged, but I could be wrong there.
However, the impression that I'm getting as someone new to the community is that, even if people were to step up to the plate, it's not clear the core team is all that receptive. That's why I thought it was important to share my views, because I work with people who absolutely won't touch Nim because of the docs, and they are incredibly smart programmers who, for instance, don't find Rust "too complicated" as many people do. They're not the kind of people to come here and complain about lack of docs, they're just going to decide it's not worth the extra effort, and not show up at all.
I suspect the thread I saw got locked because people might not want to discuss the docs. Clearly a lot of work has been put into them, and I do think they're pretty broad. The documentation feels sufficient in most areas for grey beards coming from C like myself; I picked up the language less than 2 months ago, and am quite enamored with it.
For what it's worth, I'd generally agree. The docs are mostly good to me, but they're not great either. I actually like that I can reference the manual in page and get pretty much all of the language features there. However, I also find there's odd places where the docs are lacking, or tooling is sorta broken or just not configured right out of the box.
Not that I find say Rust's documentation better -- once you get outside of the Rust book the documentation for many crates is terrible. They're often just a list of types and traits, ick.
I found giving people Dom's and Araq's book helps quite a bit. They're a bit more guided and experimental bits like concepts are avoided. The Rust book is sorta nice in that way; it's the "conical" introduction and guides people step by step and avoids some trickier areas until much later. Personally I find it way too verbose, but must admit it's effective for a lot of newcomers.
I don't think the doc for getAppFileName is confusing per se, it just doesn't have sufficient detail on semantics to be sure what the output is going to be before trying it out. So it leads to surprises. Not a big one, but if there are a lot of little things like that, you end up with people feeling "death by 1000 paper cuts".
Yes, I've run into lots of little paper cuts. Though, I'm hopeful that along with 2.0 coming out, there will be interest in fixing up many of those. I've already got on PR in for one small pet peeve (thanks @araq!).
However, the impression that I'm getting as someone new to the community is that, even if people were to step up to the plate, it's not clear the core team is all that receptive.
FWIW, I've found the core team fairly receptive to documentation PR's. Though sometimes it takes a bit of explaining or justifying a change. I'd also say they are particular in what gets added. Starting small helps too.
Personally, I think Nim's ecosystem can also grow slowly and steadily and be considered successful. It doesn't need to be a winner-takes-all American VC sort of thing. It's easy to forget that Python took a long time to reach where it is, especially pre machine learning.
That said, one of the best parts of Nim 2.0 will be setting a clearer "vision" for Nim. For a long time it seems that Nim was sorta wandering and trying to find it's stride. Getting to more of a focused vision with Nim 2.0 is a great milestone! It looks like there's already plans to begin deprecating experimental features and cleaning up parts of the stdlib. Hoorah!
I don't think the doc for getAppFileName is confusing per se, it just doesn't have sufficient detail on semantics to be sure what the output is going to be before trying it out. So it leads to surprises. Not a big one, but if there are a lot of little things like that, you end up with people feeling "death by 1000 paper cuts".
I am not saying that I am a seasoned programmer but I do know quite a few of those languages. Do you know what languages can cause "death by 1000 paper cuts"? C++ of course, and Rust, which is C++ 2.0, these languages kill lots of guys day by the day. And we all know why they kill people. It's because of history! Why did UNIX took off? Was UNIX excellent and secure? No, but it worked. And that is why C took off as well. I've got nothing against C, but today everyone can see the downsides of C. Manual memory management was not very clever, especially when you have a large code base. Yes, you can do clever tricks with C, but when you need to modify your own trick later on, you ask yourself WTF. And this counts for everything that I have seen so far, all programming languages suck in one way or the other. I am still learning Nim but so far I haven't seen that many things that sucks.
If you want to have a proper rationale of why to use Nim, go read this: https://forum.nim-lang.org/t/9655
But I agree that documentation of Nim could be a lot improved. That is also a problem of the networking effect. When you don't know the language you don't know it. So you also don't hear a lot about it. The number of articles that discuss Nim is small. When you go into Youtube there is not a lot about Nim. There is plenty of stuff around Rust and Python, but no Nim. That is the unfortunate truth. But when people are searching for it and find out the possibilities, then they discover soon enough that it's not a hoax. Nim is very clever engineering, and that counts for the tooling as well. So I think that the future of Nim looks very good.
I don't know how much documentation and library support it would ever take for Nim to be worth the hassle to some people. Not to be defeatist but outside factors are always going to be a huge contributor to how little languages are used despite how much people like them.
That's why it's not good to be vague. If we are clear then we have a good outline for what to do with the documentation when the time comes. However as was pointed out in the other thread documentation isn't nearly the #1 priority of what people want fixed in Nim
I don't understand the extremely serious atmosphere of this community sometimes. The fact that style insensitivity is the single biggest debate, the most defining aspect of this community should give you the hint to take a couple steps back. I'm saying this as someone who has a fair amount of personal stake in Nim (not financial though), it is not the alpha and the omega of programming languages
Re: priorities, as with the style-insensitivity debate, there is a strong selection bias in who one hears from (maybe stronger, actually). People @jtv mentioned who find docs lacking and immediately give up do not hang around to weigh in on project priority debates. It's hard to say how much people who do participate account for outside perspectives (or maybe those of people they have helped shepherd). { The two relate incidentally in that Zed Shaw was offering teaching/course material for changing the default to be style-sensitive. } This isn't to say anyone thinks there is a silver bullet, adoption-wise. Popularity is a fickle mistress.
To be more constructive, doc problems hit skill layering quickly..maybe faster for Nim with people coming from both beginner/Py-like languages who need to see DEBUG BUILD & kooky languages like C++/Rust with such clues traditionally absent. Skill/background assumptions drive level of detail for all writing/learning. Assumptions about go-to-def skill (of machine|man) even play a role.
Doc layering helps with bigger skill level ranges. The Unix man system has (at least) 5 levels: command/proc ident itself, one-line apropos "summary for search", synopsis, overview, full detail. The levels usually come in that order. So, you start reading & continue if you seem to be understanding/it seems relevant/you need to know more. Not sure it's best to put too much right at impl definitions..but separation can lead to doc-impl divergence, but people do like hypertext view staging.
To end really concretely, a one-liner "apropros"-like intro automatically included in The Index might really boost discoverability over in-page searching for idents/types in the stdlib. E.g., the "first blank row separated block of text in any doc comment is the "pithy summary". Almost the default structure as-is. Maybe this has been suggested before?
Doc layering/staging also takes discipline (like Nim's standardized GithHub Issue template) as well as work sourcing since few enjoy doing it. So, trade-offs all around, but I think it could help many if someone added the "pithy summary" feature for something like The Index and some other(s) to do a real thorough pass over the documentation. This has happened-ish before with runnableExamples:, but as with all things (everywhere, not just Nim!) is incomplete. There are surely many places with single-hash regular comments that could be converted to doc comments..e.g. the first 3 lines of this one (selected more|less at random..).
To end really concretely, a one-liner "apropros"-like intro automatically included in The Index might really boost discoverability over in-page searching for idents/types in the stdlib. E.g., the "first blank row separated block of text in any doc comment is the "pithy summary". Almost the default structure as-is.
I think this is a very good idea!
If Araq maybe gave a key with every physical book, maybe it could give us access to some sort of repository where we can contribute on top of his book.
I realize that may go against his intention of not having us change stuff behind his back, but he could always decline contributions.
I think this may be what his book needs since it starts off very strong but is lacking toward the end, probably because he's dedicating his time to advancing Nim. I think this would be a good way for us to pick up the slack and let the Nim developers work towards what their focus is.
https://dlesnoff.github.io/nimProgramming-blog/blogPosts/macroTutorial.html
(Beware, I'm Dutch, thus direct in a way considered rude by many.)
I only read the template section, that took some effort. The dark theme and the choice of colours and contrast levels make it very hard to read. The black/orange things jump at you and distract. The code is too flat. I had to switch/toggle to reader view in firefox (dark grey on off-white).
What I miss in the template section; Why and when to use templates? Why not use a proc?
If you don't know who to write for, aim for a lower starting knowledge of your audience but make it clear that you're going in deep in a later section. The layering mentioned earlier in this thread. As an example, you mention C/C++, something that is meaningless to me. Or, dive in deep from the start, you'll lose me, but gain an other reader, no problem.
Add a page navigation section, with links to the headings on the page. It can be put before or after the introduction. Move the, useful, reference to the end.
Thanks.
Thanks for the feedback. No problem, I have exposed the material very roughly and was expecting that kind of reaction.
I may change the style of the dark theme Nimib CSS, I have simply used the default one. I am personally more accustomed to dark theme and often toggle the CSS with my Firefox extension Dark Reader.
Why and when to use templates ? Why not use a proc ?
This is indeed a matter of a few lines.
As an example, you mention C/C++, something that is meaningless to me.
C/C++ is often considered a lingua franca but I wanted to avoid having to explain using these notions of preprocessing. I do precise (For those familiar with, ...). The similarity is actually far from perfect and should not be necessary to understand template. I am sorry if this did not explained enough. I am going to rewrite this paragraph.
Add a page navigation section with links to the headings on the page That is more difficult than you think to do it right with Nimib currently. @pietroppeter made this example https://pietroppeter.github.io/nblog/drafts/toc_mustache.html There is Nimibook, but I don't want to use it right now. It works differently in some ways.
Move the, useful, reference to the end. Planned to do it. Otherwise it is a temptation to copy the contents of these references rather than creating original snippets of code and explanation.
Thanks to you for your feedback and dedication to read (at least the beginning).
I just did not understood what you mean by :
The code is too flat
What do you suggest to change for the code exactly ?
> Add a page navigation section with links to the headings on the page
That is more difficult than you think to do it right with Nimib currently.
Indeed it is not straightforward right now, but recently I more or less settled on an api, so it should not be too difficult to do (if someone wants to give it a go; otherwise sooner or later I will get to it). Relevant issue is https://github.com/pietroppeter/nimib/issues/58
Btw this is an issue which is also present in Nim blog (no linkable headers nor an easy way to make a toc; I imagine there should be a Jekyll plugin or something to have that available).
@pietroppeter made this example (link to toc_mustache)
A better example is the cheat sheet one: https://pietroppeter.github.io/nimib/cheatsheet.html
The link you report was an exercise in trying to do a toc in mustache which is harder than in other template systems since you do not have control flows. In the end it is not what was used in nimibook (and in that case it was a toc for site navigation, not for page navigation), so not particularly relevant anymore.
Also regarding the dark theme, indeed the current default (taken from water.css) has some issues like the ones pointed out by @ingo, I am open to improvements. Personally I do not find it that bad, so it has not been a priority for me.
Markdown has become nearly universal with a massive ecosystem around it
Do you mean CommonMark, GitHub Markdown, Pandoc Markdown, Reddit Markdown, …?
I just did not understood what you mean by :
The code is too flat
What do you suggest to change for the code exactly ?
Sorry, I wasn't clear. The contrast of the code on the background is too low.
I have changed the theme to the default white theme, added a table of contents, pushed to the end the references.
I added a picture of an AST tree. My macro's example is far too stretched for a beginner's tutorial. I will probably explain the Fireship's macro in thorough details (if it has not already been done).
@jtv,
I have looked further into the subject. My answer will be based on the following papers:
Parallel Random Numbers: As Easy as 1, 2, 3, 2011
John K. Salmon, Mark A. Moraes, Ron O. Dror, and David E. Shaw
https://thesalmons.org/john/random123/papers/random123sc11.pdf
https://github.com/DEShawResearch/random123
New and Old Limits for AES Known-Key Distinguishers, 2017
Lorenzo Grassi and Christian Rechberger
https://eprint.iacr.org/2017/255.pdf
Fast-key-erasure random-number generators, 2017
Daniel J. Bernstein
https://blog.cr.yp.to/20170723-random.html
https://github.com/floodyberry/supercop/blob/a351f2c/crypto_sign/ntrumls439x/ref/fastrandombytes.c
Randen - fast backtracking-resistant random generator with AES+Feistel+Reverie, 2018
Jan Wassenberg, Robert Obryk, Jyrki Alakuijala, Emmanuel Mogenet
https://arxiv.org/abs/1810.02227
https://github.com/google/randen
Scrambled linear pseudorandom number generators, 2021
David Blackman and Sebastiano Vigna
http://vigna.di.unimi.it/ftp/papers/ScrambledLinear.pdf
(Nim uses xoroshiro128+ by default)
BearSSL - Constant-time
https://bearssl.org/constanttime.html#aes
JAX PRNG design
https://github.com/google/jax/blob/main/docs/jep/263-prng.md
Weave and Trace-of-Radiance, PRNG research for parallel Monte-Carlo simulations
https://github.com/mratsim/trace-of-radiance/pull/1
https://github.com/mratsim/weave/issues/147
Computer Go strength being highly sensitive to Monte-Carlo simulation speed:
Can be used as real-world PRNG bench: https://github.com/mratsim/golem-prime/blob/8953347/src/golem_prime.nim#L85-L101
Monte-Carlo tree search and rapid action value estimation in computer Go
Sylvain Gelly, David Silver
https://www.ics.uci.edu/~dechter/courses/ics-295/winter-2018/papers/mcts-gelly-silver.pdf
No, I did not say that non-cryptographic PRNGs would be slower than cryptographic PRNGs. What I said is that you can absolutely make AES-CTR fast enough to be the DEFAULT, because few people will need anything else. Most people grossly overestimate the cost.
First of all, there is no hierarchy in Nim stdlib, Nim provides std/random and std/sysrand. And no package within the standard library forces either.
In [1], section 4.1, on 2011 CPUs.
Using compiler intrinsics to invoke the AES instructions and gcc-4.5.2, we have measured an AES PRNG running at 1.7 cpB on a single core, faster than the Mersenne Twister in the C++0x standard lib > The software implementation we used for AES is not the fastest known. AES has been reported to run at 10–15 cpB on a variety of platforms [cites D. J. Bernstein and P. Schwabe. New AES software speed records] (without AES-NI]
In [4], chapter 3
The AES block cipher is well-understood and often hardware-accelerated. Intel’s AESNI instructions are five to ten times faster than opti- mized software implementations. This implies a software-only Randen would be unacceptably slow (and likely vulnerable to side- channel attacks). On CPUs without hardware AES, it may be faster to replace AES with SIMD-friendly permutations such as ChaCha. However, most modern CPUs have AES hardware, including POWER (VCIPHER) and ARMv8 (AESE)
In [6] Pornin provides bench in MB/s of AES-CTR with a classic table-based approach and with AES-NI: 170MB/s vs 2420MB/s, so a 14.2x factor
In [5] on the speed section of Vigna website
Otherwise, with suitable hardware support I could just use AES in counter mode and get 64 secure bits in 0.56 ns (or just use Randen). The tests were performed on a 12th Gen Intel® Core™ i7-12700KF @3.60GHz using gcc 12.2.1.
xoroshiro128+ is still at 0.34 cycles per byte so 1.65x faster.
Which brings us to the next question, does that speed difference matter when both are sub-nanosecond? Likely not, see Randen paper [4] where PCG is faster on microbenchmark but not in real-life reservoir sampling scenario.
However 8x definitely matters, in [9] in table 1 p1869, between 3000 Monte-Carlo simulations per move and 10000 simulations per move, there is a 69% to 83% winrate improvement and an ELO rating improvement from 1960 to 2110. In practice this means, that with 10k simulations per move, you would skip your first move to give a fair fighting chance to the program with 3k simulations per move.
Now, can AES-CTR be the default in Nim?
The issue is that it is way too slow when implemented in software, 8x to 14x slower than when hardware acceleration is available. Implementing it with hardware acceleration requires divergent code paths with intrinsics or inline assembly for all platforms we support and a C fallback, especially for RNG in the compile-time VM, which will slowdown drastically if we need RNG at compile-time, which does happen (https://github.com/numforge/laser/blob/e23b5d6/laser/openmp.nim#L13). Testing the ARM code will be very hard in CI as well not even talking about the rest of supported hostCPU "i386", "alpha", "powerpc", "powerpc64", "powerpc64el", "sparc", "amd64", "mips", "mipsel", "arm", "arm64", "mips64", "mips64el", "riscv32", "riscv64" (and s390x is missing from the doc, https://github.com/nim-lang/Nim/pull/20943) This is something that Nim should delegate to libraries.
Again, people use cryptographic PRNGs in these things all the time. For example, cryptographic PRNGs are perfectly capable of repeatability for monte carlo simulations, and have the advantage in such cases that random access into the output stream is incredibly cheap, which is NOT the case with any non-cryptographic PRNG, where doing so without saving state is neither straightforward nor cheap, due to the nature of the algorithms.
Besides plain AES-CTR has vulnerabilities when used as a PRNG:
So you get pain and you're still not secure enough when security matter
Note that I'm not saying to take fast, non-cryptographic PRNGs should be taken out of the library. People who are worried about "what's Nim's fastest option" can test them, otherwise they're not comparing apples and oranges.
And caring about the security of the programs written in Nim would be a MUCH more unique and valuable thing to market around. I don't see it being the thing everyone slams Rust for; instead, it's one of the things I've heard people tout about it.
Nim offers a Cryptographically-Secure PRNG in https://nim-lang.org/docs/sysrand.html. It's pretty new so discoverability is bad. It should be mentioned in std/random docs for starters. And maybe std/random should be renamed std/pseudorandom. But I don't think we can do much beyond education for this problem.
Re: security, I'm probably the one of the people caring most about it:
However, in this case either the PRNG will be too slow and insecure (software) or hard to test (HW acceleration on non-x86).
That assumes people understand well enough to realize that, for instance, the online game they're building. Most people are not security experts, make incredibly wrong assumptions, and end up with risks by default.
In that case, either their RNG is critical (say online poker) and they hire an expert and have an audit as well. Or it's not and maybe it can be exploited for lootboxes or matchmaking but those can be handled with a refund, an apology and a bugfix.
There are scenarios where you can exploit a bad RNG that can surprise devs, for example to carry an eclipse attack in a P2P setting (https://eprint.iacr.org/2015/263.pdf). But the problem is education:
If you don't say yes to the second one, even a cryptographically secure PRNG won't save you.
Finally, my recommendations. As said at the very beginning, Nim standard library provides no default, only options regarding RNG. Only thing we can do is improve discoverability and documentation:
Thank you for the thoughtful input and the real world data points.
I've felt similarly to your colleague a lot, I tend to run into situations where I'm stuck and there's nowhere to go. Then it seams that Nim is creating more problems than it solves.
I think a good word that somes everything up is friction- adopting Nim has a lot of friction.
That's when Nim creates more problems than it solves. I agree- I think this is what scares people away. It didn't scare me away- I'm motivated by passion. Nim is Genius. But it's still painful, and more than can be expected from a pragmatist to handle.