Not too long ago it was impossible to implement std::vector in standard C++, as constructing objects next to each other formally did not create an array. Therefore pointer arithmetic on the resulting pointers were undefined behavior, as pointer arithmetic is only defined within an array.
This was fixed by the array being implicitly created in certain circumstances.
Zig's stdlib is much more useful than C's, but it's still entirely possible to write useful programs without it and instead focus on learning Zig's language features first.
But on the other extreme, the whole reason why I learned Python was its "batteries included" standard library.
Yes, but also no.
The standard library is often more complex and uses more advanced features then you often need for most projects. I.e. collections in std are supper general purpose, but if you need to write a collection it's normally specific to the purpose you need it for.
I.e. std is the "most" general purpose library you normally find so even if it's written with "KISS" in mind it's still often not so simple.
Then it sometimes uses unstable language features you normally can't use (as it's often made "in sync" with the language) and/or optimizations which in most other cases would count as "pre-mature" optimizations.
Through without a question you can learn a lot there, you just should be aware of the points above.
Optimizations in standard libraries are generally good ones, and reading it can give a good idea of what is or isn't worth it.
If the standard library is ugly and complex, it tells you something important about its design, and possibly about the language itself and its maintainers. It is a good indication of where things might well end up for you.
You should look at the ugly bits, and you should ask yourself "am I going to invest in this?"
Java is pretty good in that regard, for example. I regularly browse its standard library and it's quite comprehensible. Concurrent stuff is not easy, but I guess that's the nature of underlying algorithms.
Also that's the reason that I don't like Java streams. They're as hairy as Scala collections. I'm avoiding Java streams.
IMO implementation details of any library matters as much as its public API. If library implementation is not nice to read, it's a very bad smell.
Of course if you've already got one of each major paradigm under your belt things get progressively easier because you're exposed to more ideas...
It's great to broaden your horizons and all, but that is something that needs to be done judiciously and deliberately if it is to actually be of any use.
Or, try to add a non-trivial feature to the framework.
It seems to me like you've already solved the issue of "learning the framework" if your mental model of the framework is that solid.
The bulk of the language is actually the standard library. The APIs people will be using to solve the vast majority of problems. Of particular interest are the APIs used for dealing text and I/O because everything involves them.
This is why Scheme is so easy to learn. The language itself can be learned in hours. The standard library is so small it's pretty much useless. Learning Racket on the other hand is much harder.
To go even further than standard library, read the language's source code. This is especially relevant for virtualized languages. The implementation reveals how they actually work and enable a much deeper understanding of it.
Yes, reading hundreds of thousands LoCs written in C/C++ is totally viable method of learning languages. ;)
This isn't something beginners should do, of course. It is a fact that it does lead to a much deeper understanding of things.
This is why Racket is so easy to learn. The language itself can be learned in hours. The standard library is so big that you can do anything with it. Learning Scheme on the other hand is much harder.
Most people consider learning C hard (for example, compared to python), but it is an extremely small language with a "standard library so small it's pretty much useless".
Protip: That doesn't change their mind, it just makes them hate Go.
Together with that, I agree that one should read the high literature before inventing a new writing style.
If you don't like language X, don't take a job writing language X.
One was a JS guru who literally threatened 'I can walk across the street and get another job, you know.' And we let him, and both of us are happier for it.
So I do agree, don't join a team writing a language you hate.
I think the argument instead might have been, "Go is not designed for it, and kludging in a language paradigm that the language wasn't designed for is going to make for worse code."
The fact that these engineers didn't understand this, suggest to me that perhaps they were not very good engineers as such, even if they might have been skilled software programmers.
C++ standard library is written in a heavily templates style most user code isn’t written in. That would be a terrible way to learn.
Some of Python’s standard library delegates to C code.
Much of Clojures standard library builds the language up from a small set of primitive, sometimes out of macros, and isn’ta good example of how to write good code yourself.
The standard libraries tend to be written in a different mindset than idiomatic user code is, as the requirements differ. In my opinion, the best way to learn a language is to implement a non trivial but small project in it.
At the same time, there are going to be parts of the standard library that are less platform-specific and thus more readable, for example the Java Collection Framework.
Better way to learn is making stuff with the language, having actual skin in the game. Only then bounce back to theory on the more nuanced stuff.
Reading C++ standard library gives you headache, and doesn't really teach you how to write C++ in a normal application. For a beginner, this is an impossible approach.
Reading Python standard library means reading C half of the time. Useful for some seasoned Python developers, but not for new comers who want to read Python.
At the end of the day, standard libraries aren't written to teach, and some being a good teacher is a coincident. When you are learning a new language, you really have no idea whether the standard library is a good source for beginners.
I'd suggest a less poetic, more pragmatic approach to learning a new language: ask the most active forum of the language, and use the most common learning materials.
EDIT: As others note, a good chunk of a stdlib may involve system interop that isn't representative, so that tempers my comment with regards to whether that code is idiomatic. But my case still stands regarding concrete vs. abstract.
https://github.com/llvm-mirror/libcxx/blob/master/include/ve...
I would not recommend anyone ever look through that as a way to learn C++. Heck just something as basic as a struct that stores two member variables is a 200 line of code horror show in C++:
https://github.com/llvm-mirror/libcxx/blob/78d6a7767ed57b501...
To be frank I have the same mindset, but it's good to read other people takes on it. Some prefer to have basic knowledge and feel great anxiety when they're jumping to code without any foundation.
What you described as better could be a really good fit for business-first coding opportunists who would get annoyed by perceived inefficiencies and petty politics in academia...
The article is a terrific example of basic analysis BTW. This underappreciated skill can be a huge blindspot for opportunists...
> The article is a terrific example of basic analysis BTW.
Hahaha. It's some cherry picked examples and you're already claiming it's 'a terrific example of basic analysis'. The hyperbole is real in software.
In the last decade I've spent time learning five sufficiently novel languages: Scheme, Ada, Erlang, Rust, and Go. Three of those are from the late 70's. I'm really glad I learned Ada and Rust. I started using Ada for embedded programming, and I'm trying to find more opportunities to use Rust because it so robust. I only studied Erlang, Scheme, and Go because smart people I knew told me I should investigate, but I have not used them.
It's like a modernized C with a good implementation and out-of-the-box no-nonsense tooling, and the tricky bits left out. Nothing really new to see, but there was nothing really like it when it took off. Very utilitarian. Rust, Java, C#, C++ - those are all very 'complex' or 'bloated' in many different ways to an avid Go programmer.
I'm not promoting Go (I personally don't like it), I'm just trying to understand it's appeal and popularity and what is different about it. Quality and completeness of implementation, tooling, etc. by having a big company behind it also helps of lot of course - but it isn't sufficient.
I'd recommend starting with Pascal, because of the comprehensive and high quality standard libraries (or "frameworks" -- see related recent HN discussion...) in Free Pascal and Delphi, and because Free Pascal can target a lot of different OSes. OTOH, a downside might be that you learn (to rely on) too much of the FCL/VCL in stead of just syntax, so you get confused at the lack of those libraries in Ada; that could speak for taking it the other way around.
TL;DR: IMO, in a way that's perhaps closer to two new languages to learn than three.
How would you categorize No Starch Press, Manning, OReilly as per this rubric ?
For example, I do not think it is possible to learn modern Java by reading Java Collections code. You won't see Optional<T> being used there. Instead, your takeaway might be that it is perfectly fine to return nulls all over the place.
I think Rust is in a category of it's own, mostly due to circumstances rather than anything: The ecosystem has grown immensely over the past several years and you can find a crate to solve most of your needs. But here is where thing become tricky: more often than not the documentation provided is extremely vague to put it mildly and the examples are a hello world at best. With this in mind, in order to truly use it you have little to no choice but to dig deep into the implementation and at some point reach the standard library.
In general, I'd heavily recommend studying the usage of lambdas & streams. And Optional<T>. ;)
I have found the Rust std lib to be a great resource. Much of the unsafe is necessary because there is literally no other way to build up abstractions like Box or certain data structures without it. Obviously once those are written though, you want to build on top of them where possible and not use unsafe.
It's probably important to delineate between a good example of application code vs library code also. The std lib is not going to help much with application code.
To a decent extent yeah, though I would emphasize the issue isn't quite being as fast as possible (although in some cases it is, but also see I/O streams...), but rather having near-absolute correctness, and achieving high performance as a secondary goal. You can usually find a faster third-party implementation of anything in the C++ standard library. The problem is third-party implementations always cut corners somewhere, whether it's strong exception-safety, proper trait/concept handling, thorough testing of rare edge cases, extensibility/customizability, or other stuff. Even the syntactic complexity rises as a result, let alone the complexity of the actual semantics. (Even minor stuff like using difference_type/size_type instead of ptrdiff_t/size_t makes things more verbose and harder to read in the standard library; third-party implementations would often opt for the latter.)
The frustrations people have with it are sometimes up to the point where they begin writing everything from scratch…
[0] https://www.fluentcpp.com/2018/05/08/std-iterator-deprecated...
([a b c d])
performant enough to matter in library code instead of using ([a b & more])
? I hope it’s the former.I don’t know about reading std alone to learn Zig though, I used other sources like ziglings and ziglearn which taught me syntax and patterns. Had I started with the standard library I doubt I would have picked up the language as quickly as I have.
So having learned Zig I am much more inclined to look at standard libraries for languages I learn in the future, but I don’t think it’s wise to rely only on standard libraries for learning.
At the moment since Zig isn't complete you aren't going to find documentation that is either. Particularly for newcomers.
I admittedly know C very well, but assuming you already know a language with a C-like syntax (C++, Java, JavaScript, C#, Rust, etc.) most things like functions, control flow, variables, statements map to Zig with only small syntactic differences.
One thing that may be difficult to learn not knowing C is working with strings, since they are just arrays of bytes. Most other languages have a string type, but Zig is much more like C in that strings are null-terminated fixed-sized arrays of bytes.
I agree with some of concerns from many commenters. For many languages, especially those that have been around for a long time it's probably not a good idea to look at the stdlib. C++ or Java, no thanks. But with some languages like Crystal, Golang or Julia, it can be really very helpful to look at the stdlib implementation.
Sorry, stupid question: Is this derived from the old Crystal Reports, or something completely separate?
K&R is a much more meaningful guide than unistd.h.
Certainly this is how I learn. Much more immediately useful than voluminous documentation.
However I am not sure every language has a standard library.
For example, Lua.
Also not sure every standard library is a model to follow.
For example, where feasible, I try to use and learn from djb's C functions instead of the "C standard library" ones.
For stuff in the “os” package it’s a different matter. All of that code is a bit messy. Not because the authors did a bad job, but simply because it’s hard to implement the same API on half a dozen operating systems.
Then there is the “runtime” package which relies on a lot of global state, and has to work well in cases where heap allocations are not permitted.
Sure you’ll learn how the language works, but you shouldn’t draw inspiration from those on how to write your own code.
The Python standard library is pretty crufty — lots of stylistically dated code. Same with Perl 5, and I would guess other similar languages but I can't speak from direct experience. I bet that's more a function of their age — back in the 1990s maybe it might have been unreservedly good advice to read those standard libraries.
I've also learned a lot from writing FFI extensions for languages, which for Rust and Go involves a lot of standard library diving but for languages like Python, Perl 5 and Ruby where the core is mostly written in C, it's a different experience than reading the standard library.
> I hope that you will pick up the habit of browsing through source code. You can learn from it and mine it for ideas. Having GNU Emacs is like having a dragon’s cave of treasures.
- https://www.gnu.org/software/emacs/manual/html_node/eintr/On...
Let me cite a single line from the MSVC implementation of the C++ standard library (https://github.com/microsoft/STL/blob/main/stl/inc/xtree):
using _Scary_val = _Tree_val<conditional_t<_Is_simple_alloc_v<_Alnode>, _Tree_simple_types<value_type>,
_Tree_iter_types<value_type, typename _Alty_traits::size_type, typename _Alty_traits::difference_type,
typename _Alty_traits::pointer, typename _Alty_traits::const_pointer, value_type&, const value_type&,
_Nodeptr>>>;
Also, good luck understanding this class member definition. Hope you figured out _Scary_val! _Compressed_pair<key_compare, _Compressed_pair<_Alnode, _Scary_val>> _Mypair;
(Hint: Empty base class optimization.)For Go and C on the other hand I think it works very well since the core languages are so simple it's viable to read others code successfully without being a language expert. I read the Go stdlib code all the time if something is unclear in the documentation (the docs are good but sometimes there are edge cases that are not clearly documented).
I think there’s definitely value to reading a language’s standard library, and I’ve also gotten lots of value from even reading the language’s implementation! But I hope people take this advice to start with reading the standard library with a grain of salt: it can be one extra resource for you, and likely to show you new things that weren’t written in docs somewhere, but if it doesn’t click or is proving difficult to understand, that’s fine!
In particular, for the “reading code to learn” bit, consider reading an application written in that language (command line tool, web application, etc.) and it might serve as a more reduced intro to the language.
That being said, for Erlang, I think this is a good idea. I learned a lot when reading the standard library.
That shows you call sequences in context, rather than just getting lost in the code.
We also built a simple CPU from gates using an electronic simulator.
Left me with some confidence that I could do things with a relative confidence. Definitely value in learning the basics.
1992 - French v9.a.e
2000 - French v9.e.m
2011 - French v9.m.q
Don't be deceived by the dates, though. The project isn't dead. The Larousse and Le Robert forks are actively developed.
[0] https://en.wikipedia.org/wiki/Acad%C3%A9mie_Fran%C3%A7aise#D...
Also once one gets more experienced, its better to decouple the language from programming concepts like object oriented programming, continuations, avoiding side effects in functional programming, etc. Useful to read books like SICP and algorithm books, then learn multiple languages and you will see they are not that different overall.
I recommend learning Lisp or Scheme or related languages because they have a lot of good conceptual resources to learn from. But maybe that’s my background talking, I loved SICP. I learnt SO much from studying Common Lisp in the last year. Of course it helps that it has a great language specification.
In terms of choosing a language, standard library matters a lot. Hence the explosion of JS due to NPM and also being in browser. I’m suprised SWIFT is not more popular, given Apple’s place in the ecosystem. I really liked programming in Swift, very enjoyable language. And it has generic functions too!
For instance in Scala you'll likely need to know cats-effect or zio ecosystem more than stdlib. Likewise for Rust, where futures and async stack (tokio, asyncstd) are outside stdlib.
1. A good look at long lasting, durable pure python.
2. A good look at long lasting, durable C implementations of python (dict is the core of Python. Read the source!)
3. A look at a bunch of libraries that basically never get used and a sense of how they compare to popular third party libraries. (Doing this is why I’ll never complain when a language’s stdlib is small. I get it now.)
I don't think stdlibs should be barren, but I completely get the ideas of languages like Rust that want to include only the most obvious of candidates and leave the rest for the community to organically evolve.
(Honest first-split-second reaction.)
I think is a good idea to read them, but I'd like them to be more concise.
[1]: https://docs.google.com/spreadsheets/d/1U6_NxSxcFC3FPqtPB8eI...
In C#, standard library is awesome, and indeed a good starting point for people learning the language.
On the other end of the spectrum there’re languages like C++ with these horrible templates, or Rust with tons of unsafe code. Adopting patterns or coding style from these standard libraries is not the best idea.
Nikola Motor - glad to see something good coming out of that scam...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
Edit:
And the Web API reference (which is what I was actually thinking of when I posted): https://developer.mozilla.org/en-US/docs/Web/API
JS is a bit odd here, possibly for good reasons (ubiquity + dynamic nature of the lang itself might mean runtime considerations override any degree of self-hosting), but it basically means it's not possible for standard definitions of standard library. So the question becomes... what are some masterful libraries written in JS?
I learnt more about C and C++ from studying Plauger's The Standard C Library and Plauger/Stepanov's The C++ Standard Template Library. I also remember learning Object-Oriented Framework design from MFC Internals.