6 ms·
The human typewriter, or why optimizing for typing is short-sighted
- Sytten 2y agoRust and Kotlin would like a word. What a weird take. All editors now have LSP support now and your editor/compiler should definitely figure this out for you.
- QuercusMax 2y agoAlso, any kind of weakly typed language. I kinda liked working with pytype at Google; it let me specify types when it's important either for correctness or documentation purposes, and ignore them when it's obvious. My experience working with modern C++ is that there are a zillion horrible templated types that mostly get in your way when you're trying to do something boring. 'auto' is a useful way to clear out that messy boilerplate garbage and make your code clearer. But if it's not making your code clearer, then that's what code reviews are for.
- okanat 2y agoRust and Kotlin have much stricter type systems and much saner standard libraries. C++ auto is a ticket to hell of implicit conversions and stupid extra copies that come out of nowhere.
- lifthrasiir 2y agoThe article starts with a correct problem statement and concludes with a weird claim, because nowadays IDEs like Visual Studio Code do support the best of both worlds: inlay hints. I turn them off by default on VSCode (because it messes with columns, unfortunately) but configured them to `offUnlessPressed` so that I can quickly check inlay hints by pressing Ctrl+Alt/Option.
- ReleaseCandidat 2y ago> inlay hints They are a feature of (and configured in) the LSP Server, so every editor that has LSP integration can display them. Still doesn't help when there is no LSP around.
- giomasce 2y agoI wish clangd let me configure the inlay hint elision length...
- lifthrasiir 2y agoYeah, I hope I didn't annoy anyone using editors that have IDE supports via LSP :-p
- ReleaseCandidat 2y agoWell, you never know if vim users are upset because you are calling their editor an IDE or because you are calling it "not an IDE". I'd say "vim user" is already an insult in itself, so that doesn't matter at all ;)
- falcor84 2y ago> I'd say "vim user" is already an insult in itself, so that doesn't matter at all ;) I believe that the proper term is "vim disciple"
- Ferret7446 2y agoWhere do you draw the line between what the IDE is able to show and what is saved in the file? We could remove all indentation and spaces around all operators/symbols and newlines let the IDE inlay that too.
- viraptor 2y agoYes, please? I can't wait until we stop saving code as text. It's silly. Kill the formatting, let everyone see the level they prefer, stop limiting everyone to file-level granularity. Show the types that are relevant in context and allow switching the views.
- lawn 2y ago> auto lovers will say that the IDE will resolve the types for you if you really care, but would someone please think of our poor Vim & Emacs users? This poor Neovim user also has LSP with inline hints, hover and help like IDEs. Vim/Emacs aren't just the dumb text editors anymore.
- noname120 2y agoMaybe the poor Vim & Emacs users should think about other developers that have better things to do than catering to their special needs.
- yosefk 2y agoanyone with no time to properly setup an IDE before delving into some code to quickly find something out becomes that "vim/emacs user". Certainly in C++ you can't make sense of the code without the right defines and include path and configuring the IDE to actually understand C++ code is not that quick at times (and that's before we get into things like Qt which essentially add their own language features)
- Y_Y 2y agoIf LSP can tell you the type, wouldn't it be a nice solution to just have it write it in for you?
- throwaway290 2y agoThings like that exist in neovim:) but I'm curious if LSP can write it for me why not just have compiler infer it?
- ginko 2y agoSo you can figure out the type of a variable at a glance as you read the code?
- deleted 2y ago
- huijzer 2y agoAlthough there are inline hints, I agree with you that auto makes readability worse. Especially in situations like PRs and Git forges where inline hints are not always available. LLVM has a well thought out stance on auto too: https://llvm.org/docs/CodingStandards.html#id29 https://llvm.org/docs/CodingStandards.html#id29
- boxed 2y agoIt's funny reading this coming from Python where I code without types and it's perfectly fine. That being said, there is a third option here: - type `auto` - have an autoformatter that replaces `auto` with `std::vector<std::string>::iterator` or whatever the abomination of a type you need is :P
- tsimionescu 2y ago> have an autoformatter that replaces `auto` with `std::vector<std::string>::iterator` or whatever the abomination of a type you need is :P I don't know, that is obscuring a lot of details. I think we really need it to be std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::alocator<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>::iterator How would I be expected to understand the code if I didn't know what char_traits are used in the vector's allocator when opening the file in ed???
- nottorp 2y agoYou get that in the compiler error messages when you forget a ; 10 lines above ... best of both worlds ...
- nottorp 2y ago> where I code without types and it's perfectly fine Is it? In my experience it goes downhill with the square of the size of the project. That one 500 line glue script that does one thing and interacts with just the standard library? No types, yeah baby! That 50k line app partly written by some dude who doesn't work here any more? Now it's getting annoying. More? Even worse.
- Rhapso 2y agoI think you are missing the root idea here: - you write "auto" as the type. - You run a script that updates your code and replaces "auto" with the appropriate type for you to review and keep in the code.
- jbandela1 2y agoThe code presented has problems, but they are not the problems the author thinks it is. The code is listed as c++. However, it is using a style that will result in problems. First thing that jumped out at me is using const char* for strings. Using this muddies ownership and doesn’t store the length of the buffer which can result in all sorts of fun. Add to that that many times paths are formed by string concatenation, and it is looking like a code smell. Second, there is no RAII and just manual management of resources. These problems are far more likely to cause issues that the use of type deduction which by now has pretty good tooling support and is used successfully in many languages. Of course, not using RAII, using raw pointers make it tricky, but you shouldn’t be using those like that anyway.
- deleted 2y ago[deleted]
- Animats 2y agoThis is something that seems to be settling down in language design. Local variables are usually implicitly typed, and function parameters are usually explicitly typed. This is for readability. "auto" was retrofitted to C/C++ so those languages have implicit typing of locals. C# and Java added "var". Rust uses "let". So this is now pretty standard. Type info is needed on function signatures mostly so people know how to call the thing. That's why Javascript and Python have acquired bolt-on typing systems. It's also why cross-function type inference hasn't caught on. It can be done technically, but it just confuses the humans. Humans are not good at maintaining consistency between the thing right here and that other thing way over there. It's best not to design systems which require that.
- mattmanser 2y agoIt's not settling down, as C# just changed it up again. They introduced some new syntaxes in recent versions, c#12 and 10(I think?): List<Foo> foos = []; Bar bar = new(); I expect that to replace implicit var declarations as the 'normal' way, especially as that's what VS code analysis suggests now.
- janaagaard 2y agoI believe 'var' was introduced in C# to make it much easier to work with LINQ, where you can easily return a subset of properties - without var you would have had to declare interfaces. I think ReSharper is responsible for the rapid proliferation of using var everywhere.
- mattmanser 2y agoIs ReSharper that prevalent? I've always thought it a small subset of programmer's who use it but are very vocal (and preachy). I've only seen it used twice 'in the wild'. And one of those two times most of the devs hated it because it was a performance hog, it was a preachy 'architect' shoving it down their throats. I don't use resharper, personally found it far too opinionated in what I felt were bad ways. Plus it often resulted in poor performance in VS. For years I've used var pretty much exclusively, it's just easier than typing the type twice. Even after they introduced new(). With the new array-like declarations I'm considering switching to declaring the type on the left rather than the right. Which, in the end, is all this syntax is, a pretty way to stop you needing to declare the type twice. And now you can either do it on the right of the expression like this: var things = new List<string>(); Or on the left: List<string> things = []; Although, one of the nice things about using var is that it makes it easy for your eye to scan a bunch of variables declared together as they line up.
- diffuse_l 2y agoMy take is that auto primary advantage isn't optimizing for typing, it's optimizing for refactoring.
- nottorp 2y agoIt's for job security. Your replacement won't be able to figure out anything, will be very slow, get fired, and then they'll rehire you at consulting rates.
- viraptor 2y agoIf the replacement can't figure out how to use an IDE that gives them the answer, they're very likely going to be slow - but auto has nothing to do with it. They're just not an experienced dev.
- nottorp 2y agoTo add to the original article's point, even the IDEs are optimized for typing. Think how they auto complete { and " and other stuff that comes in pairs for you. Great when you crank out new code, can be maddening when you're editing.
- Terr_ 2y agoWhile it impacts both, In wonder if--in the long run--there's more value from autocomplete in reducing error, as opposed to saving seconds of time.
- MeteorMarc 2y agoOptimizing for navigation is an interesting notion. Lack of navigation is also my main problem with class hierarchies. Importing a class is like import *: you do not see anymore in the module itself where some method is defined.
- dureuill 2y agoVery disappointing read. Starts with an interesting claim "don't optimize for typing", but then it completely fails to prove it, and confuses itself in thinking that `auto` is an optimization for typing. `auto` is: - A way to express types that are impossible or truly difficult to express, such as iterators, lambdas, etc - A way to optimize reading, by limiting the redundancy - A way to optimize maintenance, by limiting the amount of change brought by a refactor The insistence on notepad or "dumb editors" is also difficult to grasp. I expect people reviewing my code to be professionally equipped. Lastly the example mostly fails to demonstrate the point. - There's a point made on naming (distinct from `auto`): absent a wrapping type, `dataSizeInBytes` is better than `dataSize`. The best way though is to have `dataSize` be a `Bytes` type that supports conversion at its boundaries (can be initialized from bytes, MB, etc) - What's the gain between: auto dataSet = pDatabase->readData(queryResult.getValue()); and DatabaseDataSet dataSet = pDatabase->readData(queryResult.getValue()); The `dataset` part can be inferred from the naming of the variable, it is useless to repeat it. The `Dabatase` is also clear from the fact that we read data from a db. Also, knowing the variable has this specific type brings me absolutely nothing. - Their point about mutability of the db data confused me, as it is not clear to me if I can modify a "shadow copy" (I suppose not?). I suggest they use a programming language where mutating something you should not it a compile time error, it is much more failsafe than naming (which is hard) I'm sad, because indeed one shouldn't blindly optimize for typing, and I frequently find myself wondering when people tell me C++ is faster to write than Rust, when I (and others) empirically measured that completing a task, which is the interesting measure IMO, is twice as fast in the latter than in the former. So I would have loved a defence of why more typing does not equate higher productivity. But this ain't it.
- redsaz 2y ago> empirically measured that completing a task... is twice as fast in [Rust] than in [C++] I have not read up on which tasks you're referring to that are empirically measured, apologies. The reason I'm curious on what the tasks are, is that depending on the task, navigability may not matter. For example, if the task is "build a tool that does X", then navigability of the code does not matter. Once built, the tool does X, and there's no reason to revisit the code, and thus no reason to navigate the code. But if the task is "Given a tool that already does W, X, Y, make the tool also do X', Y', and Z", then navigability of the code matters. This is because the coder must understand what the tool already does, and where the changes need to be made. Most of my professional life, (and I'm willing to bet, most other coders here as well) I more often find myself in the second task than the first. But, I'm not interested in Rust vs C++. I'd be more interested in the results of "given a version that makes high use of type inference vs not, how quickly can someone new to the project add X', Y', and Z." That would be a more appropriate test for what the author describes here. And I'd imagine that probably, those that are using sufficiently advanced IDEs would beat out those without, regardless of if type inference used or not, and would probably be slightly faster when given the highly type-inferenced version.
- redsaz 2y ago> This post can definitely be considered a “religious” opinion piece The author certainly has that right, because the post steps on two programming religion landmines, from how I read it: 1. strict static typing (without type inference) is good. 2. code should be written to allow IDEs to enhance navigability, rather than written on the assumption that IDEs will be the sole provider for navigability. I believe there is a point to be made in the "when we don't know what we're getting back, that harms navigability" camp. But as another commenter posted, there's a point to be made in the "when we overspecify what we're getting back every time, that can harm readability, too" camp. I can't express where this balance is. It's somewhere between poetry and a legal document, the prose where you can really get into a good book and enjoy the world that the author presents. Some people really like the beauty of a short poem. Other people may require precise wording that leaves no room for enjoyment or interpretation. The rest of us can have the majority of fun somewhere in between. Where that "in between" equivalent would be in my day-to-day programming, I'm not entirely sure, because what I'm writing could be a short script where brevity is vital (poetry-ish) vs some section of unfortunately highly complex code with lots of tests for edge cases (legalese), and all the other code where I'm still world-building and conveying ideas (prose). And I believe that complexity should be spelt out as precisely as it can in the code itself, rather than rely on the hope that somebody else is using the same IDEs and features as me. I've tried using type inference where it seems fine to use, and then spelling out the exact type that a variable wants where it isn't clear what might get returned, all in the same app, but it comes across as sloppily inconsistent in my mind. Ah well.
- hkrpnc 2y agoThe author uses a code snippet that looks like the average Python code: Untyped, non-descriptive objects calling each other randomly, with no chance for the reader to figure out what is going on. So in this case auto is harmful. In many other cases it isn't.
- mrguyorama 2y agoPython is so much worse with it's runtime dynamism though. What's in the `request` object for this view? Whatever the fuck you want, your IDE won't help you, and even the documentation can't provide the full answer because half your stack stuffed things into there that you couldn't even guess.
- atoav 2y agoUsing one letter variables and the such is excusable if you are new to programming and don't know better or if you use it in such a local context that the short length helps readability or if it is a "known" short variable like i or some sort of speaking short variable like db. I like to think of myself as a good programmer, but whenever I encounter code where I have to figure out what "x" means, when it could have been a speaking variable like "accumulative_duration_ms" I feel like someone is trying to be clever. I see using auto in a similar light. Explicit return types are good. In fact there's a trend to retrofit typing into languages that don't have it. You showing me that you value not thinking about the return type over specifying explicit return types is a red flag to me. If we as programmers should value anything, it is the time and mental resources of the person who has to read our code in the future — very often that person is going to be you, yourself.
- lupusreal 2y agoI'm okay with x, but only x. Naming things can be hard so you get one freebie, but only one, so you better figure out a proper name for everything else after you use x.
- qnleigh 2y ago> but would someone please think of our poor Vim & Emacs users? This comment is sort of ironic given the title of the piece. As a Vim user, I opened it expecting to be called out for optimizing for typing.
- BugsJustFindMe 2y agoThe rules are simple: Use auto when the local code shouldn't care about the type as a way of signifying that the local code shouldn't care about the type. It doesn't happen all the time, but it does happen sometimes. Don't use auto when the code needs to care about the type.
- okanat 2y agoWith the complexity and the performance cost considered, I don't think there is a piece of code that is worth writing in C++ that also don't need to care about types. auto introduces quite a bit complexity to already complex C++ code. It behaves completely differently in lambdas. Using it as the return types usually causes implicit and costly conversions. Using it with primitive types is basically a booby trapped temple for juniors who didn't burned numerous times and mere mortals who don't have time to learn cppreference by heart. If I don't care about types, I would use a higher level language. Yes a compiler will give warnings and whatnot, given you have a modern enough one and somehow constantly running it. It is costly in time though. CI builds are not free. Developer time is less so.