HNHacker News
TopNewBestAskShowJobs

aseipp

5,481 karma · joined April 11, 2016

I am a maintainer for the Jujutsu version control system and work at https://ersc.io

https://austinseipp.com

submissionscomments
aseipp··on A Tour of WebAuthn
For ordinary websites none of the existing platforms support WebAuthn attestation AFAIK, because the spec for attestation was not designed with key synchronization in mind, which is a key use case; otherwise, basic features like Keychain synchronization via iCloud would not work and the whole thing would be DOA. Synchronization is widely considered to be a core necessity to match the functionality of existing password managers.

I believe you can enforce attestation using MDM and a custom app as far as I'm aware. But for general people using Safari or whatever, you can't request any kind of device attestation.

aseipp··on A Tour of WebAuthn
You can just enroll multiple keys from different devices, just like you do with SSH, that's the recommended way. But even then, there are software implementations of WebAuthn, like 1Password. You can then use the local TPM as a "last mile" authentication mechanism to quickly and effectively unlock your local encrypted password database and then get the needed key material to do WebAuthn. I use this across all my devices e.g. to login to GitHub, even on my iPhone.

You could accomplish something fairly similar to this for SSH keys actually (an encrypted sync layer + deriving master keys from a local trusted source), but I don't think anyone has done this to the same level of polish.

aseipp··on Nvidia Jetson Orin Nano Super [video]
I think the latest Orin series supports both UEFI and there is "Bring Your Own Kernel" support for more recent releases[1], but you still need to apply the patches. Also, the Tegra GPU driver "nvgpu" has been open source in this form for quite some time in the Linux4Tegra tree, but I don't see it in the patch list. So, it's still a bit of a mixed bag, I think. But UEFI and 6.x kernel support is at least an improvement...

[1] https://docs.nvidia.com/jetson/archives/r36.3/DeveloperGuide...

aseipp··on Load is not what you should balance: Introducing Prequal
The paper reiterates -- multiple times -- that optimizing for latency is obviously the right choice; the other major signal is instantaneous requests-in-flight (RIF). They explicitly mention, on the very first page, that their contributions are not that "low latency is good, aim for that", it's that A) they use a particular combination of RIF and latency to select replicas called their "hot-cold lexicographic rule" which they find works really well, and B) their "probes" (requests by the balancer to the backends, to discover what their current state is) are collected asynchronously rather than in the critical request serving path, to help further drive utilization. Most of the ink in the paper in Section 4 explains the design choices they made around probing as a result.

I'm not done with the paper yet, but the basics are in fact written on page one.

aseipp··on Review of Mullvad VPN
Because the client often has actual knowledge of their design and the places where they want force to be applied to find weaknesses, because they're trying to evaluate the results with regards to specific outcomes, not every possible open-ended question you can think up. On top of that there is a reasonable limit in terms of time/money/staff/resources that can be spent on these kinds of audits, etc. For example, if you're using a cloud provider it's not like you're going to pay them infinity money to compromise GCP over the course of 9 months through a background operator compromise or some nation-state attack. You're not going to pay them to spend all day finding 0days in OpenSSL when your business runs a Django app. You're going to set baseline rules like "You need to compromise our account under some approaches, like social engineering of our own employees, or elevating privileges by attacking the software and pivoting."

It's mostly just a matter of having a defined scope. They could of course say "You can only attack this one exact thing" that makes them look good, but this is true of many things.

Defining the threat model is standard in the infosec auditing/pentest world, FWIW.

> If Mullvad dictated how to do things or imposed limits on the reach of the testing, the results are worthless anyway

That's only true if your threat model is "literally every possible thing that could ever happen", which is so broad to be meaningless and impossible to test anyway.

Computer programmers also do not typically design their programs under the assumption that someone stuffed newspaper between their CPU and heatsink and it caught on fire. They work on the assumption the computer is not on fire.

aseipp··on Trillium TPU Is GA
That is one factor, but another is total cost of ownership. At large scales something that's 1/2 the overall speed but 1/3rd the total cost is still a net win by a large margin. This is one of the reasons why every major hyperscaler is, to some extent, developing their own hardware e.g. Meta, who famously have an insane amount of Nvidia GPUs.

Of course this does not mean their models will necessarily be proportionally better, nor does it mean Google won't buy GPUs for other reasons (like providing them to customers on Google Cloud.)

aseipp··on RISC-V HiFive Premier P550 Development Boards with Ubuntu Now Available
The only board that is cheap and available with the ratified 1.0 vector extension I know of is the Kendryte K230, which you can find on some boards for about $40 USD: https://developer.canaan-creative.com/k230/dev/zh/00_hardwar...

Note that it's only on one 1.6GHz core, and still pretty anemic otherwise (pi form factor, it's to be expected.) So something "deskop grade" with all the nice extensions and other goodies is probably still a ways off. Maybe next year; we'll have to see -- but lots of useful extensions continue to be ratified today, so it may still be a while before things "cool off."

aseipp··on Ask HN: Git Alternatives – Sapling vs. Jj
You don't need to manage the stash or index, those are just expressed as commits, so you have fewer commands and a simpler UX, and can use universal tools like 'split' to handle cases you'd otherwise need stash/apply/switch to handle.

It supports Mercurial-like "revsets", so it is easy and flexible to query the commit graph for all kinds of information, in a user-controlled way.

Features like 'sl absorb' can do git 'fixup commits' automatically.

It supports a notion of changeset evolution, so if you have `A -> B -> C` and `A` gets merged into main, it will automatically rebase `B -> C` on top (among other things).

"isl", the "interactive sapling" GUI, is absolutely stellar and I don't think there's a faster way to do tasks like 'rebase X onto Y' or "reorder commits in stack Y" than that, even with Jujutsu.

It comes with integration for a tool named ReviewStack so you can do stacked code reviews while working on GitHub.

There is an undo command to undo your mistakes.

And, while I'm not sure this is in the Git backend today, many algorithms like getting the history of a file are O(N) in terms of file history as to the history of the whole repo (e.g. try `git log file` in gecko-dev or Linux and it is slow.)

Many of these advantages (not all) are shared with Jujutsu, to be clear.

aseipp··on Ask HN: Git Alternatives – Sapling vs. Jj
It's a fair question, but the answer is simple: because there are significant design choices in the UX and algorithms which are user visible, and percolate throughout the entire system design, which can't just be wrapped or alias'd away.

There is git-branchless, which is kind of like this[1][2] and is something like a half-way point between Git and Jujutsu/Sapling. However, it needs to be stated that git branchless does NOT just "wrap" existing things or alias them. It has significant engineering to add features, using a lot of code, because you can't "just" add things like revsets or 'undo' using wrappers or aliases, at least not in an efficient way.

Some examples from Jujutsu are that:

A) jj rebase is lightning fast compared to git rebase, because it works in memory. Git rebase touches disk for all operations, so it becomes slower the larger the repo, the more history, the bigger the files etc you have. You may spend significant IOPS moving large-ish files around, flushing the index to disk, and so forth; and you also cannot do things like rebase inside a bare repository (imagine you want a handy "Rebase branch on main" button in your GUI -- you need to have the whole working copy to do that!) jj rebase works entirely in memory so it never touches the disk for any files in the commits themselves. This is called "git move" in git-branchless, but requires significant code. Git itself is trying to solve this with a new "git replay" command, but it is extremely new and has some current limitations compared to, say, Jujutsu, IIRC. (But the fact they have to add a whole new command with significant code is a good example of how the algorithmic differences matter and can't be papered over.)

B) Revsets are a non-trivial addition to make the commit graph "queryable", but they add open ended features in a way that can't easily be recreated without them, because they are composable. For example, "list all commits authored by me that are not merged into main that can be rebased on main" is written as `all:mutable() & mine()`, but to recreate this level of flexibility you would need a dozen one-off features added to something like 'git log' -- but these revsets can work with many more commands than log! You can use the above revset to automatically rebase all your open branches at once for example, which is not possible in Git without shell scripting (what about Windows users?) and duct-taping stuff. But then where's the reuse?

C) Jujutsu has a notion of first-class conflicts, which can only be vaguely approximated with something like `git rerere` and `git rebase --update-refs`, but this isn't quite the same because for example you need to know details like purging the rerere cache if you get a conflict resolution wrong and want to undo it and start over, not to mention you can still easily screw things up mid-way with `git rebase` in a form that requires you to start over. These "catches" do not apply to Jujutsu and I have no idea where you would even begin if you wanted to add a feature like this.

So, the details matter a lot in practice for users, and delivering them a good experience is something that I think is way more difficult than just a bunch of opinionated commands. To be clear, if you like opinionated aliases and wrappers, that's OK! But there's a lot more underneath the surface if you scratch at it a bit.

[1] https://github.com/arxanas/git-branchless

[2] The main developer of git-branchless also is a Jujutsu contributor, so these ideas and the implementations aren't totally a coincidence!

aseipp··on Ask HN: Git Alternatives – Sapling vs. Jj
I've used both quite a bit, first Sapling and then Jujutsu, and now I exclusively use Jujutsu and am one of the developers. I previously used Git almost every day for ~15 years. Frankly, I think you'll be very happy with either of them; they are pretty much straight upgrades from Git in most ways. Some notes (random, non-exhaustive):

Both of them are heavily Mercurial inspired; Sapling is a heavily evolved fork of Mercurial, while Jujutsu was strongly inspired by many of its concepts but shares no code (the two main developers, Yuya Nishihara and Martin von Zweigbergk, are former heavy hitting Mercurial developers.) They support features like revsets, filesets, have a notion of "changeset evolution" built into their internal models, and more.

These features actually make it possible to do things in an "open ended way" that would be difficult or not-possible to do in Git; something like finding all commits with 'description(foo) & author(aseipp)' for instance is not something I'm sure you can do in Git in a one-off way, as a counterexample to the "just run this command in Git to do that!" argument.

Both of them have a significantly simpler conceptual model because they replace concepts like "stashes" or "the staging area" with commits. To be clear: you can do all the things you like with Git, but with less conceptual overhead. There are fewer "nouns", and consequently fewer "verbs" you need to use and memorize.

They also don't tend to muddle a bunch of stuff together under one name; rebase is just rebase, not "rebase and edit commit message and reorder and throw away commits and merge commits and ..." like in Git. Or consider `git revert` and the dozen options that make it work on this-or-that. This and the previous point mean their UX is also much smaller than Git, a bit more clean and well separated, etc.

Jujutsu has an even further simplified model because it doesn't even have a concept of things like "the working copy." Everything is a commit. This has a large list of downstream consequences on things like performance (jj rebase is vastly more efficient than git rebase), internal design choices, etc but the takeaway is that you have an even simpler cognitive model. The flipside, I think, is that Jujutsu might take slightly longer to "internalize."

Both of them have the ability to expose the `.git` directory next to their own VCS directories (.sl and .jj) so your existing tools like showing status lines in the editor gutter can work. Jujutsu calls this "colocation", and Sapling calls it "dotgit" mode. Sapling's "dotgit" mode is still experimental; Jujutsu's colocation mode is well supported, and likely to become the default in the near future.

Both of them have 'undo' commands. Imagine that! A command that can undo your mistakes! Users are almost always universally filled with joy when they discover this feature.

Both make workflows like stacking or rebasing a lot easier, conceptually, so you will probably be happier with either. Sapling has ReviewStack so you can do stacked reviews a bit more clearly on GitHub. For Jujutsu we don't integrate with ReviewStack, or Reviewable/Graphite (yet), so you are still at the mercy of Github's review tools, which are a bit weak when it comes to interdiffs/stacked PRs.

Sapling has a command called "interactive sapling" or "isl" which is a web-browser based GUI that you can use to drag and drop, reorganize, split, restack commits with ease. isl is an incredible tool, it is easy to use even for newcomers, and I consider it a major advantage over Jujutsu!

Jujutsu has the notion of "first class conflicts" which make most forms of conflict resolution far easier. It's a bit difficult to explain but think of `git rerere` combined with `git rebase --update-refs`, but on steroids. I consider this to be a major advantage over Sapling.

Sapling is the VCS of choice at Meta, and they are working on making the scalable server-side components available too. Jujutsu is designated to (hopefully) become the true successor to 'fig' at Google, which I suspect you're familiar with. Maybe this matters to you as a former Googler, but maybe not. (Note: I do not and have never worked at Google, but Martin does and is the leader of this effort.)

Jujutsu actually exposes a set of APIs so you could in theory use it with other backends; that is how the Piper/CitC integration at Google works, and people have floated ideas like a Mercurial backend, for instance. In theory it is extensible, but this might not matter to you.

Jujutsu is a pure Rust codebase, having been written from scratch, while Sapling has a much longer history; it is a mix of Python and Rust. I personally think this makes it much easier to contribute to Jujutsu, and it was one of the reasons I switched because I personally tend to write patches for tools I use. OTOH, Sapling is much more refined in some ways. It is up to you if you think this matters.

Compatibility-wise, I believe Sapling uses `git` commands underneath to drive a lot of its features, while Jujutsu instead uses libgit2/gitoxide for interop. IMO, libgit2 has caused us and users a few issues long-tail issues that are hard to resolve; things like Git Credential Manager or OpenSSH config support for instance don't work as well with libgit2, which causes annoying bugs. Other features like partial clones don't work (shallow clones do.) You can just use `git` commands to work around this, typically, but I think Sapling might handle some of these quite a bit better.

In short, I think you'll probably be happy with either of them. If you have any questions about Jujutsu at least, you can open them on GitHub, Discord, IRC, etc.

aseipp··on Ask HN: Git Alternatives – Sapling vs. Jj
The command line interface for Sapling called `sl`, which is Git compatible, is fully supported by the team at Meta. You can file bugs and feature requests, etc, though the repository is a bit intimidating. It is only the non-Git server components (Mononoke, EdenFS) that are not yet really supported [1] but I think most people aren't really concerned with that, when writing a post like this.

For all intents and purposes, Sapling works very well, I think, and in some places it has a lot more polish, like the "isl" graphical interface, which makes things like rebasing and restacking incredibly intuitive even for new users. (I consider isl to be a significant advantage over Jujutsu, and I say that as a Jujutsu developer!)

[1] Though, Mononoke does support features like exporting Git repositories to remote hosts from the internal model; that's not really what people are looking for in a lot of cases though.

aseipp··on Ask HN: Git Alternatives – Sapling vs. Jj
Both Sapling and Jujutsu are compatible with Git repositories, and there are even settings to have the `.git` directory exposed so that all of your existing tools will be able to run Git commands, show hunk changes in the gutter, etc. For all intents and purposes, you can use them in place of or alongside Git, and none of your colleagues will really need to know. This is a significant advantage over competing non-Git systems, and one of the major selling points that incentivize people to even try it at all.

If it means anything, I have been using Git for 15 years and am one of the earliest GitHub users, and I have not regularly used Git for nearly anything, in any job, for over ~1.5 years now. (Disclosure: I am also one of the Jujutsu developers though, so take that for what it is.)

aseipp··on Move semantics in Rust, C++, and Hylo
A raw string literal gets embedded into the binary's data section at compile time, just like it would in C or C++. What this means is that the type of the string literal is actually a reference (to an underlying memory address). And so it has type '&str' which reflects the fact you are using a reference to a value that exists somewhere else.

The type 'String' is instead an "owned" type, which means that it is not a reference, and instead a complete value and has a copy of the data. to_string() will create a String (owned value) from a &str (reference) by copying it. This is no different than if you had a global static compile-time string in C and you wanted to modify or update it: you would memcpy the global (statically allocated) string into a local buffer of the appropriate size and then modify it and pass it onward to other things that need it. You would not modify the static string in place.

In short, no, you do not need to_string() every time you want to work with a string. You need it to convert a reference type to an owned type. Rust's type system is just used here to codify the more implicit parts of C or C++'s behavior that you are already familiar with, but the underlying bits and bytes behave as you would expect coming from C++.

> And that bizarre scoping of Person p feels very un-intuitive. How would you work around that if you need to keep using it after show()

You take a reference just like you would in C++. Possibly a mutable reference if you want to modify the thing and then use it afterwords. This is in the article as the "Advanced rust example" at the end, it's right there and not hidden or anything.

It isn't really bizarre honestly; it's a matter of defaults. The difference is that Rust uses move-by-default, not copy-by-default or ref-by-default. Every time you write `x = y` for a given owned type, you are doing a move of `y` and into `x` and thus making `y` invalid.

    let g: &str   = "Austin";      // statically allocated string
    let x: String = g.to_string(); // do a copy
    let y: String = x;             // no copy, x is moved
Once you internalize this a lot more stuff will make sense, or at least it did for me.
aseipp··on Intel announces retirement of Pat Gelsinger
They are not suing them to use "inferior designs," you're completely misrepresenting the issue. They are suing them over IP and contract violations. The ISA in question is irrelevant here, you could also get sued by SiFive if you licensed their cores and then did something that SiFive believed violated that license. It's not that deep.
aseipp··on AMD Disables Zen 4's Loop Buffer
This might come as a shock, but I can assure you that the designing high end microprocessors have probably forgotten more about these topics than most of the people here have ever known.
aseipp··on Amazon S3 Adds Put-If-Match (Compare-and-Swap)
It's not surprising at all. The scale of AWS, in particular S3, is nearly unfathomable, and the kind of solutions they need for "simple" things are totally different at that size. S3 was doing 1.1million requests a second back in 2013.[1]

I wouldn't be surprised if they saw over 100mil/req/sec globally by now. That's 100 million requests a second that need strong read-your-write consistency and atomicity at global scale. The number of pieces they had to move into place for this to happen is probably quite the engineering tale.

[1] https://aws.amazon.com/blogs/aws/amazon-s3-two-trillion-obje...

aseipp··on Bit-twiddling optimizations in Zed's Rope
Everything supports __builtin_popcount or some variant these days (__popcnt for MSVC). It's a complete non-issue, really.

And the compiler is not required to lower it to a single instruction. It will if the target architecture is specified appropriately, but there's nothing that says it has to explode if it can't. In fact, by doing it this way, the compiler is actually more free to generate code in a way that's optimal for the architecture in all cases, because all the implementation details are hidden e.g. loads of large constants may be avoided if the compiler is allowed to choose the exact implementation, while using the portable version may tie its hands more depending on how it's feeling on that day. Here's __builtin_popcount working just fine while targeting a ~20yo architecture without native support for SSE4.2; it can generate this code knowing what the proper instructions and schedules are: https://godbolt.org/z/ra7n5T5f3

The moral here is that the primitives are there for you to use. Just use them and save yourself and your would-be code reviewer's time.

aseipp··on Using gRPC for (local) inter-process communication (2021)
> If I gave you a JSON object with name, age, position, gender etc. etc. would you not say it has structure?

That's too easy. What if I give you a 200KiB JSON object with 40+ nested fields that's whitespace stripped and has base64 encoded values? Its "structure" is a red herring. It is not a matter of text or binary. The net result is I still have to use a tool to inspect it, even if that's only something like gron/jq in order to make it actually human readable. But at the end of the day the structure is a concern of the application, I have to evaluate its structure in the context of that application. I don't just look at JSON objects for fun. I do it mostly to debug stuff. I still need the schematic structure of the object to even know what I need to write.

FWIW, I normally use something like grpcurl in order to do curl-like requests/responses to a gRPC endpoint and you can even have it give you the schema for a given service. This has worked quite well IME for almost all my needs, but I accept with this stuff you often have lots of "one-off" cases that you have to cobble stuff together or just get dirty with printf'ing somewhere inside your middleware, etc.

> I would also add the GRPC implementation I used in Javascript (long ago) was not actually checking the types of the field in a lot of cases so rather than being a schema that rejects if some field is not a text field it would just return binary junk. JSON Schema or almost anything else will give you a parsing error instead.

Yes, I totally am with you on this. Many of the implementations just totally suck and JSON is common enough nowadays that you kind of have to at least have something that doesn't completely fall over, if you want to be taken remotely seriously. It's hard to write a good JSON library, but it's definitely harder to write a good full gRPC stack. I 100% have your back on this. I would probably dislike gRPC even more but I'm lucky enough to use it with a "good" toolkit (Rust/Prost.)

> If you’re using JSON Protobufs why would you add this extra complexity - it will mean messaging is just as slow as using JSON. What are the core advantages of GRPC under these conditions?

I mean, if your entire complaint is about text vs binary, not efficiency or correctness, JSON Protobuf seems like it fits your needs. You still get the other benefits of gRPC you'd have anywhere (an honest-to-god schema, better transport efficiency over mandated HTTP/2, some amount of schema-generic middleware, first-class streaming, etc etc.)

FWIW, I don't particularly love gRPC. And while I admit I loathe JSON, I'm mainly pushing back on the notion that JSON has some "schema" or structure. No, it doesn't! Your application has and knows structure. A JSON object is just a big bag of stuff. For all its failings, gRPC having a schema is a matter of it actually putting the correct foot first and admitting that your schema is real, it exists, and most importantly can be written down precisely and checked by tools!

aseipp··on Using gRPC for (local) inter-process communication (2021)
> JSON contains a description of the structure of the data that is readable by both machines and humans.

No, it by definition does not, because JSON has no schema. Only your application contains and knows the (expected) structure of the data, but you literally cannot know what structure any random blob of JSON objects will have without a separate schema. When you read a random /docs page telling you "the structure of the resulting JSON object from this request is ...", that's just a schema but written in English instead of code. This has big downstream ramifications.

For example, many APIs make the mistake of parsing JSON and only returning some opaque "Object" type, which you then have to map onto your own domain objects, meaning you actually parse every JSON object twice: once into the opaque structure, and once into your actual application type. This has major efficiency ramifications when you are actually dealing with a lot of JSON. The only way to do better than this is to have a schema in some form -- any form at all, even English prose -- so you can go from the JSON text representation directly into your domain type at parse-time. This is part of the reason why so many JSON libraries in every language tend to have some high level way of declaring a JSON object in the host language, typically as some kind of 'struct' or enum, so that they can automatically derive an actually efficient parsing step and skip intermediate objects. There's just no way around it. JSON doesn't have any schema, and that's part of its appeal, but in practice one always exists somewhere.

You can use protobuf in text-based form too, but from what you said, you're probably screwed anyway if your coworkers are just churning stuff and changing the values of fields and stuff randomly. They're going to change the meaning of JSON fields willy nilly too and there will be nothing to stop you from landing back in step 1.

I will say that the quality of gRPC integrations tends to vary wildly based on language though, which adds debt, you're definitely right about that.

aseipp··on It's time to replace TCP in the datacenter (2023)
QUIC and Homa are not remotely similar and have completely different design constraints. I have no idea why people keep bringing up QUIC in this thread other than "It's another thing that isn't TCP." Yes, many things are not-TCP. The details are what matter.
aseipp··on M4 chips: E and P cores
The quoted sentence is poorly worded. The P and E cores are fully instruction set compatible. It isn't possible to meaningfully know ahead of time if the instructions will be used on any given core, and trapping along with a migration is expensive and needless. The M4 as a whole does not support the SVE/SVE2 extensions anywhere, which is what the article is saying in the given quote.

The M4, on all cores, does support the SME extension, which includes a subset of SVE instructions at a wider vector length (512-bits), optimized for throughput. SME instructions are handled by a separate accelerator coprocessor unit attached to each cluster, shared by a number of cores, and don't "exist" in the normal instruction pipeline (where e.g. 256-bit SVE2 instructions would be handled.) This was all true of the proprietary Apple AMX extensions in previous cores as well, as far as I'm aware.

aseipp··on We are shutting down Ondsel
In the case of FPGAs it doesn't really matter that the proprietary tools are buggy. What matters is the features and utility they have. Open-source FPGA design is still extremely, extremely far behind the proprietary alternatives in many dimensions (power support, integration tools, many aspects of simulation and test, general tools like floorplanners, and so on.) That isn't because people aren't trying either. It's just really hard and has limited talent pool.

I've spent a lot of time at this point with both toolkits. I use the open source tooling extensively for my own designs. But you tell some grizzled RTL person there's no power analyzer or native SDC support or that UTM was only recently supported in some simulator, and they're going to laugh at you. They've been doing that stuff for 20 years. I know this because I've done it several times (though other people find particular things, like free RTL verification tools, much appreciated.)

I think FOSS/software people paint some very rose-tinted picture in their mind where the mere availability of something for $0 would make it an obvious choice, even at only 10% of the functionality. But that's not how people see it in reality. Many people, including engineers, think of it the other way: if it's so good, why is it $0 and how do I know it will keep being developed? They've made their peace with the fact that the $5000 tool will exist practically for as long as they need, get the job done, and be supported.

aseipp··on Logica – Declarative logic programming language for data
Ah, I see what you mean. I'm not sure predicates like NewsData can actually be overloaded by arity, I'd have to check the docs. It mostly just seems like a shorter way to write the predicate with unbound variables.

> Are you aware of any SQL transpilers that spend so much time transpiling that you get irritated? I'm not.

Again, when you are running a tool on something that returns results in ~millisecond time, it is important the tool does not spoil that. Even 100-200ms is noticeable when you're typing things out. They could have worded it differently, it's probably just typical "A programmer wrote these docs" stuff, so it's just bad copy. A dedicated technical writer would probably do something different.

aseipp··on Logica – Declarative logic programming language for data
Mangle looks very interesting, thanks for the share. In particular I love your GRPC demo, because it shows a prototype of something I've been thinking about for a long time: what if we did GraphQL, but with Datalog! Maybe we could call it LogiQL :)

In particular many people talk a lot about concerns like optimizations across GraphQL plans and how they are expected to behave on underlying tables, but this is something that I think has seen a lot of research in the Datalog realm. And to top it off, even ignoring that, Datalog just feels much more natural to write and read after a bit of practice, I think. (Obviously you need to be in the pure fragment of datalog without recursion, but even then it might be feasible to add those features with termination criteria even if it's just "decrement an internal counter and if it hits zero throw a big error")

What do you think the plans for the Rust implementation will be? That's probably the most likely place I'd use it, as I don't really use Go that much.

aseipp··on Logica – Declarative logic programming language for data
I mean, yes, that's sort of how linguistics works in general? You can't just look at a language with completely different orthography or semantic concepts and expect to be able to reliably map it onto your pre-existing language with no effort. That's sort of the whole reason translation is a generally difficult problem.

I don't really get this kind of complaint in general I'm afraid. Many people can read and write, say, Hangul just fine -- and at the same time we don't expect random English speakers with no familiarity will be able to understand Korean conversations, or any syllabic writing systems in general. Programming language families/classes like logic programming are really no different.

> it's English language syntax made things really easy

That's just called "being familiar with English" more than any inherent property of SQL or English.

aseipp··on Logica – Declarative logic programming language for data
For the record, I don't use Logica myself so I'm not familiar with every design decision or feature -- I'm not a Python programmer. I'm speaking about Datalog in general.

> making variables implicit at the call site

What example are you looking at? The NewsData example for instance seems pretty understandable to me. It seems like for any given predicate you can either take the implicit name of the column or you can map it onto a different name e.g. `date: date_num` for the underlying column on gdelt-bq.gdeltv2.gkg.

Really it just seems like a way to make the grammar less complicated; the `name: foo` syntax is their way of expressing 'AS' clauses and `name:` is just a shorthand for `name: name`

> In light of that quote it's also weird that they mention that they are able to run the SQL they compiled to "in interactive time" on a rather large dataset, which they supposedly already could with SQL.

The query in question is run on BigQuery (which IIRC was the original and only target database for Logica), and in that setup you might do a query over 4TB of data but get a response in milliseconds due to partitioning, column compression, parallel aggregation, etc. This is actually really common for many queries. So, in that kind of setup the translation layer needs to be fast so it doesn't spoil the benefit for the end user. I think the statement makes complete sense, tbh. (This also probably explains why they wrote it in Python, so you could use it in Jupyter notebooks hooked up to BigQuery.)

aseipp··on Logica – Declarative logic programming language for data
> If I understand you correctly, you can easily get the same with ephemeral models in dbt or CTEs generally?

You can bolt on any number of 3rd party features or extensions to get some extra thing, that goes for any tool in the world. The point of something like Datalog is that it can express a similar class of relational programs that SQL can, but with a smaller set of core ideas. "Do more with less."

> I guess, but how can you guarantee correctness with flexibility involved?

How do you guarantee the correctness of anything? How do you know any SQL query you write is correct? Well, as the author, you typically have a good idea. The point of being compositional is that it's easier to stick together arbitrary things defined in Datalog, and have the resulting thing work smoothly.

Going back to the previous example, you can define any two "tables" and then just derive a third "table" from these, using language features that you already use -- to define relationships between rows. Datalog can define relations between rules (tables) and between facts (rows), all with a single syntactic/semantic concept. While SQL can only by default express relations between rows. Therefore, raw SQL is kind of "the bottom half" of Datalog, and to get the upper half you need features like CTEs, VIEWs, etc, and apply them appropriately. You need more concepts to cover both the bottom and top half; Datalog covers them with one concept. Datalog also makes it easy to express things like e.g. queries on graph structures, but again, you don't need extra features like CTEs for this to happen.

There are of course lots of tricky bits (e.g. optimization) but the general idea works very well.

> Could you share a more specific example or scenario where you have seen Datalog/ Logica outperform a modern SQL setup?

Again, Datalog is not about SQL. It's a logic programming language. You need to actually spend time doing logic programming with something like Prolog or Datalog to appreciate the class of things it can do well. It just so happens Datalog is also good for expressing relational programs, which is what you do in SQL.

Most of the times I'm doing logic programming I'm actually writing programs, not database queries. Trying to do things like analyze programs to learn facts about them (Souffle Datalog, "can this function ever call this other function in any circumstance?") or something like a declarative program as a decision procedure. For example, I have a prototype Prolog program sitting around that scans a big code repository, figures out all 3rd party dependencies and their licenses, then tries to work out whether they are compatible.

It's a bit like Lisp, in the sense that it's a core formulation of a set of ideas that you aren't going to magically adopt without doing it yourself a bunch. I could show you a bunch of logic programs, but without experience all the core ideas are going to be lost and the comparison would be meaningless.

For the record, I don't use Logica with SQL, but not because I wouldn't want to. It seems like a good approach. I would use Datalog over SQL happily for my own projects if I could. The reasons I don't use Logica for instance are more technical than anything -- it is a Python library, and I don't use Python.

aseipp··on Logica – Declarative logic programming language for data
Logica is in the Datalog/Prolog/Logic family of programming languages. It's very familiar to anyone who knows how to read it. None of this has anything to do with OOP at all and you will heavily mislead yourself if you try to map any of that thinking onto it. (Beyond that, and not specific to Logica or SQL in any way -- comparing two 3-line programs to draw conclusions is effectively meaningless. You have to actually write programs bigger than that to see the whole picture.)

Datalog is not really a query language, actually. But it is relational, like SQL, so it lets you express relations between "facts" (the rows) inside tables. But it is more general, because it also lets you express relations between tables themselves (e.g. this "table" is built from the relationship between two smaller tables), and it does so without requiring extra special case semantics like VIEWs.

Because of this, it's easy to write small fragments of Datalog programs, and then stick it together with other fragments, without a lot of planning ahead of time, meaning as a language it is very compositional. This is one of the primary reasons why many people are interested in it as a SQL alternative; aside from your typical weird SQL quirks that are avoided with better language design (which are annoying, but not really the big picture.)

aseipp··on M4 Macs can't virtualise older macOS
Back when IDA Pro for Linux & macOS was finally released, they decided to make every OS a separate license purchase. The net result of this was that every single person I knew who used it just kept buying Windows licenses and using it under WINE when they wanted to use it on their other computers.
aseipp··on Retrofitting spatial safety to lines of C++
I meant security engineers/exploiters actually, but yeah, I can see how most working C++ programmers who aren't security specialists might not be as familiar with it.
← PreviousPage 6 of 34Next →