HN user

giomasce

1,209 karma

Mathematician, computer scientist, programmer. Currently Wine hacker @CodeWeavers and developer @Debian.

Posts10
Comments412
View on HN

What Every Programmer Should Know About Enumerative Combinatorics -> Nothing.

It can be interesting to know something (or even a lot) about enumerative combinatorics, and certainly there are some specific programming contexts in which that's a hard prerequisite, but it's not a topic that necessarily concerns every programmer.

OTOH I think it would greatly help programmers, especially beginners, to have fewer click baity titles around.

Yeah, that's the theory, and by any mean we definitely need to pursue that as well. I wish we had the luxury of making it work on its own. But since we do not, we need to pull all the levers we have, not just one.

Expecting each individual person to be their own EPA and research how every single item they consume is produced idiotic and doomed to failure.

That's a false dichotomy. There are many middle grounds between researching every single item you buy and dropping the problem as a whole. You can focus on items which are most likely to bring negative impact, you can draw information from journalistic reports and material produced from dedicated associations. There are many ways to be sensitive to economic externalities of the things you buy without getting insane and without considering the whole problem moot on general phylosophycal principles.

Sure, I am responsible for my own actions, and buying something is an action I (can) make. Therefore I bear responsibility for the side effects of my buying actions. Not the same kind of direct responsibility of those that directly make bad actions, and I don't think I should become insane over evaluating the impact of every single thing I buy, but there's a middle ground between that and ignoring the side effect of anything you buy.

There's a better viewpoint on that, though: ignore moral responsibility, think in terms of agency. Choosing from whom you buy is one of the few ways you (as an ordinary citizen) have to make the world a little steer towards a better form of itself. My own choice alone won't change much (which is correct, otherwise we'd be in an economic dictatorship), but if many people consistently care about that capitalism will work its magic and make wonders happen.

Giving up something you'd otherwise enjoy or find convenient because it would indirectly bring harm to other people feels a very virtuous action to me. I wish more people (including me) had the ability to do that more.

AFAIU it is essentially mass-produced (pun intended?). The master is carefully handwritten, all the others are copies taken with an industrial (if high quality) process.

EDIT: That's not meant to be dismissive of it. It looks like a very beautifut book, and I'll probably buy one.

Suppose I want to do this with my laptop, and dump my drive to the cloud (say accessible via SSH) to reinstall another operating system overwriting it. It's likely that the new operating system won't touch most of the blocks in my drive, so when restoring after having passed the boundary I don't want to transfer those unchanged blocks. Is there a good tool to do that easily?

By my experience, it helps a lot to have a handful of patches in Wine already. Doesn't have to be anything especially great, but showing that you can work with the conformance tests (both write them and fix them), create good commits, go through the patch review process, interact constructively with the maintainers can get you a lot of points and make up for a not necessarily perfect interview test.

Do not look for the super-core stuff like user32.dll and ntdll.dll. There is already a lot of folks working there and it's hard to make an improvement if that's your first contribution. But there are a plethora of random forgotten libraries in dlls/ which usually nobody cares about until some application depends on those, and they are quite likely to have a good amount of low hanging fruits. Look for the todos in the tests, for example.

Disclosure: I work for CodeWeavers, but I am not involved in the hiring process.

Agreed. Many smaller MRs are likely to get the same amount of changes accepted in far less time. Some of the factors include:

* After each change you have to review the whole MR, either because you have to rebuild the context or because it's not obvious how the new changes interact with the old ones. Hopefully the new review won't take as much as the first one, but still it's linear, and the number of changes request is also likely linear in the MR size, so that's already total quadratic.

* More iterations often mean higher review fatigue, at some point I don't want to rehash the same code over and over again, and I tend to postpone bigger MRs in favor of smaller ones.

* Larger MRs are correlated with the author not having a full grasp of what they are doing, and therefore are unable to segment it properly and organize the code properly. Sometimes there are not many alternatives to a large MR, so that's not a hard rule, but there is certainly a decent correlation.

In my experience (admittedly with a company that is not necessarily statistically meaningful) when I began doing code review that helped with my own MRs getting reviewed (and also contibuted positively to performance reviews). First and foremost because it helped me getting a better understanding of the whole code base, not just the parts that I ended up touching; and then, I suppose, also because it made me more trustworthy towards the code maintainer.

How does that interact with cache? Does accessing the ring buffer using the second set of mapped pages ends up using the same cache line, or is it a fresh request to main memory? If it's the latter, I guess that's has good chances of making your circular buffer slower, depending on how big it is, how does your cache work and how much cache pressure you experience. I don't think I know enough about actual caches to say whether that's probable or not.

That still requires you to plan how you use the virtual address space, though. You can't just add more memory pages on the back of your vector if you've already started using those virtual memory locations for other stuff. So you have to know in advance how much space your vector might end up using, and carefully avoid placing anything else there. If you're willing to come up with such an estimate, and if your OS is happy to overcommit memory (and I think Linux is, by default at least), then you can just malloc() all that memory in the first place. With overcommitting no physical page will be used to back your virtual memory block until you really use it.

If your system doesn't do overcommitting, then I guess that with some mmap() trickery (using the appropriate flags) you could do more or less the same thing, reserving the virtual address space that you need and then actually backing with memory as you need.

Whose end goal? The tenant's goal might be, as you say, to convince the landlord that the device is unreliable, and cheat on the rent agreement. If you want to cheat, as I guess some people do (otherwise there wouldn't be need for a monitor), asking if it's ok to host a party isn't a good solution.

My personal end goal is speculation. Each time a technology is discussed it's pretty automatic for me to think about what are its weaknesses and strengths, and how its behavior can be subverted or the same thing can be used in unintended ways.

The nice thing of intrusive sensors that sense things that are not sensed by your usual senses, like this, is that it's easy to saturate them while faking innocence. I.e., set up your laptop so that it does many scans and/or associations to the local WiFi, and then some light internet activity (the usual suspects: WhatsApp, Facebook, etc). The detector triggers, the landlord shows up to check what's going on, you show it's just you and your partner. Do that a few times until the landlord is convinced that the sensor is malfunctioning; unless they are IT technicals themselves, which I guess won't happen often, they will have a hard time understanding what's really going on, even more to prove it.

We never take a software methodology, school of programming or some random internet dude's "manifesto" at face value. Rules must be broken, when necessary.

In this specific case it seems particularly necessary. I don't think I will take this manifesto at face value.

In some conditions, yes. You need a cluster of points which have good reflectivity and coherence properties to microwaves over some time (months to years). Manmade steel and concrete structures, like bridges, houses, dams, etc, usually work very well.

You can't measure their position to the millimeter range, but with some interferometry techniques you can measure their movement to the millimiter range, relative to close points. Some variation of https://www.sciencedirect.com/science/article/pii/S092427161... was likely used in that work, I've seen it done for many other structures (and I even tried to setup a pipeline for doing that for commercial customers, but in the end we didn't manage anybody to fund us).

You can probably get better measurements with an onsite survey, but using satellite data has the advantage that with a handful of satellites you can map an entire country once every one or two week, and after throwing some computing power at it you can theoretically monitor all the bridges and houses at once and get early predictors of possible problems.

These case studies give you a hint of what can be done: https://www.sarproz.com/case-studies/ (I'm not and never have been affiliated with that product, just linking some cool pages).

I don't think that going into implementation details is what I would expect from an interface specification. The interface exists precisely to isolate the API consumer from the implementation details.

And while they're much better than nothing, those documents are certainly not a specification. They're are individual documents each covering a part of the API, with very spotty coverage (mostly focusing on new features) and unclear relationship to one another.

For example, the precise semantics of ResourceBarrier() are nowhere to be found. You can infer something from the extended barrier documentation, something is written in the function MSDN page (with vague references to concepts like "promoting" and "decaying"), something else is written in other random MSDN pages (which you only discover by browsing around, there are no specific links) but at the end of the day you're left to guess the actual assumptions you can make.

*EDIT* I don't mean to say that Vulkan or SPIR-V specification is perfect either. One still has a lot of doubts while reading them. But at least there is an attempt of writing a document that specifies the entire contract that exists between the API implementer and the API consumer. Missing points are in general considered bugs and sometimes fixed.

Your quote is also: "Capitalization matters a tremendous amount". But at least in some positions capitalization is mandated by grammar rules. So, when a noun should appear in such a position (e.g., just after a full stop), how does one distinguish between its two forms (capitalized and not capitalized)? There should be a way, if that "matters a tremendous amount".

Mitochondrial Eve 2 years ago

To me it's not even that incredible, after some thinking. The number of descendants (and ascendants) of a single person grows exponentially with time. Assuming that a certain closed population remains constant, it means that most of the 2^n descendants of a single person after n generations are actually a much smaller group of people counted many times each (i.e., through different lineages), for n large enough (but not even too much). So there is some "pressure" for essentially everybody in the closed population to eventually become descendant of a given person after a number of generations roughly comparable to the logarithm of the population size. Estimating that a generation take 25 years, 5000 years means 200 generations. 1.12^200 ~= 7 billion, so a logarithm base of 1.12 is already around enough to justify the common ancestor age.

The world population is not constant, of course, and it doesn't behave according to the assumptions I made implicitly, but the order of magnitude makes sense. A single person moving from a people to another is enough to unify the two lineages.

Mitochondrial Eve 2 years ago

- "Mitochondrial Eve" was not the only woman alive at the time, just the only one who still has surviving descendants

The only one who still have surviving descendants /in a purely maternal line/. I guess most of the women of her time have descendants today, but at some (many, in most cases) point in the descendance passes through a male.

Digital markets do not need more government regulation; they need more companies willing to innovate and compete

Fully agreed. So why are you defending what is essentially a (private, even) regulator in the crucial sector of smartphone software?

It's not very clear to me why in paragraph "Truncation matters" it is claimed that the strlen variant is necessarily better than the strlcpy variant. the strlcpy variant only scan the source and destination string once in the fast case (no reallocation needed), while the strlen variant needs to scan the source string at least twice. I guess in the common case you have to enlarge the destination a few times, then once it's big enough you don't have to enlarge it anymore and always hit the fast case, os it makes sense to optimize for that.

It might also be that in some programs with different access patterns that doesn't happen and it makes sense to optimize for the slow case, sure, but the author should acknowledge that variability instead of being adamant on what's better, even to the point of calling "schizo" the solution it doesn't understand. In my experience the pattern of optimizing the fast path makes a lot of sense.

BTW, the strlcpy/"schizo" variant could stand some improvement: realloc() already copies the part of the string within the original size of the buffer, so you can start copying at that point. Also, once you know that the destination is big enough to receive a full copy of the source you can use good old strcpy(). Cargo cult and random "linters"/"static checkers" will tell you shouldn't, but you know that it's a perfectly fine function to call once you've ensured that its prerequisites are satisfied.