HNHacker News
TopNewBestAskShowJobs

hddqsb

421 karma · joined September 6, 2017

submissionscomments
hddqsb··on Open-source tool to enforce privacy/security best-practices on Windows, macOS
I'm curious, does the company-issue PC also prevent you from opening CMD and PowerShell? (If not, you can probably paste the commands directly there; or create a .bat file yourself as suggested in a sibling comment. But as another comment points out, trying to circumvent company restrictions is risky. Ideally you'd just have to ask IT to do it for you, until they get tired of fulfilling your requests and give you access to your machine.)
hddqsb··on Rob Pike's simple C regex matcher in Go
Just a heads up that this implementation has exponential time complexity on pathological patterns.

Demo: https://tio.run/##tVddc6IwFH3nV0Q7WyXFIlrdUWr7uC/9B213BkIQKo...

    pattern = "a*b*c*d*e*f*g*h*i*j*k*l*m*n*o*p*q*r*s*t*u*v*w*x*y*z"
    text    = "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzza"
    running time = 1.6s
It should be relatively easy to fix this. Insight: If the pattern contains two or more wildcards (i.e. it has the form "<A>*<B>*<C>"), and you've found a match for "<A>*<B>", but you can't find a match for "*<C>", you can stop immediately without considering longer matches for the first wildcard. The reason is that a longer match for the first wildcard will mean you to start looking for "*<C>" later in the string, and that's strictly harder.
hddqsb··on Tell HN: Reddit mandatory login to see sensitive pages
It's still possible for me, I think @NowhereMan just didn't realise the email field could be left blank. Dark pattern working as intended, most likely.
hddqsb··on Tell HN: Reddit mandatory login to see sensitive pages
This completely unintuitive trick also works on reddit.com.
hddqsb··on Autonomous Reputation System
Yes, that's what I was looking for too. I think the following quote is meant to address that:

> To bootstrap the system, an initial set of Actors who share the same core values about the to-be-created reputation each gets allocated a bootstrap Reputation Score. This gives them the ability to receive Rating Tokens with which they can rate each other and newly entering Actors.

So basically it assumes there is an initial set of trusted Actors.

But even with this assumption there are potential issues (e.g. good Actors may be bribed).

hddqsb··on Show HN: Markdown as web page/site
It's in a sibling repo: https://github.com/casualwriter/casual-markdown
hddqsb··on Rob Pike's simple C regex matcher in Go
> horrible run times on craftily-constructed regexes

Here is a simple patch to make the runtime O(len(pattern) * len(text)) instead of exponential. It adds 5 lines and a new parameter. The idea is to memoize (cache) the results, specifically the failures (there is no need to cache the successes, because all the functions return immediately on success).

     // Match reports whether regexp matches anywhere in text.
     func Match(regexp, text string) bool {
    +    seen := make(map[[2]int]bool)
         if regexp != "" && regexp[0] == '^' {
    -        return matchHere(regexp[1:], text)
    +        return matchHere(regexp[1:], text, seen)
         }
         for {
    -        if matchHere(regexp, text) {
    +        if matchHere(regexp, text, seen) {
                 return true
             }
             if text == "" {
                 return false
             }
             text = text[1:]
         }
     }
     
     // matchHere reports whether regexp matches at beginning of text.
    -func matchHere(regexp, text string) bool {
    +func matchHere(regexp, text string, seen map[[2]int]bool) bool {
         switch {
         case regexp == "":
             return true
         case regexp == "$":
             return text == ""
         case len(regexp) >= 2 && regexp[1] == '*':
    -        return matchStar(regexp[0], regexp[2:], text)
    +        return matchStar(regexp[0], regexp[2:], text, seen)
         case text != "" && (regexp[0] == '.' || regexp[0] == text[0]):
    -        return matchHere(regexp[1:], text[1:])
    +        return matchHere(regexp[1:], text[1:], seen)
         }
         return false
     }
     
     // matchStar reports whether c*regexp matches at beginning of text.
    -func matchStar(c byte, regexp, text string) bool {
    +func matchStar(c byte, regexp, text string, seen map[[2]int]bool) bool {
         for {
    -        if matchHere(regexp, text) {
    +        if seen[[2]int{len(regexp), len(text)}] {
    +            return false
    +        }
    +        if matchHere(regexp, text, seen) {
                 return true
             }
             if text == "" || (text[0] != c && c != '.') {
                 return false
             }
    +        seen[[2]int{len(regexp), len(text)}] = true
             text = text[1:]
         }
     }

Demo: https://go.dev/play/p/aD9vzXwTHGE
hddqsb··on AutoRegex
Obligatory example where the extra backslash makes a difference:

    $ printf '%s\n' 'asterisk: *' 'backslash: \' | grep '[*]'
    asterisk: *
    $ printf '%s\n' 'asterisk: *' 'backslash: \' | grep '[\*]'
    asterisk: *
    backslash: \
It depends on the regex flavour though (doesn't happen with Python, JavaScript, or Perl for example).
hddqsb··on Where to wait for an elevator (2010)
> You're relying on the assumption that, in the above example, the fine (which should be minimized) is directly proportional to difference from the estimate. But that assumption doesn't appear in the explanation of why one metric or the other will minimize the fine.

Yes, my argument is specifically for the case where the fine etc. is directly proportional to the difference (or absolute difference). I'm pointing out that the two cases are similar apart from the signedness.

To put it mathematically, I'm just observing that if you have a set {x_i}, then:

- avg{|x_i - y|} is minimised by setting y to median{x_i}

- |avg{x_i - y}| is minimised by setting y to avg{x_i}

The excerpt in the article says "the mean minimizes the average squared distance" (i.e. setting y to avg{x_i} minimises avg{(x_i - y)^2}), which is correct but not obvious (the proof is non-trivial, and if you were to ask the students who chose the mean why they chose it I bet none of them would say "because it minimises the squared distance"). So I find it odd to include that statement. If I was the author I would have said "the mean minimizes the average signed distance", which I find more intuitive and think is a better explanation of why those students chose the mean. (Also, I like how "average value of the absolute difference" and "absolute value of the average difference" are the same words just in a different order.)

hddqsb··on Where to wait for an elevator (2010)
I was trying to come up with a scenario where you have to choose between the mean and the median, and the correct choice is the mean due to signedness (in contrast with the elevator example, where the correct choice is the median because the distance is unsigned). Do you have a better example?

It should be obvious that the mean is the correct representative value for weighing nails. My point is that there are cases that call for the mean and cases that call for the median, and the distinction can be explained by considering the signedness (without having to consider squared distances).

Maybe the following variation on the nail example would help: Suppose the manufacturer of the nails must publish a reference value for the weight of a nail, and will be fined for every nail that is not exactly the correct weight. The fine is proportional to the absolute error. Question: Should the manufacturer publish the mean or the median in order to minimise fines? Answer: The median.

Why is the mean the correct representative value for counting nails, but not for minimising fines? I'm arguing that it's because when the nails are weighed together the errors are signed, but when the fines are calculated the errors are unsigned (in the same way that the distances to the elevators are unsigned).

hddqsb··on Where to wait for an elevator (2010)
> But you can't know what the mean is without having already answered your original question of "how many nails are there?", so as a formal matter this is completely useless advice.

Yes, obviously you'd estimate the mean/median by taking a small sample (or using a published value). I left that detail out because it's not relevant to the choice between mean and median.

hddqsb··on Where to wait for an elevator (2010)
> standing at the mean minimizes the average squared distance

This is true, but I find it more intuitive to think about the signed distance: if you define signed_dist(x, y) = x - y, then the mean is the value that makes the average signed distance closest to 0. Of course in reality distance is unsigned – if you walk 1m left then 1m right, you've walked 1m + 1m = 2m, not 1m + -1m = 0m, so the signed distance is not appropriate.

Here is a practical example where the aim is to get the average signed difference to be closest to 0: You want to count a large number of nails by weighing them. To do that, you need to know the weight of a single nail. But the nails have slightly different weights, so you need to pick some representative value. Question: Should you pick the mean or the median? Answer: You should pick the mean, because when you weigh all the nails together the differences will cancel out.

So the rule is:

- To minimise the average value of the absolute difference, pick the median.

- To minimise the absolute value of the average difference, pick the mean.

hddqsb··on HNNotify.xyz: Subscribe to Your Hacker News Feed
It works for me.
hddqsb··on Improve Git monorepo performance with a file system monitor
[deleted]
hddqsb··on Forebruary is a wall calendar that you do not need to replace every year (2013)
If you mean day-of-the-week, that's easily fixed by adding labels to the movable frame (like the existing red marking which indicates the weekend).
hddqsb··on Forebruary is a wall calendar that you do not need to replace every year (2013)
I was taught the knuckle mnemonic, which I really like: https://en.wikipedia.org/wiki/Knuckle_mnemonic
hddqsb··on Forebruary is a wall calendar that you do not need to replace every year (2013)
Yeah. I guess you could manually fix it with some white magnets / reusable stickers.
hddqsb··on Forebruary is a wall calendar that you do not need to replace every year (2013)
Neat. Some limitations:

- It doesn't tell you how many days there are in the month (31/30/28/29).

- Working out how to move the frame at the end of the month isn't very difficult, but it's not trivial either (especially given the previous point).

hddqsb··on C#: IEnumerable, yield return, and lazy evaluation
They did:

> An iterator could query a database, for example—including the unfortunate possibility that it might alter data, or that iterating through it twice might yield completely different results! Some tools (like ReSharper) will warn you against multiple enumeration for this reason.

hddqsb··on Cool desktops don’t change
Edit: "A little" is inaccurate, the probability of the remaining lifetime being at least T is actually 25%[1]. And all this is assuming a "Lindy proportion" of 1 (which seems reasonable) and that no other information is known.

[1] Calculation: Lindy proportion 1 corresponds to a Pareto distribution with probability distribution function `a / x^(a+1)` where a = 2 and the range of x is [1, ∞). The cumulative distribution function is `1 - 1/x^a`. So the probability of the remaining lifetime being less than or equal to the observed lifetime is CDF(2) = 0.75.

hddqsb··on Cool desktops don’t change
I don't see any issue, as long as you consider the time until the system crashes or stops for any other reason rather than the time until the system stops specifically due to a crash.

And note that the Lindy effect is about the expected value (mean). The statement "probably run another T hours without incident" could be interpreted as relating to the median, which is actually a little less than the mean. So the statement should either be "the expected value of the number of hours until the system stops is T", or "the probability of the system running for at least another T hours is a little less than 50%".

hddqsb··on Find a good available .com domain
It's possible to avoid `cat` and still keep the filename separate from the rest of the command by placing the redirection at the start of the command:

    < /tmp/com.txt awk ...
It might look a little odd, but it's portable.
hddqsb··on The Beauty of Unix Pipelines (2020)
To improve performance, consider using `export LC_ALL=C` (credit: https://benhoyt.com/writings/count-words/). But note that it sorts uppercase and lowercase separately, and doesn't handle Unicode well.
hddqsb··on Deprecation of OpenGL and OpenCL (2018)
Ha ha, no. The macOS 10.14 SDK deprecated OpenGL in 2018, and the page currently shows what's new in macOS 12. Here is a live page with the macOS 10.14 release notes showing the deprecation: https://developer.apple.com/documentation/macos-release-note...
hddqsb··on Deprecation of OpenGL and OpenCL (2018)
The page shows the current news, here is an archived snapshot from 2018 that talks about the deprecation: https://web.archive.org/web/20181226081443/https://developer...
hddqsb··on Dozens of high-traffic websites vulnerable to ‘account pre-hijacking’, study
I'm curious, have you ever tried contacting that guy and explaining that he shouldn't use your email address?

This design seems like a surprising oversight on Google's part. The correct design is to only add the recovery account if a verification link is clicked (which is in fact what they do for enabling mail forwarding). That way you could simply create a filter to mark the requests from that guy as spam. However, being the recovery address of this guy doesn't seem like such a serious problem – it should be relatively easy to filter the emails that Gmail sends to recovery accounts (something like "from:no-reply@accounts.google.com <guy's email address>").

hddqsb··on Manifest v3 in Firefox: Recap and Next Steps
FYI: You can bypass the lock by copying places.sqlite and places.sqlite-wal then reading from the copy. Not exactly ideal, but might be useful.
hddqsb··on Go's Concurrency Examples in Java 19
The explanation in the video is good, here is a transcription for convenience (emphasis added):

> OpenJDK implements threads as thin wrappers around the OS thread [...] OS threads are expensive, by which I mean that we cannot have too many of them. Maybe a few thousand active ones, maybe ten thousand active ones, but that's about it. And the reason for that is that the OS doesn't know the various languages, and the most costly component of a thread is its stack, and the operating system doesn't know how the various languages it might support makes use of the stack. So it must address the worst case and allocate a very large stack. It's usually on a megabyte scale. And even though we use virtual memory and not all of it is committed to physical memory, once we touch a page it becomes committed – it can't be uncommitted again because the OS doesn't know how the stack is used. And in any event, all the operations are done at a page granularity which is 4k, it's also not that small.

There may also be arbitrary OS-specific limits. For example on Linux there is system-wide limit on the number of threads, controlled by /proc/sys/kernel/threads-max (docs: https://www.kernel.org/doc/html/latest/admin-guide/sysctl/ke..., see also: https://stackoverflow.com/a/8849114). On my system it's ~60,000 (with 8G RAM).

hddqsb··on Crimes with Go Generics
Nope.

If you call `time.Sleep()` the reported duration will reflect that call, but it's only simulating the delay. The duration of a CPU-heavy task is always reported as 0.00s.

Demo: https://go.dev/play/p/UZToqFseAwO

Output:

    === RUN   TestSleep // calls time.Sleep(2 * time.Second)
    Real duration: 554µs
    --- PASS: TestSleep (2.00s)
    === RUN   TestBusyLoop // for i := 0; i < 1000000000; i++ { ... }
    Real duration: 390.826ms
    --- PASS: TestBusyLoop (0.00s)
    PASS
The simulation is quite good: if you have multiple threads that use `time.Sleep()`, their output will be interleaved correctly. The output panel will even display the lines one at a time as if it's streaming them from the server, but in reality the entire output is received at once and the "streaming" effect is simulated on the client.

Concurrency is one of Go's core features, so it figures the playground would allow some form of concurrency even when the clock is fake.

hddqsb··on Crimes with Go Generics
Unfortunately Go's playground messes with the time, so it's always going to say 0.00s even for the slow version.

Here is a hacky workaround to measure the actual time using a syscall: https://go.dev/play/p/kF6Bh048siE

It shows 979ms for the original version and 0.212ms for the fast version.

← PreviousPage 6 of 8Next →