Languages often have a bunch of implicit assumptions which are not stated outright in the material.
As a example, the Foo-lang [1] books starts (obviously) with how to write and compile a hello world program. Bar-lang books typically postpone this to the end of the book since IO and deployable programs are advanced concepts. I once talked to some Bar-fans about this and they simply did not understand why this could be an issue. Surely you could just echo "Hello world" in the repl as the first exercise?
The underlying unstated assumption is that Bar-lang programs are primarily something you write for yourself and interact with in a repl, while Foo-programmers assume programs are written to be deployed and executed.
Such unstated assumptions are not written on first page in the manual because they are invisible when you are immersed in the culture.
Another example is a discussion I saw where a Baz-user claimed that everything was simpler in Baz than in Bong. The Bong-fan then asked how you loaded data from a relational database. The Baz-fan replied that only an incompetent moron would use a relational database, real men use text files which have less overhead. Now this could be dismissed as cognitive dissonance because Baz didn't have a nice RDBMS interface, but I think it is indicative of a deeper cultural assumption that the application can decide which format to persist data in, where Bong comes from an assumption that the data is already there in a given system and a workable program will need to be able to interact with it whether the developer like it or nor.
Again, such underlying assumptions are typically not written in the tutorial, but have deep implications for the language design and ecosystem.
[1] I changed the language names so as to not start a discussion about the particular languages. Although I'm sure there are actual languages called Foo, Bar etc.
Mention language names and people get hung up on the specific languages chosen, use generic names and people try to figure out what the obscured specific languages might have been ….
Cool. I expect it to happen with all kinds of languages, it's interesting to see it happening.
Just a decade ago, databases weren't the go to solution to all kinds of software. Now we have sqlite everywhere, so those arguments will probably get less common with time.
For me the worse part of every new language is deal with ecosystem. Holy fuck. It is so annoying. Scattered info, standards, many solutions for the same thing and none is good, style guide, plugins and editors, debugging, packaging, testing, libraries, environment quirks, deployment compatibility, vendoring/semantic-versioning etc.
Ironically, learning the language itself in general is the easy part, that other stuff that are just pain.
I just love learning new languages, but I hate to deal with new ecosystems and all their bullshit. It is just terrible, always seems totally wrong for a outsider (ex.: JS with npm, .Net with versioning hell, Scala with sbt bugs, Haskell with Cabal Hell, Mobile dev with all complex setup)
Fun thing: to make anything useful, dominate the ecosystem is essential.
To be realistic about it I stopped calling things I don't understand "bullshit" and "terrible". What I use instead is "I don't know why it is that way", "I don't understand" and finally realization "OK, I don't want to spend my time on understanding this because I have better things to do".
I would love to spread this approach in developer community. Be honest that you don't understand stuff and you don't have time to learn it because you have better things to do.
Though if someone is paying me to do something in a language I will put my time into learning it. If it is just a hobby who cares that it is not easily grasped, I don't have to spend time on it.
You're entitled to your opinion, but most of it is 100% bullshit in my eyes.
I'll use Haskell as example. The ecosystem is a mess. `stack` is admirable effort to make development palatable, but it's ultimately a technical solution papering over a cultural issue: The community [including the language designers!] have 0 respect for backwards compatibility.
The node ecosystem is seems to be the worst at this. Not only is there no real respect for backwards compatibility, but it seems that the real purpose for a lot of the stuff is created is to 1) bolster the creator's resume and status or 2) to get funding from a VC. Certainly all ecosystems have that to some degree, but node just feels like the worst, by far.
I've written all the major languages with this problem professionally [except node]. It's not that I don't understand. It's that I did spend my time on understanding this and it was such a complete waste of time in retrospect. The solution isn't to spend more time learning the tooling. It's to only work in ecosystems that don't waste your time.
edit: Any ecosystem that has some notion of a "langauge version manager" is a big clue to me that I'm about to spend a lot of time learning a bunch of non-portable information.
Have you had an experience with Cargo, the Rust package manager? It is an absolute joy to work with, clean repeatable builds, and fast for what you are getting (speed of C++ with the correctness of Haskell).
Not really. I've played with Rust but haven't used it in anger. One thing I've noticed about my programming style is that I LOVE to learn about new languages and language features. Using a language like Go or Java forces to me concentrate on the problem at hand [which almost always something where GC is fine for what I'm working on]. That said, the Rust ecosystem seems pretty solid [except the edition stuff, that makes me very leery...]
I’ve been happy with the Elixir/Erlang world. Especially as a scripting/dynamic language it’s been remarkably stable from a "don’t waste my time" perspective. Core system features from years back work, and generally work with updated libraries.
Well despite a few major changes to Phoenix, but that was mostly changes to the naming patterns. It also switched to web pack which I consider a pain point of following JS development. With LiveView I only have a dozen JS deps and ~50 lines of JS so now I can get off the JS ratrace too! Well github complains about outdated npm deps. I should make a GH action for that or something.
It has a decent standard library (so you don't waste tons of time evaluating/choosing libraries for basic things) and has a simple package management story with bundler, which separates what libraries you want (Gemfile) from what specific versions you happen to be using (Gemfile.lock).
The more experienced I get, the primary transformation I see in myself is being less dismissive of existing work that I wasn't involved in.
Were they insanely time crunched? Was this a prototype by a lawyer who painstakingly taught himself Excel and then taught himself Python again to port the Excel sheet he had into a service? Were the abstractions they chose based on whatever was the best practice at the time?
I've stopped scoffing at a simple app that I think I can "hack together in a weekend". No I can't. There are complexities and corners I don't see at the moment.
The competent ones I’ve worked with invariably convince engineers their “weekend project” will take at least 2 months. They start by getting the engineer to spend an afternoon enumerating all the tasks they need to complete to implement and ship it.
Then the engineer takes 3 months, when they would have taken 6 without help from the PM. This is because the PM follows up, and helps them be ruthless with the requirements list.
I agree we should be more positive, but I think it's a mistake to think that if we understand enough, we stop calling things bullshit. I think that there are two common meanings of the term that are analytically useful.
One is Frankfurt's, as explained in his book On Bullshit [1]. His definition is "speech intended to persuade without regard for the truth". There's a lot of this in tech. Ego-driven posturing. Blind ideology. And a bunch more that comes from American business culture, where we have a special legal category for bullshit so obvious that it legally doesn't even count as false. [2]
The other is what Lean process experts call Muda [3]. It can be translated as: "futility; uselessness; wastefulness". But bullshit is often a perfectly good translation. As the original article points out, there can be an enormous amount of wasted effort coming up to speed, like "the footguns that will cost me a day to debug". Just yesterday I spent a day on what turned out to be a bug from 2015 that hundreds of people have voted on, but the tool maintainers have refused to solve because it doesn't fit with their initially chosen architecture. I am comfortable calling that bullshit.
I also think your "I don't have to spend time on it" bit is, well, let's gently call it "erroneous". Languages aren't like books, where a reader's choices are infinite. There are a finite number of languages popular enough for practical use, and every one of them was built with the express intention of having a lot of people use it. Every one of them has people who make their living from maintaining it, and many are purely corporate profit-driven considerations. When people set out to insert themselves into other people's lives, there's an inherent level of responsibility there. It shouldn't be handwaved away.
The ecosystem around a language is not different because each language needs a wildly different ecosystem. It’s mostly an accident of history where different tools and techniques are adopted by different communities over time.
For me, part of the problem is the fixation towards a "language ecosystem" per se that people seemingly have come to expect. What has happened to the idea that you could link object files/libs compiled from any number of different programming languages, all adhering to the OS's platform ABI? Where you the developer, and you alone, decides which language to use for coding a particular aspect of your app based on the respective language's fit to the problem in a polyglot fashion? For example, if your app needs a parser for a config language, say, you're free to use Prolog with its built-in parsing DSLs. Similarly, if your app involves DBs or GUIs, etc. PLs today are huge, unportable monoliths with shiny web sites when the point of a standardized PL, for me at least, has always very much been that it fences you against overreaching vendors, language world domination aspirations, and churn disguised as march of progress.
Because once you get beyond the simplest runtimes maintaining compatibility between things becomes difficult fast and more complex runtimes have enabled a lot of things people want, like actual portability between systems, JIT compilation, garbage collection, etc. Most language runtimes have native interop these days but it’s always a worse experience all around than using language-native libraries.
... C++ with CMake, oh wait Ninja, oh wait nevermind, and also you have to catch up on a bunch of random bloggers and various conference recordings to have a clue as to what are the community recommendations for the libraries, or coding standards.
When people compare C++ with Rust, quite often the only thing measured is performance where depending in your cxx compiler Rust (or rather, llvm) may lose sometimes.
What is often forgotten is the ecosystem.
To build a cxx project you'll probably need to learn CMake and ninja; maybe Buck or Bazel too. If your project has eternal dependencies you may have to figure out yourself how tl link everything together using whatever build tools the authors were using. For docs, you'll have to learn and use doxygen; for style formatting, something like a clang-format and its presets and options; for linting, something like clang-tidy or cpplint, etc. For testing, probably catch2 or one of similar frameworks. There's no universal concept of "package" or "version", you're completely on your own here; most open source cxx repos that have dependencies just add them as git submodules.
In Rust, cargo build to build, cargo doc to generate docs, cargo test to run tests, cargo publish to push your crate to the index; cargo fmt to format the code and cargo clippy to lint it - that's it, we're done.
In my experience, Rust certainly has one of the easiest language ecosystems to use.
I've been using Rust for ~3 years now, and have been trying to learn C++, but I've been so spoiled by the entire Rust ecosystem's user friendliness that it's a very daunting task.
Or Makefile, or Meson, or autotools... And beyond to infinite.
Man, that type of stuff don't motivates anyone to learn a new language. If all what we should do it is code a solution and deploy with one command, oh God, will be a dream.
But no, beyond all this clusterfuck, by doing cloud stuff will be need probably Docker too, Kubernetes. Maybe ansible too? Oh, no, your team use terraforms.
It's the Cambrian explosion in SW Dev tools. What amazes me though is how undead everything is. It seems that even ancient stuff is still somewhere out there waiting to be maintained. And there's a gazillion more every year adding to the pile.
There's something of a paradox to build tools - people like to have one in "their" language, but most languages are ill suited for it. Half of the people need something really simple. The other half need something extremely complicated. There's a mountain of edge cases, most of which people don't even notice, but which make other people's lives a misery.
For git, I felt kind of sad that "linus branding" helped it to beat out mercurial. git's UI is kind of monstrous (even linus admitted that). It's one of those rare technologies where a bad UI is branded as "you're just not smart enough to understand it".
Magit is great! I use everyday. The more useful feature for me is partial staging by simple text selection. Help so much to create better atomic commits
probably so many things are undead because we don’t need to /can’t litteraly eat slow/bad designed SW to survive as the analogy in the nature out there
Off topic, but anyway. I hate cmake, its overly complex and I can never remember how to do things with it. The thoughts of having to set up even a small cmake project has put me off starting new personal c++ projects. Its a headache I simply don’t want to have to deal with. I eventually gave up and started using tup for personal porjects. It doesn’t have the same support for prepackaged libraries, but I’m much happier and no lobger dread setting up new projects.
So, for me, its much worse than just “omg which tool, so many!” because the most used tool is also, in my personal opinion, terrible.
I suggest learning make. It is a wonderful language. Start with the GNU make manual.
When you find yourself manually listing the .h files that a c/c++ file includes, learn how to generate .d files (it is in the manual, but stack overflow has some better patterns).
Then, figure out how to use make to automatically generate the list of source files required to build each binary. At this point, your makefile will have surpassed the usability of cmake in my opinion.
Soon after that, you’ll think you need recursive make to deal with vendored dependencies. Instead, read “recursive make considered harmful”.
At that point, you’ll start to hit rough edges, but you’ll be well beyond a “small project”.
Next on my make reading list is the BSD ports system.
I’ve heard bazel is a decent make replacement, but I haven’t used it.
Ninja doesn’t aspire to be one, and cmake/autotools are the reason I decided to go with raw make in the first place.
I provide a simple Makefile for almost every project, mostly as a reference to myself and others. Add a "build", "clean", "deps", and maybe "install" targets and then regardless of the specific tooling/language it’s easy to figure out what to do or where to start. Even if that project/language has a good build system or scripts. Simple makefiles aren’t too much worse than yaml.
I think this is a point where Go is very good at and JavaScript sucks pretty hard. Mostly because Go brings many things by default and JavaScript has such a high rate at which new tools become mainstream/obsolete and so many options to choose from and combine with.
I found the opposite to be true. With javascript I never saw the package.json not work for the other developers on the team; with go, half of my team can't successfully update vendoring for no apparent reason.
Commands frequently error with messages that are completely worthless.
Go seems to have made up it's own path syntax with things like "...", and commands like "go test foo/bar" will fail with an error message that gives no clue as to the problem, but work fine with "go test ./foo/bar". Why?
What's the command to see if any of my dependencies have a CVE against them? Oh, there isn't one. What's the command to prompt me to pull in a new version of my dependencies? Oh, there isn't one.
This is a language that has made some promise about backwards comparability, but every release seems to break how things are built, and you have to fiddle with bizarre environment variables like GO111MODULE to find the incantation to make things happy again.
I mean, Node and Go were released within 6 months of each other. When jquery was the dominant tool in the ecosystem, there wasn't nearly the level of breakage that there is now.
Don't bother using SBT. Just build Scala with Maven. It's wonderful, everything works how you'd expect, all the documentation from the Java world is still valid.
I've never got the hate for Maven - all the design decisions people dislike seem to be the same things that people praise Cargo et al for. If anything it suffers for being ahead of its time.
Visual Studio for C# development got this right: powerful language with super good IDE support and a rock solid standard library. Good documentation online too. It hides complexity that can bite later, and it can be complex to chose a framework to target, but otherwise it’s super easy to get started.
A lot of this stems from the fact that most languages start out thinking they won’t need an ecosystem and what emerges evolves rather than is designed.
I've just introduced a new engineer to a project in a language he hasn't used before. All of these points ring true! I want to suggest C# on .NET Core as a pleasant, fast language and ecosystem to learn.
I used to avoid anything Microsoft like the plague. A friend of mine used to call me "the Unix beth din" [1]. By necessity I needed to use C#/.NET for a project. It changed my view, mostly because almost all of Mr Wayne's questions could be answered quite easily. The package management, build system, IDE, installers, test framework, debugger, and documentation are all from Microsoft, come well-documented, and on all platforms of consequence. It's a breath of fresh air compared to the clusterfuck of competing tools (e.g. gulp, webpack, yarn and friends for JS) with overlapping features and bad docs that some other languages are plagued with. In C# on .NET Core, MSBuild + NuGet handles this for you. Compiler selection, package installation, building, test running, custom build steps, code generation, etc etc. Plus, NuGet's website and interface in the canonical IDE (Visual Studio) shows you the "'canonical' packages the community has consensus on".
Agreed. .NET Core and C# have been genuinely pleasant to work with from the start because of who was behind them — Anders Heijlsberg, who was author of Turbo Pascal and architect of Delphi. Anders is one of those guys with good taste and a practical streak.
Many of us dismissed Microsoft back in the 80s and 90s, not primarily because it was predatory but because most of its stuff felt like commoditized output, had rough edges and lacked taste (Java today continues to have this latter problem). It was a bad halo effect.
I’m primarily a Linux guy but I started out in .NET Framework a couple of years ago, and am now writing in .NET Core. The experience is definitely much more cohesive, more curated and less fragmented than the JS ecosystem.
Anaconda Python for the most part is pretty cohesive in the Python world. (The Python packaging story is somewhat broken still but it works — packaging is a very difficult problem and no one gets it right entirely unless one is willing to tolerate opinionated inflexible solutions).
Besides focusing on language 1 vs language 2 I think the author is also highlighting just how hard it is for people to get started in any language. You mentioned R/Rstudio ....
I just wanted to work through an example in a book that I'm reading that has corresponding R code. I type require(package_name) into the command window and that doesn't work. I look at the help for "require" and there is nothing about how to install packages - I would think a reference to the install packages command would be useful (they link to how to check, but nothing obvious on how to install, maybe I missed it). After some searching I find the command and it prompts about whether I want to use the source code or not (after a few reads I understood what was going on but it could be improved). Things started compiling and then I tried to run my package again, no luck. So then I try reinstalling and this time I noticed the error - something like "exited with non 0 status". Awesome. Looking a bit closer I noticed one of the dependencies was not installing. After trying to install the dependency manually I somehow realized it was only for R version > 3.6, I'm on 3.5. So I figured updating RStudio would fix the problem, no luck. It's not like RStudio advertises what version of R they are shipping with Rstudio .... Now I'm on someone's Linkedin post (wtf?) looking at how to upgrade R from within RStudio. They indicate that on my mac I should updateR (or wait, they say that turns out to be not good, so just install from CRAN). Hopefully that works. Do I try my luck with R v4? Nothing's going to break there right ...?
This isn't meant to be a "R is bad" rant. Maybe C# or some other language really does avoid these problems, I don't know. However my experience has been the problems the author mentions are a problem everywhere.
You make a good point -- these problems exist everywhere. It's a trade-off between flexibility and restrictions/constraints. Some platforms manage this balance better than others.
The other issue is that many of us don't notice certain roadblocks because we're so used to working around them. In your case, my first instinct would be to `install.package(package_name)` and if something breaks, I google the error. Usually within 3-4 steps I'm on my way. But if something has just been released and no one's hit issues yet, google might not turn up anything. So then I'd have to open an issue on their github page and wait.
CRAN generally does a good job curating -- it has strict policies like if a package submission doesn't pass tests and doesn't succeed on automated builds on x number of platforms, it doesn't make it to the repo. That said, I've experienced a few package breakages before so I also want to validate your experience.
While I'm here, I also want to say as a Linux person, I hate the "compile first" culture of UNIX based software -- I'm not sure where it originated, probably GNU and open-source? Sometimes I just want to install a library and have it work -- just give me static binaries, don't make me compile stuff. I really don't care about the source code. To me as an end user, the appeal of open-source is that the source is available if I want it, but most of the time I really don't.
I get really frustrated when some Python packages don't offer wheels, and when the compilation breaks I have to spend hours/day figuring out what went wrong. TensorFlow 1 was particularly bad -- even with Bazel, things would break between releases. It's a huge productivity suck.
My introduction to Python (a long time ago) and "batteries included" was going to some random guys website to download all the compiled packages I needed. Thanks Christoph!
JS peasant here, I have not touched python recently but had to run a .py script to automate a task with FB website, sure enough had to download a couple of things from this person's website.
I am like the "before" version of you, so I have a question.
How did you get around the problem of not having any integration with Unix tools (or did you just not bother)? Maybe I'm not familiar with .NET. I see you can run it on Linux or Mac, but I don't imagine you can use Make or helper shell scripts if you want developers who use Windows to be able to build your code.
Quite apart from my loathing for Microsoft products, the reason I don't try things like .NET is that building for Windows when you're developing on Linux or Mac seems like POSIX, but 100 times harder.
You could use nmake and use a build.sh (well, build.cmd) if you wanted to, although it's not really common. My sense is that the hierarchy of build tooling goes something like this depending upon complexity:
1. Hit the "Build" button in Visual Studio with the MSBuild file it generates for you.
2. Write a custom MSBuild file that embeds your logic in XML and run it via the msbuild CLI.
3. Write the build script with something like Cake. Closest to writing sh to perform your build except that your script is done in C#/F#/etc. the same as your app. More verbose than sh for simple things but you get the same tooling assistance you would writing normal code.
> Quite apart from my loathing for Microsoft products, the reason I don't try things like .NET is that building for Windows when you're developing on Linux or Mac seems like POSIX, but 100 times harder.
It's actually less bad than you think. At the low end it's just `dotnet build` everywhere; maybe a `dotnet publish` is involved but you can cross-compile fairly easily. At the high end the build libraries are cross-platform, and should work anywhere dotnet itself does as long as you avoid embedding any platform-specific assumptions into your logic.
> How did you get around the problem of not having any integration with Unix tools (or did you just not bother)?
Emacs with Omnisharp gives you the usual autocomplete/inline docs/semantic rename/etc., although I'm not sure if you'd consider Emacs a Unix tool ;)
I'm told it works well in Vim though I've never used it myself.
Realworld [1] is the closest thing I know. The implementations usually have everything except the list of tools necessary to actually run and develop the app.
Rust (Rustup) + IntelliJ (Jetbrains Toolbox) is the single best way to get the same thing for native code. Version manager for environments, cross toolchains, package management and building (Cargo).
Another approach is to just not use these stupid tools. I don't want to propose anything in particular, but it is nice to have an environment with bounds. I like to have something that just lets me create my own shit. And lets me use the occasional library to avoid a year-long extra project, without requiring me to buy in to another ecosystem.
Microsoft changed the official way to write Windows apps so much in the last decade(s), that it's hard to keep track of what combination of tools/SDKs and languages one should use.
They're the least stable platform by far when it comes to tooling right now and the perfect example of "fire and motion". Linux, Mac, Android, iOS all had fewer major changes in their development toolchains.
Those are quite the weasel words. Stay within the narrowly-defined targets for any language or ecosystem and you'll be happy. Once you start trying to do something interesting and supporting multiple versions of Windows Server $oldversions-that-your-customers-insist-on you will run up against the rough edges and will be screaming at Microsoft's handling of: codepages, charsets, filenames, installer standards (anyone actually using MSIX now? Do you enjoy writing your own installers using WiX or one of the proprietary fragmented toolchains?).
Microsoft still sucks, still seeks to restrict your freedoms with licensing and copyrights and is infinitely more fragmented and complex and incompatible than *NIX.
The fact is that most of the things on the list are just trivial, but a nuisance to do because it is the boring, not glamorous part of the programming job.
For me, the really difficult part of the language is understanding the core concepts, like what is a monad? or a functor? or a lambda, or a map, or an S-expression, a pointer, automatic reference counting,ip stack, neural network and so many more.
Each of those concepts isolated can take more than a week to deeply understand.
What this man calls "The hard part of learning a language" is quite simple and easy to do with the right method.
The method I use is:
- Take a notebook and write down a checklist with all the things you need to do.
-Set an alarm clock to alert you after an hour of work.
-Start following the steps on the checklist, mark them when finished and write notes of what you did.
-When the alarm alerts you, stop working.
Now rinse and repeat every day as a routine, doing other (fun) things so you don't emotionally link learning a new language as something terrible or bad.
Instead of trying to do all the boring stuff one single day(and burning myself out) I split it.
Learning different approaches to programming will pay off over time. It compounds and makes solving problems so easy in the middle and long term. But you are not entitled to improving.
The fact is that nobody cares if you stop learning. They will just pick someone better solving problems and not making mistakes than you(because they continue improving).
I've also found a timer-based approach to drudgery very helpful. Your technique is reminiscent of the "Pomodoro Method"; you should check it out if you're not familiar with it already.
> For me, the really difficult part of the language is understanding the core concepts
Well, it might be difficult in an absolute sense, but it's exactly the difficulty that you're motivated to overcome. You started learning the language in order to understand new concepts/techniques. And so it's the "easy" difficulty, because in some sense it's fun.
It's the difference between climbing a mountain (difficult, but rewarding) and climbing a mountain with holes in your boots, no food, and a broken strap on your pack (difficult and annoying).
> I prefer to just get started by building something.
I think you're missing the point (of the original article). That's pretty much the issue here, some languages have such complicated ecosystems that you can't "just" build something.
To go from "ok I've written some code" to "it runs", sometimes it takes hours of wrestling with complicated tools and reading poorly written docs. It's infuriating.
Though those are good points, there are a few things to mention: once you know a few programming languages, jumping into a new one becomes relatively easy. That said, there are a few traps here and there(something I've also noticed when studying a foreign languages after knowing 2 others): "Oh that's the same as in {{X}}". And you pay no real attention to it as a result. A few days later you end up going to check what "{{X}}" was.
My methodology as far as programming languages go, is the following:
1. Learn the nature of the language by understanding it's internals - is it dynamically typed, statically typed, functional, object oriented, single threaded, multi threaded etc.
2. If it's a compiled language, learn the hello-world and then spend some time to figure out how the compiler works.
3. Ecosystem - packaging, distribution, community, etc.
4. No IDE's, plain and simple vim. Getting off the line becomes a lot harder but it teaches you the fundamentals from the start without relying on anything fancy: Get your hands dirty.
5. While you are studying it, think of a small project to work on along the way in that language and try to push your current knowledge over the edge of what you've learned. After you learn a new concept, go over the entire project and see where it can be applied and what would be the benefits/drawbacks. Even if that means re-writing 90% of the project.
Definitely. I consider myself somewhat of a PL polyglot. After you've gotten experience in the different semantic paradigms (functional, OOP, imperative, etc), I think it's relatively simple to pick up a new language. It's mostly just a matter of learning some surface syntax and the standard library functions ('how do I concat two lists?', etc).
The hard part is when you encounter a language that has complicated semantics.
I actually think #5 is the most important and shouldn't be discounted. I like three month projects - something moderate hard that might or might not get shipped. A summer of evenings sort of thing is usually enough to get a good grasp for me.
While this approach seems to work for a lot of people, personally I'm in the crowd that has a really hard time with that.
I'm just not a creative person. I consider myself a good developer when it comes to diving into an existing code base and figuring it out, fixing things and adding new features. But I simple cannot come up with stuff on my own. I've been trying ever since I was a kid and started programming, and now it's been 20+ years of drawing blanks when I try to "think of a project."
There's no need to be creative about it. I never try to (re-)invent the wheel myself. Once I'm done with #1 on the list I posted, I evaluate the strengths and weaknesses of the language and pick something that probably already exists. Say for the case of Rust when I was learning it ~3 years ago, that was a private dropbox-like service which syncs files I listed in a config file to a GCP filestore bucket. Nothing fancy or complicated but still - doing checksums, syncing, error reporting, all the usual stuff. Eventually further extended it to encrypt personal documents before pushing them and so on. Doesn't have to be big or complicated or something that no one has done before. Matter of fact, doing something that already exists is the better option cause you can transfer concepts.
Parts that are harder (for me) than anything on the list:
- buying into a paradigm specific to the language at the beginning. Sure, everyone tells me that multiple dispatch is great in Julia, but that doesn't click until you write a decent amount of code.
- frustration of dealing with exceptions, special cases and unexpected behaviour (R is full of these, for example)
- teaching materials that pile all language features too early on which makes it realy hard to understand why you're doing things in a certain way (the Rust book stands out as an example of this)
- the mental block of comparing the ease of use of the new language to one you already know ("this can be done easier in Python" can be applied to a lot of cases when you're a beginner)
- more limited reasources than what you're used to. If you're used to a hugely popular language like JavaScript or Python, it's really noticeable when your new language doesn't have a StackOverflow answer for every question that you can possibly have.
When first I read the title I thought it meant human language and so figured “oh yeah, be in a relationship with a native speaker”
I’m not going to break up with my gf but we met specifically (at first) as we are both lisp programmers. Hmm, but actually it’s probably not a bad form of pair programming: “oh, you’d donut that way? Wouldn’t it be easier to express it this way?”
The last year or so I really gotten into learning/exploring new languages and frameworks(don't flame me).
I used to do it the old fashion way of just reading the docs or doing some tutorial.. BUT what I found out this last year, learning a new coding languages (and all it's eco-system) the best way is to watch a good YOUTUBE video !
It's sooo underrated I think ! You get to see all the steps (I hate it when the web-based-examples have code-snippets but the omit the filenames !) Try doing that in a new language or framework that uses a LOT of files (java, angular etc), plus you can speed up the video, I watch most "learning videos" at 1.25x
Oh, I try never to have a video at all. It's slow, hard to search, hard to go back, hard to jump useless stuff, hard to comprehend, and hard to interrupt.
Yet, the GP's point stand. If you see the video of a person starting a python project, it won't be missing the `virtualenv` parameters that he would omit in the text tutorial.
Video also beats anything else (except physical presence) on discovering what somebody did to cause a bug.
So, a Python fanboy. Well, I remember when I learned Python 5 years ago, I did all of these. Before that I did them all with C# 14 years ago, and before that I did the same with Java, VB, PHP, C/C++, ASP, HTML etc etc(you insert any fad in past 20 years, I've done it) all the way back to 90's when I started with Pascal and Assembler.
The general answer to all of them is "you grind and RTFM". I too am awaiting the time when all I need to be expert in a new technology is to just go buy the plugin I'll insert into my brain (hopefully we'll become cyborgs, that's my optimism) but until then is grind & RTFM.
Nothing is more true, as I start to relearn C after 20 years, that there is no substitute for the above. Literally, there is no good C tutorial or way to learn other than just writing some goddamn code and trying to make it compile.
And then release your code and watch the people roll into the comments to tell you how you are doing everything wrong. Where were those people when I was trying to learn? Why haven't they written some God damn documentation? I know C lets you do whatever you want. I don't want to do whatever. I want to write software that is easy to maintain and doesn't fall over in a light breeze.
I can relate a lot to this. Maybe a part of this is also due to the language we are already familiar with. I'm not sure if the difficulty of your language would affect this, but I feel like learning a new programming language is difficult because we are very comfortable with the one which we already know.
I mostly use JavaScript for various purposes. While moving to other languages, we expect certain things to be present naturally and be as easy as they were in your previous language.
Several strong reasons, as you mentioned too, occasionally encourage me to learn a new language, but after a few days of frustration, I end up coming to JS. Maybe this is how JS/Python has spoilt me with the flexibility they provide, or maybe I am utterly lazy.
One solution to this which I can think of is building a mini project related to something the new language you are learning was originally made for. For example, if you are planning to learn Rust, try a small CLI, or some low-level project instead of directly building a web server. I'm not sure if I'm correct though.
I kind of think the author is coming up with excuses, because he is afraid to learn a new language. Like, just start a new project, learn as you go. In a couple days, you should know enough to figure anything else you need to know on your own. In those first couple days, post on reddit or whatever.
Also, why would you use Windows as a dev environment unless you absolutely had to?
The author is creating artificial obstacles in order to justify not learning.
Well obviously if you're willing to spend the time you can do it.
The issue is that they're not willing to spend the time, given that there are so many unknowns and decisions that have to be made. That's a very legitimate point, given that the default attitude in most programming communities is to pretend that learning new languages is almost zero cost and pure benefit.
Not included: where’s numpy? Where’s networkx? Where’s either scikit-learn or scipy.sparse.linalg?
I’m not a C.S. undergrad. I can be coaxed into rewriting random forest regression or whatever but there are even more pressing underlying matters. What’s the pipeline for reading CSV files or querying sql databases and laying results out on a dataframe-like for transformations?
At this point the hardest part of learning a language is unlearning the other languages. Is it "if-else if-else" or "if-elif-else"? Is it "def blah()" or "fn blah()" or just "blah()"? Is it "len(string)" or "string.len()" or "string.length()" or "string.size()"? Do I need a semicolon? Is it "lambda x: x+1" or "x => x+1" or ...?
After that, I find the nano-culture of the place I'm using a language the hardest to figure out. "How dare you use {} instead of end", "Everything must be split into fine grained functions because long functions are death!", all the shit that really doesn't matter that much, but is just the fashion of the group I find myself in.
It's like learning regional accents and terms with human languages.
All languages have an ideological component to them. Here is a list of languages with "everything is a $THING" in it. https://argumate.tumblr.com/post/118013166244/python-what-if... As a pythonista language-naut like the author I think the fun part is trying on the language du jour's ideology and figuring out if you can get productive with it.
This is why e.g. JavaScript on the backend, web frontend and mobile can be compelling. Figuring out IDEs, code standards, test frameworks, build tools etc. for two languages can be a lot of work.
I feel those are more the tedious parts, then they are the hard parts. Maybe I just have a nack for that stuff, but it rarely takes me more than a day or two to have all that figured out.
Once you get to mastering the paradigms, syntax and semantics is when the hard part begins.
OT: is there a reason why my submissions are often attributed to other people right after I posted them when they posted before me and submissions of other people aren't attributed to me even tho I posted before them?
It's interesting that some things (even the same thing) reach the front page and some things don't though.
It may depend on time of day, the interests of who's reading or checking "new", what other submissions are competing with it and perhaps who submitted it and/or who upvoted it.
This has 111 upvotes now but even that raw number doesn't seem to matter; submissions can and do reach the front page with just a handful of upvotes.
Database connectivity and OO are the point at which every new language becomes useful for me. I try to get there as fast as I can without skipping any fundamentals.
This list almost perfectly matches my frustrations when learning a new language, and to be honest it's why I don't bother anymore.
I started off in Python and have looked at Ruby, Pony, Rust, JavaScript, etc so I'm aware there are other ecosystems out there but I feel none of them really approach the ease of C# .NET, especially with .NET Core.
On a new system I can install the dotnet core sdk, call `dotnet new mvc` then `dotnet add package npgsql`. I've got everything I need to write a web app that connects to a Postgres database. I can launch up Visual Studio for free and have almost unparalleled intellisense, etc. Or on a non Windows system Visual Studio for Mac or Visual Studio code. The project template gives me everything set-up and it 'just works'. If I'm not sure how to use a library I don't have to leave the IDE to browse through variable quality documentation, I can autocomplete to victory or use the REPL or just debug and write the code in the debugger with edit-and-continue.
Once it's time to move to production `dotnet publish -r linux-x64 -c release` and I have my production ready deployable application.
Now when I go back to Python or these other languages at least one or more parts of that process is missing. I know I'm biased but it feels like for other ecosystems the 'pain is the point'. It should be as simple as that and it needs tooling, especially an IDE to match.
Almost certainly people feel this way about other languages they use, but I think there's an enraging habit for software development as a field to throw away the old tool we were used to and that was comfortable and worked, for some new thing that doesn't get the job done and is a godawful pain to work with (goodbye XML hello YAML). This really contributes to my burnout and disillusion with the field in general, though I'm on the road to recovery.
Edit: This rant clarified what I'm actually frustrated with. There's no way .NET would have reached the (excellent) point it is now without competition from other ecosystems, the whole dotnet CLI owes a lot to other ecosystems and evolution does improve things.
But I'm just sick, in this field, of feeling like a failure, or a fossil because people are constantly hyped about some hot newness and if it gets introduced, I'm going to have to learn it because that's the job. I'm not excited to learn flavour of the month cloud tool, or database replacement, or configuration language (I hate YAML so much) or language or framework. Other people are, and that's fine and good, but if those people introduce the thing at work then I now have to learn it and 9 times out of 10 we'll be having discussions 5 years down the road about why micro-services, or NoSQL or whatever it might be, was overhyped and we've found the right approach (which was almost identical to the approach before we started this). People should be free to have fun with those new tools, but I feel there's explicit or implicit judgement of people who just want to use the tools they know, that have known best practices and failure modes and whatever else. TLDR: you'll take my RDBMS from my cold dead hands.
Yes, I was wondering. I know of one prominent open source programmer who was a murderer, but he invented no programming languages and committed only a single murder.
The list of 'what' to learn is the list itself, with the exception of the unknown unknowns which will become known unknowns when encountered. This to me IS learning. Still reads like a rant after being faced with more learning than hoped.
- How do I install it?
- Which editor? IDE? Vim plugin?
- How do I.. read a file? parse JSON? environment variables?
How do I do any of the things that aren’t part of the core syntax/semantics but are super common problems people face every day? I’m going to have to memorize another 100 functions and their parameters, aren’t I?
- What are the language quirks that will cost me an hour to discover?
- How is the help organized?
- I hit problem X.
- How do I debug?
- Testing.
- How do I build? package? manage environment?
- Package management.
- So… the language community.
Is it worth it? For most languages the answer will be "No", for others unless you've already really gotten into several very different ones you won't know.
> He should honesty consider using a different operating system one thing.
Why exactly? Cross-platform is pretty much dead if people start thinking that way. It's not just Windows either - I recently experienced the same sort of pain when trying to install a language on a Unix that wasn't MacOS or FreeBSD.
So you'd think that at least the install script is Posix-compliant and runs on your shell? Think again! Despite it starting with an innocent #!/bin/sh , the script was actually bash-only and used GNU-extensions all over the place, too...
As a example, the Foo-lang [1] books starts (obviously) with how to write and compile a hello world program. Bar-lang books typically postpone this to the end of the book since IO and deployable programs are advanced concepts. I once talked to some Bar-fans about this and they simply did not understand why this could be an issue. Surely you could just echo "Hello world" in the repl as the first exercise?
The underlying unstated assumption is that Bar-lang programs are primarily something you write for yourself and interact with in a repl, while Foo-programmers assume programs are written to be deployed and executed.
Such unstated assumptions are not written on first page in the manual because they are invisible when you are immersed in the culture.
Another example is a discussion I saw where a Baz-user claimed that everything was simpler in Baz than in Bong. The Bong-fan then asked how you loaded data from a relational database. The Baz-fan replied that only an incompetent moron would use a relational database, real men use text files which have less overhead. Now this could be dismissed as cognitive dissonance because Baz didn't have a nice RDBMS interface, but I think it is indicative of a deeper cultural assumption that the application can decide which format to persist data in, where Bong comes from an assumption that the data is already there in a given system and a workable program will need to be able to interact with it whether the developer like it or nor.
Again, such underlying assumptions are typically not written in the tutorial, but have deep implications for the language design and ecosystem.
[1] I changed the language names so as to not start a discussion about the particular languages. Although I'm sure there are actual languages called Foo, Bar etc.