Development Environments
phaazon.net
phaazon.net
A couple of decades ago they were problematic. But today's unified toolchains and improvements made them far better. The one semi legitimate problem people have is performance. I run on an M1 Max with 64gb of RAM and gave a lot of RAM to IntelliJ (Ultimate). It flies. As professionals we need to spend on our tools and on our hardware to get the most out of both.
The depth of insight that IntelliJ allows me at a glance when debugging, reviewing, refactoring, etc. is as a league that is so beyond what the CLI enables. I can't even begin to describe that.
To be fair, this isn't universal. E.g. for kernel development, some embedded use cases, etc. the IDE might have less of a benefit. But for most day to day app development avoiding an IDE seems like a Luddite approach.
When you write on a terminal, you are encouraged to make good choices so that your code is clean, with a well-thought-out structure and conventions that allow it to be read and processed by a number of tools as painlessly as possible.
When you're on the IDE, your code structure invariably reflects whatever workflow template has been defined for that particular IDE, and good conventions matter less because you can always use live links and stuff to inspect stuff via the IDE.
Of course, you could argue that there's nothing stopping you from following those good practices on your IDE too, or making the extra effort to configure it with good structure and conventions. But in practice, it's a bit like making the extra mental effort to choose salad when there's steamy melty pizza right in front of you every single time. The temptation to take shortcuts and not think your code out properly and just rely on the IDE to dump its defaults is just too great. In the end, when you compare (professional) well-thought out code written in a terminal vs templated code written in an IDE, I feel that the difference in quality is often palpable.
Also, I reject the idea that "tooling" is a concept unique to IDEs (or, in any case, that IDEs should necessarily imply superior "tooling"). Yes they offer the convenience of a suitethat is (hopefully) interoperable by design, but for me arguing that this makes them better tools is a bit like saying the Apple Store has better software than "the internet" and you should therefore only stick to Apple Store stuff.
It was impossible to navigate and I spent most of my time constructing complex regexes for grep just to follow the flow. In an IDE I can right click an element to find usages/dependencies, etc. Some of them are just highlighted.
1. google xxhash, click first result (github)
2. open xxhash.c
3. see it is mostly empty, go back and open xxhash.h. this file is 6k lines (not 20k), it probably has most or all of the implementation somewhere.
4. starting from top of file, read intro docs: "xxHash [...] is proposed in four flavors, in three families: 1. @ref XXH32_family: Classic 32-bit hash function." i will select XXH32 for illustration.
5. scroll down to examples, which calls "return XXH32(string, length, seed);"
6. ctrl-f "XXH32(", could be done in any text editor (even notepad)
7. press enter 6 times
8. see "@brief The implementation for @ref XXH32().", we have probably arrived at the core or reasonably close to it. if that didn't work, then I would try "XXH32 (", which would immediately find the XXH32 function.
of the 6k lines, about 550 are empty, about 2800 are comments, and about 800 are preprocessor directives. the comments appear to be mostly useful comments, not the "/* Frobnicate the bar. */ int Bar::frobnicate()" type which tend to be seen in IDE-overuse projects.
And then you realize you have to refactor 25% of it, or the requirements change, or a newly incorporated library suggests a naming convention change would be wise... IDEs not only show the code, you can pick a function argument, rename it, and get it renamed across all source files, comments included.
If your terminal editor does that, then you've partially transformed it into an IDE.
What really set IDEs apart from text editors was integrated build tools and the ability to directly consume (and act on) build errors and the like. Search-and-replace long predates IDEs, as does 'code comprehension.'
sed absolutely cannot rename all the occurrences of something like a class method, since it would require deep dependency graphs to find all the class instances.
In an IDE, I can do something like this:
# All three classes have a do_thing() method.
my_instances = {
1: Class1(),
2: Class2(),
3: Class3(),
}
my_instances[1].do_thing()
my_instances[2].do_thing()
my_instances[3].do_thing()
In the IDE, I can rename the do_thing method for Class2, and it will correctly change the line "my_instance[2].do_thing()" to reflect the new name, leaving the others alone. This is not possible without something mostly indistinguishable from an IDE.I like small editors for small jobs, but I wouldn't dream of doing a new business application without an IDE these days. With sed a simple search and replace would need to be manually checked for unintended effects, but an IDE will do it without problems in seconds, unless you go out of your way to confuse it.
I believe the main reason why gdb kinda stinks is that it can be: traditional Unix-like operating systems typically have smaller components with well-defined interfaces, making them much easier to debug. Windows has too many DLLs, too many interfaces between them, and poor definition of layers. Quick, what's the difference between kernel32 and kernelbase? How do I tell which one a program is using?
This is not to say that Unix-like systems have perfect interfaces, merely that they're generally better-factored than interfaces inside Windows and Windows applications. Further comments can be made of the differences between Windows and Mac "applications" and Linux "programs": for example, the difference is not only in GUI or TUI or CLI: Firefox is an "application", but Notepad and Calculator are "programs"; Paint is a "program", but Paint 3D is an "application".
If you use default templates and don't really care about the structure of your code when using an IDE, you won't suddenly start to care when using an editor. If you don't care about all kinds of shortcuts and specific functionality in your editor, you won't care about learning the shortcuts (and even functionality) in your IDE.
Some people seem to think they will become better developers by learning to do their development with an editor, but I do not believe that is true. Maybe except for one thing: if you do use an editor and don't use something like LSP in your editor, you will be forced to memorise the standard libraries of your programming language; you need to memorise those to stay productive with an editor. And in general, I do believe that the pure text editing part is often more advanced in a good editor than in an IDE.
But, a good IDE is an amazing tool when you have the hardware to run it. Especially with typed languages, an IDE makes it a lot easier to refactor code and change the design of your code. This really lowers the threshold to change the design of your code when requirements change. Since the changes are simple and fast, developers are more confident to do those changes and will consider those changes in more cases. And aside from that, IDEs also often include an analysis part and warn you about fishy things in your code.
I have been an Emacs user for a very long time. I used it for C long time ago, and recently used (limited) it with an LSP server for C# (using the Doom Emacs distribution). And that is working nicely: magit is great, integration with LSP servers is great... you can get a lot of the stuff that is typical for IDEs. But when you do activate all those integrations, you will notice that it is also heavier to run and less responsive. So, in the end, when the hardware can run it, my preference is still the full-blown Rider IDE for C#. The IDE is much more complete out-of-the-box.
This reads a little bit like a dynamic language vs a typed language. One argument for writing dynamic language is kinda similar to this.
When I write code in a typed language I have to think far less than if I write it in a dynamic language as the tooling takes care of it for me. But in my experience no matter how much I think about how to solve something in a dynamic language I make far less mistakes in a typed language.
to that extent which everything ends up philosophical, why not both?
The number 1 thing I hate about IDEs and will always hate about IDEs is that you open a "workspace" you cannot access all of your files at once. So often I am working with multiple git repos or various things scattered around my computer. In emacs I can simply open the file and have all the syntax highlighting, linting, etc just work. Instead of waiting for 10s for a whole new IDE workspace to open. And then not even have the ability to switch between them easily.
Anyway, I don't think I am Luddite and I try to love modern IDEs and editors because everyone says how much more productive they are in them. I honestly have to think that editors are not whats holding back software development, and seems disingenuous to say shying away from them is somehow negative.
Whenever there's some hot new IDE feature it'll end up in Emacs sooner or later. Sometimes better than the original implementation, sometimes not.
What I like about Emacs is that it is timeless, works on a lot of platforms, supports a lot of programming languages (while a lot of modern IDEs are focused on a single language[1]) and also supports e-mail, Twitter, IRC, Matrix, etc. etc.
[1] Which makes them very good for that specific language, I get that. But I prefer Emacs' "just good" support if that means I don't have to learn a new IDE again.
I’ve worked with tools my entire life and the main difference between Emacs / VI and other IDEs is they’re tools you can hone infinitely and truly make an extension of your mind, as opposed to IDEs which more fit the “choose the best tool for the job” mentality, which I appreciate, but does not apply to text editing to me because of how Emacs / VI shifted my mindset.
Emacs still feels 1000x more modern to me than any IDE, especially VS Code. And I agree that text editing / better IDEs really are not the problem in software development.
A programmable editor can, by programming (and in many cases, this means using modules others have programmed) become a Development Environment both more powerful and more adapted to your particular use than any available Integrated Development Environment, but it's not an IDE because no vendor integrated it for you (though sometimes, rather than collecting small modules of your own, you can get a pre-integrated set of modules for a particular use for a programmable editor, and that is exactly an IDE.)
> Emacs still feels 1000x more modern to me than any IDE, especially VS Code
VS Code, like Emacs, is a programmable editor, not an IDE. (though I guess it's built-in, first party tooling for certain languages makes it a very light IDE for them.)
If it's a text editor with an understanding of the code, that also allows debugging, then it's an IDE by definition.
Yes a JetBrains IDEs will take longer to build the AST model in RAM but once you have it they do amazing things with it. E.g semantic search and replace, etc. The debugger capabilities are spectacular, they literally show the values of variables on the side of the line you stepped over. Another cool thing, inferred types just show next to the variable definition, parameter names appear in the method call, etc. These are small things that add up to a lot on the day to day.
About projects. JetBrains do create project files but don't require a project structure in newer versions of their IDEs.
The problem is that IDEs are very simple to pick up and people stop after that basic usage. They have depth that exceeds emacs in some respects.
Easy extensibility. Read email. Run a calculator. Run Lisp …
Meanwhile, there is literally no feature any IDE has which Emacs cannot do. It's just a simple matter of programming.
IDEs are 100% extensible via plugins. Wrote a few of those myself.
That's what LSP does, and emacs supports LSP. Heck, it even has two packages implementing support for LSP.
For that matter, I don't see any reason why Emacs would be any worse at keeping a full AST in RAM that is an IDE. Emacs Lisp is not the most efficient runtime out there, but it's acceptable.
> IDEs are 100% extensible via plugins.
Plugins are not 100% extensibility: they only enable one to extend the IDE in the ways the plugin system was designed to allow. Emacs, OTOH, enables one to extend or replace all editor functionality implemented in Lisp. I am not aware of any other IDE which offers, for example, all of the following: multiple email clients, a net news client, an IRC client, a Slack client, multiple web browsers, a Git UI, a spreadsheet, a personal organiser, multiple calendaring systems, a computer algebra system, multiple file managers, multiple shells and terminal emulators, an RSS client, a music player and Tetris.
I can totally write these sort of plugins for any IDE I worked with. Notice that all of these capabilities are symbols of a bygone time where you stuck everything into an editor. There's no motivation for a plugin developer to do these sort of things. Instead we have plugins like Lightrun, TabNine/Copilot, etc. Stuff that's actually useful for development.
JetBrains (and some other IDEs) have a builtin file manager, terminal, etc. These make some sense for development.
Not built-in, but there are packages available for that.
I tried writing a plugin for Visual Studio Code. It made me want to throw furniture.
Emacs has all of the things mentioned, either through plugins (LSP, Tree sitter, DAP) or built in (tags, GUD). Especially LSP-mode has over the last few years made sure you can integrate your favorite text editor into pretty much any language, for certain languages/technologies it still makes sense to pull up the specialized tools for e.g. debugging, deploying, building, publishing etc, but you can do a lot with the more general tools too.
Are things highlighted directly in the editor as you step over the lines.
This is a different workflow than the average use of an IDE, particularly for, say, Java or C# development. Personally, if I am working on a web app with a fairly large codebase, I use VS Code, but if I am editing a few scripts or other files, I absolutely use Neovim from the terminal.
It requires a bit of memory though as IJ just works better if you give it a lot of memory. Not really a problem for me as my dev machines have at least 32 or 64G and besides IJ, firefox and a terminal I don't have much open.
https://www.dodgycoder.net/2012/09/q-with-nine-great-program...
It wasn't XEmacs, but rahter the genesis of Emacs itself (I got that wrong).
https://www.youtube.com/watch?v=IT__Nrr3PNI&t=1642s
https://en.wikipedia.org/wiki/Gosling_Emacs
Got to love all the St. Thomas requests on developer forums.
The comparison and conversion can and will depend on many factors, the first and most likely is that the version of emacs he wrote didnt have standard lisp, not that elisp is much more standard.
When a non free ($395 in 1980 money) vs free (as in GNU/GPL) version of emacs, its not surprising that GNU emacs was the crowd favourite.
I'm not convinced that goslings move to an IDE as the gos emacs creator is a fair datapoint when comparing modern emacs though.
Imagine if all professions would behave the same way.
IntelliJ is special. Last I had seen they employ their own language tooling for almost everything. Nowadays the CLI (TUI) experience is capable of a LOT. CLI editors have fantastic integration with languages via LSP. You end up with similarly fat but more modular tooling. They offer a modularity and options that give you more choice in building the experience you want. (Not just color schemes and layouts)
You have to do more work to configure and learn your tools but it makes so much more personalization of workflow possible.
My personal CLI tooling for git is really nice and hacking on it keeps teaching me more about git creating a flywheel of optimization and joy from using things I made.
There is a cost to changing your personal workflow. As nice as some new and shiny things appear I don’t like flip flopping on my personal/professional setup. There comes a time when you start fresh. That will be when I try something different.
Intellij / PyCharm does remarkably well with large Python code bases lacking type annotations, even if it has to take a guess here and there. But when you add type annotations, it's even better.
It's so much easier than going through NPM noise. Just auto fix and in 95% of the cases it's just what I need.
The JetBrains IDEs for other platforms have almost the same level of capabilities. I also worked a lot with xcode, its not nearly as good as AppCode but it's still an improvement over trying to build iOS from the command line... I did that a lot and that isn't a pleasant experience in the least.
For now, Spyder (for Python) is just right. VSCode is too much, and I haven't figured out how to turn off the features that I don't care about.
The rest of us just don't have that many files to refactor when we change things.
I don't really hate ide's, I get the appeal, and sometimes it works out useful. It's just that most of the time it comes back to enterprisey software being the source of your problems, not the lack of features in your editor.
The anti-IDE crowd seems to like to pick on Java.
It's largely because Java is verbose. Because of that, the java ecosystem continues to produce frameworks and libraries that make it easier for programmers to convolute their code behind functionally opaque interfaces, eg Spring, Lombok, etc. which also happen to provide "solutions" to reducing repetitive or traditionally verbose code.
We have computers to automate processes, primarily. Not using computers to do rote inspection (like argument intellisense or class method discovery), is backward and it helps a great deal until you start using pre-processor annotations which are a series of programs that run before your program is run. 1 step forward, 1 step back.
Ofc there are still people who use handmade nails and leaves for toilet paper and they insist it's better than Java. I'm not sure they are wrong.
I started with Java 27 years ago and back then text editors were the only option for years. So I can use them just fine for Java.
I'm old and wise enough to not get between developers and their tool choices no matter how odd they are. So, I tend to give a lot of freedom to my people; and also take that freedom occasionally because I love trying out different things and optimizing my workflow. I love learning from others on how to improve my own workflow.
I have a simple rule: your code must be properly formatted, refactored, and free of warnings when you create a pull request. Boy scout rule basically. Anything less than that is sloppy work and I'll call it out and will make you fix it. Always be refactoring and cleaning up code. I don't care how you do it and whether you do it the smart way (using proper tools) or the dumb way (manually using notepad and staring at compiler output) as long as you do it and know how to do it and when to do it.
If it looks like you are being clumsy/sloppy/negligent with your tools, I'll have to have a word with you and tell you how to improve. That may include some not so subtle hints about your tool choices.
In particular, they are great if you follow the happy path anticipated by the IDE developers, but when things get weird, the IDE won't help you. So I tend to see a lot of IDE users alt-tabbing between their IDE, terminals, Postman, DBVisualizer, and what else have you which plays havoc with my brain and would only slow me down if that were my workflow.
There's a perspective dependency to whatever the best tool for the job is. Some people can't live without a bell- and whistle-laden IDE; I can't live without a code editing tool that I can shape to my needs while I'm using it
Which is why I won't be giving up Emacs any time soon.
Again, I programmed without an IDE (in Java too) and manage that completely fine. Just like I can walk barefoot without shoes. Same thing. It's a power tool that provides amazing capabilities.
I go out of the IDE a lot too. I prefer using the native terminal rather than the one builtin the IDE (although some use that and that's fine) we each have our habits.
CTO of my current company is a VIM nut. Uses it a lot. And an IDE. He uses each in the context he sees fit to his needs. I used to see a lot of people at my later days in Oracle (after the Sun acquisition) switching between Emacs and an IDE back and forth. Sometimes even on the same project. Each tool has its own power.
It isn't a zero sum game between the two. I use external editors too for the right things.
For what it's worth, IntelliJ use an IDE with an inbuilt terminal, HTTP client, and DB GUI.
Embedded devs have the fanciest of IDEs.
#1 If you need an IDE to handle simple things like you list I think the language's development model is designed with IDEs in mind (eg. Java). Better language support and tooling makes all these things trivial without an IDE.
#2 There are no good Free Software IDEs and I will not make ethical compromises with my maker tooling.
I'm not smart enough to keep an entire code base of every project I ever worked on in my head. Maybe you're a genius of a different level, even then... Wouldn't it make sense to clear the area of your brain that needs to remember every parameter name to a method call so the IDE will show that to you.
IntelliJ community is free and open source. NetBeans too and it's decent. So is Eclipse. VSCode isn't exactly an IDE so I won't go into that.
And none of this covers the fact that none of the good IDEs are Free Software. Which automatically removes them from consideration.
When debugging it shows the values that changed in each line in an area next to the line of code. It's amazing.
I think this is the problem, not the editor. Overriding methods is inherently bad, and doubling down with complex methods is worse. That sounds like it needs a refactor.
I also don't regularly use languages that require debuggers, so the latter doesn't comes up often enough to worry about.
https://en.wikipedia.org/wiki/Gosling_Emacs
XEmacs is the Lucid one, https://www.emacswiki.org/emacs/LucidEmacs
from open source work at home to the most paranoid of high security environments, vim tends to be there pretty reliably.
I get that it's a muscle you need to practice. But limiting yourself to fit a potential restriction makes no sense.
It also promotes a pet peeve of mine, which is programmers that can barely type. I know plenty of people will yell at me saying that doesn't actually matter, but it's wild to me in a profession where typing is the primary way you interact with your work that so many folks can barely manage a typo-ridden 60wpm
Why would I want to type? It's entirely the wrong model for interacting with code. I think a lot of languages are held back by this idea that the best way of using them is typing out every character.
To give an example of what I mean, 'toDring()' is meaningless, it's garbage, it's not something I care about. 'toString()' however is useful. I don't remember the casing in JS but I think 'tostring()' is also useless. What's important here isn't the 10 characters in any event and I don't care to type them effectively. If my language can't tell me which is valid it's frankly like mowing a lawn with nail scissors. Fun for a certain kind of eccentric but not what you need when your day job is gardening.
If I have defined a 'toDring()' method then expose it by letting me type 't', 'down key' (to choose the non tostring version), 'enter'. If I haven't then don't let me type it. I think (heavy reliance on) text manipulation as a way of interacting with languages is a sign of either a bad/underdeveloped language, or a community which gets off on the 'hard for the sake of it' mindset.
i've encountered these ides in various corporate environments in varying degrees of broken where fixes are essentially impossible. (assuming they're available in the first place)
i like vim, and other simple open source tools as they work reliably and are reliably available.
The problem with that is you'll more than likely create applications that work fine on your fancy high-end systems but end up unusably slow on normal people's hardware.
For mobile I use a device.
For desktop stuff we have a minimum machine which we test. Also IDE's have profilers integrated where you can see if you take up too much RAM or CPU. There's no need to suffer slow performance to create apps that run in constrained resources. You can have more than one computer too. Even as a one person shop.
Now you're only as good as your tool (IntelliJ) and you cannot work with any other language or tool which isn't 1:1 feature complete.
If you had an extensible text editor beit vim, neovim, Sublime Text, emacs, VS Code or others then you could add extensions or features per language and keep using your single core tool (said text editor) with a configuration per-language.
I used Visual Studio when working with C# which is fine. Not as great. Didn't get a chance to do either Zig or Rust in practice (both look great and I would want to go there).
This argument is like arguing against shoes because of "what will you do when you're barefoot".
I accept that some people live in poorer countries. I work with a lot of them and spend a great deal of time abroad. Even they have more powerful machines than the median and they get great discounts for those machines. Maybe not a machine as powerful as this but somethings that can still make the IDE fly.
1. Quick go to _anything_. In IntelliJ IDEs, it's double-shift, and then start typing some of what you want. Usually you can find the class or module or file you want easily, if not automatically.
2. Interactive debugging. This is so very useful. Usually it's just the fastest way for me to inspect a data structure at a certain point in time, or even find out what's going on in a framework that uses a lot of metaprogramming.
3. Jump to definition of thing (function, constant, etc.), and conversely show usages. In a well designed system of composable single responsibility functions, one can almost forget about files and navigate only with these (and (1)).
4. Git diff my branch to branch X. Lots of extra goodies can be included in this, such as interactive merge conflict tooling, etc.
Its not for everyone though and it takes a lot of time to customize it perfectly for you.
What you have is a text editor that you've (presumably) augmented with a ton of plugins to turn it into a full IDE.
formatting code: `lua vim.lsp.buf.formatting_sync()`
go to definition: `lua vim.lsp.buf.definition()`
rename variable: `lua vim.lsp.buf.rename()`
type information: `lua vim.lsp.buf.hover()`
find references: `lua vim.lsp.buf.references()`
code actions (add missing import etc): `lua vim.lsp.buf.code_action()`
For more commands `:h vim.lsp.buf`.
There is plenty available through LSP today supported by all editors. IDEs provide a better debugging experience (with breakpoints and variable values) though that too can be done with vim/neovim using the debug adapter protocol and plugins built on it (similar to language server protocol but for debugging).
For example I hit ,gd which I have mapped to the go to definition.
I also have ,fr mapped to find references.
You can come up with whatever mappings you want.
I have K (so shift + k) to show the type information.
Etc etc. Vim and neovim let you customize all this and anything else.
That's what any REPL does. And it works great with typed data. Sometimes even with graphical output.
An IDE would be used to develop those commands, more than compose them.
> text to be the only format for exchanging information
For this to work, with non-text data, you end up using the file system as a buffer, then passing filepaths between commands. For many contexts, this isn't performant enough.
Emacs makes it easy to run commands, e.g. with M-&; the output goes into a buffer called `Async Shell Command`. Unfortunately, that buffer gets replaced each time we run a command. It's common to override this behaviour (as I do), so a new buffer gets spawned each time, which gets a bit closer to that workflow. Still, I've never really used this to chain commands together; this post has inspired me to try that a bit more :)
What I was describing above is manipulating such buffers with external commands (similar to Emacs `shell-command-on-region`)
That said, I have learned to stick to defaults and start from a clean slate every time. I often say that the main problem in software is containing complexity. When you need to deliver a product that works reliably, you want to remove all but essential concerns from your routine work. So I'd rather create a clean VM, install git CLI, VSCode, write a Dockerfile and get a nice clean package. If I learn how to use everyone of these tools out of the box with the default configuration, then I never have to think about dotfiles, plugins, set up etc.
I think we need more software hygiene. Keep environments clean and ready to go.
I memorise how to configure vim how I like it and do it each time. Or how to change tmux bindings to use ctrl-a which I still need to memorise.
Then I'm someone who remembers commands and switches and doesn't need to use recursive search to find commands I type in.
Starting from fresh each time gives you a perspective of what is easier. Reader, can you write a Java application build.gradle, C makefile or Kubernetes YAML without copying and pasting from the web? Can you SSH jump from a bastion host from memory with -W? Can you create the directory structure of a Java project without copying from existing? Or do you write some terrible static configuration generator that doesn't get updates I've seen that so many times on projects. Saving time on the wrong thing rather than just learning the thing to begin with.
I also prefer IntelliJ to Emacs and vim to Emacs. But I use Emacs keybindings in bash. Also I prefer bash to the other shells.
I was sort-of agreeing with you until this point. In my experience "write a Dockerfile" usually means "run a bunch of fragile, non-deterministic nonsense, like `apt-get update && apt-get -y install`, `yum install`, `pip install`, `npm install`, etc.; often all at the same time!"
(AWS are a serial offender IMHO, e.g. their documentation recommends this sort of crap https://docs.aws.amazon.com/lambda/latest/dg/images-create.h... https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-dat... etc.)
Compared to the old way of doing these things (which would likely be a shell script that would run those exact same apt-get/pip/yum/npm install commands), Dockerfiles give you:
- a much more predictable starting state, which lets you remove a bunch of complexity from your installation script. The old style of installation script might need to detect which OS it's running on, which version of Python is installed, whether you're using GCC or clang, whether libgomp or lzma or whatever is installed, whether or not the script is running as root, whether or not there are existing sites configured in the local nginx install. With a Dockerfile built on a slow-moving image, you can know exactly where everything is, what version is installed, and whether there are any other conflicting applications.
- limiting side effects (As a user, you can be fairly sure that a `docker build` isn't going to clobber your nginx configs.)
Containers have a whole pile of downsides, but making builds _more_ fragile is not really one of them.Shell scripts are certainly an "old way" of doing things, dating back to the 1970s. However, since the 1990s there's been a safer, more declarative way to solve this problem: package managers!
> detect which OS it's running on, which version of Python is installed, whether you're using GCC or clang, whether libgomp or lzma or whatever is installed... isn't going to clobber your nginx configs
These are trivially solved by making a package:
- To specify the desired OS, just depend on e.g. ubuntu-minimal-1.417 (or equivalent)
- To depend on Python, libgomp, lzma, etc. we just declare those as dependencies (specifying exact, known-good versions)
- To use gcc but not clang, specify one as a dependency and the other as a conflict (or vice versa)
- Packages cannot "clobber" existing files (like an Nginx config): if multiple packages try writing to the same path, the package manager will abort and roll back the transaction
In contrast, writing `apt-get install` in a script (whether it's inside a container or not) is just flat-out wrong: it's using a package manager incorrectly.
> Dockerfiles give you... a much more predictable starting state
"Much more predictable" than what? Established tools like `debootstrap` start from an empty folder; I can't imagine anything more predictable.
> Containers have a whole pile of downsides, but making builds _more_ fragile is not really one of them.
I never said containers make builds "more fragile"; I actually think the exact opposite! Containers are great; in the above example, after debootstrap is finished we can run `tar` on the result to get a standard OCI container image.
My complaint is about Docker, and in particular Dockerfiles, which encourage fragility and non-determinism in two ways:
- For some reason, there's a strange belief that Dockerfiles are somehow related to building/packaging software (e.g. projects providing their software in container images, defined using Dockerfiles). That's a bait-and-switch: Dockerfiles are basically just scripts; we still need to choose what commands to run in order to actually build/package our software. If we believe that Docker is solving our building/packaging problem, then we're less inclined to run "proper" build/packaging tools in those containers (e.g. dpkg, rpm, nix, etc.); we're more likely to write crappy imperative shell scripts instead, since that's all that Docker itself provides.
- Container images produced by Dockerfiles are essentially a cache of their output. This avoids having to deal with the fragility and non-determinism of our scripts up-front, until we need to rebuild. As long as it "worked for me" at some point, we can keep using the resulting binary blob, even if it's completely unreproducible and bears no relation to its supposed "source code" (e.g. `apt-get update && apt-get -y install` just copies whatever files happen to be on the server that day). We can even "push" those blobs to a "registry", so others can avoid having to run our crappy scripts.
(Note that the above focuses on binary package managers, since the example was Dockerfiles running `apt-get` and `yum`. Personally I switched to using Nix about a decade ago, which is source-based and even more deterministic than those tools; e.g. apt-get and yum use version numbers and constraint solvers, whilst Nix uses hashes)
If I need a VM for things, I typically start a small rsync or ftp server on the host so the VM only has to mirror the files, build and run.
While acme can seamlessly support external commands, a limitation, however, is there is no metaprogramming facility for changing the functionality of the editor itself. This makes acme less powerful than Emacs, which has the Emacs Lisp subsystem for extending and modifying the behavior of the editor. For example, suppose I wanted to add syntax highlighting to acme. Doing so requires modifying acme's source code. However, if acme provided some type of metaprogramming interface to the editor, then I could write code adding syntax highlighting. Ideally, this metaprogramming interface should be language-agnostic and take advantage of the 9p protocol. This would make acme just as powerful as Emacs, and in fact would give acme an advantage since extending acme won't require a specific language.
Come to think of it, some of this metaprogramming capability may already be present in Plan 9 through the use of the /proc directory, thus obviating the need for application-specific metaprogramming mechanisms, though its offered at the binary level. I'll have to investigate this some more, though.
My thought is that sophisticated IPC protocols and support for application-level metaprogramming can provide the rich interoperability that the writer of the article wants for creating composable development environments.
This is as ridiculous as saying an electrician will forget how to correctly wire because their wire cutters are too good.
I used to be a build-my-own IDE person via VIM. After using PyCharm and realising an IDE is more than an editor, I realise the productivity gains every day.
If I need VIM or something else, it's just another tool in the box and the partisan fist shaking has no place in a mature profession and trade.
I watch senior engineers struggle with basic CLI usage daily. In the modern sense of Senior of course.
That aside, what one doesn't learn doesn't mean the mistake is what one does. Just that they didn't.
However, what I never found convenient in cli was debugging. I was a print debugger for years until my job convinced me to try PyCharm.
I've always thought the reason I never found a suitable debugger in cli was just because I was either too dumb to figure out integrating something like vimspector, or too lazy to get used to gdb/pdb. Ctrl-f on this article has no mention of the word "debug." I think I'm not the only one that never used a debugger before I tried an IDE. I wonder how many people still feel superior in their CLI-Vim/Emacs-only workflow and are just print debugging.
VSCode with rust-analyzer (edit: and CodeLLDB) provides a very nice environment for Rust development in my experience, including debugging.
Or as ridiculous as people forgetting huge parts of their first language because they haven't spoken it in years. Which absolutely happens.
Actually this sounds a lot like OLE 2.0 from 1995.
You have references to previous outputs, don't recompute things, and in browser can have GUI interactive elements. You can likely find live streaming monitors too. Though that starts to break what the environment is best at: composing an edited, rational path through a process based on interactive exploration, trial and error.
https://en.wikipedia.org/wiki/Project_Jupyter#Jupyter_Notebo...
Also notebooks are a horrible way of working. They encourage code to get extremely unwieldy and make managing state harder than it needs to be.