9 ms·
This question reminds me of the first time I met a blind programmer. I asked him how he managed to code, and he replied with something that stayed with me: a g
by daltonpinto 2y ago
This question reminds me of the first time I met a blind programmer.
I asked him how he managed to code, and he replied with something that stayed with me: a good programmer should organize software in such a way that every piece of code has a clear and logical place. The organization should be so intuitive that anyone could build a mental model of the structure and navigate it easily, even without seeing it.
It felt like something out of a Yoda or Mr. Miyagi lesson. Skeptical, I asked his colleagues if he was truly able to code or if he was just exaggerating. To my surprise, they told me not only was he capable, but he was the best programmer they had ever worked with. They said no one else came close to writing code as organized as his.
That conversation changed my perspective. Ever since, whenever I’m unsure where to place new code, I don’t think about DDD or any specific methodology. Instead, I try to follow the logic and structure of the project in a way that feels natural and easy to follow later.
Later in life, I met two other blind programmers and heard similar stories about their ability to produce well-organized code.
To bring this back to the original question: I view LSP/IDE features the same way those programmers view "visual aids." Code should be organized according to a clear and logical structure that makes it easy to navigate.
Relying on features like Ctrl+Click to find where things are located worries me. Why? Because it can mask structural flaws in the codebase. If we can't intuitively figure out where something belongs, that’s a sign the codebase lacks structure—and that should motivate us to refactor it.
Not only do I avoid using LSP features, but I’m also opposed to their use. While they can help with navigation, they may prevent developers from experiencing and addressing the underlying structural issues in their code.
- mckn1ght 2y agoOf course I agree that code should be organized logically, but I wonder if you could expand on what you mean. Do you drill down into finer and finer directories of detail, code units, classes and functions? I work with someone that navigates the tree structure of all our directories every time they need to look for something. It is painfully slow to watch and if you ask me, they produce fairly spaghetti architecture. Some of that could be a lack of familiarity with the idioms of our platform and its available SDKs. But I ⌘ click all the time as well as quick-open right to the class, variable or function I need to work with, and I feel like I still organize things better. I’m constantly fixing the weirdness and proposing even more things that should be improved. You might even get a bit of a Conway’s Law effect by committing unnecessarily to a specific, onerous work style.
- xlii 2y ago> I work with someone that navigates the tree structure of all our directories every time they need to look for something Counter example: I’m working with LSP dragging codebase where basic code lint takes 45s. My colleague takes a break after each change so that their code navigation starts working again. Inefficient people are inefficient. Not using LSPs isn’t guarantee of efficiency just as using LSP isn’t one. Different strokes for different folks - one has to accept consequences though (more automation means less presence, but it’s everyone’s own choice to make).
- deleted 2y ago[deleted]
- rerdavies 2y agoNeeds more RAM? I've been doing work on a Raspberry Pi project, which got large enough that it took forever to get code nav back after an edit. I switched to using VSCODE remote from a beefier machine with 32GB of memory (and an admittedly better processor). Editing response is now under 10 seconds. Sweetness and light! And even the compiles (which still take place on the Pi) run about 6x faster.
- xlii 2y agoNope, we are working on beefy machines. Problem are circular dependencies that trigger recompilation multiple times and macros sprinkle on top. We’re refactoring it and get there eventually but without LSP and types (stack is dynamic) there is only so much that can be done.
- daltonpinto 2y agoIt is not about speed, is about quality. When I met the other 2 blind people, one of them joked that yes, they were very organized, but because they had to be, unlike us, being not organized wasn't an option for them. I don't question the ability you may have to deliver quicker results, but I bet that your incentive to organize stuff is smaller than what your friend has. Maybe he will be more inclined to refactor that than you and take even more time, and that maybe it pays off. Of course, I have no idea of your deadlines or if you are in a rush for MVP in search of market fit. But this also follows those lines of: "wanna go fast go alone, wanna go further go together". I value more quality than speed, but also understand that sometimes speed is what is needed.
- samsquire 2y agoI greatly enjoyed this comment of yours daltonpinto. Thank you. I do not rejoice with code bases where every file has no logic or code in it but there are hundreds of methods and files with everything spread out. I have no idea how those projects fit together because the actual logic is spread out. For my personal side project hobby work it's all in one file.
- lloeki 2y ago> I have no idea how those projects fit together because the actual logic is spread out. There are two kind of mazes: - those that are so tangled up that you can't make out any kind of structure. - those that are so regular that you can't make out any kind of structure.
- daltonpinto 2y agoExactly! Not because it is split it means that was well split. If you can reason where something should be, it may be badly organized. Even single file projects can be organized. If is small enough and makes sense, why not? But even in a small file, how is it organized? Utility functions maybe at bottom so you keep business logic together and visible? Maybe some other logic to make it cleaner? The way functions are named follow some convention? What about variables? I once read one opinion that software developers had more in common to artists and writers than engineers. Writing code is like an art of expressing yourself well to your peers in a way that a computer will also execute what you meant, not the opposite. The computer can understand whatever entangled mess you write, other people (which may include your future self) may not.
- samsquire 2y agoA word cloud could be a useful navigation technique if the words were clickable and the sizes of words could be customized. They could also link to other word clouds Generated and updated automatically
- pjc50 2y ago> For my personal side project hobby work it's all in one file. Ok, so this is work, but: find . -name '*.cs' -type f -print0 | wc --files0-from=- 1035617 3438912 47446211 total Not many editors are comfortable with a million line document that's 47MB. And that doesn't include generated code (which I very rarely need to look at, but is right there under F12 if I do)
- brabel 2y ago> Not only do I avoid using LSP features, but I’m also opposed to their use. While they can help with navigation, they may prevent developers from experiencing and addressing the underlying structural issues in their code. LSP by itself will not prevent anything. LSP (using the terminology from OP, but any IDE really) is just a tool like any other which allows you to do things faster. It doesn't matter how organized your code base is, it will never be as fast to find some definition as hitting a keyboard shortcut (please don't use Ctrl+Click, my gosh... learn the keyboard shortcut for things you do often like this). I want to see docs for a function without moving my eyes from the code I am currently writing. I want to be able to jump back and forth between definitions without interrupting my chain of thought, see function definitions inline instead of having to jump to the file it's defined on. When you have to manually search for files and then Ctrl+F to find functions, lookup docs in a web browser (which I hear is how people who don't use IDEs still do that), or manually run a linter/compiler to see warnings in your code, you're just being really inefficient. I can't understand that at all. Why don't you use automation to help your job when the whole point of your job is automation? Keeping the code organized is still good advice, but has nothing to do with using an IDE.
- daltonpinto 2y agoOf course that are good things and maybe I wrote in a too much harsh way. Linting features and autocompletes are nice, also autocomplete features are nice to have. The issue that I pointed mostly resonates with the idea that depending on LSP is the big issue. I personally use Neovim with minimal stuff, I run lint and tests manually and not automatically, because it feels to me like push notifications taking my attention elsewhere, so I go to fix them later after what my intention is already expressed in code. But agree and dyisagree that "Keeping the code organized is still good advice, but has nothing to do with using an IDE.". It should not be based on IDE, but an IDE on the hands of an inexperienced dev may lead to some comfort that should not be there. I reviewed many code written by junior people, and very often I see people adding code in random places that later may let the application to be hard to follow and everything "seems fine" to them. Other smell is like, but "it is so easy to rename a variables with my IDE" even though I believe that refactoring is nice to be done, but if we keep changing names so often, why don't we read the code that is being edited to understand well its intention and maybe realized that a big chunk of code should be split and the name choice will be completely distinct once proper refactor is made. My point is not about avoid automation, is about having a dependency on that because the code is not manageable to people anymore, but manageable by automation mostly.
- wruza 2y agoI fully agree with the idea but disagree with the… submission to the norms. We rarely talk about it and it’s also the constant source of teamwork issues. Look, if our code needs structure to be observable, it lacks structure in the first place. Languages and editing methods — not talking IDEs here, it’s more fundamental — are still “empty file canvas, paint anything” model. That must be stopped. These structural issues are analogous to malformed xml issues. They should not exist normally. We could start with e.g. better isolation/visibility systems than “files with exports”, then address lack of annotated TOCs for projects and modules. Then replace files with something more database-like. Theeen we could talk about someone breaking a nice structure. Because this structure only exist in a human’s mind, blindness only serving as a bitter “equalizer” to it.
- svilen_dobrev 2y agosome colleague some time ago argued that one can write code without much/any spaces, because, "you can see, it's colored differently".. sounding like, "i am breathing". All these IDE+- things may be nice-to-have but most soon become crutches, and then you cannot live without them, and only walk their walk, not yours. Just turning off syntax coloring freaks recent developers.. even quite good ones.. i observed it. Then the trend to pollute untyped-languages' codebases with so-called-"typing" noise, because "it would be IDeditor-friendly" (??) . Form over function, yes.. And another observation from many experiences.. any kind of generated code alienates its users, i.e. programmers. Yet to see how current LLM-ical trend scores in this.. As of last interview, "we need software curators, not programmers" have fun!
- pjc50 2y ago> pollute untyped-languages' codebases with so-called-"typing" noise Yeah, this is going to be extremely controversial: your so-called untyped language actually has types in, and they're important, but only the program can see them at runtime because you've not written them down anywhere. The real solution to "repeating myself writing down types" is Hindley-Milner inference, which dates back to 1958, and more languages should use it!
- rootnod3 2y agoYeah, but even there, if one were to use no LSP or other completions, Hindley Milner doesn't help while editing as you won't see the inferred types. It comes down back to good naming and the compiler at the end.
- zahlman 2y agoIMX, people who use the term "untyped language" generally: a) use languages with Hindley-Milner inference; b) don't consider things that can "only the program can see at runtime" to qualify as "types".
- pjc50 2y agoIf your language lets you add a number to a string or divide a dictionary by a boolean, that's .. exciting, but also the sort of thing that produces https://www.destroyallsoftware.com/talks/wat https://www.destroyallsoftware.com/talks/wat
- sourcepluck 2y agoWow, excellent insight from these programmers. Very cool. Will be keeping this in mind!
- tekkk 2y agoI myself coined a term "kitchenware principle" that I have applied to my codebase as well. You put forks and knives adjacent because they serve similar utility and common purpose. Same with plates, cups, weird gadgets in separate drawer. You should organize your code similarly and with as little fanfare. They are just tools, dont get clever with them. Sometimes, you get too many forks in same holder so you have to divide them but again, common sense prevails.
- zahlman 2y agoI feel much the same way about how to write the code, but the idea of losing my sight is still horrific. I can't imagine having an easy time adapting to it and can very easily imagine giving up on coding.
- zelphirkalt 2y agoThis matches my experience as a non-blind programmer. If the code is not well structured, I have issues finding things by intuition. The mental model or map does not work. Then I rely on searches or various kinds. It is annoying, and one can't always change this, when working on a non-restructuring MR. Others relying ore on LSP might not even see this issue.
- kapitar 2y agoThis is one of the features I like most about F#, after some years experience with it. The project is structured with a specific file ordering, and there's no forward referencing. Similar within a file/module as well, most of the time. So to understand a project, you start at the top and work your way down, you wont encounter anything you haven't come across yet as you go. Ironically, this 'feature' so annoyed me when I first came across the language in 2015 or so, that I put it down after five minutes and forgot about it for years.
- fnordsensei 2y agoI wonder if this makes it easier for LLMs to navigate your code as well. They are effectively blind.
- nickd2001 2y ago" a good programmer should organize software in such a way that every piece of code has a clear and logical place. The organization should be so intuitive that anyone could build a mental model of the structure and navigate it easily, even without seeing it." sounds like very good advice to me. In the mid to late 1990s I worked somewhere that tried to do this with a big C++ codebase, because we didn't have IDEs (vi wasn't even vim at the time), unless you count emacs which some people were good at, not me at the time. I believe that IDEs are in many ways a backward step ,because they allow people to develop lazy habits and make a hideous sloppy mess of meaninglessly-named spaghetti, knowing that there's autocomplete and advanced search functionality.
- scarface_74 2y agoThis is the AWS SDK for Python. Everything is “logically organized” am I suppose to remember every method on every class? The C#, Java, Go and other SDKs are the same (they are all auto generated by the same definition file) It doesn’t matter how well structured a codebase is, once it gets large, you’re not going to remember every method on every class
- rnewme 2y agoOf course, but there is a difference between programing using sdk/library/api and some glue, and actually engineering some self standing solution, and everything in between that. I belive blind programer wouldn't fare well in fast churn ci/cd every minute startup, but would be amazing in embedded space with multi year release cycles.
- scarface_74 2y agoHow many large applications are made with no dependencies or frameworks? In another life, I worked on a SaaS app around railroad car repair billing. These are the industry requirements. https://public.railinc.com/sites/default/files/documents/CRB_UG.pdf https://public.railinc.com/sites/default/files/documents/CRB... And this doesn’t include addendums, regulation updates, industry norms, extra requirements by clients etc No matter how well structured the codebase is, it will become large and had a lot of classes. Not to mention the underlying .Net framework Have you worked with either the iOS or Android SDK? Do you expect people to know that entire SDK and a sufficient large codebase? Autocompleting IDEs are not a new concept. It’s been part of Visual Studio since the mid 1990s.
- rnewme 2y agoI perhaps didn't express my point clear enough. If you're developing net framework, ios or android sdk itself, you're trying to be consistent and well structured, and you'll probably mostly work in one part of the code base. Then app dev will again use your structured expected layout as part of his structured system. The point wasn't to know the whole code base, but rather that it's made in a way that it makes sense how to use nth thing after you use first few. I developed ios apps, and it's vastly different experience than android or flutter. And then that is not even comperable to JS and dozen build steps, standards, and libraries that are countless and all with different approaches to how they're structured and built...
- nox101 2y agosounds great if youre starting from scratch. I work on a project with 250k+ files I didn't create
- registeredcorn 2y agoRegarding organization, I heard an interesting perspective that may be worth consideration that I would like to hear your input on. The opinion went something like this: > Well written, clean code is amazing. It is also an issue because the second features or specs change, you have to undo/redo the work you just did! Further complicating things are two other real-world concerns: > 1) Looming deadlines might make the time needed to express "best organized" code to either be executed suboptimaly, or outright incongruities, leading to confusion due to parts A, B, and D being expressed very well, but C, and E-J are left looking wonky. > 2) It can foster a "Don't touch" mentality. "Oh, Bob (the pro) wrote that! Better not mess with it. I'll work around it with a hack-y solution." Basically it's a suggestion that, "In order to write very well organized code, you have to be an excellent programmer. So what do you do if you work with subpar to average programmers?" It would almost seem to suggest that by writing well organized code, you are giving yourself even more work, because it is intimidating or too daunting to other programmers who aren't at that same level. I'm not sure how much I agree with those points, myself. I kind of feel like they are a cop-out, a kind of excuse to go with less thought out designs. I do see, however, that as far as real world situations are concerned, managers and even fellow programmers might prefer "good enough" to be done with it. I'm not really sure what to make of it, but it does seem to make a kind of sense.
- yodsanklai 2y ago> a good programmer should organize software in such a way that every piece of code has a clear and logical place How many programmers have the luxury to organize the code in the way that exactly suit them? most of the time, I work on code I didn't write myself. In the past, I used to try to refactor but I grew tired of having to justify why it's useful. Nowadays, I just deal with the code the best I can, and LSP is a big help.
- pjerem 2y agoI do think - my pet theory - there is two sorts of « good » code : - The solo programmer’s code : it’s smart, small, straightforward, does what it needs to do and it benefits from being able to fit in the author’s head but it would be a team’s nightmare, hard to add unanticipated features. - The team’s code : it’s verbose, full of boilerplate, follows strict programming patterns and rules, is easier to modify/add features. Anyone in the team can add or maintain parts but give it to a solo programmer and it would become a nightmare to just maintain. For a long time in my career, I opposed the two. Being too straightforward and not strict enough in a team setting is often a recipe for disaster in the long term. In the contrary, being too professional in your solo project is often the way to abandon it. Being able to write those two types of code is an incredible skill - that I mostly don’t have.
- kapitar 2y agoI’m sorry to say that some of the gnarliest and most boneheaded codebases I worked on were ones where I was the ‘architect’. It was a startup environment and hectic, but I had total control over everything, more or less. Just to say that having the luxury of a greenfield start doesn't mean you'll end up with a nice result.
- sn9 2y agoMy understanding of successful blind programmers is they basically are forced to write code in a way that fits in their head, and this is the essential feature of good code. I'd be interested in more concrete examples of what specifically you're referring to though.
- Phlebsy 2y ago> I asked him how he managed to code, and he replied with something that stayed with me: a good programmer should organize software in such a way that every piece of code has a clear and logical place. The organization should be so intuitive that anyone could build a mental model of the structure and navigate it easily, even without seeing it. I had a similar conversation with a blind classical guitarist before I ever played, which was echoed by my instructor when I started to learn a few years later. Something along the lines of "If you don't know a piece of music to play it with your eyes closed then you haven't practiced it enough for a performance." I'm not sure I follow the same idea with not utilizing available tooling in software development, but I do believe that most developers would benefit from intentionally going 'back to basics' and limiting their use every so often and shining a light on what you might think you have a solid grasp of but are actually at the limit of your unassisted capabilities.
- ozim 2y agoYou are lucky to have small code base or one that you write mostly? With 6 other devs on the team and 5 apps our team supports there is no way I get code well organized especially when as a senior I have devops stuff to deal with meetings, explaining features to business, checking up support tickets and random stuff happening all the time. I don’t know the code base and there is no way to keep up. While I have to dive in and fix shit ASAP or when I get to code review I have to fix some less experienced guy code. Or write part of code when proposing architecture solution, because just telling people “I am right do it my way” does not work until I write piece of code and then they understand. Language server and ctrl-click is my bread and butter because that is the fastest way while also going slow enough to understand context.
- deleted 2y ago[deleted]
- nimih 2y agoI'm curious what you do when you encounter issues in a 3rd party dependency, or (since it sounds like you do dev-ops work) in an infrastructure process or tool whose code you didn't write? I use auto-complete and LSP features pretty heavily myself in my day-to-day development work, but when debugging an issue, I sometimes run into issues with a 3rd party library, or a kubernetes component, or whatever, and it's necessary to jump into those codebases and understand what's going on, whether the bug is with the library or with our own integration, whether it's more expedient to patch the dependency or write a workaround in our own code, &c. And in those cases, I generally do not have a LSP running, or my editor properly configured beyond basic syntax highlighting, and I have to rely on, presumably, the same techniques that devs who don't use LSPs at all employ in their day-to-day work: being able to quickly read and understand other peoples' code, being able to approximate jump-to-def with find/grep/ag/rg, being able to effectively trace datatypes and control flow through multiple definitions/files, being able to take effective notes to improve my working memory, and so on.
- ozim 2y agoWell yes I still do lots of grepping and just search in all files if needed. It is not exclusive but if I can use good IDE features it helps to be quicker. I also have notes I write down where search is must have as my notes are not structured anyway.
- thunderbong 2y agoThis HN thread was posted on Reddit and that programmer commented [0]. The full comment - > Oh hey this is me. My typical setup is two terminals: one for vim, one running the compiler and other tools. I just make edits, then invoke the compiler, in a loop. As for finding a definition, most of the time I'm just familiar enough with the code that I know where it is. But when I don't, usually a well designed grep command will do the trick. > The why: my job involves frequently doing development in environments I don't have much or any control over, and often don't even have Internet access. Over the years, I just learned to work with the basics (vim and a shell) since I can't take my favorite IDE with me to these different environments. > Additionally, my vim configuration just involves setting up tabs to be 4 spaces and turning on line numbers. Having a complex config just became too much to try to keep in sync across environments. [0]: https://reddit.com/comments/1hld3s4/comment/m3ladrs https://reddit.com/comments/1hld3s4/comment/m3ladrs
- dataflow 2y ago> Relying on features like Ctrl+Click to find where things are located worries me. Why? Because it can mask structural flaws in the codebase. If we can't intuitively figure out where something belongs, that’s a sign the codebase lacks structure—and that should motivate us to refactor it. This argument sounds nice in theory but it seems to have some serious fundamental flaws w.r.t. "how do you code without an LSP": - What do you do about dependent names? i.e. names that resolve to something different based on various conditions in the code? They might be defined in multiple places conditionally, their default definitions might be overridden for particular cases (and you'd have no idea if you just saw the default definition - think "template specialization" if you write C++), they might have different definitions on different platforms... do you seriously want to explore the entire codebase manually with all the compiler flags to figure out what something resolves to? - What do you do about code that you can't refactor? Like third party code? - Not every question the IDE/LSP answers is of the form "where does this belong". What do you do about things that aren't names? Like say, there's a quantity calculated at compile time and want to know its value? I'm not talking Math.PI here, I'm talking about something like STACK_BUFFER_SIZE. It can easily be something like (sizeof(T) + sizeof(U) * 4) / sizeof(void*). How much of your life do you want to spend simulating the compiler in your brain vs. having it just tell you what it already knows? etc.
- zkry 2y agoThis is a great tie in point. I've had simmilar feelings that a lot the conveniences we have as developers only end up letting us dig ourselves into ever deeper messes of complexity.