I've been programming since well before we had IDEs... I love them. Proper modern IDEs provide a level of insight and tooling that the anti-IDE crowd just don't get.
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.
I realise I'm probably alone in this, but this "depth of insight" is exactly one of the curses of IDEs for me.
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.
I worked on the mess of make file and C dependencies created on Emacs in Sun Microsystems back in the day. You can make a mess with any tooling.
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.
As a point in support of this comment, I recently perused the xxhash sources looking for the actual implementation of the hash functions, but it's difficult because there are like 20kloc of mostly preprocessor macros. This probably was not created using an IDE, and if it was, the IDE is not the cause of these issues...
i was able to find the xxhash core within 5 minutes, with no particular experience in xxhash or hashing algorithms.
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.
> 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
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.
I get that functionality with go-guru for Go. Having powerful refactoring and static analysis tools shouldn’t require them to be integrated into a monolithic application.
You don't even need a terminal editor to do that; sed will do it fine. If you want to be pedantic about the mechanism by which you achieve the result, you can just use ctags, which even plain vi and emacs support.
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.'
An IDE is aware of the structure/meaning of the code, giving in much more power.
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.
You need a project view for that since it needs to go into all the files and do the "right thing" all over. It needs to verify external dependencies aren't broken as a result, etc.
I've coded in plain text editors all the way to full blown IDEs, and you're partially right, it's not the tooling that sets IDEs apart, but the seamless integration between several useful tools.
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.
This reminds me of when people say that the Visual Studio debugger is much better than gdb, or that Windows developer tooling in general is better than Linux tooling.
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".
I think it's a bit naive to think that a given developer will produce better code when using an editor instead of an IDE. I believe that a certain developer will produce the same quality code whether he uses an editor or an IDE.
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.
> 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.
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.
I dunno. I have used a lot of IDEs in my day but I always go back to emacs. I know its not for everyone but I can still have a running python, ruby, etc process and send bits of code to the process and interactively iterate on ideas smoothly. Also with the advent of language servers jump to definition, large refactoring of symbols, etc are pretty straightforward.
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.
In my experience, most IDE users don’t know that Emacs is effectively an IDE that can do all of the same things, and even more. When you show them, then the complaint is that it’s a hassle to configure, and I don’t really know what to do with that. I like configuring my text editor.
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.
> In my experience, most IDE users don’t know that Emacs is effectively an IDE that can do all of the same things, and even more
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.)
I program my Emacs for very basic stuff, but very specialized for projects. For other developers (even who use VSCode) it's black magick. I think Emacs has also a culture of tinkering.
A lot of my friends used emacs back at Sun. Modern IDEs really improved since then and I haven't seen a feature that emacs can do that they can't.
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.
Everything is "just programming" but deep semantic heuristics from an IDE can't be done reasonably in Emacs. Most of the big features require keeping a full AST model of the project in RAM. That would make emacs/vi really slow.
IDEs are 100% extensible via plugins. Wrote a few of those myself.
> Most of the big features require keeping a full AST model of the project in RAM. That would make emacs/vi really slow.
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 haven't written LSP so I'll reserve the opinion at that. What I understood about emacs is that it doesn't have a concept of a project so I don't see how it can form dependencies that are more sophisticated. But maybe I don't understand something about that.
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.
Extensibility via plugins is quite a bit different from extending the editor as you use it. Emacs admits the latter, and useful functionality can be added in a page or less of Emacs Lisp.
I tried writing a plugin for Visual Studio Code. It made me want to throw furniture.
That is true. IDE plugins are a nightmare to write and VSCode is by far the worst to write. Still, JetBrains is remarkably extensible and mature, I was able to integrate things very deeply in the editor. The downside is writing in Swing which is pretty long in the tooth by now.
> 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.
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.
Things are highlighted as you go through, the buffers showing various values in scope is updated all the time, you can add certain variables/objects to be watched. GUD (built in) supports pretty much anything GDB can do (and also supports JDB afaik and a some others), check the manual for full feature set https://www.gnu.org/software/emacs/manual/html_node/emacs/De.... DAP (plugin/extension) is a bit more flashy and "modern", I haven't used it too much though, but it looks interesting https://emacs-lsp.github.io/dap-mode/page/features/. A nice video showcasing some of it can be seen here: https://www.youtube.com/watch?v=0bilcQVSlbM.
For Java Emacs is terrible. I loved IntelliJ. But for Python, Haskell, Common Lisp, Clojure, OCaml, I turn back to Emacs, because it is very familiar, and very nicely integrated.
I've used Emacs for development before, and like it. I also like the more purposed IDEs. I consider Emacs a general purpose IDE because with all the packages I add it has IDE functionality (source jumping, refactoring, syntax highlighting, debugger interface, compiler interface, code completion, etc.). It takes a bit to get it set up just right for a given language though.
> 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.
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.
I sometimes find myself using neovim _in_ the VS Code terminal when I need to quickly jump out and edit a non-project file like a ssh config or something
The way I get around that is by opening multiple workspaces so I can alt-backtick between them. At least on my setup the ideavim copy buffers are shared between workspaces so I can easily yank from one and paste in the other.
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.
For anyone following along, that quote is from the first link.
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.
I’ve yet to give VSCode a fair shake. I used IntelliJ a lot back in the day.
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.
This has been my experience. I'm by no means an IDE power user, but the only things I really missed while using vim were finding references and going to definition. Nowadays I can do that in vim for every language I care about without much configuration or effort, and there's a bunch of additional features available I still leave on the table
It seems like Java is in a pretty unique place in terms of the quality of the tools and the frequent need to use complex tools to get even a vague idea what's going on.
Any large code base benefits from complex tools to get an idea of what's going on.
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.
True. But Idea Ultimate works surprisingly well with JavaScript and very well with Typescript including react code, etc.
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.
I should give it another go I guess. My last serious shake of Jetbrains for JS was on an angular 1 + gulp project a few years ago and it just couldn't do anything helpful.
The only reason Java can even have the most powerful tools is because it is easy to see what is going on. Also, JetBrains does really well with all languages, generally more than any other IDE.
I haven't encountered features in other languages that are pervasively used and work by leaving meaningless markers in the code which some other (typically undocumented, typically in another repository) code will eventually use to do codegen, AST rewriting, and so on. But other than this feature that's like way more difficult than macros in Lisp or C, which makes up like 20% of non-whitespace lines in Java code I have encountered in the last few years, I agree.
If you mean annotations that are easily traceable to the package that provides them, I suppose. That isn't how I program in Java these days but a lot of people do like that style. Honestly though I don't find it much different than Derive in Rust or extension methods in Swift.
What finally pushed me to use an IDE was the code inspection tools running in the background, and lighting up my likely bugs and style mistakes. So it's actually reacting to my code and doing something, rather than just flooding me with information.
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.
Yea but you only need all that junk because you use Java.
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.
Somehow it is still much better than most hispter frameworks with their interpreted languages and monkey patching galore, or this Google worshipped language thanks its author's pedigree.
I write most of my code in Java but I have a lot of C, Objective-C, JavaScript and many other languages. In fact I found IDE's to be even more useful for JS since it's such a mess. It's much easier to shoot yourself in the foot in other IDEs.
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 think a professional software engineer can be expected/required to use proper tools. That includes using decent hardware. Fast computers allow you to wait less and waste less time. If you are any good, the accumulated savings in time are worth more than the hardware in a matter of days or weeks. So, don't cheap out on hardware. It's unprofessional. Within reason, you can actually get away with some budget hardware these days. And you can also use remote tools to make your hardware matter even less. But whatever you do, minimize the waste of time. And if you use e.g. rust, kotlin, or js based development tools, you likely have some non trivial build times that can benefit greatly from good CPUs, fast SSDs and enough memory. Those build times add up quickly.
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.
If you need an IDE to manage the complexity in large, complex software projects, then you need an IDE for the kernel -- one of the largest, most complex single software projects around. IDEs are written for this purpose -- modern CodeWarrior, for one. The fact that many kernel devs including Linus himself get along fine without one suggests that IDEs are not the universal good you seem to think they are.
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.
I accept that I'm not nearly as smart as Linus. Also most Kernel developers know their own relatively narrow module not the entire project.
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.
#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.
Java didn't have a decent IDE for the first 10 years of its existence and I hated IntelliJ/NetBeans etc. when I first used them. The tools improved. They work great for all the languages I use.
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.
You don't need an IDE to get, eg. function parameters, all normal programming oriented text editors do this now. IMO all of the 'editor' focused parts of IDEs are done great by the programming oriented text editors. It is the non-editor parts where IDEs differentiate themselves. Integrating testing, debugging, project management, refactoring, etc. Some of these things IDEs do pretty well and would be nice but they are not worth the tradeoffs you give up IMO. I prefer the looser coupling and composition you get with CLI oriented tools and value those aspects over the limited things that IDEs would offer.
And none of this covers the fact that none of the good IDEs are Free Software. Which automatically removes them from consideration.
Editors get this wrong when there are multiple complex and overriden functions/methods. Furthermore, they can't display things in the same way an IDE displays them. I suggest checking out a modern (admittedly non-free but open source) IDE. JetBrains displays argument names in an ineditable area next to the argument values.
When debugging it shows the values that changed in each line in an area next to the line of code. It's amazing.
> [..] multiple complex and overriden functions/methods.
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.
There's something to that argument, though. You probably shouldn't use an IDE when you're learning a language. You should at least understand what it's doing behind the scenes and why.
Good IDE will usually highlight style and basic issues as you're typing them, and you can get a better idea of what 'canonical' foo-lang is. I'm not a ruby expert, but using RubyMine I'm reminded of some things while I'm coding, and (some) errors (or just style issues) are spotted before I run.
100% agree with this. I've seen plenty of devs who type a couple dozen characters in a session and spend the rest of their time clicking around on IDE prompts. This isn't necessarily a bad thing, but I've seen newer devs become completely crippled if their IDE misbehaves. And it's not uncommon for them to have very little understanding of the project structure because their IDE abstracts most of it away.
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
No one has yelled at you yet so let me be the first to represent for the can't type contingent.
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 made use of various windows based microsoft ides, intellij, eclipse, wind river tornado, the qt creator, various activestate ides, various notebook ides and others i probably cannot even remember.
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.
i got stuck with 'vi' at a place a few years back because "that's good enough - they're pretty much the same". I don't mean as main development tool, but on server builds, 'vi' was 'good enough' and also "it's smaller - we need to keep this small". So any time anyone had to do anything on those remote servers... years of muscle memory gone because... oh yeah, it's 'vi' not 'vim'. it was jarring to be reminded of how different they are.
> 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 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.
That's why we have software testers. Most of the stuff I build nowadays is server backend stuff and mobile. For server backend this runs on strong machines. No problem.
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.
What happens when you now want to work in say.. Crystal, or Shell, or Rust, or Zig, or any other language for which there is not an IDE (even those also by JetBrains) which is 1:1 feature compatible to IntelliJ? Not all JetBrains IDEs have the same features. Rider (for .NET) only recently got remote editing support which IntelliJ already had for instance.
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 can use text editors and other IDEs just fine. An IDE gives me more power and for 99% of my work I can live within it. I'm just slower.
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".
If I have no budget then I'm probably not a professional. Would you expect a contractor to build your house with just a hammer just because he ran out of cash buying the materials?
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.
I have to admit I'm guilty of this, so much so that I'm tending towards discussing programming language features is moot without discussing the available tooling. In fact, I'm starting to think tooling is (slightly) more important.
Tooling and an active ecosystem around a language are generally more important for most projects. Lang-feature-X, on its own, is almost never the reason a project succeeds or fails. An active community fostering discussion about the best ways to address particular problems, with an ecosystem of libraries and examples that show one or more ways to deal with those problems - that is useful. As the language develops, the ecosystem will incorporate those newer features to build on the previous approach.
There are four things which IDEs typically provide which I find invaluable. It's probable that some or maybe even all of them could be wedged into Vim or Emacs, but then you'd have basically an IDE.
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.
My neovim does all of this and more. Yes ive blurred the lines of text editor and IDE. I enjoy the portability, speed, and customization it offers. I also like that I have everything I need in the terminal.
Its not for everyone though and it takes a lot of time to customize it perfectly for you.
I'm able to do all these with a simple text editor, an IDE takes up resources, implements tracking, and real programmers basically have no use for anything aside from a simple text editor.
How's refactoring support and formatting code? Navigating code as in click and go to definition? I say this because I work with someone who uses VIM and these are constant issues working with them.
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).
So, am I supposed to type all that cruft? Instead of just pressing alt-enter to bring up the suggestions menu, choose the obvious first item by pressing enter again, and have everything you have to remember several arcane incantations for done automatically..?
I never got the command line purist crowd. I prefer spending time on solving business domain problems…
What if the suggestions menu crashes? Have you considered the extra RAM that is being used that could go further towards solving business problems? What if the curated menu of autosuggestions doesn't contain what you need?
I’m not sure whether you are sarcastic or not, but come on.. what if the LSP crashes, or you know, that also eats more RAM (and I am sure that someone with a 128GB laptop doesn’t get more work done than someone with only a 16GB one..).
My experience is quite different: I feel extremely productive working in the terminal, and what is described in the article as "The frozen world" is for me a virtue of the UNIX philosophy: the structure is not embedded in the data, but the programs can project a structure on it. That allows programs to be filters, and text to be the only format for exchanging information. What the article describes as "The nightmare that is composition iteration" is for me a very pleasant experience: the terminal provides a very fast feedback loop where I can iteratively examine the output of a command and refine the filters I apply. As a result, I am able to prototype commands quickly and accurately.
> the terminal provides a very fast feedback loop where I can iteratively examine the output of a command and refine the filters I apply. As a result, I am able to prototype commands quickly and accurately.
That's what any REPL does. And it works great with typed data. Sometimes even with graphical output.
> the terminal provides a very fast feedback loop where I can iteratively examine the output of a command and refine the filters I apply
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.
I agree that it would be nice to cache a command's output, so we can iterate processes on it. I'm a heavy user of Emacs, which is based around "buffers", so should naturally support such a workflow; yet in the decade I've been using it, such a workflow hasn't really occurred to me.
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 :)
This is how I use NeoVim's terminal: run a command, visually select the lines I want to operate on and yank them, then paste them in a new buffer. After that, it's a matter of transforming the text via whatever means one normally does (macros, text objects, search/replace, etc.)
Manipulating text within the editor is pretty common; e.g. I use shell-mode in Emacs, which is mostly just a normal text buffer (except Return acts differently when the cursor is over the commandline!); eshell is similar.
What I was describing above is manipulating such buffers with external commands (similar to Emacs `shell-command-on-region`)
I understand where the author is coming from and I myself sympathize with the idea of sticking to Unix philosophy of composing small focused tools instead of using complicated tools.
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 completely agree. I find the idea of using someone else's Vim or Emacs config horrifying. They'll do everything differently and not necessarily better.
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!"
Docker is a way of taking fragile, non-deterministic things like package installations, and make them less fragile, in very practically-useful ways.
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.
> 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)
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)
While I agree that this sort of workflow keeps development environments reproducible, I disagree with freezing editing tools like this. Nothing about your project should require specific IDEs or similar software. Like you said, less complexity is easier to make more reliable, so stick to purely the tools necessary to build and run the software, rather than including the tools to edit it.
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.
Absolutely. I am not installing VSCode on production VMs, the step I described is purely for setting up a portable developer environment. Then instead of telling other developers to install a laundry list of tools I can just give them a copy of my VM. Throw in something like Vagrant and it's easy to share a standard work environment. Then to roll things into production it's another game.
Default configurations change too often. I maintain two scripts on github that revert Ubuntu and MacOS to a stable setting where UI and UX things don't change.
One part of the article that resonates with me is the need for composable software that uses a more sophisticated mechanism than Unix pipes to connect components to provide an integrated experience. Over the past few years I've been interested in the idea of component-based software through IPC protocols and metaprogramming. This year I've been playing around with Plan 9, and I've found its ideas of component-based software through the 9p protocol interesting. I also got to spend some time using acme, which is one of the editors that comes with Plan 9. What makes acme interesting is that I can run external commands in the editor to perform various tasks, ranging from text manipulations to tasks such as compiling code. Each output shows up as its own window pane. One could create a sort of IDE using acme's ability to run external commands.
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.
Many people seem to think using a commercial proprietary IDE means you somehow forget how to use the CLI or other editors to get the job done. Like they're junk food that makes you dumb.
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 consider myself quite adept at cli, I can sed, grep, find, vim, and git quite well.
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.
I use NeoVim for everything except debugging. For that I (frequently) open up VSCode or Chrome to debug (NodeJS). I haven't figured out a good debug workflow for Rust, though, because I hate print debugging.
>We could write a code / text editor that wouldn’t have to be worried about extensions like Git: the Git support would come as a native application (equivalent of the CLI git application) that would open an overlay, for instance. That application wouldn’t even know about the code editor: you would make that connection via the platform.
>Applications could communicate between each other to manipulate buffers, get the contents of the buffer and do various kind of operations on them (LSP servers, for instance).
>Because the protocol would be completely rendering-agnostic, that would allow people to write an application that would work for any kind of “platform implementations.”
Composition would use the low-level protocol to compose applications. You could imagine supporting an interface between applications allowing to filter the contents of the buffer of one by using another application. Applications such as fzf could branch on the buffers of a text editor, for instance. Or you could even open a buffer in the text editor by running a fuzzy finder as another application. All of that would compose in a seamless way.
Etc. etc.
Actually this sounds a lot like OLE 2.0 from 1995.
The workflows enabled by Jupyter and iPython address some of your biggest concerns.
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.
The problem with in browser anything is that editing text in the browser sucks. It steals a lot of key bindings you can never get back, it allows for selection of the wrong element.
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.
"Modern" IDEs suck. They are not meant to be _fully_ controlled by the keyboard, have delays, cluttered UIs and interrupt your workflow with popups. That's why I prefer Neovim.
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.