HNHacker News
TopNewBestAskShowJobs

charles-salvia

618 karma · joined December 29, 2016

I develop software that works sometimes.
submissionscomments
charles-salvia··on Whatever became of the summer of love?
If we were to somehow perform a Principal Component Analysis on the amorphous, contradictory mess of "hippie ideals", we could probably distill them down to something like a call to implement a post-scarcity, socialistic society with few restrictions on human social behavior.

Of course, that kind of radical change isn't achieved by smoking pot and playing the guitar in downtown San Francisco. It's achieved by major technological changes that would make such a society even functionally possible, like practically-unlimited renewable energy sources. Needless to say, nobody involved in the 1960s counter-culture movements was in any position to actually implement the kind of changes needed to realize the grand vision of an ideal hippie society. (Some of them tried to do the next best thing, and form their own mini-societies in communes out in the country, all of which ultimately turned out to suck.)

I would also note that another 1960s icon, Gene Rodenberry, at least seemed to realize that the kind of changes needed to implement a hippie utopia would likely only be possible after many other practical societal problems were solved via technology.

charles-salvia··on Concentration camps reveal the nature of the modern state
>> What concentration camps reveal is that modern people are squeamish about killing.

Well, there's a difference between exterminating a foreign and/or conquered city-state, and isolating/quarantining undesirable sub-groups from within a larger civilization (often for reasons that are more ideological than political). What the Mongols, Romans, Assyrians, etc., did was less like isolating an ethnic sub-group and more like inflicting punishment upon a city-state for not paying tribute. (Also, I think the Assyrians would also export the population of a city-state and resettle them elsewhere, to remove their national identity, just as often as they would kill and/or skin-alive everyone in a targeted city-state.)

It's probably worth noting that what happened recently to the Yazidis in North Iraq was closer to what used to happen in antiquity.

charles-salvia··on The Horror in the Standard Library
I'm a bit confused here.

>> Most operators in C++, including its memory allocation and deletion operators, can be overloaded. Indeed this one was.

Okay, well, firstly - the issue here seems to be a problem with the implementation of std::allocator, rather than anything to do with overloading global operator new or delete. Specifically, it sounds like the blog author is talking about one of the GNU libstdc++ extension allocators, like "mt_allocator", which uses thread-local power-of-2 memory pools.[1] These extension allocators are basically drop-in extension implementations of plain std::allocator, and should only really effect the allocation behavior for the STL containers that take Allocator template parameters.

Essentially, libstdc++ tries to provide some flexibility in terms of setting up an allocation strategy for use with STL containers.[2] Basically, in the actual implementation, std::allocator inherits from allocator_base, (a non-standard GNU base class), which can be configured during compilation of libstdc++ to alias one of the extension allocators (like the "mt_allocator" pool allocator, which does not explicitly release memory to the OS, but rather keeps it in a user-space pool until program exit).

However, according to the GNU docs, the default implementation of std::allocator used by libstdc++ is new_allocator [3] - a simple class that the GNU libstdc++ implementation uses to wrap raw calls to global operator new and delete (presumably with no memory pooling.) This allocator is of course often slower than a memory pool, but obviously more predictable in terms of releasing memory back to the OS.

Note also that "mt_allocator" will check if the environment variable GLIBCXX_FORCE_NEW (not GLIBCPP_FORCE_NEW as the author mentions) is set, and if it is, bypass the memory pool and directly use raw ::operator new.

So, it looks like the blog author somehow was getting mt_allocator (or some other multi-threaded pool allocator) as the implementation used by std::allocator, rather than plain old new_allocator. This could have happened if libstdc++ was compiled with the --enable-libstdcxx-allocator=mt flag.

However, apart from explicitly using the mt_allocator as the Allocator parameter with an STL container, or compiling libstdc++ to use it by default, I'm not sure how the blog author is getting a multi-threaded pool allocator implementation of std::allocator by default.

[1] https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/ma...

[2] https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/ma...

[3] https://gcc.gnu.org/onlinedocs/gcc-4.9.4/libstdc++/manual/ma...

charles-salvia··on The Horror in the Standard Library
The C++ delete[] operator doesn't take a size parameter either. This is neither here nor there, and unrelated to the problem the blog post is talking about.
charles-salvia··on SQL is 43 years old – Here’s why we still use it today
The main reason is the object-relational impedance mismatch[1]. Basically, programmers like working with objects that have data fields. This is because most modern, widely-used programming languages treat objects/aggregates with data fields as a first class concept. But SQL isn't designed around objects with fields, it's designed around tables, rows, and result sets from queries. Therefore, working with SQL in most modern programming languages generally requires layers of annoying result-set->object or object->row plumbing/conversion code. (Not to mention the vagaries of type conversions.) Of course, these days, this problem can be substantially mitigated to a certain extent by clever ORMs, but an ORM is generally a leaky abstraction at best. Obviously, whether or not any of this bothers you will depend on your use cases and a lot of other factors.

[1] https://en.wikipedia.org/wiki/Object-relational_impedance_mi...

charles-salvia··on Our Machines Now Have Knowledge We’ll Never Understand
>> Our brains are fallible, and so only approximately equivalent to Turing machines; and even ignoring that can only compute every computable thing given both infinite error-free storage capacity (which they don't have internally or externally) and sufficient time to execute the necessary steps of the computation.

So are actual computers. They're just "less fallible" and closer to a Universal Turing Machine than human brains in certain ways. A Commodore 64 is also incapable, in practice, of computing certain computable functions, due to memory limitations and what have you, but nobody would really claim a Commodore 64 is not Turing complete.

charles-salvia··on Asynchronous Programming in Python: Asyncio
The practical difference is that with async I/O, there's less overhead because you don't need a separate thread for each blocking I/O operation. It's the difference between using a single-threaded event loop to demultiplex between 10,000 sockets, and using 10,000 threads to read one socket each. The former strategy has way less overhead.

Of course, many high-performance, I/O intensive applications like web-servers can effectively make use of a combination of multiple threads and I/O demultiplexing as well.

charles-salvia··on Programming as a Way of Thinking
k, along with j, is also often an index.

Of course, this mathematical convention carried over into programming as well, with i,j, and k serving as index variables.

charles-salvia··on A Closer Look at North Korea’s Ullim Tablet
> It's odd how this is portrayed as a negative aspect of Japan's militarism, when the Allies were fighting the same war with the same attitude.

That's not the point, obviously. The point is Japan's militarism combined with their utter over-the-top brutality and expansionist agenda.

charles-salvia··on The problem with superlatives in the history of science
The "lone genius" is somewhat of a myth, but also has a certain amount of truth to it. For example, Einstein was certainly a lot smarter than the average person - indeed, probably a lot smarter than most highly-accomplished scientists and engineers. However, he also was at the right place at the right time, and would never have come up with General Relativity had it not been for the work of his predecessors, such as, e.g., Riemann, who enabled Einstein to think of space-time in non-Euclidean terms, etc.

I think the biggest problem with the "lone genius" mentality is that it encourages the popular notion that "if it wasn't for Einstein, we'd never have General Relativity." But of course, this is most certainly false. If Einstein never existed, someone else would have eventually noticed problems with Newtonian mechanics over large distances, and ultimately applied Reimannian geometry to spacetime as a solution. It may have happened years or decades later, but overall scientific progress is very rarely strictly dependent on one individual.

charles-salvia··on Just Say No
Ethics aside, at a certain point, you realize you can make a lot more money legally and legitimately using your technical skills than through any sort of "clever" technical scheme that involves hacking odometers or scamming people in some way.
charles-salvia··on New Bridges Rise in New York
Okay, well - never knew this. But that example seems really cherry-picked. Many NY street names are just numbers, even in other boroughs outside Manhattan. Many streets in the Bronx are just a number (130-something street to 230-something street, carrying over from upper Manhattan).
charles-salvia··on New Bridges Rise in New York
I've lived in NY my whole life, but am not familiar with this stereotype about unpronounceable names. Apart from Kosciuszko there aren't too many difficult to pronounce names of bridges/tunnels/express-ways, etc. Kosciuszko is a Polish name - the bridge is named after a Revolutionary War general, not a local New York politician. Most other bridges/tunnels/express-ways are named after famous American politicians (Washington/Lincoln/RFK), or are just named obvious descriptive things like "Brooklyn-Queens Expressway". Every now and then some bridge gets renamed (Triboro -> RFK), but nobody cares. AFAIK the only bridge named after a local New York politician is the "Ed Koch" bridge, but nobody calls it that anyway.
charles-salvia··on Linux Programming: Signals the easy way
Basically, the main problem with signalfd is a problem with the Linux implementation of signals in general: if your program requires some kind of logic where each individual signal delivery somehow "counts" in some way, you may run into a problem because the kernel may coalesce/collapse multiple identical signals delivered consecutively into a single signal delivery. So if your program has some kind of logic that relies on responding to each individual signal, you may have a problem. (Note that this problem does not apply to POSIX real time signals.)

But as far as I know, the only reason you'd ever care to actually count individual signal delivery events is with SIGCHLD. So when waiting for SIGCHLD, using signalfd is not sufficient. You'd need to also use one of the wait/waitid/waitpid variants to ensure that you can respond appropriately to each individual SIGCHLD delivered.

charles-salvia··on Evidence-based advice we've found on how to be successful in a job
People talk about Marx as if he wrote some kind of blueprint for a Communist state. But he really didn't. He was basically writing a philosophy of history centering around a problem he observed - he wasn't necessarily writing about ideas for implementing particular solutions beyond vague notions that a Socialist revolution and subsequent Communist society is ultimately inevitable due to built-in flaws of any Capitalist system. The TLDR version of Marx is:

"All of human history is based around class struggles punctuated by revolutions, and in modern times this continues with those who own the means of production (Capitalists) having all the power over the common workers (employees). But don't worry because Capitalism is a self-destructive system, and soon there will be a socialist revolution, which will ultimately evolve into a Communist state, and then everything will be cool."

The only real implementation details he talks about have to do with some kind of transitional "pre-Communist" society, where he talks about nationalization of banks and railroads and other things.

I think Marx is better read as a philosophy of human history rather than as a blueprint for creating a Communist society.

The reality is Marx is right in the sense that the "ownership class" (those who own the means of production) continue to accumulate wealth and project disproportionate power because they own large amounts of corporate stock and by extension have control over the physical (or digital) means to keep making money. However, in the Western World, no revolution was forthcoming due to (I conjecture) rising standards of living and a consumer-oriented society, along with a blurring of the lines between the "ownership" class and everyone else (via things like stock options, entrepreneurship, Unions, employee rights, etc.), which certainly diluted Marx's eternal class-struggle narrative. Still, at the end of the day, we find ourselves in a Capitalist world where the majority of wealth is concentrated in < 0.0001% of the overall population, which seems to be an undesirable situation.

charles-salvia··on Thunder Run to Seoul: Assessing North Korea’s War Plan
Obviously the DRPK stands no chance of tactical victory in any sense. But they have a very good chance of just saying "fuck it", and causing arbitrary damage and mass civilian casualties on the order of dozens of September 11 attacks. It's basically the nation-state scale equivalent of the fact that a single lone shooter can hurt a lot of people before the police take him out.
charles-salvia··on Thunder Run to Seoul: Assessing North Korea’s War Plan
That's a subjective value call. It depends on how many North Koreans are being brutalized/dying right now. We don't have that number, but it's likely that tens of thousands of the hundreds of thousands of political prisoners will die of starvation or execution within a few years. So unspeakable carnage is already the default state, and we already have a situation here that is comparable to Khmer Rouge or Stalinist Russia levels of human-rights violations.

Regardless, the colonial past of Western powers is not relevant here. I am not suggesting a policy of Imperialism. I am just pointing out that North Korea's very existence comes with a serious cost in human life. This might be something we should at least factor in when weighing the heavy costs of destroying the Kim regime.

charles-salvia··on Thunder Run to Seoul: Assessing North Korea’s War Plan
The assessment predicts: "Tens or hundreds of thousands could become casualties" ... in the event of an all-out DRPK/(US+ROK) conflict.

One factor to consider here is what happens if no conflict occurs? In that case, there are ... still likely tens of thousands of civilian deaths happening as the status quo in North Korean labor camps[1]. Allowing the regime to continue to exist also has a major cost in human lives. I'm not saying war is clearly a superior option - I'm saying this whole situation is mostly losses.

[1] https://en.wikipedia.org/wiki/Prisons_in_North_Korea

charles-salvia··on Software Developers after 40, 50 and 60 Who're Still Coding
Doctors rely on software a lot to do their job. One day they may even be replaced by software.
charles-salvia··on Universities finally realize that Java is a bad intro programming language
I agree - I think for the most part, Java is a simple language that has straightforward C-like syntax. The main problem is specifically the boiler plate class and static main method you need to blurt out just to get anything even compiling. (Also the inevitable CLASSPATH errors that are an initiation rite for using Java).

This is a direct result of the design decision to enforce an OO class structure on all Java programs. You literally can't write any code that isn't somehow part of a "class" (an OO concept that, as an intro CS student, you haven't even learned yet).

charles-salvia··on Universities finally realize that Java is a bad intro programming language
ECMAScript is a general purpose programming language that, historically, just happened to be made specifically for the purpose of standardizing a language made specifically with a web-browser (Netscape) in mind.
charles-salvia··on United isn't entirely to blame for David Dao's controversial removal from flight
Some upper-scale restaurants charge you a "no-show" fee, using the credit card used for the reservation. Maybe airlines could do this? (Of course, the difference is that restaurants don't receive the actual payment for services with no-shows.)
charles-salvia··on United isn't entirely to blame for David Dao's controversial removal from flight
Good article. But I have to ask for clarification for this statement:

"Empty seats cost the airlines money, and they need to recoup those losses somehow."

What does this mean? The issue here is overbooked seats. If a seat is physically empty during the flight because the passenger just doesn't show up, the airline doesn't lose any money - the ticket/seat is still (pre)paid for. Overbooking is simply a way for the airlines to make extra money on top of what they would normally make, gambling on some percentage of customers not showing up for the flight.

So, is the airline industry operating on such a slim margin that giving up the practice of overbooking would force airlines to take noticeably drastic cost-cutting measures?

charles-salvia··on Why MIT Switched from Scheme to Python (2009)
Of course C doesn't map to all that. Neither do most of the MIPS emulators they actually use to teach MIPS assembly in universities. But it does map pretty well to basic loops/conditionals and other intro-to-programming stuff.

I mean, just write a simple C program that reads in argv[1] and then loops from 1 to atoi(argv[1]) doing fizzbuzz. Then compile the program (without optimization) and look at the generated assembly. I just did that on an x86_64 using gcc, and the generated assembly is pretty straightforward and maps pretty well to the actual C code.

The only part that doesn't neatly map to the C code is the boilerplate call-stack stuff, (subq instructions on the rsp register, etc.). But everything else maps rather neatly. The library calls to printf, etc. are mapped to a simple call instruction. It demonstrates how closely C code maps to the actual assembly for these sort of simple programs, which is what actually matters in a pedagogical environment.

This compared to similar Python code, where the actual op codes being executed would be vastly more complicated and less obviously related to the actual "business logic" of the program - you'd have constant incref/decref'ing of objects (assuming CPython), byte code execution in the main ceval loop, hash table lookups for globals, etc. etc. The point is C code maps much better to what the hardware is actually doing. Your arguments to the contrary (talking about vectorized instructions and GPU) are really just being nitpicky. That stuff can be covered later in more advanced courses.

charles-salvia··on Metaprogramming is less fun in D
Yeah, automatic static reflection for serialization of standard-layout structs in C++ would certainly be nice. You can achieve something like that with std::tuple, but it's certainly not comparable to first-class serialization.

PS, I used to enjoy your posts on SDN, before the site owner threw a fit. :-)

charles-salvia··on AmigaOne X5000 – first impression
As a child, I remember walking into a "World Computers" retail store and seeing a Commodore Amiga running some graphics demo. I was utterly blown away. It was far beyond what I had ever seen with a home computer, which at that point, was limited to a Macintosh SE and an 80286 PC running DOS 6.
charles-salvia··on Metaprogramming is less fun in D
While I kind of like D, it's hard to really make the case for using it. The thing is, it simply doesn't provide that much of a significant advantage over modern C++14/17 to make it worthwhile. At least Rust introduces an entirely innovative new concept with the borrow checker. D is just basically C++ with optional garbage collection and better syntax for meta programming, but without the vast Universe of existing C++ libraries to leverage.
charles-salvia··on Why MIT Switched from Scheme to Python (2009)
I know - I'm being facetious, but really, if you want to really understand how most modern computers actually work, there's probably no better way than to learn C. It's high level enough and provides enough structure so that you don't need to actually blurt out a bunch of assembly instructions, but low-level enough so that your code mostly more or less corresponds to what the underlying Von Neumann hardware is actually doing.
charles-salvia··on Why MIT Switched from Scheme to Python (2009)
Functional programming is an attempt to pretend that Von Neumann machines are abstract, mystical mathematical engines, rather than a bunch of registers that read in values from an electronic grid, mutate them, and write out new values back to the grid.
charles-salvia··on 'Fight Inequality' Is a Poor Rallying Cry
After running a mental Principal Components Analysis over the whole liberal/conservative ideological spectrum, I'm increasingly inclined to reduce the entire divide between conservatives and liberals to whether any given individual is more irritated by the prospect of (A) poor people being lazy and abusing handouts or (B) rich people abusing poor people.
Page 1 of 5Next →