justinpombrio's comments

justinpombrio | 1 year ago | on: Can we get the benefits of transitive dependencies without undermining security?

That's an ordinary argument type. Like:

    void my_function_to_connect_to_server(
        Network network,
        int port,
        String server_name
    )
It's not categorically different than the other arguments, and doesn't require an effect type system.

At this point I'm not sure if you're misunderstanding what I'm proposing, or if you don't know what an effect system is. If you care to communicate, you'll need to say something more substantial. Walk me through what you're trying to say.

justinpombrio | 1 year ago | on: Can we get the benefits of transitive dependencies without undermining security?

No it's not. I'd guess you're imagining a type signature like this one?

    void effect:Network my_function_to_connect_to_server() {
        ...
    }
I mean a type signature like this one:

    void my_function_to_connect_to_server(Network network) {
        ...
    }
Where there's absolutely nothing special about the Network type, except that (i) it has no constructor, and (ii) nothing in the Java language lets you talk to a network without it. All of this is expressible with Java's type system today.

justinpombrio | 1 year ago | on: Can we get the benefits of transitive dependencies without undermining security?

That's what I'm calling capabilities at the application level (where you say "this .jar can't access the network"), rather than at the language level (where you say "this function wasn't given access to the network as an argument"). I don't think any widely known language has tried capabilities at the language level. (The language not widely known that does it is E.)

The real power will come when you can mix them. In one direction, that looks like `main()` not getting passed a `Network` object because the ".jar" wasn't granted network access. In the other direction, that looks like the system C library you invoked failing to access the network because when you invoked it from Java you failed to provide a `Network` object, so it was automatically sandboxed to not be able to access the network.

justinpombrio | 1 year ago | on: Can we get the benefits of transitive dependencies without undermining security?

You can do a lot with capabilities at the language level, if the language supports it. It doesn't require effect types: it's extremely boring from a type system perspective, which is an advantage.

Imagine these changes to a language, making it "capability safe":

- There is a `Network` object, and it's the only way to access the network. Likewise, there's a `Filesystem` object, and it's the only way to access the file system.

- Code cannot construct a `Network` or `Filesystem` object. Like, you just can't, there's no constructor.

- The `main()` function is passed a `Network` object and a `Filesystem` object.

Consider the consequences of this. The log4j vulnerability involved a logging library doing network access. In a capability safe language, this could only happen if you passed a `Network` object to the logger, either in its constructor or in one of its methods. So the vulnerability is still possible. But! Now you can't be surprised that your logger was accessing the network because you gave it the network. And a logger asking for network access is sufficiently sketchy that log4j almost certainly would have made network access optional for the few users that wanted that feature, which would have prevented the vulnerability for everyone else!

I talked about there being a single monolithic `Filesystem` object. That is what would be passed into `main()`, but you should also be able to make finer grained capabilities out of it. For example, you should be able to use the `Filesystem` object to construct an object that has read/write access to a directory and its subdirectories. So if a function takes one of these as an argument, you know its not mucking around outside of the directory you gave it.

Capability safety within a language is stronger than the sort of capability safety you can get at the process level or at the level of multiple machines. But we want those too!

justinpombrio | 1 year ago | on: I'm Peter Roberts, immigration attorney, who does work for YC and startups. AMA

Any idea how the executive orders will effect trans people renewing their passports?

A trans friend already changed the gender marker on his passport, and it's expiring in two years. He's deciding whether to renew it ASAP or wait. Any guess how likely it is to come back with the wrong gender marker, or get stuck in a bureaucratic mess?

Thank you so much for doing these! No worries if this question is outside your wheelhouse.

justinpombrio | 1 year ago | on: I ditched the algorithm for RSS

But it's so little hassle: just send the blog author an email saying vaguely what the problem is!

Someone emailed me about an issue with my RSS feed once. I don't remember what the issue was anymore, but I was grateful and I fixed it. Being the author of a tiny blog, it was just really nice to know that someone wanted to read what I wrote enough to care that my RSS feed was borked.

justinpombrio | 1 year ago | on: Rational or not? This basic math question took decades to answer

Stating that more precisely, if you pick a real number uniformly from the range [0, 1), the probability that it's rational is 0.

One way to see this is to imagine a procedure for picking the number:

- Start with "0."

- Roll a D10 and append the digit.

- Repeat an infinite number of times.

- In the unlikely event that you wrote down a number that's not in standard format, like "0.1499999..." (which should instead be written "0.15"), toss it out and start again.

The digits of every rational number eventually repeat forever. For example, 1/7 is "0. 142857 142857 ...". So what's the probability that your sequence of rolls settles on a pattern and then repeats it forever, without once deviating in an infinite number of rolls? Pretty clearly zero.

justinpombrio | 1 year ago | on: Penrose Mazes (2020)

I'm away tonight, but the source code is there if anyone wants to make that change. I imagine it would make the mazes a lot smoother.

justinpombrio | 1 year ago | on: Penrose Mazes (2020)

Walk with a green wall to your right, and a blue or white wall to your left. It's a long path, but shouldn't be too hard to see?

I remember being amused that Paint's flood fill could be used to solve mazes. It shows that flood fill is, worst case, as hard as solving a maze, so it needs to do something like DFS or BFS.

justinpombrio | 1 year ago | on: C++ exception performance three years later

How do you deal with putting information in your error messages?

My understanding is that Zig errors can't contain any data. But an error message like "file not found" is awful. Are your error messages awful, or is there some way to get information into them so that you can say "file 'foo/bar.json' not found"?

justinpombrio | 1 year ago | on: Tree Calculus

Maybe for some people. Personally I find the concatenative calculus more natural to think about/in than the lambda calculus!

justinpombrio | 1 year ago | on: Tree Calculus

> The lambda calculus is only more useful because it's become the basis for a lot of existing programming languages.

But there's a reason for that. Functions make a good basis for programming languages. It's not the only good basis! Concatenative combinators make a good basis too: see Factor and Joy.

If you take the lambda calculus and add numbers and a few operations on them, it's easy to program in it. Likewise for the concatenative calculus. But not so for NAND gates or SK combinators. You certainly can do anything you want with them, but doing so feels more like solving a logic puzzle than programming. I am likewise skeptical about the tree calculus.

justinpombrio | 1 year ago | on: Tree Calculus

Quick summary:

It's a programming language whose programs (and whose values) are unlabeled trees.

An unlabeled tree is a tree-shaped data structure whose nodes hold no data. The children of a node are ordered, though. The "Tree Calculus" defines a set of rules by which you can "evaluate" an unlabeled tree to get another unlabeled tree. If you apply these rules repeatedly, either you'll get into an infinite loop, or you'll get a tree that the rules say doesn't change anymore. The rules are designed so that the rules don't effect binary trees, so if you evaluate a binary tree you'll get the same tree back out and the computation is "done". These rules are written as a small-step semantics (a standard way to write down evaluation rules in PL) in the "specifications" page.

They claim that:

- The evaluation rules for trees are Turing Complete, meaning that you can express any computation, e.g. any JS program, using the Tree Calculus. More precisely, the claim is that there's a straightforward way to convert any (say) JS Program into a tree, and any tree into a JS value, and now you can use tree evaluation to run a JS program by doing (i) convert the JS program into a tree, (ii) evaluate the tree to get another tree, and finally (iii) convert the tree into a JS value, which is the correct output of the JS program. To prove this you wouldn't actually use JS as the language, you'd use something simpler that we already know is Turing complete like the lambda calculus, but it's the same idea. Though glancing at the page they might have actually done this for JS.

- The evaluation is asymptotically optimal, meaning that for any programming language P (like JS), there's a conversion f(prog) from programs in P to Tree Calculus trees and constants a and b such that running_time(f(prog)) <= a+b*running_time(prog). That is, you can run programs in any language using the Tree Calculus with ~constant overhead. This is true for all the programming languages you love, e.g. you could write a JS program that takes a Java program, compiles it to bytecode, and run that bytecode, and unless you did this reasonably badly the running time won't be worse than a factor of 1,000,000.

- A whole bunch of other stuff too. It's all plausible at first glance (i.e., I don't think they're making any of it up), but not obviously consequential.

What's it good for:

Some PL people might think it's cool. Conceivably useful to simplify some theory of computation proofs.

If you find this sort of thing interesting, though, I'd recommend learning the lambda calculus instead. The lambda calculus is simpler, more well known, and more useful (it's a model of functions, instead of some made up rules about trees).

justinpombrio | 1 year ago | on: Willow, Our Quantum Chip

From Wikipedia[1]:

A poll of 72 "leading quantum cosmologists and other quantum field theorists" conducted before 1991 by L. David Raub showed 58% agreement with "Yes, I think MWI is true".[85]

Max Tegmark reports the result of a "highly unscientific" poll taken at a 1997 quantum mechanics workshop. According to Tegmark, "The many worlds interpretation (MWI) scored second, comfortably ahead of the consistent histories and Bohm interpretations."[86]

In response to Sean M. Carroll's statement "As crazy as it sounds, most working physicists buy into the many-worlds theory",[87] Michael Nielsen counters: "at a quantum computing conference at Cambridge in 1998, a many-worlder surveyed the audience of approximately 200 people... Many-worlds did just fine, garnering support on a level comparable to, but somewhat below, Copenhagen and decoherence." But Nielsen notes that it seemed most attendees found it to be a waste of time: Peres "got a huge and sustained round of applause…when he got up at the end of the polling and asked 'And who here believes the laws of physics are decided by a democratic vote?'"[88]

A 2005 poll of fewer than 40 students and researchers taken after a course on the Interpretation of Quantum Mechanics at the Institute for Quantum Computing University of Waterloo found "Many Worlds (and decoherence)" to be the least favored.[89]

A 2011 poll of 33 participants at an Austrian conference on quantum foundations found 6 endorsed MWI, 8 "Information-based/information-theoretical", and 14 Copenhagen;[90] the authors remark that MWI received a similar percentage of votes as in Tegmark's 1997 poll.[90]

[1] https://en.wikipedia.org/wiki/Many-worlds_interpretation#Pol...

justinpombrio | 1 year ago | on: Ask HN: Who wants to be hired? (December 2024)

Location: Cambridge, MA

Remote: Yes

Willing to relocate: No

Technologies: Rust, C++; JS; Python; Java; FHIR/HL7v2

Resume: https://justinpombrio.net/about-me/resume.pdf

Email: On resume

About me: PhD in programming languages. I've worked on healthcare software, mapping, programming languages, parsers, and editors, and I'm happy to add to that list. Passion for writing performant and correct software.

Open to full-time, part-time & contract opportunities.

justinpombrio.net

page 2