HN user

justin_

564 karma

Yet another software person on HN. I'm from the northeast US, but have been traveling around the world for years.

  https://justinchines.com
  @justinchines
  justin@chines.me
  λ
[ my public key: https://keybase.io/iamjustin; my proof: https://keybase.io/iamjustin/sigs/1tuafAWmDIAw3Da9OLMCVtskR6CRz9NnXiehcUL9sbo ]
Posts16
Comments73
View on HN

But what are the “awful effects” of sending FIN instead? Can someone explain?

The RFC explains.

The other side - the server - will be stuck on `send(sock_fd, more_bytes...)`. If it's the 90s and your FTP server is single-threaded, that means the server will appear completely stuck. This won't resolve for several minutes, or possibly forever if the server-side TCP stack is buggy or lacks timeouts.

The client's connection, even after the process is gone, will still be alive in the kernel. It will be in FIN-WAIT-2, waiting for the server to send its FIN. The remote sender will be stuck waiting for the zero-window state to pass, sending probes to figure out when the receive window opens (which will never happen). Things will be stuck in this state until one of the sides times out, which could be several minutes. Or if the implementations are buggy, it could be permanent.

From RFC 2525, 2.17

      Failure to reset the connection can lead to permanently hung
      connections, in which the remote endpoint takes no further action
      to tear down the connection because it is waiting on the local TCP
      to first take some action.  This is particularly the case if the
      local TCP also allows the advertised window to go to zero, and
      fails to tear down the connection when the remote TCP engages in
      "persist" probes (see example below).

https://datatracker.ietf.org/doc/html/rfc2525#page-50

The program in the boot sector is run similar to other software: the code is loaded into memory, and then the processor is jumped to the first instruction. This loading and jumping is done by the firmware, which is included in your hardware, separate from your disks.

Let's back up to the start. When you switch on a computer, the power rails on a bunch of the chips come up. As this happens, the chips enter a "reset" state with initial data that is baked into the circuitry. This is the power-on reset (PoR) circuitry. When the power is up and stable, the "reset" is over and the processor starts executing. The initial value of program counter / instruction pointer is called the reset vector, and this is where software execution begins. On an x86 PC, this is something like 0xFFFFFFF0. The memory controller on the system is configured for reads from this address to go NOT to the main RAM, but to a flash memory chip on the board that holds the firmware software. From there the firmware will find your bootable disks, load the bootloader, and pass control to it.

In practice, systems vary wildly.

Light is integrated over a finite area to form a singke color sample. During Bayer mosaicking, contributions from neighbouring pixels are integrated to form samples of complementary color channels.

Integrated into a single color sample indeed. After all the integration, mosaicking, and filtering, a single sample is calculated. That’s the pixel. I think that’s where the confusion is coming from. To Smith, the “pixel” is the sample that lives in the computer.

The actual realization of the image sensors and their filters are not encoded in a typical image format, nor used in a typical high level image processing pipelines. For abstract representations of images, the “pixel” abstraction is used.

The initial reply to this chain focused on how camera sensors capture information about light, and yes, those sensors take up space and operate over time. But the pixel, the piece of data in the computer, is just a point among many.

Usually people choose nearest neighbor in scenarios like that to be faithful to the original

Perhaps I should have chosen a higher resolution. AIUI, in many modern systems, such as your OS, it’s usually bilinear or Lanczos resampling.

You say that the resize should be faithful to the “100x100 display”, but we don’t know whether it was used from such a display, or coming from a camera, or generated by software.

I'm almost certain this process didn't preserve sharp pixels

Sure, but modern image processing pipelines work the same way. They are working to capture the original signal, with a hopeful representation of the continuous signal, not just a grid of squares.

I suppose this is different for a “pixel art” situation, where resampling has to be explicitly set to nearest neighbor. Even so, images like that have problems in modern video codecs, which model samples of a continuous signal.

And yes, I am aware that the “pixel” in “pixel art” means a little square :). The terminology being overloaded is what makes these discussions so confusing.

The camera integrates incoming light into a tiny square [...] giving a brightness (and with the Bayer filter in front of the sensor, a color) for the pixel

This is where I was trying to go. The pixel, the result at the end of all that, is the single value (which may be a color with multiple components, sure). The physical reality of the sensor having an area and generating a charge is not relevant to the signal processing that happens after that. For Smith, he's saying that this sample is best understood as a point, rather than a rectangle. This makes more sense for Smith, who was working in image processing within software, unrelated to displays and sensors.

Audio samples are point samples (usually). This is nice, because there's a whole theory on how to upsample point samples without loss of information.

This signal processing applies to images as well. Resampling is used very often for upscaling, for example. Here's an example: https://en.wikipedia.org/wiki/Lanczos_resampling

It was already wrong in 1995 when monitors where CRTs, and it's way wrong in 2025 in the LCD/OLED era where pixels are truly discrete.

I don't think it has anything to do with display technologies though. Imagine this: there is a computer that is dedicated to image processing. It has no display, no CRT, no LCD, nothing. The computer is running a service that is resizing images from 100x100 pixels to 200x200 pixels. Would the programmer of this server be better off thinking in terms of samples or rectangular subdivisions of a display?

Alvy Ray Smith, the author of this paper, was coming from the background of developing Renderman for Pixar. In that case, there were render farms doing all sorts of graphics processing before the final image was displayed anywhere.

A camera does not take point sample snapshots, it integrates lightfall over little rectangular areas.

Integrates this information into what? :)

A modern display does not reconstruct an image the way a DAC reconstructs sounds

Sure, but some software may apply resampling over the original signal for the purposes of upscaling, for example. "Pixels as samples" makes more sense in that context.

It is pretty reasonable in the modern day to say that an idealized pixel is a little square.

I do agree with this actually. A "pixel" in popular terminology is a rectangular subdivision of an image, leading us right back to TFA. The term "pixel art" makes sense with this definition.

Perhaps we need better names for these things. Is the "pixel" the name for the sample, or is it the name of the square-ish thing that you reconstruct from image data when you're ready to send to a display?

A Pixel Is Not A Little Square!

This is an issue that strikes right at the root of correct image (sprite) computing and the ability to correctly integrate (converge) the discrete and the continuous. The little square model is simply incorrect. It harms. It gets in the way. If you find yourself thinking that a pixel is a little square, please read this paper.

A pixel is a point sample. It exists only at a point. For a color picture, a pixel might actually contain three samples, one for each primary color contributing to the picture at the sampling point. We can still think of this as a point sample of a color. But we cannot think of a pixel as a square—or anything other than a point.

Alvy Ray Smith, 1995 http://alvyray.com/Memos/CG/Microsoft/6_pixel.pdf

I believe it is a bug in the the emulator's implementation of COMMAND.COM. Often, these DOS "emulators" re-implement the standard commands of DOS, including the shell[1]. This is in addition to emulating weird 16-bit environment stuff and the BIOS.

The bug can pop up in any C program using stdio that assumes it's fine to do `fread` followed immediately by `fwrite`. The spec forbids this. To make matters more confusing, this behavior does _not_ seem to be in modern libc implementations. Or at least, it works on my machine. I bet modern implementations are able to be more sane about managing different buffers for reading and writing.

The original COMMAND.COM from MS-DOS probably did not have this problem, since at least in some versions it was written in assembly[2]. Even for a shell written in C, the fix is pretty easy: seek the file before switching between reading/writing.

The title of this post is confusing, since it clearly _is_ a bug somewhere. But I think the author was excited about possibly finding a bug in libc:

Sitting down with a debugger, I could just see how the C run-time library (Open Watcom) could be fixed to avoid this problem.

[1] Here's DOSBox, for example: https://github.com/dosbox-staging/dosbox-staging/blob/main/s...

[2] MS-DOS 4.0: https://github.com/microsoft/MS-DOS/tree/main/v4.0/src/CMD/C...

UNIX time counts the number of seconds since an ``epoch.'' This is very convenient for programs that work with time intervals: the difference between two UNIX time values is a real-time difference measured in seconds, within the accuracy of the local clock. Thousands of programmers rely on this fact.

Contrary to this, since at least 2008[0], the POSIX standard (which is just paper not necessarily how real systems worked at that time) has said that "every day shall be accounted for by exactly 86400 seconds." That means that in modern systems using NTP, your Unix timestamps will be off from the expected number of TAI seconds. And yes, it means that a Unix timestamp _can repeat_ on a leap second day.

There's really no perfect way of doing things though. Should Unix time - an integer - represent the number of physical seconds since some epoch moment, or a packed encoding of a "date time" that can be quickly mapped to a calendar day? "The answer is obvious" say both sides simultaneously :^)

EDIT: I know DJB is calling out POSIX's choices in this article, but it seems like his "definition" does diverge from what the count actually meant to a lot of people.

[0] Also: "The relationship between the actual time of day and the current value for seconds since the Epoch is unspecified." https://pubs.opengroup.org/onlinepubs/9699919799.2008edition...

Linus himself has credited Monotone with the content-addressing by SHA1: https://marc.info/?l=git&m=114685143200012

I think the main issue with Monotone was the performance. Linus also hates databases and C++.

--

Hoare didn't come up with this idea either, but he did apply it to version control. He had potentially been influenced by his earlier work on distributed file systems and object systems. Here's his 1999 project making use of hashes: https://web.archive.org/web/20010420023937/venge.net/graydon...

He was in contact with Ian Clarke of Freenet fame (also 1999). There seems to have been a rise in distributed and encrypted communications around the time, as kragen mentions in his other post.

BitTorrent would also come to use hashes for identifying torrents in a tracker, and would come out in 2001, created by Bram Cohen, the author of the post here :)

This isn’t about signing the OS updates. This is about the device contacting Apple’s activation servers during initial setup.

In the linked thread, the users have a “working” device with software already installed, but the activation fails with a cryptic “Activation Error” without any reference to the fact that they must update.

Typically, Apple continues to allow activation on older OSes, as long as they were installed previously. I’ve intentionally kept some devices on older versions, and personally have never had a problem activating after a reset. But I suppose that’s only possible because Apple allowed it.

EDIT: I was wrong about the "Activation Error" not mentioning a software upgrade. It does mention it. But my point about Apple controlling access to the software still stands. It's something weird that Apple did specifically for iOS 9 and the iPhone 6s. Naturally, who really cares about one random version combination? I don't in this particular case, but the fact that Apple can control it is weird to me.

Even more concerning is that some users report that the device locked them out _even during normal use of the phone_: https://www.reddit.com/r/iphone/comments/acmytg/iphone_6s_pl...

Activation Lock is a weird feature. Users love it when it helps prevent device theft. But really, at the end of the day, you're giving up control of the device to Apple.

Apple has already stopped supporting activation of certain versions of iOS[0]. Also, just as a user can request locking down a phone at any time, Apple could technically lock down your device when they see fit. They're not going to do that, but the fact that it's possible is a bit freaky.

Someday, far in the future, their activation servers will go down, and no unactivated Apple device will be usable. Already, it is not possible to set up a new device without an Internet connection. Hopefully the jailbreak community figures something out by then, or maybe Apple would release a tool...

[0] https://forums.macrumors.com/threads/apple-no-longer-activat...

AIUI, another big problem with the 80286 was that it did not support returning to real mode after switching to protected mode. This made compatibility a huge issue, which was a big problem for Microsoft. The 80836, besides marking a switch to 32-bit, added virtual 8086 mode, which allowed for emulating real mode after already having switched to protected mode.

https://web.archive.org/web/20021003235610/http://osdev.berl...

This "virtual 8086" mode is what was used for the VMM kernel of Windows 9x, and later the NTVDM system on 32-bit versions of Windows NT. I remember being able to run some DOS software on Windows XP (but it wasn't perfect).

I was referring to the fact that interaction with the disk itself is asynchronous. Indeed, the interface provided by a kernel for files is synchronous, and for most cases, that's what programmers probably want.

But I also think the interest in things like io_uring in Linux reflect that people are open to asynchronous file IO, since the kernel is doing asynchronous work internally. To be honest, I don't know much about io_uring though - I haven't used it for anything serious.

There's no perfect choice (as always) -- After all, for extremely high-performance scenarios, people avoid the async nature of IO entirely, and dedicate a thread to busy-looping and polling for readiness. That's what DPDK does for networking. And I think for io_uring and other Linux disk interfaces have options to use polling internally.

Asynchronous programming is a great fit for IO-driven programs, because modern IO is inherently asynchronous. This is clearly true for networking, but even for disk IO, generally commands are sent to the disks and results come back later. Another thing that’s asynchronous is user input, and that’s why JS has it.

As for threading vs. explicit yielding (e.g. coroutines), I’d say it’s a matter of taste. I generally prefer to see where code is going to yield. Something like gevent can make control flow confusing, since it’s unclear what will yield, and you need to implement explicit yielding for CPU-bound tasks anyway. Its green threads are based on greenlet, which are cooperative coroutines.

Cooperative multitasking was a big problem in operating systems, where you can’t tell whether other processes are looking for CPU time or not. But within your own code, you can control it however you want!

This is the kind of debate that has been going on surrounding virtual memory forever[0][1]. If you can keep everything in memory, then you're golden. But eventually you won't, and you'll need to rely on secondary storage.

Is there a performance benefit to be had by managing the memory and paging yourself? Yes. But eventually you will also consider running processes next to your database, for logging, auditing, ingesting data, running backups, etc. Virtual memory across the whole system helps with that, especially if other people will be using your database in ways you can't predict. As for the efficiency of MMUs and the OS, seems like for almost all cases it's "satisfactory" enough[1].

[0] http://denninginstitute.com/pjd/PUBS/bvm.pdf

[1] From 1969! https://dl.acm.org/doi/pdf/10.1145/363626.363629

This is an excellent explanation. If we imagine the triangle being swept about in a circle, the points in the "outer" section (forming the circle at edge of the base our our cone) will cover more distance the points in the "inner" section (the points near the center line of our cone that we're revolving around). The distance moved by the centroid, then, is the average distance a point travels.

If you're looking for where the 1/3 "comes from", I think using Pappus' second theorem[0] is the way to go. The theorem states that the volume of a solid of revolution formed by a revolving shape is the area of the original shape multiplied by the distance traveled by its _centroid_. The centroid of a triangle is determined based on distances from the three sides, and this is where thirds come from. For example, the centroid of a a right triangle with points (0,0), (0,1), and (1,0) sits at (0.33(3), 0.33(3)). That's a third!

The OP alludes to this with the mention of a solid of revolution in the post. And someone mentions Pappus in the thread there. How did Pappus figure out the centroid was distance to consider? I think that's another mystery, since the proofs of the theorem seem to depend on calculus, which brings us back to the original question.

Anyway, I was looking into the exact question of the OP a few months and this was the most satisfying answer I could find for where the 1/3 comes from geometrically.

[0] https://en.wikipedia.org/wiki/Pappus%27s_centroid_theorem#Th...

He probably means the algebraic structure of a field. "A field is a set on which addition, subtraction, multiplication, and division are defined and behave as the corresponding operations on rational and real numbers do."[0]

You might be tempted to think of complex numbers as "just" being 2-dimensional real vectors (x, y). Looks pretty similar to how you can plot a complex number a + ib at point (a, b) on a 2D plane. But importantly, division is defined on a field, which is not necessarily true for vectors. For any complex number (except 0), you can find another complex number that multiplies with it to give 1, the multiplicative identity.

You _can_ think of complex numbers as being "made of" real numbers though. a and b above are just real numbers. Complex numbers are the two-dimensional normed division algebra over the reals[1].

[0] https://en.wikipedia.org/wiki/Field_(mathematics) [1] https://ncatlab.org/nlab/show/normed+division+algebra

Dreyfus, the author here, is a pretty infamous critic of computers, writing books on their limitations.

His writings here on "Heideggarian AI" call for making AI more contextual and embedded into the world. That is, AI should "be" in the world, instead of just executing a function. I've seen some comments on HN lately talking about making embodied AIs and having them function as self-directed agents, and it reminded me of this paper.

I definitely saw a chat history that wasn't one I started. It was a single question and response in Japanese (which I don't know). The title in the sidebar seemed to match the conversation.

Edit: I'm getting upvoted, so I want to clarify that I don't have proof, but this did happen, only for a single chat. I dumped all the text into Google Translate (don't judge me - you'd do the same!) and it was a boring scientific question. I was amazed that it happened at all and felt pretty gross about it. Like most other people, I also saw a lot more chats in the sidebar that I couldn't open.

Weirdly, I was just thinking about this earlier today. Years ago, Wine developers basically refused to add Wayland support. They told the Wayland devs that they'd stick with X11 and XWayland. Why? Because X11 and Win32 specify position windows in absolute screen coordinates, whereas Wayland positions windows relative to their parents. This broke some assumptions across the Wine project about positioning windows, and it didn't seem worth it to fix[0][1]. (And there may have been other issues. I'm not an expert).

Even when the driver was being developed around 2021, it seems like the Wine developers only begrudgingly accepted it[2].

Exciting to see this finally hitting upstream. Progress in desktop Linux often seems slow, but things are moving forward.

[0] https://bugs.winehq.org/show_bug.cgi?id=42284#c1

[1] https://news.ycombinator.com/item?id=19127952

[2] https://www.phoronix.com/news/Wine-Julliard-Wayland-2021

I just want to say thank you for creating emuparadise. As a kid (~2005) searching for ROMs online, I remember finding a ton of ad-ridden fake sites, endless demands for "voting" on link aggregator sites, and malware downloads. Emuparadise was like a breath of fresh air compared to those sites, and it basically instantly became my favorite ROM site. While not perfect, it actually had all the games I was looking for, and the community actually seemed to care. I was able to play so many classic games that way that I otherwise never would have had access to. (Including Chrono Trigger :)

Emuparadise is also the site that introduced me to BitTorrent, and my very first torrent was downloaded from there. That would get me interested in file sharing. In some way, it's partly responsible for why I'm interested in archiving and links like the OP. I'm sure I'm not the only one.

So, thank you for creating such a wonderful library and community back then! It was a great part of my childhood and adolescence, and it showed me how important preservation and sharing can be.

I think it might be this one:

Adaptive flight control with living neuronal networks on microelectrode arrays

The brain is perhaps one of the most robust and fault tolerant computational devices in existence and yet little is known about its mechanisms. Microelectrode arrays have recently been developed in which the computational properties of networks of living neurons can be studied in detail. In this paper we report work investigating the ability of living neurons to act as a set of neuronal weights which were used to control the flight of a simulated aircraft. These weights were manipulated via high frequency stimulation inputs to produce a system in which a living neuronal network would "learn" to control an aircraft for straight and level flight.

https://ieeexplore.ieee.org/document/1556108

https://sci-hub.ru/https://doi.org/10.1109/IJCNN.2005.155610...