You can't do that because I hate you
bvisness.me
bvisness.me
Reality is messy, there are trade-offs, and a lot of smart people think very hard about what the correct trade-offs should be given a particular situation.
And, the last pet peeve of mine. If I got a dime every time someone says ‘why don’t you just’ without even beginning to start to realize the depth of an issue, I’d be a very rich man. That’s about this quote here:
> What would it possibly take to “stabilize” such a feature? It is a completely trivial feature!
Some open source projects get this right, and others don't. Some projects don't care about wasting the user's time. Or they berate the user for wanting to do something in the 'wrong' way. Or they break things that worked just fine in the pursuit of some abstract purity.
It's not about complexity or technology at all. It's an attitude problem.
"I'm sorry bryanlarsen, I'm afraid I can't do that." - 2023 a rustfmt Odyssey.
For the former then sure, it should just let you do the thing and simply fail loudly if it fails. For the latter, there's not much they can really do without switching you over to nightly rust.
really depends on so many factors that this isn't a good general sentiment. Sure, if this is a professional grade tool targeting corporate, it better be polished or have excellent support for when stuff breaks. If it's some small scrappy tool handling a complex task with all kinds of edge cases I can give some leeway to the UX and even some very esoteric use cases.
vector graphics comes immediately to mind. I won't be too griped if Krita as a FOSS has some subtle bugs. I can at the very lest throw out an issue to at least bring awareness. I'd be much more miffed if Illustrator had some issue given how closed up and hard to contact Adobe is if you're not a million dollar business (not to mention Adobe's general philosophy of how they approach software these days).
Attitude is a factor, but I do take into account the problem space when evaluating feature completeness.
This is great and all, but misses the point. If you have made a decision to cut a feature then at least explain why. This then circumvents the 'why don’t you just' mentality. That is the root of the issue in the examples provided. It would be trivial to drop a warning about the comments not being formatted and include a link to the issue. Then there is no question of 'why' and thus you're now heading off the 'It is a completely trivial feature!' attitude, and blog posts complaining about it. Communicate clearly.
Anything else is a tribute to the rant.
But I could see the the madness anytime I squint my eyes, a large part of computing is just this.
It’s a miracle that it works at all..
It pisses me off when programmers add "features" which forces users to deal with them.
For example, pipenv always prints a message when you activate an environment (I don't know if it's still the case because I don't use it anymore). I had to migrate a cronjob which ran a Python script and sent an error email if anything got printed to stderr.
This is a pretty standard Unix thing to do, but pipenv decided to always print to stderr that the environment got activated, even though it's not an error. And there is of course no way to get it to shut up. I had to use some Bash hackery to filter that out.
Ryan Dahl's 2011 rant on this is quite relevant:
> Those of you who still find it enjoyable to learn the details of, say, a programming language - being able to happily recite off if NaN equals or does not equal null - you just don’t yet understand how utterly fucked the whole thing is. If you think it would be cute to align all of the equals signs in your code, if you spend time configuring your window manager or editor, if put unicode check marks in your test runner, if you add unnecessary hierarchies in your code directories, if you are doing anything beyond just solving the problem - you don’t understand how fucked the whole thing is. No one gives a fuck about the glib object model.
This is a pet peeve of mine. I see it every so often and every time, I wonder if the dev wasn't familiar with the norms of the platform or if the dev was being malicious.
Either way, it doesn't speak well for them.
It's a rant so I won't take it TOO literally, but: The opposite extreme of this philosophy is why we have stuff like Blender pre-2.7 and GIMP. There is some use to polishing up a proper looking UI and ensuring familiar UX. Especially if your audience is non-developers.
But yes, I understand. configs and CLIs should be as "dumb" as possible. Proper line breaks for readability and maybe color if needed, but there's nothing more frustrating than debugging what comes down to a bare basic command.
I’m old enough to remember that Python 2 in fact had “print <string>”, and I think also “exit”. Exactly because once upon a time Guido thought about what would feel nice to users. In time it turned out that special casing a handful of special functions introduces pain across everywhere else. Because of its valid syntax in REPL, it’s valid Python. So they removed the special casing for these functions, and added a helpful comment for people who might be confused.
Ditto for wrapping comments in Rust. Doc strings in Rust can have doc-tests in them. Meaning that whatever comment wrapping you do must not break syntax there. I don’t know what feature exactly is needed there that’s currently nightly only, but I’m very sure it’s not just something trivial that nobody has gotten around to yet.
Point being, no, everyone else except _me_ is not some dumb f*ck, who doesn’t do the obviously right thing because they hate me.
Like, that _sometimes_ happens. But these are not those cases, and in my experience it actually happens pretty rarely. I think the default disposition towards seemingly stupid implementations or behaviors should be that people working on the implementation were not sloppy idiots who hate their users, but rather that they had their reasons, and me being put into their shoes would’ve likely done the same.
Technically correct. But: what happens is that when you start python, it outputs:
Type "help", "copyright", "credits" or "license" for more information.
But when you type "license", you get this:
Type license() to see the full license text
Why that happens? Because "license" is a special object that has string representation as presented above and to actually read the license, you need to call it and not just request string representation. Technically it's all clean and correct. But guess what - the user does not care. Your design is not the user's problem, the usability is the user's problem. And the usability of this kind of solution is terrible. I know why it's done, I know how it's done, I can appreciate the technical beauty of it - and it still pisses me off. They clearly knew about this case, they themselves told me to use "license" and when I did it, they say "nah bro, you forgot the parens, you idiot, try again, har har har!" It's not a huge deal, but when it happens to you thousands of times, it eventually starts to piss you off. Avoiding this kind of thing is not easy - it may actually require departing from the nice and clean design you envisioned internally, and that may be annoying to a programmer - but as a user, I much prefer that this is how it would be done. I know there are reasons, in many cases I know exactly what the reasons are, because I've been guilty myself, but that doesn't help - the whole point is, as a user, it makes my life harder. So, in our development as a software engineers, once we learn how to build technically correct things, we also need to start thinking past that - how to build things that people would enjoy using.
A ‘Don’t Suck’ Button is a setting, turned off by default and usually hidden in a corner of the UI or configuration file, which fixes a common issue that new users experience, and/or turns on the behavior that everyone wants from the product in the first place.
The best examples of ‘Don’t Suck’ Buttons involve settings with no obvious disadvantage to turning them on. They’re just turned off by default and the software makes you go through extra effort to tell it “No, I don’t want you to suck.”
Usually these originated from some kind of automation, new protocol or new feature that started out as experimental and was locked behind a setting, then became universally relied upon but somehow never enabled by default.
I used to have a list of examples of these. One that comes to mind from my TV: “Allow HDMI Devices to Control this TV”. If you have an Apple TV or something, it won’t change the volume or be able to turn the TV on or off automatically unless you know enough to go into settings and tell the TV “Don’t Suck”.
Legacy code if fun. Almost as fun as the ways people get around such cruft.
In its defense, Emacs predates most modern UI paradigms (including, y'know, Ctl-C/V for copy-paste, or calling things "windows" vs "frames"), and is very conservative about updating defaults due to inertia.
Display the current column number in the modeline with (setq column-number-mode t)
Delete the selected area when overwriting by enabling (setq delete-selection-mode t)
Save sessions (all open buffers/files) automatically on quit with (setq desktop-save-mode t)
Display line numbers in the left gutter with (setq global-linum-mode t)
Wrap lines (with a convenient icon in the gutter to indicate line continuation) with (setq global-visual-line-mode t). Bonus: linum-mode compatible!
Skip that startup screen with (setq inhibit-startup-screen t)
Remove the limited and redundant icon toolbar with (setq tool-bar-mode nil)
Make emacs automatically refresh buffers whose underlying file has changed (and has no local unsaved modifications) with (setq global-auto-revert-mode t)
All of the above variables can also be customized through Emacs' excellent Customize, which is better than individually doing each (setq ...) I wrote above.
And these are just from a quick skim of my .emacs file... Decades ago, when a college friend espoused the merits of Emacs, I didn't get it because my first experience with a vanilla setup was so... limited. This is also why people will laud more "batteries-included" distributions like Spacemacs or Doom Emacs.
I'm not a fan of most of your changes though, which highlights how hard it is to have defaults that please everybody in something as complex as Emacs.
```
(setq column-number-mode t
desktop-save-mode t
display-line-numbers t
global-auto-revert-mode t)
(delete-selection-mode)
(global-display-line-numbers-mode)
````delete-selection-mode` when set as a variable didn't work.
`display-line-numbers` appears to replace `global-linum-mode`
I consider myself a seasoned programmer, but after a decade I continue to fail to do any significant customization (other than a tidy .emacs leveraging use-package (since before it was cool^H^H integrated by default)).
Lisp's syntax is easy, but Emacs' API surface and concepts are bewildering, especially due to its aforementioned mismatch with modern terms.
I also don't think they were jackasses by default...
It would IMO be nice to have a default-off option to disable CEC on a specific port. Or to disable certain CEC features.
And this kind of thing is how “new” outlook gets written, which is an absolute shitshow compared to the legacy outlook client.
Often it's not that universal; especially for older software there's a lot of variety in how people use it, and changing defaults can be hugely confusing for existing users. A lot of these (alleged) "don't suck" buttons are probably more subjective than you might think.
The HDMI thing may be a security-related, or maybe there are is another reason. I think it's important to know why something behaves as it does, without too quickly assuming there's no good reason for it. That's also my criticism of this submission by the way: it makes little to not effort to understand why things are as they are.
(Or you know, you dig a bit and find a thinly documented fix to that issue from 5 years ago).
iPhone Haptic Touch duration not set to “Fast” by default.
I didn’t even know this was an option. Thank you.
Any time an assumption is made, it's guaranteed to be wrong for someone. In your example, there are two really positive factors in play:
1. The user can change the setting.
2. It's pretty clear what the default should be.
Most of the time, we don't get either of these.
I turn the ps5 off and the TV off and the PS4 Pro starts and turns on my tv
The one example I, as a former FiOs Technician for over 10 years, would argue should default to off.
I recall mid 2000s, when they started making TVs, devices, and stbs, that could communicate both ways through what I think was an HDMI pin reserved for that purpose when it was designed. I think it had something to do with audio control and maybe there's another pin for back and forth communication. Sometimes, I'd run into problems where one device defaulted to using the pin while the tv, audio system, or earlier stbs weren't really designed with the pin in mind. The box would keep browning out like it was getting its ass kicked. Sometimes the customer's equipment would get damaged, which was a mess where I'd need to defend my job to managers that want to blame me and know nothing about Home Media beyond telephone. So, I think defaulting off with a prompt is appropriate.
An example I would agree with was the data.frame() function with R. For far too long, everyone had to designate stringsAsFactors=FALSE just to avoid it turning every character variable into factors. Every R tutorial or Stack Overflow answer, even if there were no strings, you'd find it because typing "stringsAsFactors=FALSE" every time was easier than fixing the complete mess that happened when you should have. They fixed it in a recent upgrade, though.
The default in the settings was removed because it apparently was 'confusing', but the change makes for a suckier UI, especially evident if you're adding 10 or 20 items. My personal rule for UIs is that if there's a setting where you choose from two or more alternatives, let the user set defaults.
Because it's not in fact part of their project, despite their assertion that it is.
>But you can’t. cargo fmt doesn’t have an option for that. How is even possible for your format command to not let you format an individual file?
Because cargo is a tool for working with projects, not with individual source files.
>Problem is, I had never even heard of rustfmt.
Putting "rust how to format a file" into a search engine returns rustfmt in the top results. But in any case, the problem they needed to fix is to make that file a part of their project so that `cargo fmt` will format it, not work around that by running rustfmt manually. But alas they've convinced themselves that's not the problem.
>At this point I was just hopping mad. It knew that I wanted to wrap comments. But it refused, because this was “unstable”. It knew that I wanted to opt into experimental features, but refused again.
Whatever method they used to install nightly, they're not using it here. The error is coming from the non-nightly rustfmt that they were using originally.
>It would literally have been better if they had not shipped this wrap_comments feature at all. Instead they just keep dangling it in front of my face and snatching it away as soon as I try to use it. Because they hate me.
I'd be amused at this trolling if I didn't know the author is completely serious.
I cd’d into the folder with the cargo.toml, ran cargo fmt, and nothing happened. I dunno what else to tell you. Sometimes things just aren’t set up the “right way”, and yet we still have to do our jobs.
Programming languages follow rules and programmers should follow the rules. Just because mistake is common doesn’t mean the language should incorporate it into its functioning. That makes inconsistent behavior and is a pain in the long run because instead of learning and following logic, programmers have to guess what’s a common enough error that the language compensates. And over time the language drifts and is hard to work with.
It seems easier to me to just suck it up and learn the right way to do things in a language.
A good example of why having a language that is squishy to common errors is valuable. I still understood your point even though it’s grammar wouldn’t compile.
It’s ok for things to be different.
It’s cool that I understood what you meant when you said “it’s grammar wouldn’t compile” but I would definitely expect a compiler to barf unless you entered “its grammar.”
Being frustrated that this is the case is expressing an underserved need in the market. You're aware of the limitations and have grown to be okay with them because otherwise you'd probably hate programming, but that doesn't mean we should all always be okay with them forever.
"Be liberal in what you accept, and conservative in what you send"
This follows its internal rules.
The dutch make a strong case for the rules to follow what the people do naturally, and using design to make the correct thing the easiest one, rather than presenting a stiff ruleset and expecting people to contort themselves around it.
I don't know what a dutch programming language looks like, but i think it'd be better than what we've got now in terms of all readers and writers getting the same understanding of the same code
Python? Heh. (Not Pascal: Wirth is Swiss). And of course, Dijkstra was involved with Algol 60.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
People react strongly to "I'm Sorry Dave, I'm Afraid I Can't Do That" types of messages, and the exit command one is pretty close to that. If instead they went for a more question like "unrecognized command. Did you mean 'exit()' ?" type of prompt users would react in a milder way.
In particular, choosing an imperative tone in help messages is probably not optimal.
But:
> Either support the feature, guide the user toward a better solution, or do nothing.
The first two examples _explicitly_ guide the user toward better solutions. That's much more than many tools do. If the Python repl behavior isn't "guide the user toward a better solution" in both letter and spirit, I'd love to know why.
There are much lower-hanging fruit than these examples, which makes a good point harder to agree with.
1: One of the first-page Google results for me on quitting vim is somehow this HN comment thread from 2017, in which the Python repl behavior catches strays with almost identical arguments as this article. https://news.ycombinator.com/item?id=14403297
When you work with _precise_ systems, they sometime take _precise_ input to work. That's kinda just part of the job.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
const b = 1
[1, 2, 3].forEach(console.log)
(from your linked page) does the wrong thing, because both forms (with and without a semicolon) are syntactically valid. I would much rather just always use semicolons (or, like Python, never use them) than have to memorise the 5% of oddball cases where I need to add them manually to resolve ambiguity.We have AI now that can write the entire code for you. Surely it's not much to ask that a compiler, as it parses your code and likely already has high confidence you need a semicolon in a certain spot, can just correct it for you and move on. Maybe have a --fix-errors option to the compiler command line or something.
The code is here: https://github.com/python/cpython/blob/3.12/Lib/_sitebuiltin...
The object shouldn't be in scope anywhere other than the REPL, but that doesn't mean that something, somewhere, isn't stringifying everything because $REASONS and changing the behaviour won't cause an obscure "crash" somewhere unexpected and hard to debug.
We saw this play it with web browsers in the late 90s early ‘aughts where they’d do their best to render what they thought you meant if your html was wrong, and it was indeed chaos.
Strict systems with strict inputs makes for a better overall ecosystem.
>>> print
<built-in function print>
>>> exit
<built-in function exit>
Hint: Use exit() or Ctrl-D (i.e. EOF) to exit
>>>
This way, it does do the thing you literally asked for, but also does help a newbie out.… or a long-time dev that switches languages fairly often :)
The regular Python REPL doesn't distinguish between stdout and stderr (perhaps it should!), but you can embed it in things like Jupyter notebooks that do.
That makes sense from a unix tool perspective, but not from a python repl perspective. The repl's behavior is to print the result from the last executed statement. For the exit function, the __repr__ method was overwriten to print the message. That way when you type in "exit", the last value would be exit (the function), and the overwritten __repr__ method causes the help message to be printed. There's no way to have it print to both without adding in some repl specific hacks.
>>> exit
Use exit() or Ctrl-Z plus Return to exit
>>> exit.__repr__()
'Use exit() or Ctrl-Z plus Return to exit' def __repr__(self):
import warnings
warnings.warn("Use exit() or Ctrl-Z plus Return to exit")
return super().repr()I think I agree though: what you really want to special case is the situation where the user types precisely 'exit<cr>' at a REPL prompt, and that hack needs to exist further up the stack than in the implementation of __repr__.
>>> print('%r' % str)
<class 'str'>
>>> def whatisit(x):
... print('It is %r' % x)
...
>>> whatisit(min)
It is <built-in function min>
>>> whatisit(exit)
It is Use exit() or Ctrl-D (i.e. EOF) to exit
Excuse me?IMO if the REPL wanted a friendly feature like this, it should be a generic REPL feature, not a hack applied to the function exit.
>>> def get_function():
... return exit
...
>>> a = get_function()
>>> a
Use exit() or Ctrl-D (i.e. EOF) to exit exit.__class__.__repr__ = lambda _: exit()
quit = exit
Edit, you also need this in your bashrc: export PYTHONSTARTUP=~/.pythonrcI think telnet does something stupid along the same lines "I know you want to quit but please ask address me as Sir first".
Programming languages have rules that the programmer is expected to learn. Part of being a programmer is foregoing a certain amount of user friendliness in favor of an environment that is more powerful so that we can actually get things done. Programmers are paid to memorize and follow these rules so that the end user does not have to learn them.
It's pretty easy to think of a good solution with few enough downsides that overall the design is much better:
In the REPL only, if you type "exit" and press enter, it quits.
No changes to Python semantics required. All code still works. Much friendlier UX.
I wonder what dubious justification the Python Devs would come up with to avoid implementing that (and therefore admitting they've been wrong for 20 years). They'd probably try and claim it is more confusing to beginners or some nonsense like that.
Is it too hard to write exit() or press Ctrl+D after having incorrectly entered exit?
[0] https://github.com/Source-Python-Dev-Team/Source.Python/blob...
I agree; Python is actually helping you out here, since just typing `exit` doesn't actually call the callable.
Also, Python being Python, while not recommended, there's nothing stopping the user from assigning to `exit` then printing it in the repl:
>>> exit = 42
>>> exit
42
What would the author expect Python to do in this instance?With about five minutes of my time, I found out:
wrap_comments was introduced in 2019 [0]. There are bugs in the implementation (it breaks Markdown tables), so the option hasn't been marked as stable. Progress on the issue has been spotty.
--no-merge-sources is not trivial to re-implement [1]. The author has already explained why the flag no longer works -- Cargo integrated the command, but not all of the flags. This commit [2] explains why this functionality was removed in the first place.
Rust is open source, so the author of this blog post could improve the state of the software they care about by championing these issues. The --no-merge-sources error message even encourages you to open an issue, presumably so that the authors of Cargo can gauge the importance of certain flags/features.
You could even do something much simpler, like adding a comment to the related issues mentioning that you ran into these rough edges and that it made your life a little worse, or with a workaround that you found.
Alternatively, you can continue to write about how much free software sucks.
[0]: https://github.com/rust-lang/rustfmt/issues/3347
[1]: https://github.com/rust-lang/cargo/pull/10344
[2]: https://github.com/rust-lang/cargo/commit/3842d8e6f20067f716...
I have no idea how the Rust project organizes itself, but my guess is that this simply isn't a high enough priority for them, which would explain why it hasn't been made stable.
Large backlogs with stale are a common problem that software projects have.
So I can understand why such a feature remains behind an experimental flag. "But you are not touching code, only reformatting comments!" - well, not just thta. Adding whitespace and N+1 effectively empty lines will at some point cascade into whatever logic the wider code formatter will have to consider. The number of edge cases must be non-trivial.
I think that's unfair. He wasn't writing about how much free software sucks, he was writing about how some of the rust tooling sucks.
Even in the larger context, everything he wrote applies just as readily to proprietary software. These sorts of issues are everywhere.
You're right that "frustrating to use software" applies to proprietary software as well, but the author only gives very specific examples all of which involve open source.
Well, sure, the post is a good old-fashioned rant to vent his frustrations. The title is part of that. A well-written one, but nothing more than a rant.
Rants are fine, and I've been frustrated by software too many times to count.
I'm being a bit protective because I would feel hurt if someone wrote that "I hate them" about some of the software I've worked on for free and open sourced.
I once said - and still maintain - that all devs need a life-long lesson in empathy. For our users and our library consumers and so on.
It will be impossible to fix every conceivable issue and sometimes we will have to deprecate or break backward compatibility or features or whatever. But if maybe some more effort to understand and respect our users was made as a matter of course, then when we are users we will be more inclined to give the benefit of the doubt to the developer who created the thing.
Also the post made me laugh.
Sentence 1 provides a clear justification for the behavior. Then sentence 2 declares, by bare assertion, that it's "insulting".
I find sentence 1 more persuasive than sentence 2.
Are you sure you want to exit? [y]
and then you press enter again to exit.
All of these examples are devs trying to make sure users understand what’s going on. Nothing wrong with that when it is necessary complexity. The trouble I think comes when you’re making sure the user understands something that really shouldn’t matter - unnecessary complexity. Especially complexity that is just a byproduct of a disorganized group of people building a “bazaar”, like in the Node ecosystem (and apparently Rust too). Who cares if X is actually a fork of Y that was merged into Z.
I wish the author had written what the real issue is. It feels like they are contributing the the very problems they are complaining about with a flippant line about it being something else.
Yes, mindreading is tricky, but sometimes you don't need to read minds to just work with the user.
Even for low hanging fruit. eg, `exit` in Python can be redefined as a variable - so if I do that and then type `exit`, should it print that value for me or quit the REPL? Is it better to guess, or just not encourage the user to do the wrong thing?
If I make `-?` print help, what happens when I want to define `-` as "read the following text as input" and then users start getting bizarre behavior instead of the help file?
You can probably come up with ever-fancier ways to work around this, but that takes effort, and more testing, and more code...
I'm not sure what that means, but if you're saying that you would want your program to interpret "-?" as though somebody had run it with no option at all and then provided a question mark on the standard input, that's really obnoxious and grounds for torches and pitchforks from all users.
Look, on a command line, a bare hyphen, given as an argument where there might otherwise be a filename, can reasonably mean "read from the standard input" or "write to the standard output", but only because it's been so common for so long. As an alternative to it, you can just use standard input/output by default, or you can just punt and make the user give you something like "/dev/stdin".
In any other context, a hyphen introduces an option that modifies normal program behavior. If it's a single hyphen, then the option name is a single character. If it's a double hyphen, the option name is the rest of the argument up to any equal sign. It should consist of complete words and be in `kebab-case`, not `snake_case`. But even if you violate those rules, it's a far more basic rule that an argument starting with a hyphen is an OPTION NAME, not arbitrary data.
And the options "-h", "--help", and I guess maybe "-?" and "--?" are pretty much universally used to mean "print help about how to use your program". Changing that is insane.
I know that code on on Windows does horrific stuff (including pretending it's freaking RSX-11 and using slashes of all things). I know that some really old UNIX stuff written in the bad old days also breaks the rules. But even those don't just arbitrarily redefine what the hyphen means. Redefining absolutely everything under the user, to the point where they can't even guess how to ask for help, is just crazy.
... but don't get me started on people who think it's ok to use a single hyphen to start a multicharacter option, or don't let you put multiple single character options after the single hyphen...
-h/--help are all I ever see in macOS CLI tools, in any case.
-? has been a common switch for decades. I've been implementing it (along with the synonyms -h, --help, etc.) in all of my programs since about the '90s.
I suggest supporting at least all of the following: -h, -help, --help, -?, /h, /?, help, <no flag> (if possible). Other flags don’t have to follow these rules, but I think help can be an exception.
And maybe you should print the help any time the user enters a bad command.
I'm just saying that I hadn't realized programs did that. And I've been around a long, long time. I guess I'm just blind.
There are quite a few older programs that do that, including ImageMagick and FFmpeg.
exit is unambiguously broken syntax, it doesn't fit into what the REPL promises, it's an error.
newbies to unix need to learn about Ctrl-D, and it should be taught. But it should not be the job of every tool to teach that lesson, it's one step removed from QWERTY. There are actually apps that break Ctrl-D and they are another abomination in the direction of newbie hand holding.
the_command -foo
...and the tool responds with: -foo: No such option. You probably meant --foo
Well shit! Thank you for that burst of empathy. If you, developer, are that confident that's what I meant why couldn't you just make both inputs do the same thing? You went out of your way to make the code handle -foo, but only to have the program fire off that snide remark instead of doing what you know the user meant to do. Maddening. git psuh
To be told "you probably mean push"... yeah it'd be easier for me if they went ahead and accepted the typo :D [alias]
psuh = push
to your ~/.gitconfig?I personally have "ull = pull" and "ush = push" in this section, together with "alias gitp='git'" in my ~/.bash_aliases because of how often I type "gitp ull".
And if you've got something like 'sed' overwriting the input file (-i), it'd better make sure the flags are exactly as documented.
It is implemented, but there are probably edge cases where the proper way to wrap and retain the best possible formatting is still disputed. Since a lot of people format on save, via commit hooks or during CI, having this feature enabled as stable and _changing the behavior later_ would cause massive annoying diffs in the future, or CI failures for a ton of projects.
This would be fine if "unstable" features were actually experimental messes, but all sorts of completely-benign utility functions are "unstable". You have to throw out all guarantees for your entire toolchain just to use, say, `Result::into_ok`, which was introduced in 2019, but is still unstable due to being "newly added".
At best, this is misleading, at worst, this greatly compromises the developer experience, especially when writing libraries which need to work on stable or else nobody will install them. Even for application projects, I don't want to use unstable features, because it's extraordinarily stupid to make the entire project nightly-only just because I want to use a two-line utility function, and I'm petty that way.
Sure, I'll use unstable for things like bare-metal programming that deserve to be unstable, but if I'm writing regular application code and the perfect utility function is "unstable", I'm not going to lock myself into nightly just for that.
Where did you get this from? The tracking issue says nothing of the sort: https://github.com/rust-lang/rust/issues/61695
That issue had been filed by its OP as a feature request. It then got repurposed into a tracking issue for the feature, but it's not following the standard tracking issue template that lists any blockers, stabilization steps, etc. (Compare to https://github.com/rust-lang/rust/issues/119364 that happens to be the newest "Tracking issue" atm.) Also since the OP didn't intend for it to be the tracking issue, it's possible they're not intending to do the rest of the bureaucracy to get it stabilized either, which is why it's stalled.
It absolutely was, but now it seems to be mostly that the stabilization process is tedious enough that nobody has done it yet for this tiny utility function. There are tens of other tiny utility functions in the same situation that have been sitting for years, I run into them all the time.
The whole situation surrounding "unstable features" is just super disappointing for me. This stuff doesn't deserve to be unstable, and I shouldn't have to switch to an experimental toolchain that breaks all the time just to use these tiny utility functions!
No, there is no such absolute requirement that "newly added" functions cannot be stabilized. Off the top of my head: https://github.com/rust-lang/rust/issues/111544 `OsStr::as_encoded_bytes` was proposed in 2023-05, finished being implemented in 2023-07, stabilized in 2023-09, and released in 2023-11.
>https://news.ycombinator.com/item?id=38801228
The reason attr of "newly added" is the reason to *mark the function unstable* when it was implemented. It's not the reason to *prevent it from being stabilized.*
I never said so.
The source code?
#[unstable(feature = "unwrap_infallible", reason = "newly added", issue = "61695")]
And that issue you linked is from 2019 and full of people asking when it will be stabilized. Last activity was in late 2021.Your comment said:
> `Result::into_ok`, which was introduced in 2019, but is still unstable due to being "newly added".
Your comment makes it sound that the Rust team considers a four year old utility method as "newly added", and that's the reason why this method is marked as unstable. More likely, this "newly added" reason is something they add for any new unstable feature, and it is now out of date.
Considering that repository has 9,000 open issues, and 50,0000 total issues, you can imagine that this issue has simply not been prioritized. Rust being poor at prioritizing, handling issues, etc. is a totally separate discussion from "Rust thinks four year old code is new"
[0]: https://github.com/rust-lang/rust/commit/c784720f3a2d0b66142...
This is just a process error, IMHO. The process for stabilization in general just results in outliers like this and it's really frustrating for everyone involved. I know Rust is sort of unique here, just like it's unique in all sorts of other ways, but I can't help but think that there could have been some sort of provision for small methods like these.
He wants a function to work as a keyword!
He wants comments word wrapped by default, when this would break comments that contain stuff like packet fields schemes.
Terrible ideas, and he complains they aren't the default. Well that's because they aren't good ideas and he hasn't thought about it long enough to figure it out.
In some fields, the decision is easy. We're by now culturally aligned that shipping encryption libs with bad APIs or a default-on footgun option is a bad idea.
Clearly, with less impactful tools, we still have more debate ahead of us. I'm hoping that we'll realize at some point that proper engineering is always fail-closed[1] if there are destructive consequences. Yes, it might temporarily inconvenience some, but it prevents harm to more.
Ultimately, the question is "Who is more important, you, or the rest of the world".
[1] fail-open if you're EE. We're so bad, we can't even decide on terminology.
For everything you think should obviously be A there are many vocal people who think B...
It’s like when you ask “can I go to the bathroom” and the teacher says “I dunno, CAN you?”
OK, nighty builds. So, some features could be coded, but haven't been tested for a long enough time to say "this feature is rock solid and the behaviour is good for all combinations of code". In the formatter, we probably would not wanna change the behaviour of a flag once it goes stable (and in the formatter there are always several ways to do anything, because it is just how code is).
So, there are more or less two options when adding new features: only merge a feature branch when you are 100% happy (that could make releasing hard) or have a feature behind a flag and document it is an experimental. In the real world - having feature behind a flag is good. For some reason people assume that open source projects have a huge team, and all their time is free. So, adding a new feature to a formatter is "easy and trivial" (and make that feature stable is "trivial" too).
Python's error message is a compromise, they could've just printed the unknown variable error
Rust has unstable features to prevent tooling running into issues like ci failing everytime there's a minor version update
Fun to see which is thriving and which is still niche!
That message *could* be updated to point to https://github.com/rust-lang/cargo/issues/10310 instead of asking for new issues to be created or suggesting the old `cargo-vendor`. (The author of TFA already knows about that issue, since they commented on it before they published their article.)
(You might say it would've been better to let cargo-vendor remain separate instead of merging it into cargo, but the reason that was done was to ensure it would continue to work with changes to cargo. Indeed that is why the original cargo-vendor does *not* work properly any more.)
Stop being toxic and patronizing towards open-source developers out of ignorance.
https://ipython.readthedocs.io/en/stable/api/generated/IPyth...
And repr(exit) also works fine:
> In [1]: repr(exit)
> Out[1]: '<IPython.core.autocall.ExitAutocall object at 0x102772770>'
Maybe don't be so eager to accuse people of ignorance and toxicity.
No one hates software developers more than other software developers, and no one understands usability less than a software developer.
This is one of those things I thought would get better over 30 years but has just continually gotten worse.
In early versions of COBOL exit was frequently used to go out of loops and out of sections and so on. Maybe a message is nice for someone still trying that while learning modern stuff, but I admit it’s farfetched/unlikely.
Yes it might save a bit of time for you, but it also potentially waste orders of magnitude more time for other developers. Developers who will positively hate you for forcing them to fix something that is not a problem for them!
Instead keep the old API working and make the path to upgrade easy and smooth. Your API users will love you for it.
Haven't finished the whole thing, but wait till you start reading about LaTeX.
"If you don't enjoy programming, don't worry, it is not your fault. Thousands of people around the world work hard day and night to make programming as miserable for you as possible."
An apprentice woodworker is going to fuck up a cut and have to spend hours rebuilding. An aspiring musician is going to pour hours into mediocre music that nobody listens to. A new software engineer is going to get lost in the sea of complexity built on top of the rapid growth and death of fads and doctrines and tools (good and bad) that is decades deep.
It’s fucking hard. I do think the pay reflects that, though perhaps is a biiiiit inflated. Regardless, shit ain’t easy. That being said, people generally quite enjoy sharing their knowledge, and helping the next generation of software people ramp up and kick ass, so there may be hope yet :)
for example argparse and similar cli argument parsers _know_ the basic structure of the command line, but they don't provide it in machine table form, to interactive shells, so these could ask CLI tools: "hey, what do you expect at this point?"
$ git log directory --stat
fatal: option '--stat' must come before non-option arguments
Come on, Git, you know what I want. Just do it without making me repeatedly edit the middle of the command.There is a third one. Since exit is a binding to a function, it should print that function.
>>> print
<built-in function print>
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
What? I expect <built-in function exit>It definitely seems to be specific developers/communities that suffer from this "UX doesn't exist" sort of attitude.
I have also run into Rustfmt issues when trying to format single files (necessary for Phabricator's arc lint) and they have an unreleased "version 2" which we dutifully used from source... for 5 years. It turns out their plan is to never actually release this.
Python also seems to fuck over its users quite a bit. Two examples:
1. Setuptools has broken editable installs so that static tooling (IDEs, linters, type checkers etc.) can't work with editable installs. Because who would want to edit Python code with an IDE, amiright? Facepalm.
2. On Windows there is no python3.exe. Say goodbye to portable instructions/scripts. Why you ask? Well there's some obscure situation if you have multiple Python installs in your PATH and by some miracle that hasn't totally trashed your system already (relevant XKCD) that it would trash your system slightly more. So we won't ever fix that. And please don't point out that if you install Python from the Microsoft store it does install python3.exe.
Nailed it. A few years ago, I was deep enough in the zeitgeist of Rust (or whatever project) that I would maybe even be offended by a blog post like this; bro, do you think you're better than Rust? Keep up like the rest of us!
After years of doing actual things (and not meta-learning), when there's something that makes no sense that ruins my day, I hate it.
Its menu contains an 'Add-Remove Software' GUI tool, which seems to be a thin and ill-conceived wrapper around apt-get (?). It combines several horrible choices, which conflict and clash perfectly. (1) it appears to insist on retrieving and building its entire list of apt packages, EVERY TIME YOU TRY TO OPEN OR OPERATE IT. (2) it doesn't give you any choice to CACHE this data, or any choice to skip this "refresh". (3) it takes five minutes or more to refresh this list, on our raspberry 3. (4) on any excuse you give it, it will refresh the list again. (5) once it succeeds in retrieving this insane 5-minute list, it presents it to you in an unnavigable manner - no sorting, no searching, no filtering, just a scrolling list with something like 10.000 apt packages.. page up/page down doesn't seem to work. For example, I naively pressed the cursor keys, wrongly assuming it would move my selection point in the 10.000+ list.. WRONG: Instead, it navigated a category-word-list, causing it to redo the 5-minute re-init. In effect, it because a 'trial and error game from hell', where you can attempt 10 wrong ways to navigate the list, each time being punished with a 5-minute "no you can no longer view the list you just waited 5 minutes to retrieve, you must now wait 5 minutes again for your next wrong attempt!" (6) oh yeah, and you are not allowed to view the partial list during load. I really really wonder who decided to implement that window in that maddening way??
In the end, I resorted to using apt search in the command line, which of course works perfectly, but not before having wasted about an hour together with my less-tech-savvy dad, trying to make the raspian package install UI "work" in the naive idea it would be easier for him to use :-/.
I remeber when Linux GUI users were asking for a "Right click -> run/open as root" feature just like in Windows, and the devs basically said something along the lines of "we're not gonna do it just because the way Windows does it means it must be wrong; if you need to run stuff as root it means you're a poweruser so you should use the comand line anyway; you're welcome". Linux Mint was the first and only to have this feature in the GUI early on, then came the other DEs who ceded defeat to sanity.
They implemented it in a test environment with either an emulated device pulling packages from the host, or pulling packages over a gigabit network from a local cache on their LAN, or on a high-speed fiber connection where it took far less than 5 minutes to retrieve the list.