Readit News logoReadit News
WalterBright · a year ago
> Originally, if you typed an unknown command, it would just say "this is not a git command".

Back in the 70s, Hal Finney was writing a BASIC interpreter to fit in 2K of ROM on the Mattel Intellivision system. This meant every byte was precious. To report a syntax error, he shortened the message for all errors to:

    EH?
I still laugh about that. He was quite proud of it.

vunderba · a year ago
> EH?

I feel like that would also make a good response from the text parser in an old-school interactive fiction game.

Slightly related, but I remember some older variants of BASIC using "?" to represent the PRINT statement - though I think it was less about memory and more just to save time for the programmer typing in the REPL.

chuckadams · a year ago
It was about saving memory by tokenizing keywords: '?' is how PRINT actually was stored in program memory, it just rendered as 'PRINT'. Most other tokens were typically the first two characters, the first lowercase, the second uppercase: I remember LOAD was 'lO' and DATA was 'dA', though on the C64's default character glyphs they usually looked like L<box char HN won't render> and D<spade suit char>.

All this being on a C64 of course, but I suspect most versions of Bill Gates's BASIC did something similar.

nikau · a year ago
How wasteful, ed uses just ? for all errors, a 3x saving
ekidd · a year ago
Ed also uses "?" for "Are you sure?" If you're sure, you can type the last command a second time to confirm.

The story goes that ed was designed for running over a slow remote connection where output was printed on paper, and the keyboard required very firm presses to generate a signal. Whether this is true or folklore, it would explain a lot.

GNU Ed actually has optional error messages for humans, because why not.

nine_k · a year ago
There are really few systems where you can save a part of a byte! And if you need to output a byte anyway, it doesn't matter which byte it is. So you can indulge and use "?", "!", "*", or even "&" to signify various types of error conditions.

(On certain architectures, you could use 1-byte soft-interrupt opcodes to call the most used subroutine, but 8080 lacked it IIRC; on 6502 you could theoretically use BRK for that. But likely you had other uses for it than printing error diagnostics.)

cma · a year ago
Earliest I've seen with 'Eh?' as an interpreter response is RAND's JOSS:

https://en.wikipedia.org/wiki/JOSS#/media/File:JOSS_Session....

https://en.wikipedia.org/wiki/JOSS

They had about 5KB of memory but comparing to the Intellivision the machine weighed about 5,000lbs.

zubairq · a year ago
Pretty cool.. I had no idea Hal was such a hacker on the personal computers in those days... makes me think of Bitcoin whenever I hear Hal mentioned
WalterBright · a year ago
He wasn't hacking. Hal worked for Aph, and Aph contracted with Mattel to deliver console game cartridges.

There was once a contest between Caltech and MIT. Each was to write a program to play Gomoku, and they'd play against each other. Hal wrote a Gomoku-playing program in a weekend, and it trashed MIT's program.

It was never dull with Hal around.

furyofantares · a year ago
I run a wordle spinoff, xordle, which involves two wordle puzzles on one board. This means you can guess a word and get all 5 letters green, but it isn't either of the target words. When you do this it just says "Huh?" on the right. People love that bit.
speerer · a year ago
Can confirm. I loved that bit.
dotancohen · a year ago
> People love that bit.

Add another seven Easter eggs, and people could love that byte.

WalterBright · a year ago
I've been sorely tempted to do that with my compiler many times.
dredmorbius · a year ago
ed (the standard editor) optimises that by a further 66.7%.

<https://www.gnu.org/fun/jokes/ed-msg.html>

euroderf · a year ago
Canadians everywhere.
nl · a year ago
It'd be interesting and amusing if he'd made the private key to his part of Bitcoin a variation on that.

RIP.

physicles · a year ago
The root cause here is poorly named settings.

If the original setting had been named something bool-y like `help.autocorrect_enabled`, then the request to accept an int (deciseconds) would've made no sense. Another setting `help.autocorrect_accept_after_dsec` would've been required. And `dsec` is so oddball that anyone who uses it would've had to look up.

I insist on this all the time in code reviews. Variables must have units in their names if there's any ambiguity. For example, `int timeout` becomes `int timeout_msec`.

This is 100x more important when naming settings, because they're part of your public interface and you can't ever change them.

TeMPOraL · a year ago
> I insist on this all the time in code reviews. Variables must have units in their names if there's any ambiguity. For example, `int timeout` becomes `int timeout_msec`.

Same here. I'm still torn when this gets pushed into the type system, but my general rule of thumb in C++ context is:

  void FooBar(std::chrono::milliseconds timeout);
is OK, because that's a function signature and you'll see the type when you're looking at it, but with variables, `timeout` is not OK, as 99% of the time you'll see it used like:

  auto timeout = gl_timeout; // or GetTimeoutFromSomewhere().
  FooBar(timeout);
Common use of `auto` in C++ makes it a PITA to trace down exact type when it matters.

(Yes, I use IDE or a language-server-enabled editor when working with C++, and no, I don't have time to stop every 5 seconds to hover my mouse over random symbols to reveal their types.)

OskarS · a year ago
One of my favorite features of std::chrono (which can be a pain to use, but this part is pretty sweet) is that you don't have to specify the exact time unit, just a generic duration. So, combined with chrono literals, both of these work just like expected:

    std::this_thread::sleep_for(10ms); // sleep for 10 milliseconds
    std::this_thread::sleep_for(1s);   // sleep for one second    
    std::this_thread::sleep_for(50);   // does not work, unit is required by type system
That's such a cool way to do it: instead of forcing you to specify the exact unit in the signature (milliseconds or seconds), you just say that it's a time duration of some kind, and let the user of the API pick the unit. Very neat!

theamk · a year ago
It should not matter though, because std::chrono is not int-convertible - so is it "milliseconds" or "microseconds" or whatever is an minor implementation detail.

You cannot compile FooBar(5000), so there is never confusion in C++ like C has. You have to do explicit "FooBar(std::chrono::milliseconds(500))" or "FooBar(500ms)" if you have literals enabled. And this will handle conversion if needed - you can always do FooBar(500ms) and it will work even if actual type in microseconds.

Similarly, your "auto" example will only compile if gl_timeout is a compatible type, so you don't have to worry about units at all when all your intervals are using std::chrono.

physicles · a year ago
Right, your type system can quickly become unwieldy if you try to create a new type for every slight semantic difference.

I feel like Go strikes a good balance here with the time.Duration type, which I use wherever I can (my _msec example came from C). Go doesn’t allow implicit conversion between types defined with a typedef, so your code ends up being very explicit about what’s going on.

codetrotter · a year ago
> Yes, I use IDE or a language-server-enabled editor when working with C++, and no, I don't have time to stop every 5 seconds to hover my mouse over random symbols to reveal their types.

JetBrains does a great thing where they show types for a lot of things as labels all the time instead of having to hover over all the things.

scott_w · a year ago
Yes and it's made worse by using "deciseconds," a unit of time I've used literally 0 times in my entire life. If you see a message saying "I'll execute in 1ms," you'd look straight to your settings!
bmicraft · a year ago
> Variables must have units in their names if there's any ambiguity

Then you end up with something where you can write "TimoutSec=60" as well as "TimeoutSec=1min" in the case of systemd :)

I'd argue they'd been better of not putting the unit there. But yes, aside from that particular weirdness I fully agree.

physicles · a year ago
> Then you end up with something where you can write "TimoutSec=60" as well as "TimeoutSec=1min" in the case of systemd :)

But that's wrong too! If TimeoutSec is an integer, then don't accept "1min". If it's some sort of duration type, then don't call it TimeoutSec -- call it Timeout, and don't accept the value "60".

yencabulator · a year ago
I do that, but I can't help thinking that it smells like Hungarian notation.

The best alternative I've found is to accept units in the values, "5 seconds" or "5s". Then just "1" is an incorrect value.

physicles · a year ago
That’s not automatically bad. There are two kinds of Hungarian notation: systems Hungarian, which duplicates information that the type system should be tracking; and apps Hungarian, which encodes information you’d express in types if your language’s type system were expressive enough. [1] goes into the difference.

[1] https://www.joelonsoftware.com/2005/05/11/making-wrong-code-...

MrDresden · a year ago
> I insist on this all the time in code reviews. Variables must have units in their names if there's any ambiguity. For example, `int timeout` becomes `int timeout_msec`.

Personally I flag any such use of int in code reviews, and instead recommend using value classes to properly convey the unit (think Second(2) or Millisecond(2000)).

This of course depends on the language, it's capabilities and norms.

kqr · a year ago
I agree. Any time we start annotating type information in the variable name is a missed opportunity to actually use the type system for this.

I suppose this is the "actual" problem with the git setting, in so far as there is an "actual" problem: the variable started out as a boolean, but then quietly turned into a timespan type without triggering warnings on user configs that got reinterpreted as an effect of that.

bambax · a year ago
Yes! As it is, '1' is ambiguous, as it can mean "True" or '1 decisecond', and deciseconds are not a common time division. The units commonly used are either seconds or milliseconds. Using uncommon units should have a very strong justification.
deltaburnt · a year ago
Though, ironically, msec is still ambiguous because that could be milli or micro. It's often milli so I wouldn't fault it, but we use micros just enough at my workplace where the distinction matters. I would usually do timeout_micros or timeout_millis.
seszett · a year ago
We use "ms" because it's the standard SI symbol. Microseconds would be "us" to avoid the µ.

In fact, our French keyboards do have a "µ" key (as far as I remember, it was done so as to be able to easily write all SI prefixes) but using non-ASCII symbols is always a bit risky.

hnuser123456 · a year ago
Shouldn't that be named "usec"? But then again, I can absolutely see someone typing msec to represent microseconds.
3eb7988a1663 · a year ago
ms for microseconds would be a paddlin'. The micro prefix is μ, but a "u" is sufficient for easy of typing on an ascii alphabet.
thousand_nights · a year ago
can also do usec for micro
miohtama · a year ago
It's almost like Git is a version control system built by developers who only knew Perl and C.
jayd16 · a year ago
What would you call the current setting that takes both string enums and deciseconds?
physicles · a year ago
help.autocorrect_enabled_or_accept_after_dsec? A name scary enough to convince anyone who uses it to read the docs.
thedufer · a year ago
> Now, why Junio thought deciseconds was a reasonable unit of time measurement for this is never discussed, so I don't really know why that is.

xmobar uses deciseconds in a similar, albeit more problematic place - to declare how often to refresh each section. Using deciseconds is fantastic if your goal is for example configs to have numbers small enough that they clearly can't be milliseconds, resulting in people making the reasonable assumption that it must thus be seconds, and running their commands 10 times as often as they intended to. I've seen a number of accidental load spikes originating from this issue.

snet0 · a year ago
This seems like really quite bad design.

EDIT: 1) is the result of my misreading of the article, the "previous value" never existed in git.

1) Pushing a change that silently break by reinterpreting a previous configuration value (1=true) as a different value (1=0.100ms confirmation delay) should pretty much always be avoided. Obviously you'd want to clear old values if they existed (maybe this did happen? it's unclear to me), but you also probably want to rename the configuration label..

2) Having `help.autocorrect`'s configuration argument be a time, measured in a non-standard (for most users) unit, is just plainly bad. Give me a boolean to enable, and a decimal to control the confirmation time.

jsnell · a year ago
For point 1, I think you're misunderstanding the timeline. That change happened in 2008, during code review of the initial patch to add that option as a boolean, and before it was ever committed to the main git tree.
iab · a year ago
“Design” to me intimates an intentional broad-context plan. This is no design, but an organic offshoot
snet0 · a year ago
Someone thought of a feature (i.e. configurable autocorrect confirmation delay) and decided the interface should be identical to an existing feature (i.e. whether autocorrect is enabled). In my thinking, that second part is "design" of the interface.
userbinator · a year ago
IMHO this is a great example of "creeping featurism". At best it introduces unnecessary complexity, and at worst those reliant on it will be encouraged to pay less attention to what they're doing.
cedws · a year ago
That's git in a nutshell. An elegant data structure masked by many layers of unnecessary crap that has accumulated over the years.
snowfarthing · a year ago
What I don't get is why anyone would want to allow the automation. Is it really that difficult to use the up-arrow key and correct the mistake? Doing something automatically when it's sort-of correct is a recipe for doing things you didn't intend to do.
dtgriscom · a year ago
Double this. If I don't type the command that I want, I never want my computer guessing and acting on that guess. Favors like that are why I hate Microsoft Word ("Surely you didn't mean XXXX; I'll help you by changing it to YYYY. Oh, you did it again, and in the same place? Well, I'll fix it again for you. High five!")
userbinator · a year ago
Things seem to be going in that direction with LLMs, unfortunately.
zX41ZdbW · a year ago
> Which was what the setting value was changed to in the patch that was eventually accepted. This means that setting help.autocorrect to 1 logically means "wait 100ms (1 decisecond) before continuing".

The mistake was here. Instead of retargeting the existing setting for a different meaning, they should have added a new setting.

    help.autocorrect - enable or disable
    help.autocorrect.milliseconds - how long to wait
There are similar mistakes in other systems, e.g., MySQL has

    innodb_flush_log_at_trx_commit
which can be 0 if disabled, 1 if enabled, and 2 was added as something special.

stouset · a year ago
The “real” issue is an untyped configuration language which tries to guess at what you actually meant by 1. They’re tripling down on this by making 1 a Boolean true but other integers be deciseconds. This is the same questionable logic behind YAML’s infamous “no” == false.
Dylan16807 · a year ago
I'd say the new addition is more of a special case of rounding than it is messing up types.
JBiserkov · a year ago
NO is the country code for Norway.
smaudet · a year ago
Not sure where the best place to mention would be, but 0.1 deciseconds is not unreasonable, either...yes fastest recorded random reaction time maybe 1.5 ds (coincidentally this is the average gamer reaction time), however non-random reaction times can be much faster (e.g. on a beat).

So if you wanted to go that fast, you could, the invokation should have relatively stable speeds (order of some milliseconds...

catlifeonmars · a year ago
I enabled autocorrect (set a 3sec) a year ago and have the following observations about it:

1. it does not distinguish between dangerous and safe actions

2. it pollutes my shell history with mistyped commands

Reading this article gave me just enough of a nudge to just disable it after a year.

layer8 · a year ago
If anything, it’s better to set up aliases for frequent typos. (Still “pollutes” the shell history of course.)
darkwater · a year ago
About 2, well, you are the actual polluter, even if you just scroll back in history andnuse the same last wrong command because it works anyway.
bobbylarrybobby · a year ago
The issue is if you accept the wrong command instead of retyping it correctly, you never get the correctly spelled command into your history — and even worse, you don't get it to be more recent than the mistyped command.
catlifeonmars · a year ago
Well to put it into context, I use fish shell, which will only save commands that have an exit code of 0. By using git autocorrect, I have guaranteed that all git commands have an exit code of 0 :)
Reason077 · a year ago
Deciseconds is such an oddball choice of units. Better to specify the delay in either milliseconds or seconds - either are far more commonly used in computing.
ralgozino · a year ago
I got really confused for a moment, thinking that "deciseconds" was some git-unit meaning "seconds needed to make a decision", like in "decision-seconds" xD

Note: english is not my mother tongue, but I am from the civilised part of the world that uses the metric system FWIW.

legacynl · a year ago
I get where your coming from, although deci is certainly used, it's rare enough to not expect it, especially in the context of git
ssernikk · a year ago
I thought of the same thing!
cobbal · a year ago
It's a decent, if uncommon, unit for human reactions. The difference between 0 and 1 seconds is a noticeably long time to wait for something, but the difference between n and n+1 milliseconds is too fine to be useful.
jonas21 · a year ago
Milliseconds are a commonly-used unit. It doesn't really matter if 1 ms is too fine a granularity -- you'll just have to write "autocorrect = 500" in your config file instead of "autocorrect = 5", but who cares?
bobbylarrybobby · a year ago
But the consumers of the API aren't humans, they're programmers.