Hacker Newsnew | past | comments | ask | show | jobs | submit | ptrl600's commentslogin

Because it puts the history of the article behind a lock

I wonder if there are any privileged Wikipedia accounts who have defected and are doing a sci-hub thing.


I wonder if that "fake permissions" Android sandboxing thing from like a decade ago still works.

The right to lie to apps should be part of the new tech Magna Carta


I hate to sound like a those pesky Kagi supporters, but that is built into Graphene OS.

It's not, though. If you deny location permissions the app will still know and pester you to enable. Same with other sensitive permissions with the exception of internet.

Thats a shame, I used to be able to pass fake location data through on an app by app basis using an Xposded module. That was probably 10 years ago though.

This has been a thing for rooted devices for a long time with faking senstive data on android Although i wouldnt root any sensitive devices nowadays

Isn't that a moot point with the graphene location proxy tool?

Are you talking about their network location provider? That doesn't do anything to spoof location. It just allows querying apple (optionally via graphenos proxy) for the location of nearby wifi networks, rather than going through google play services. Apps can still figure out whether you denied location permissions.

The Python library "enaml", which is kind of wrapper around QT, has a constraint-based layout engine: I think it's successful, I made a fairly complicated GUI and it didn't have any performance issues. Of course I was only developing for desktop...


I had a laptop in the mid 00s which made a strange buzzing sound when scrolling a document in Adobe Reader, and in no other context.


Low kolmogorov complexity equals suspicious


This is wordier than just "as const", what advantage does it give? (I am a newbie and genuinely don't know)

edit: perhaps the advantage only comes into play for mutable values, where you want a narrower type than default, but not that narrow. Indeed, this is covered in the article, but CTRL+F "as const" doesn't work on the page for whatever reason, so I missed it.


The satisfies keyword is quite different than "as const." What it does is:

1. Enforce that a value adheres to a specific type

2. But, doesn't cause the value to be cast to that type.

For example, if you have a Rect type like:

    type Rect = { w: number, h: number }
You might want to enforce that some value satisfies Rect properties... But also allow it to have others. For example:

    const a = { x: 0, y: 0, w: 5, h: 5 };
If you wrote it as:

    const a: Rect = // ...
TypeScript wouldn't allow you to also give it x and y properties. And if you did:

    as Rect
at the end of the line, TypeScript would allow the x, y properties, but would immediately lose track of them and not allow you to use them later, because you cast it to the Rect type which lacks those properties. You could write an extra utility type:

    type Location = { x: number, y: number };
    const a: Location & Rect = // ...
But that can get quite verbose as you add more fields. And besides: in this example, all we actually are trying to enforce is that the object is a Rect — why do we also have to enforce other things at the same time? Usually TS allows type inference for fields, but here, as soon as you start trying to enforce one kind of shape, suddenly type inference breaks for every other field.

The satisfies keyword does what you want in this case: it enforces the object conforms to the type, without casting it to the type.

    const a = { x: 0, y: 0, w: 5, h: 5 } satisfies Rect;
    // a.x works
Then if someone edits the code to:

    const a = { x: 0, y: 0, width: 5, height: 5 } satisfies Rect;
TypeScript will throw an error, since it no longer satisfies the Rect type (which wants h and w, not height and width).


This was a fantastic writeup, thanks. If you don't mind an additional question...

How does this work,

    function coolPeopleOnly(person: Person & { isCool: true }) {
        // only cool people can enter here
    }

    const person = {
        name: "Jerred",
       isCool: true,
    } satisfies Person;

    coolPeopleOnly(person);
Since

- person isn't const, so person.isCool could be mutated

- coolPeopleOnly requires that it's input mean not only Person, but isCool = true.


If you ignore the `satisfies` for a moment, the type of `person` is the literal object type that you've written (so in this case, { "person": string, isCool: true }). So coolPeopleOnly(person) works, regardless of whether `satisfies` is there, because TypeScript sees an object literal that has all the person attributes and also `isCool: true`.

(You could mutate it to `isCool: false` later, but then TypeScript would complain because `isCool: false` is different to `isCool: true`. When that happens isn't always obvious, TypeScript uses a bunch of heuristics to decide when to narrow a type down to the literal value (e.g. `true` or `"Jerred"`), vs when to keep it as the more general type (e.g. `boolean` or `string`).)

What `satisfies` is doing here is adding an extra note to the compiler that says "don't change the type of `person` at all, keep it how it is, _but_ also raise an error if that type doesn't match this other type".

(This is only partially true, I believe `satisfies` does affect the heuristics I mentioned above, in that Typescript treats it a little bit like `as const` and narrows types down to their smallest value. But I forget the details of exactly how that works.)

So the `coolPeopleOnly` check will pass because the `person` literal has all the right attributes, but also we'll get an error on the literal itself if we forget an attribute that's necessary for the `Person` type.


Why is satisfies needed at all, when can't. Typescript realize that `a` satisfies `Rect` automatically?


It does; the code will still type-check without the satisfies operator. satisfies lets you say "if this value doesn't conform to this type then I want that to be an immediate compile error, even if it would otherwise be okay". Which isn't needed all that often since usually getting the type wrong would produce a compile error elsewhere, but occasionally it proves useful. When designing the feature they collected some use cases: https://github.com/microsoft/TypeScript/issues/47920


Thanks; succinct and for me, I understood it.


I've really only found benefit on the return type of functions, when you can say that a type parameter satisfies a type (with the return type being a boolean). This let's you use `if (isPerson(foo))` and typescript will narrow the type appropriately in the conditional


With as const you can’t verify against another interface


In the situation that the personnel and legal code of the government depend very little on the outcome of elections in practice, would you say that the incentives for a government would be rather different?


It's a trivial exercise to get plaintext copies of Apocalypse Culture, Anarchist's Cookbook etc. and "spin" them using old-school SEO textual manipulation methods to create infinite variants of basically any offensive concept I want. I don't see how uncensored AI is remarkably more dangerous than this.


For once the comment “AI brings nothing new, this was always possible” makes sense. Because this is about getting existing data, not generating new data, or coorrdinsting swarms of agents etc.


Yeah it was superb for the layman.

If there's ever a project for an alternative OSS Flash authoring tool, something intended to be as accessible as Flash 5 or so, I'd love to contribute somehow


If it doesn't require a Google account and just means jumping through a bunch of hoops the first time, maybe requiring a USB cable, OK. If it does require a Google account, or won't let you give permission to F-Droid to install stuff, I call foul.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: