Hey there! I'm going to start with your ending, then go back up to the top.
> Finally, there are enough breadcrumbs in your replies to make me guess > (without being afraid of an unintended reveal ;)) that your identity is John > Viega, correct? It is very nice to see an established industry player > approach Nim and share their perspective. I particularly enjoyed reading a > recent write up of yours: > <https://blog.crashoverride.com/a-personal-history-of-the-appsec-industry> Yes, that's me. Thanks very much for your kind words. And just to be clear, while I was happy to be anonymous, I definitely don't mind, or else I wouldn't have dipped into any of the details of my personal experience. > > 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. > > Not the first time that I have seen this confusion about concepts. The > (experimental) manual defines them as user-defined type classes, and the > manual warns about type classes being compile time only concepts. Probably > the docs on concepts could link to type classes and might give an additional > warning. The main problem though is that concepts in Nim are very little used > in the wild so you will find in general very few documents around that talk > about them and very few codebases that use them. They recently went through a > refactoring and I would say that they actually might have a revival. I guess > the still lingering question is whether or not they advantages they provide > over generics is enough. Also, being very little used they seems to still > have quite some bugs. I was trying the code coming from this nice comparison > with generics (forum thread) and bizarrely enough it does not compile > (playground) Personally, I'm a fan of concepts, and think they could be valuable to others. When I needed them, it was definitely the place where I got bogged down the longest. I'd stare at all the available docs, try what I thought should work, get an error, stare at the docs some more, then try it another way. I eventually started looking at code, but ElegantBeef provided the illumination I needed. But, while I might have hit some bugs during that process, the only thing I was doing wrong when I was finally set straight was that I was expecting UFCS to bind the same way with generics as without. That one is on me, because I had read that a few times and was originally taking note about it, but I lost the thread. But, then again, the compiler didn't help me pick the thread back up. I'd get the inscrutable "Could not Instantiate T" with _no_ other context to indicate WHY instantiation wasn't possible. Since then, I've had 0 problems making use of concepts. But, two things here: 1. It definitely would be good to have a how-to (and/or a tutorial) for concepts that absolutely hammers home some of these "gotchas". This is one thing that I definitely _do_ intend to write, assuming I find time while it's still fresh enough in my mind. 2. I've seen some mention that compiler error messages have gotten a lot better recently. I'd say that, while the above error was the LEAST enlightening one, I _frequently_ get errors that were not as easy to understand as I would have liked. Two examples of this. One, often when there are type mismatches between A and B, it is not clear from the message which type is the "expected" type. For the average developer to know the expected type when they first arrive, they'd have to know, (for instance), if you "expect" the formals to be the source of truth, or if the actuals are, because that's the part of the parse tree you're on, and what you've been inferring types for. I would have much rather the compiler said something that clearly identified what type Nim things each construct is. For actual proc calls, this wasn't often a problem since I think it does so this (and then shows me every possible match). But either there are plenty of other cases where this isn't as clear, or at least it's not clear enough when there's only one matching procedure. Because I KNOW that I've had some cognitive burden multiple times, trying to figure out which type is which (esp when it's something like an operation on two objects where both of the types are being inferred). This has never slowed me down for long, but it still happens sometimes, and was bad when I started. Second, I _frequently_ would get "invalid indentation" errors at the end of a line. Once I realized that it meant I did something wrong on the line leading up to it, it was not a problem, but before I internalized that, it was often a head scratcher, where I'd keep rewriting the same thing until it ended up working. Perhaps one of those HOWTO guides should be a recipe on what to look out for, based on the compiler error message? That's one of those things where, having done a lot of compiler work, I know how hard it can be to avoid some cases where there are head scratchers, and how hard it can be to actually make further improvements. So docs might actually be helpful here. > from what I can tell the best replacement for go's interface is > <https://github.com/yglukhov/iface> > >> 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. > > I would say the reference library for cryptographic algorithms in general and > AES in particular is <https://github.com/cheatfate/nimcrypto> Since it is > part of status and has undergone what seems to be a rather extensive > cryptographic audit (which had in scope that repo, see e.g. this aes issue, > now fixed) hopefully it is not too crappy :) I am pretty opinionated on cryptography as you might imagine. I think that even excellent cryptographers have gotten things wrong in this domain, and it's much better to give people, to use an analogy, pre-fab'd houses instead of a tool-box and other raw materials. That is, crypto libraries are doing the world a disservice when they're not use-case based (generally, based on standards well vetted by cryptographers), and are more tool-box based. I specifically helped out someone a few days ago who was using nimcrypto, and I was really disappointed how far on the 'toolbox' side of the equation it is. For instance, bcmode.nim lets you choose modes that no cryptographer would ever use for any reason anymore (particularly, CFB, OFB). And, while GCM mode is there (which is good, since it's ubiquitous as the default ciphersuite in TLS and elsewhere), it does NOT actually conform to the GCM spec. Specifically, in GCM, encryption produces a single ciphertext that's supposed to be treated as a single unit, especially when passed to the decryption operation. Decryption is NOT supposed to succeed unless the integrity check passes. Yet, in nimcrypto, it's easy to just call the API in such a way that you never handle the tag... it will happily decrypt a message without any integrity check. That's easy as pie to do, and indeed one thing I saw with that person I was helping. By the way, this reminds me, that Nim with 2.0 should do the one thing I liked best about Rust... make the "standard" library random() call a secure random call. In my early career I found it pretty to break tons of practical systems for using a non-cryptographic generator, exploiting such things in online gambling sites, slot machines, games, ... Why let people shoot themselves in the foot? I can argue this one at great length, but suffice to say, you can always have an "insecure" interface somewhere for anyone who thinks they know better, but the average developer shouldn't have to be an expert on security, they should be able to just call "random()" and not worry. If I knew people were receptive to this one, I might actually go out of my way to do a PR. Happy to take it to another thread or offline if people are interested in discussing. Coming back to what I'd call the "developer onboarding" experience, though, I think I'd ask you all to reconsider the trend of slimming down the libraries that ship with Nim. In the early days of Python, the standard libraries were VERY extensive for a programming language in its day, and that's part of why people found it very easy to get things done in it. The language syntax is what comes to mind for many, but having watched it happen, I'd say the libraries played a much bigger part. Some of those libraries weren't awesome, sure, but I believe it was, by a long amount of time, the first language where you could get a web server or SMTP server in a line of code, etc. I do see the value in keeping a tight language core, with a "slim" standard library for environments where that is important. But, slim is often not important. So I'd suggest have essentially 3 rings of libraries, the minimal core, the stable, mature, widely useful core, and then as many decently written modules as possible that provide interesting, orthogonal capabilities. Here, too, have a team explicitly responsible for grooming the libraries, but have it be both official and, VERY importantly, (unlike fusion is today), shipped with the language. For instance! You mentioned iFace as a good option for interfaces. It gets suggested frequently in the chat room. One person recently said that it looked unmaintained, and didn't want to take the risk. I said I'd looked at it enough to say it does the job it's supposed to do, and looks well written. But Nim is changing pretty fast for a programming language, and if I want _my_ code to not have to go through major rewrites in the future, I don't want dependencies down the road that aren't going to change with the language. Having the broader Nim project take ownership of such things, gives people confidence that they can use it. And, I love the idea of a standard library of "use them if you want them" language features like interfaces. I shouldn't have to look at 8 different pattern matching libraries, unless I don't like the one in the standard library. There's a lot of cool software in Nim already, and centralizing it will help adoption. Leaving people on their own to figure out which solution seems like it might work, and which ones are likely to be broken in a year, figuring out if I need to do it myself... that's all a lot of friction that deep standard libraries can fix. Another example of that one; I recently had need to use object storage. There's one fairly complete Nim library that covers a lot of AWS's services (I didn't look for other cloud providers). But, unfortunately, it makes it VERY hard to figure out how to use it. Then there are a few really basic ones that only do object storage, and aren't always even well written. I took the easy path for now, but I was thinking, there are good C libraries here; NIM would do well to have a strong, well-documented library, even if it wraps under the hood. Especially if it can abstract across multiple providers reasonably well. Even if someone were to do that, and it were to become fairly popular, if it's not part of something "official", you're going to leave engineers doing a lot of legwork on these kinds of decisions. > > 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. > > this is definitely sad to hear. from what I can tell, go seems very strong in > network security area and nim might not be that enticing to them until it > grows and settles better for that niche. I don't think it's particularly security-industry related feedback. I've heard it from a couple of friends who I've gushed about the language to, who aren't in security. Though, I guess to the discussion above, the crypto in Nim isn't easy well-documented (and nimcrypto is certainly not thorough either). But nobody on my team was looking at any of the crypto bits. > > 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. > > I agree there are a number of paper cuts like these occasionally to be found > in the docs. They are not too many nor not too bad and I would say these are > the type of things that individual contributors could improve on without too > much guidance. You're right, I think the reference docs are solid reference docs. There aren't too many paper cuts there, but some of the things we discuss above (including compiler messages, some gaps in more tutorial/howto style content, and the ability to easily find either the docs or libraries that are most appropriate) are probably more important. > instead I would like to remind myself and others on one of the great efforts > that I think contributed a lot to improve the documentation, at the same time > onboarding new people: an activity to improve stdlib docs led by @miran in > 2019 <https://github.com/nim-lang/Nim/issues/10330> > > still thankful about that, not sure if it would be worth the effort of doing > again something similar but it is a great example of past work in > documentation. Yes, perhaps I didn't state it clearly enough, but I found the reference docs to be quite good, and when I went beyond that to the tutorials and so on that do exist, they were usually good as well. It's nice to see, and do appreciate all the hard work that's gone into everything. > > 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). > > I would say this is another known pain points of nim. Debugger is not a > widespread or straightforward practice. Another good place for some "official" docs... a HOW-TO for setting up debuggers on various platforms (not just on the command line, but specifically in VSCode, by far the most popular IDE today), and a tutorial on debugging, because a LOT of people coming to Nim (esp. those coming from Python who never discovered pdb) would love to learn if it could be made accessable enough. > > 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. >> >> 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. > > this is very nice to hear and I think we all share the fact that we feel like > it should be a lot more popular than it is. > > indeed this leads to what was indeed the main topic of the thread: how can we > drive Nim's adoption? and I gather a partial answer you give in this thread > is: > > the topic of how do we make nim successful is also a topic that is > occasionally discussed here in the forum (that might excuse some of the > rudeness of other commenters ;)), but it sure is not a topic that is going to > go out of fashion too soon (alas!). it is a very broad topic. I am still not > convinced by this discussion that reference docs are the most important thing > to focus on, but I have always believed that more general documents (as > @mratsim reminds us: how to, tutorials, explanation) should definitely be a > priority! (my number one priority is community building) That all makes sense! I was never trying to say the docs are the big problem, just a) point out that it's probably still part of the issue, and b) understand more deeply what can be done to drive more adoption. > In my spare limited spare time, I have started nimib project with the > explicit goal of producing more of this kind of nim documentation (I think > last year I have produced over 20 single documents using this on various nim > topics, in nblog and elsewhere - unfortunately discoverability is rather bad > yet). Incidentally there is also a ongoing very welcome effort to translating > the wiki to nimib(ook), which might help with wiki. Thank you as well for your hard work :) > Apart from this type of documentation, I think a very welcome type of nim > related content from experienced newcomers such as yourself is some kind of > formal or informal essay on why they find nim great (given their background). > There has been a recent example shared in the forum which made some waves > also on HN and given your background I think it an extended essay would be > very much welcome (here on forum but possibly also as a guest blogpost). Well, I personally will try to find time to do such things. I can't make any guarantees, but I'm far more excited about Nim in 2023 than I was about Python in 1994 (and I was pretty excited about it), so I do want to help if I can! I should say thanks again, too. I really appreciate you putting so much effort in your thoughtful response. John