HNHacker News
TopNewBestAskShowJobs

Joker_vD

7,550 karma · joined December 26, 2019

submissionscomments
Joker_vD··on USPS now offers official ZIP Code boundary polygons
No, it didn't. I admit I don't know the history of zip codes in the US, but over here the postal codes weren't a thing until the 70s when the OCR devices were introduced: the idea was that you'd write a 6-digit postal code in the weird 9-segment font in the specific place where the machine would be able to scan it, and then sort and route it automatically. Of course quite quickly it turned out that people wrote wrong postal codes, or postal codes needed to be changed, so in the end the post service started filling those themselves, and they later started printing and sticking barcodes with internal routing information onto the letters, and using those.

> Getting a human to sort mail without looking up a big list was pretty useful.

Mail gets sorted several times. At the ingress, there is a rough sorting of "okay, this one leaves the city, this one doesn't" kind, where the former ones are thrown in a large bag and sent upstream, and the latter ones get divided into delivery groups — yes, by a person looking up a list of local addresses. They don't need to have a list for the whole country, only for their city/local district, so it's not that big of a list. And not making this list of internal routing codes public has the benefits that A) that number needn't be double-checked for correctness, saving the labour, B) the list can be changed often to better suit the way the delivery routes are organized, and you don't need to notify the general public about the changes.

I'd be willing to bet $50 that USPS has some internal DB, changed very often, that they use to remap zip codes into something actually useful for both the bulk- and last-mile delivery.

Joker_vD··on USPS now offers official ZIP Code boundary polygons
...Can someone please explain why ZIP codes are even a thing people need to bother about? Like, there's an address on the letter/parcel — that should be enough for the USPS to deliver it, right? If they use some internal classification/address grouping for better routing — fine, whatever, they can use it but surely they themselves can look it up in their internal DB quicker and more reliably than I can on some random web-site of dubious progenity?
Joker_vD··on The first 300-millimeter power silicon carbide (SiC) wafer
...Can't we just go back to thermionic vacuum tubes at this point? Those worked just fine at kilowatt powers and megahertz frequencies.
Joker_vD··on Is Opus 5.5 nerfed? Thinking patterns changed on November 3
> If I order a 16oz beer and get a 12oz pour, I'm going to call it out.

And then Sam Altman is gonna sue your ass for owning a measuring cup.

Joker_vD··on What is malloc doing, anyway?
> and writing a toy allocator especially useful because you learn about the brk() syscall

Nobody in their right mind (except musl) use brk(2) nowadays; mmap(2) is pretty much universally accessible, and brk() has been non-portable for more than 20 years already (POSIX ditched it in 2001) anyhow. For goodness sake, stop keeping this stupid API from VM-lacking PDP-7 alive, and let it go away!

Edit: also, I have no idea how musl even uses it:

    uintptr_t new = ctx.brk + pagesize;
    int need_guard = 0;
    if (!ctx.brk) {
        need_guard = 1;
        ctx.brk = brk(0);
        // some ancient kernels returned _ebss
        // instead of next page as initial brk.
        ctx.brk += -ctx.brk & (pagesize-1);
        new = ctx.brk + 2*pagesize;
    }
    if (brk(new) != new) {
        ctx.brk = -1;
    } else {
        if (need_guard) mmap((void *)ctx.brk, pagesize,
                PROT_NONE, MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0);
        ctx.brk = new;
        ctx.avail_meta_areas = (void *)(new - pagesize);
        ctx.avail_meta_area_count = pagesize>>12;
        need_unprotect = 0;
    }
That's... not what brk() returns; it returns 0 on success and -1 on failure. Huh?
Joker_vD··on Nvidia's China Problem [pdf]
OMFG, it's an open secret that lots of Malaysia-, Indonesia-, and Singapore-registered businesses resell GPUs to China instead of building AI datacenters themselves. And they don't need to sleep with NVIDIA's CEO to do that, you know.
Joker_vD··on What do the next 4000 emoji look like?
> and just displays the individual parts in a sequence and it makes no sense.

IIRC some earlier version of UTC 51 explicitly stated that the implementations of a particular version of Unicode absolutely should not try to show any sequences, not mentioned in the emoji-sequences.txt and emoji-zwj-sequences.txt, as a single glyph and must treat them as distinct graphemes. It apparently has been removed in the recent years so there is apparently now absolutely no guarantee of what visuals and when exactly you can expect.

Joker_vD··on Port 0: The Port That Does Not Exist
And then there is OpenSSH...

    joker@joker:~$ ssh localhost -D 127.0.0.1:0
    Bad dynamic forwarding specification '127.0.0.1:0'
    joker@joker:~$ ssh localhost -D 127.0.0.1:9999
    ssh: connect to host localhost port 22: Connection refused
    joker@joker:~$ ssh localhost -L 127.0.0.1:0:localhost:8080
    Bad local forwarding specification '127.0.0.1:0:localhost:8080'
    joker@joker:~$ ssh localhost -L 127.0.0.1:9999:localhost:8080
    ssh: connect to host localhost port 22: Connection refused
Oh well.
Joker_vD··on Partial Operator Precedence
> The question is whether or not the rules set you up for scenarios where misunderstandings are likely.

No, this is a misleading statement of the problem because it tacitly assumes that programmers write arbitrary expressions with almost the same probability, so the rules should accommodate them all, at the same expense. This is patently false, and is a horrible policy for any UI/UX/DevEx/etc. designer. The very existence of linters and static analyzers, hell, even the warnings in the modern compilers about suspicious operator precedence and "this expression doesn't mean what you probably think it does" — all that suggests that some kinds expressions are more probable than others; ergo, those should be accommodated for at the expense of the unlikelier ones. So, the precedence levels and PEMDAS it is, instead of the abstractly-pure, from-the-first-principles, strictly left-to-right order which makes only its inventor, with a very peculiar kind of mind, happy at the expense of most of the actual programmers and users of the language.

Joker_vD··on Partial Operator Precedence
In that case, I'd rather just have explicit bitfield getter/setter functions à la

    slct(var, 6, 2) = expr;  // var = (var &~ (0b111111 << 2)) | ((expr & 0b111111) << 2);
    var = slct(expr, 6, 2);   // var = (expr >> 2) & 0b111111;
Freaking BCPL had those in 1976, and that language was more primitive than C (it didn't even have any types beyond "machine word, reinterpreted accordingly to the operation applied to it").
Joker_vD··on sshole
Amusingly, Win API of all places generally evades this pattern: 0 timeout means "no waiting", and to wait indefinitely, you use timeout of INFINITE which is actually UINT_MAX or, equivalently, -1 (in Win API, timeouts are unsigned, not time_t).
Joker_vD··on Evergreen: A Provably Safe Systems Language
> I have implemented one such language, and while it is indeed doing fine, the dots-everywhere syntax really does complicate name resolution.

Can you share an example? In my experience, this only happens with serious reuse of names across both types and values, e.g. with something like

    struct a { 
        struct x {
            typedef int y;
            y x;
        };

        struct y {
            typedef double x;
            x y;
        };

        static x y;
        y x;
    };


    a a;
after which the unified syntax "a.x.y" could either mean a typedefed int from struct x, or a double field from struct y... but why would you even want to support such scenarios? C++, for example, prohibits namespaces from sharing the names with types and values in the same scope, and even though it uses "::" for namespace lookups, it still had to introduce "typename" keyword to explicitly disambiguate the type names from values anyhow so...
Joker_vD··on Partial Operator Precedence
> When read procedurally (left to right) it is quite okay though,

Except that there are almost no circumstances in which "((a & b) + c) >> d" is a sensible expression. The only reasonable interpretation is "(a & b) + (c >> d)", and even then that plus is suspicious.

In practice, the worst offenders are "a & b >> c" and "a & b << c". The first expression is usually intended to mean "(a & b) >> c" — it's a bitfield extraction; the second one is usually intended to mean "a & (b << c)" — it's clearing of all but one bitfield. As you can see, those semantics are impossible to achieve with << and >> having the same precedence.

Joker_vD··on AI is forcing us to pay off 40 years of technical debt
Separating the call stack (and probably inventing a very specific "the only valid reads/writes in this area are the ones made by the CALL/RET instructions" permission bit for it) from the data stack would make almost all buffer overflows useless for taking over the control flow: the normal STORE instruction simply can't overwrite the return address, period.

Of course, the interpreters would still be vulnerable, but even for them having separate (and distant) stacks make this particular vulnerability much harder to exploit. And again, a generalized technique having different processor instructions for manipulating differently "painted" memory regions would help there too — at least, it would be there so the implementers of the interpreters could reach for it if they decided to.

In the end, of course, nothing can save you from having a program that insists on literally doing eval(fetch(url=input())), or curl "$(read ; printf "%s" "$REPLY")" | "$SHELL", or something else to this effect.

Joker_vD··on Death Comes for XSLT
> and yet a single newline in a text field will shatter its validity or force you to enter escaping-hell.

So would a single & or > in the body of an XML element, you know.

Joker_vD··on BioWare co-founder: game execs "have never made a game" and don't get it
Hey, everybody (who matters) knows that an MBA can successfully manage any kind of firm; there is no field-specific knowledge required, nosirree.
Joker_vD··on Trigger.dev customer environment variables exposed
> As an eternal reminder of the need to do better?

Eternity is a very, very long time. Longer even than 80 years (arguably the total age of the whole "programmable electronic computing and data storage machines" industry), you know?

So I don't think that having an open issue in a bug tracker forever is even possible; not that it would even serve as a remainder — I assure you, most long-existing firms have "ignore open issues older than X years" filter enabled by default in their Jiras or whatever people use nowadays, those are only ever looked at once year by the upper management when they're out of ideas.

Joker_vD··on Show HN: I've updated my Linux System Call website and API
Uh, sorry, what? Trying to measure similarity between syscalls is a) impossible, b) pointless, so obviously I'd really like to understand why someone would want to do something like this — but I'd rather not speculate about what and why you think and believe, and instead to just straight hear from you.

If you're interested in why I think what I think — there's a sibling comment where I tried to articulate my position. I'd like to hear about yours, if you don't mind.

P.S. You didn't actually offer any argument, logical (?) or technical (?!), in your original comment, and I think you're actually have the meaning of those words reversed: "logical argument" appeals to logical relations between the abstract concepts, while "technical argument" appeals to the underlying technology (the kernel implementation in our case) and tries to deal with particularities of reality. So if anything, my argument was the logical (semantical?) one, not that it really matters.

Joker_vD··on Show HN: I've updated my Linux System Call website and API
I think you're missing the point I'm trying to make. Both pipe2 and openat has about 70% similar functionality (and so do the IORING_OP_PIPE and IORING_OP_OPENAT operations) — really, the only difference is that pipe2 returns two new fds instead of just one, and that the file opened is not a regular file. So, are those 2 syscalls or 1.3? What about triples or quadruples of syscalls with overlapping functionality, do we go full inclusion-exclusion formula on them? What about that 70% similarity estimation — how do establish that? Do you count the similarity/overlap of the underlying implementations? Only of the user-facing functionality? Both, somehow? Something else entirely?

Or, you know, we can instead not engage in this subjective quagmire and look at the actual, factual number that undeniably exists. It may not be very useful for any practical purpose except for pointless dick-measuring between OSes with radically different APIs and internal architectures — but neither is this trying to measure syscall similarity, really.

Joker_vD··on Show HN: I've updated my Linux System Call website and API
Yes, the ioctl has been notorious for sneaking in arbitrary amount of functionality into the kernel space, and serving generally as a kitchen sink: "You can rarely convince Linus to make a new syscall, but making a new ioctl is much easier". That's still one syscall though.

And how do you even compare how the distinct the syscalls are (e.g., pipe() and open() are about 70% similar)? And after that, what do you do with this metrics? How do you sum it up? Again, pipe() and open() are 70% similar — does that mean we have 1.3 syscalls instead of 2?

Joker_vD··on Show HN: I've updated my Linux System Call website and API
Well, there really is about 400 syscall numbers allocated, and each has its own entrypoint in the kernel. That's an entirely objective criterion as opposed to arguing "well, sbrk and mmap (or recv and read) are kinda similar, maybe we should count them as just one syscall instead of two", because in the end we can might as well say "well, technically there is only one syscall, it just has an additional seventh argument that serves as the 'function denominator', like the ioctl's request parameter, you know".
Joker_vD··on Trigger.dev customer environment variables exposed
Why? What purpose would having an eternally open incident serve?
Joker_vD··on So I guess everyone uses LLMs to think now
Two local models I've tried were dead sure that "How Much Is the Fish" was a 1956 song by Dave Brubeck. When asked why they thought so, both just kinda shrugged. At least that was sort of free but seriously — that's the basic knowledge recall scenario, how did it get this garbled? What else gets so horrendously garbled? How can we even know?
Joker_vD··on No AI, 52 min. Build all Linux Files utils in C by Hand [video]
> Why would one would like to truncate an existing file? To overwrite it. It's a very common use case.

Yeah, but we have plain "w" for that already.

> What I have never found any use for personally is opening a file in read-write mode, while also truncating it, which is the full extent of w+ behaviour. I cannot think of many reasons to have an output stream to also function as an input.

Exactly my point. If I am about to fully overwrite the file content, why would I want to re-read them without even an intermediate fclose()? I know that content already, I've just wrote it out! The only fringe use cases I can think of are really the edge cases of some general scenarios that would normally use "r+" (e.g. databases) but could occasionally go "okay, let's drop everything and start ab initio" — but those can just call ftrunc() in those circumstances. Or just open the file twice with different modes, the filesystem being what it is (global shared mutable state), you'll see your changes through.

Joker_vD··on Copper – A minimal low-level programming language with OOP and generics
Surprisingly, the most irritating nitpick for me is the choice of the file extension — surely that should've been ".cu", not ".co"? If I were developing an e.g. Iron programming language (hypothetically — although perhaps so named a language already exists), I'd pick ".fe" in a heartbeat.

Then again, I'm the kind of person who've chosen $'.\U0001F9CC' (that is, $'.\xF0\x9F\xA7\x8C') for a file extension of my own toy language so...

Joker_vD··on No AI, 52 min. Build all Linux Files utils in C by Hand [video]
Such a baffling option, to be fair, I don't think I've ever used it. Like, what's even the point?
Joker_vD··on Avoid Public Functions Calling Other Public Functions
Another reason, which I think I wrote as an answer to the very Stack Overflow question mentioned in TFA, is because of data structure invariants and the function contracts.

    Public methods usually have a contract of "take the object in a consistent state, do
    something sensible, leave the object in a (possibly different) consistent state". Here,
    "consistent" may mean, for example, that the `Length` of a `List<T>` is no greater than
    its `Capacity` and that referencing the elements at indices from 0 to `Length-1` won't
    throw.

    But inside the object's methods, the object may be in an inconsistent state, so when
    you call one of your public methods, it may do a very wrong thing, because it wasn't
    written with such a possibility in mind. So if you plan to call your public methods from
    your other methods, make sure that their contract is "take the object in some state, do
    something sensible, leave the object in a (possibly different) (maybe inconsistent — but
    only if the initial state was inconsistent) state".
Joker_vD··on Iterating Backwards in C
Well, the array indices are allowed to be any sorts of integers, and the standard is worded in such a way that such addition must work correctly without overflowing — provided, of course, that the array you're indexing into is large enough. So in practice, you're bounded by the width of size_t.

Oh, and did you know that the width of ptrdiff_t is not required to have any relation to the width of size_t? There is even an explicit provision in standard for the case when subtracting two pointers into the same very large array can't fit into ptrdiff_t:

    When two pointers are subtracted, both shall point to elements of the same array object, or one past
    the last element of the array object; the result is the difference of the subscripts of the two array
    elements. The size of the result is implementation-defined, and its type (a signed integer type) is
    ptrdiff_t defined in the <stddef.h> header. If the result is not representable in an object of that
    type, the behavior is undefined.
So yeah; you should try to work strictly with indices only, they're guaranteed to be correctly addible to pointers no matter the sizes of your arrays.
Joker_vD··on Iterating Backwards in C
That's the price of innovation, I guess; before C invented its "for"-loop, other languages had their equivalents generally looking like this:

    FOR var = start [DOWN] TO end BY step DO ... END
No custom increment expressions, and "step" even usually was only allowed to be a constant (in which case, the language usually didn't have DOWN specifier and used the step's sign instead). Then Dennis Ritchie invented C, and ditched the traditional "do"-loop (Fortran started that construct with DO, so it was called DO loop; Algol used FOR instead, but most people preferred the Fortran's nomenclature... until C came to dominate, but that wouldn't happen for yet another 20 years) in favour of his invention because he felt that easily iterating through linked lists or strings was a much more pressing concern:

    for(p=head; p; p=p->next) { ... }

    for(s=str; *s; s++) { ... }
The downside, of course, is that now you can't straightforwardly write

   for size_t i = count - 1 downto 0 do
      ...
   end
Joker_vD··on The Exponential Time Hypothesis Is False [pdf]
"I see your particle physics paper (on sustainability of neutron-induced chain fission reaction in uranium), how does this affect the world politics???"

Turns out, it affected the global politics tremendously.

Page 1 of 34Next →