That doesn't seem right. Consider the function f(x: ℝ) = 1 if x ≥ 0, 0 otherwise. That's computable but not continuous.
6,144 karma · joined October 23, 2018
Knowledgable & helpful person, available for hire :-)
I'm looking for more work, ideally on a consulting / freelance / part-time basis.
LinkedIn is better than email to make first contact if you'd like to talk, whether for work or just chat about something you liked here on HN! (I often miss interesting one-off mails among the deluge, and don't check it every day.)
I work 80% time at a funded stealth startup as hands-on tech lead, with zero-knowledge (ZK) cryptography, Bluetooth low energy (BLE), and peer-to-peer distributed systems, linking physical devices as well as the usual web stack. Can't say more, but it is intended to become open source. This a really fun and challenging project, with a great team! (It's not on my LinkedIn - stealth).
With my remaining 20% I am currently available and looking for software dev and/or tech leadership and/or business strategy consulting.
I'm versatile but develop mostly low-level or "system" software in C, C++, Go, Rust and Nim, with Linux as my main OS (but MacOS and Windows also). I have about 30 years professional dev experience over a wide range of systems, from embedded to supercomputers, Linux kernel, database engines, as well as GUIs, the web, and even games. Good at performance optimisation, debugging. Also good math & physics.
I've worked as an Ethereum core dev (EVM), so I know that environment well, especially improving EVM database speed, which is a critical factor! Currently my rabbit holes are ZK cryptography speed optimisation, and a novel fast database engine (neither B-tree nor LSM-tree, but with characteristics of both).
(ZK = zero-knowlege cryptography).
That doesn't seem right. Consider the function f(x: ℝ) = 1 if x ≥ 0, 0 otherwise. That's computable but not continuous.
The article talks about "opts.URL" in its example being accepted by the compiler, which accesses "opts.FooService.URL" without using the embedded type's name.
Once it took Vivado 40 minutes just to add one small Verilog file to a project. Not to compile it. Just to add it to the list of project source files, for which it scanned the file for definitions. Each time I edited the file, Vivado stalled for another 40 minutes. Same file compiled and ran all its simulation tests in Verilator (an open source tool) in a couple of seconds.
For my compiles, Vivado routinely took hours for sparse designs and over 24 hours for dense (but still conceptually small) ones. This made iteration impossible on the timescales my last FPGA project required, so I had to stop using Xilinx.
I accept that dense P&R compiles may take a long time, as it's algorithmically complex. But Vivado's occasional extremely slow and janky process for minor things left my wondering if the full P&R compile time was more due to similar bad coding issues on their side, not any real need to take that long.
> Google is pretty useful. It uses 15 TWh per year.
15TWh per year is about 1.7GW.
Assuming the above figures, that means OpenAI and Nvidia new plan will consume about 5.8 Googles worth of power, by itself.
At that scale, there's a huge opportunity for ultra-low-power AI compute chips (compared with current GPUs), and right now there are several very promising technology pathways to it.
But from an optical and electronics point of view, it's much harder to process the return signal that way, and probably uses a lot more energy due to the processing required (with current tech).
With liberals saying the "think of the children" argument is a specious, misdirecting, crude appeal to emotion that should be looked past.
Perhaps the old adage "it's getting hard to find X employees [at the price we are willing to pay]" applies.
That surprised me because I've seen articles and heard podcasts for years where they've said COBOL programmers are well paid due to scarcity, though never quoting amounts.
Until mirrored life evolves enzymes to eat non-mirrored sugars, mirrored life will be at a large disadvantage.
But with exposure to our environment, replete with non-mirrored sugars, that sets up a large evolutionary pressure in the direction of finding those enzymes, in addition to the mirrored enzymes they will already have for eating mirrored sugars.
With such evolutionary pressure, it seems plausible mirrored life will evolve those enzymes, even though non-mirrored life appears not to have done so, or at least not retained it. Because there has been no equivalent evolutionary pressure for non-mirrored life to eat mirrored sugars.
If mirrored life does evolve those enzymes, due to that asymmetric evolutionary pressure, then instead of being at a disadvantage, it might give them a temporary advantage over non-mirrored life.
Until mirrored life evolves enzymes to eat non-mirrored sugars, mirrored life will be at a large disadvantage.
But with exposure to our environment, replete with non-mirrored sugars, that sets up strong evolutionary pressure in the direction of finding those enzymes, in addition to the mirrored enzymes they will already have for eating mirrored sugars.
With such evolutionary pressure, it seems plausible mirrored life will evolve those enzymes, even though non-mirrored life appears not to have done so, or at least not retained it. Because there is no equivalent evolutionary pressure for non-mirrored life to eat mirrored sugars.
If mirrored life does evolve those enzymes, due to that asymmetric evolutionary pressure, then instead of being at a disadvantage, the ability to eat both types of sugars might give them a temporary advantage.
That made me curious, so I took a photo of my laptop screen running this page.
With default camera settingse, the text wasn't visible to me in the photo on my phone screen.
However, setting the exposure time manually to 0.5s, the text came out white on a noisy background and I could easily read it on the phone screen.
I would not be surprised if the default camera settings photo could be processed ("enhance!") to make the text visible, but I didn't try.
They don't make it clear in the messaging during the sign-up flow, which just says Microsoft Authenticator everywhere. But when you proceed through the steps to get a TOTP code for Microsoft Authenticator, there's a step with a link to something like "I want to use an another authenticor app", which presents a QR code for any generic TOTP app.
In my own measurements with NVMe RAID, doing this works very well on Linux for storage I/O.
I was getting similar performance to io_uring with O_DIRECT, and faster performance when the data is likely to be in the page cache on multiple runs, because the multi-threaded mmap method shares the kernel page cache without copying data.
To measure this, replace the read() calls in the libuv thread pool function with single-byte dereferences, mmap a file, and call a lot of libuv async reads. That will make libuv do the dereferences in its thread pool and return to the main application thread having fetched the relevant pages. Make sure libuv is configured to use enough threads, as it doesn't use enough by default.
In Java common errors and exceptions, like file I/O errors, have to be declared on each function signature, except everything under the RunTimeException hierachy is exempt from this requirment. In the language, RunTimeExceptions these are the messy errors like NullPointerException and ArithmeticException.
In practice, people do subclass program-specific exceptions under RunTimeException in Java, as well as wrapping existing exceptions inside a RunTimeException, for the sole purpose of not having to add them to function signatures all over the place.
There are neighbours in both directions in each dimension, i.e. 20 neighbours in 10 dimensions if you're allowed to wrap around the edges of the lattice.
With wrapping, I think the probability is 0.2 × (0.8^20) ≈ 0.002306 ≈ 0.23%.
If you're not allowed to wrap at the edges, a unformly random point has 2/N probability of having one neighbour on each dimension independently, and (N-2)/N probability of having two. With D dimensions, that's on average D(2N-2)/N neighbours.
With D = 10, N = 5, I think it's 16 neighbours on average, with a distribution from 10 to 20.
That makes the probability of landing on a mountain peak lower than ~2% and higher than ~0.23%. (Not 0.2 × (0.8^16) though, due to the distribution.)
This:
entry = list_search(key, list);
becomes: entry = list_search(key, lists[hash(key) % (sizeof(lists)/sizeof(lists[0]))]);
This: list_add(key, entry, list);
becomes: list_add(key, entry, lists[hash(key) % (sizeof(lists)/sizeof(lists[0]))]);
etc.A simple hash(), not high quality but good enough for non-adversarial inputs, can be a one-liner.
A good dictionary does more than this of course, especially dynamic sizing, but this simple change can radically speed up simple linked list code when the lists are long, you don't have a hash table implemention you can use, and you want to keep the code change very small.
The same principle can be used with other things than lists too.
And then every year after that they required another 12 months rent up front, when it came to the annual tenancy renewal. Track record of paying the rent wasn't good enough to prove that I could keep paying the rent.
But three out of those four features: page cache, dynamic I/O buffering and shared memory between processes, do not require that kind of VMM subsystem, and memory-mapped files don't require it for some kinds of files.
I've worked on the Linux kernel and at one time understood it's mm intimately (I'm mentioned in kernel/futex/core.c).
I've also worked on uClinux (no-MMU) systems, where the Linux mm behaves differently to produce similar behaviours.
I found most userspace C code and well-known CLI software on Linux and nearly all drivers, networking features, storage, high-performance I/O, graphics, futex, etc run just as well on uClinux without source changes, as long as there's enough memory, with some more required because uClinux suffers from a lot more memory fragmentation due to needing physically-contiguous allocations).
This makes no-MMU Linux a lot more useful and versatile than alternative OSes like Zephyr for similar devices, but the limitations and unpredictable memory fragmentation issues make it a lot less useful than Linux with an MMU, even if you have exactly the same RAM and no security or bug concerns.
I'd always recommend an MMU now, even if it's technically possible for most code to run without one.
The no-MMU version of Linux has all of those features except that memory-mapped files (mmap) are limited. These features are the same as in MMU Linux: page cache, dynamic I/O buffering, shared memory. No-MMU Linux also supports other modern memory-related features, like tmpfs, futexes. I think it even supoprts io_uring.
mmap is supported in no MMU Linux with limitations documented here: https://docs.kernel.org/admin-guide/mm/nommu-mmap.html For example, files in ROM can be mapped read-only.
Executables in a no-MMU environment can also share the same code/read-only segments between many processees, the same way shared libraries can, to save memory and, if run-time relocation is used, to reduce that.
The original design of UNIX ran on machines without an MMU, and they had fork(). Andrew Tanenbaum's classic book which comes with Minix for teaching OS design explains how to fork() without an MMU, as Minix runs on machines without one.
For spawning processes, vfork()+execve() and posix_spawn() are much faster than fork()+execve() from a large process in no-MMU environments though, and almost everything runs fine with vfork() instead of fork(), or threads. So no-MMU Linux provides only vfork(), clone() and pthread_create(), not fork().
Having heard so much about anti-Tivoization when the GPLv3 was being drafted, and the discussions about it on linux-kernel when Linus decided the kernel will remain GPLv2-only, I was left with the impression that the GPLv2 only required the provision of source code, build scripts, etc. but not the ability to reinstall a new version. [1] makes a pretty good case that the ability to reinstall is also required GPLv2, and I'm heartened that's how Tivo saw it too.
[1] https://sfconservancy.org/blog/2021/jul/23/tivoization-and-t...
They have a nice web app, but you must use their mobile app to login on the web version. The app takes a video of a QR code on the web page during login. Web login completes as soon as the mobile app notifies the server. There's no 2FA code to enter, and no alternative.
I asked them about this, by phone call, when my phone screen broke and I urgently needed to make a transaction. Surely there as an alternative? Or could I do the transaction by phone call?
They told me that indeed there is no other option. Despite having phone customer support, they had no phone or web banking service at all which could be used without a registered mobile device. The only phone service they could perform was to register a new mobile device, which I didn't have. I had a tablet, but it was too old.
So I had no good choice. The Android phone I'm using right now was bought in a hurry just so I could be allowed to make a bank transaction.
It wasn't my first choice of phone. I didn't have time to investigate alternative devices, let alone weigh up open alternatives. I ended up buying a mid-range device under pressure that seemed ok and was available in a store without waiting. (It was a brand new Samsung, and despite the IP rating it got water damaged and stopped working entirely after a few splashes a year or so later, but I was able to get it repaired.)
But the Linux kernel is GPLv2, and only v2. For better or worse, locking down the bootloader is (probably) pernitted with the Linux kernel.
Unfortunately, voters rejected that change quite strongly, and that probably set the trend for a while against further steps to proportional or more direct democratic systems.
AV is a type of transferable vote system, and a step closer to proportional representation. In AV you get two votes, so you can vote for your preferred candidate first (who may be niche but represents you better), and your tactical-vote candidate second (who doesn't represent you but are better than the even-worse candidate). As opposed to the current FPTP system, where you often have to tactical-vote for candidates who don't represent your interests much, and your actual preference is not recorded at all.
Even though AV is far from ideal, if voters had said yes then I think just the symbolism of changing the system, would have resulted in a greater inclination to change the system again later.
AV, STV and PR have been debated a number of times in the UK parliament in the last centery, so it does keep coming up, and will likely come up again, eventually.
Recently I asked for my software developer colleage to be bought a 24 GB Macbook Air instead of 16 GB, and boss came back with "not everyone needs a super-big machine like yours Jamie!".
They seriously spent contractor time investigating whether 16 GB was "enough" to get by for our app development, for a price difference on one laptop (second hand) that was negligible compared with cost of my colleage's time.
When I was using 16 GB I regularly had to watch the spinning beachball waiting for tasks due to memory pressure. Between browsers and VMs, it was nowhere near enough for how I worked. So I knew why I was asking, and I knew the price difference was so small for the company, that it was a no-brainer. I gave justifications but it was seen as over-indulgent.
Yes, this is exactly what's done. The queue node is an declared as a local variable in kernel code, i.e. on the kernel stack, and its address is passed to the wait function which links it into the waitqueue and then blocks in the scheduler.
Notable well-known things from DeepMind are AlphaGo (the first time a computer beat a world champion at Go), AlphaFold (resulting in a Nobel prize). Gemini (LLM, a variant of which is used in Google search results) and Gemma (open-weights LLMs).
They were acquired by Google, so you could argue they aren't centred in the UK any more, but I still think they qualify as international leadership in AI coming from the UK.