Hacker News new | past | comments | ask | show | jobs | submit | tpolzer's comments login

One of the oldest (AFAIK) occurrences of this was AOL releasing a data set of "anonymized" search queries in 2006 and it took a about a day for the first person to be deanonymized.

https://www.nytimes.com/2006/08/09/technology/09aol.html

https://techcrunch.com/2006/08/09/first-person-identified-fr...


A std::monostate member will still have non zero size, because it needs a unique address.

See https://en.cppreference.com/w/cpp/language/ebo


...except if you use the standard [[no_unique_address]] attribute.


What's really weird to me is not that C++ has a unit type and picked a weird name for it (that's just C++). The weird thing is how many unit types it has:

- std::nullopt_t

- std::nullptr_t

- std::monostate

- std::tuple<>

And I'm sure there's more.


The distinct types are the whole point. You wouldn't want a std::tuple<> to be implicitly convertible to a std::optional<T> (for arbitrary T), and std::nullptr_t exists to be the type of nullptr, which captures the conversion behaviours appropriate for null pointer literals and has nothing to do with the variant use case std::monostate exists to serve.


If there was a std::unit_t and it was implicitly convertible to optional, tuple and pointer, I don't think that would be worse in terms of usability at all (maybe worse in readability for people who haven't heard of a 'unit' type).

As for the std::variant use case, using std::monostate is only a matter of convention there. You could use any of the other unit types just the same.


std::monostate is explicitly provided for use with std::variant. It's in the <variant> header. Sometimes people use it for other things, but that's really an abuse, especially given defining your own type suitable for such cases is typically as simple as `struct mytype{};`.

Using one type to represent empty literals for optional, tuple and pointer types, implicitly convertible to all of them, would make the compiler accept many obviously accidental constructs. In a world where the maintainers of C++ are trying their hardest to make the language safer what conceivable benefit would there be?


Then you're basically back to "anything can convert back and forth with void " -- the point is to avoid* that.


Why wouldn't you want std::tuple<> to be the same as std::monostate, though? In many languages with a proper unit type such as Haskell and Rust, the zero tuple is the unit type.


What about "void"?


void isn’t a unit type (inhabited by a single value), it’s a “bot” type, I.e. no values inhabit it.


void is the unit type. The fact that it is not constructible is a wart of the language, inherited from C. It would be easy to fix and would simplify a significant amount of generic code.

A function returning bottom cannot return, yet void foo() {} can. In fact it can even return the result of calling other void functions:

   void bar() {  }
   void foo(){ return bar();}
In generic code void is usually internally replaced by a proper, regular void_t unit type and converted back to void at boundaries for backward compatibility.

  [[noreturn]] void bar(); 
would be a candidate for a bottom-returning function, except that [[noreturn]] isn't really part of the type system.


> void is the unit type. The fact that it is not constructible is a wart of the language, inherited from C. > A function returning bottom cannot return, yet void foo() {} can.

Or you could say it the other way, that it is the bottom type, and the fact that it can be used as the unit type for returned values is a wart of the language. Furthermore, void* isn't a pointer of the unit type, it's a type for pointers to undefined/unspecified value types.


nothing is gained by making void a proper bottom type. It would only break existing code. OTOH make void a proper unit type would be backward compatible and actually make the language simpler both from a specification point of view and in practical terms.


I didn't mean that it should be made into a bottom type, even though it sort of looks like it on the surface.

I think the original idea was that void meant "unknown", not "empty" or "non-existent": It was all about whether values could be allocated or not (the wart mentioned above). A plain void variable cannot, but a void pointer can be allocated. For functions, they just reused the keyword to mean "no return value" or "no arguments".


A pointer to the bottom type would make even less sense as an interpretation for void *, since such a pointer couldn't possibly point to any initialized value.


Sorry, I wasn't clear enough: I meant that void is not just a mix of the unit and bottom types, it is also in used for unspecified (unknown actually) types.


I ran into this recently writing some C++20 coroutines. The protocol for delivering values from a coroutine that was previously suspended has two flavors: one for values and one for void. My initial draft just implemented the value version and used a struct VoidTODO {} where void should be.

It's too late now. void pointers are used as a pun to mean "type wildcard." If void were a real thing that could have a size and address, that wouldn't work anymore.


Yes!! Been there done that. Two flavors of EVERYTHING: one to deal with functions that return values; and one to deal with void functions. It's awful.


Void means "it is a syntax error to construct a value of this type". This is not a type that exists in category theory or Haskell. (But similar to the "bottom" type.)

Hence, "void*" - a pointer to something, but it would be a syntax error to derefence this pointer.


In that regard void behaves like any incomplete type. In C and C++ you cannot construct objects of incomplete types nor you can assign through pointers of incomplete types. But you can construct pointers to void and other incomplete types.

Differently to other incomplete types void has some special behaviour: you can declare a function as returning void and return with no arguments is also special cased. You can also cast to void.

A void with proper unit semantics would simply be a complete type instead. The only special case would be return with no arguments implicitly returning a void instance, but that would be pure sugar.


That's a good point. Maybe one could argue that rather than the unit type not being constructible, the wart of C is that functions that return "bot" can still "finish executing without returning".

I would almost rather argue that void is indeed the "bot" type, and a function marked with a void return type shouldn't be said to "return void;" rather we should say that it's an overloaded syntax that means the function has no return value at all. Same for "return bar()" there, that's just a false-friend of the syntax for returning a value, just syntactic sugar for "bar(); return;".


void is not a subtype of all types, though.

C and C++ don't have a type spindle, where void would be at the bottom. Only C++ has the concept of subtype, only in the class system, and the C++ class system doesn't have a bottom type; there is no bottom class that is a base for all the others.

void is not a proper type; it's just a hack shoehorned into a convenient spot in the type system.

Which is why the C++ people have to invent this whole zoo of other things.

If void were a type, then, for starters, "return x;" would be syntactically valid in a function returning void. (Only, no possible x would satisfy the type system, so there would have to be a diagnosable rule violation in that regard.)

A function returning void does not return a type. It doesn't return anything; it is a procedure invoked for side effects.

The same situation could be achieved in other ways, like having a procedure keyword instead of void.

The (void) parameter list is another example of void just being a hack. It was introduced in ISO C, and then C++ adopted it for compatibility.

The 2023 draft of ISO C finally made () equivalent to (void), though it will probably take many decades for (void) to disappear.


> C and C++ don't have a type spindle, where void would be at the bottom. Only C++ has the concept of subtype, only in the class system, and the C++ class system doesn't have a bottom type; there is no bottom class that is a base for all the others.

A bottom type is not the base of all other types.

> void is not a proper type; it's just a hack shoehorned into a convenient spot in the type system.

It is a type, but it is not Regular and it is incomplete. 'return x;' is invalid in a void-returning function because it doesn't type check. 'return void()' or 'return (void)0;' or 'return void_returning_function();' are all valid because they type check.

Making void regular has been proposed multiple times [1]. It is a relatively simple extension but nobody that cares has the time to carry it through standardization.

[1] https://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0146r1...


In C, it is not like that. From the 2023 draft:

6.8.7.5 The return statement

Constraints

1 A return statement with an expression shall not appear in a function whose return type is void.

It's a constraint violation. It doesn't matter what the type of the expression is.

It looks as if C++ made a small improvement here.

Yes, the bottom type is at the bottom of the type derivation hierarchy. That's why the word bottom is there; that's what it's at the bottom of. It's also why it can't have any instances. Since every other type is a supertype, then if the bottom type contained some value V, that value would be imposed into every other type! V would be a valid String, Widget, Integer, Stream, Array ... what have you.


To clarify, it could be that the bottom type is not the base of all types, if the language has a split between some types which participate in that sort of thing and others that don't (e.g. class versus basic types or whatever).

But void is not the base of anything in C and C++.

You could argue that void is in some category of types where it is at the bottom; but no other types are in that category.

There is another problem: a bottom type should be the subtype of all types in that category. That includes being its own subtype. There we have a problem: C and C++ void is not a subtype of void in any sense.


That doesn't seem right to me. I can define a function returning "void", and it can terminate. I would expect that a function returning an uninhabited type can never complete.


And “bot” refers to the bottom type: https://en.wikipedia.org/wiki/Bottom_type


I find it annoying that (a) this seems to be a hardware feature that is almost universally permanently disabled in firmware and (b) it's almost impossible to find out whether it is supported by any given product (neither of the two products you link provide any mention on the spec sheet).


The theoretical limit is 50% according to Wikipedia, but there's other factors being optimized for as well aside from efficiency:

https://en.wikipedia.org/wiki/Engine_efficiency#:~:text=Mode....


SD Express is basically dead as far as I can tell.

SD card users who care about speed have UHS-II equipment, but SD Express and UHS-II use mutually incompatible high speed signalling on the same pins (so cards and readers are only supporting one of the two - I guess technically this could be fixable with special purpose chips, but at large cost).

Users who care about speed but not about SD card compatibility are already using CFExpress, which is supported by most modern professional cameras and has much better hardware availability than SD Express.


Ideally with PPS, your device can actually just ask exactly for the regulated voltage it needs on USB-C.

Most modern smartphones can use that to charge their batteries more efficiently/with less heating of the phone.


Sure but that doesn't take into account charger efficiency.

Something designed to output 5V-48V might be quite inefficient at generating an asked for 6.65V, perhaps. Optimizing just for the device might be missing gobs of energy efficiency that could easily be found with a little testing & discovery.

There's decent odds that a good PPS implementation on the device - one that can directly connect the supply and battery without having to do intermediary conversions - is the most efficient option. PPS probably is the best choice. But it's not guaranteed. And particularly as we create higher power higher voltage capable chargers, their optimization point might be tuned to much bigger outputs (where they will absolutely require that efficiency to keep cool enough under load). Losses from running your charger sub-optimally could dwarf losses from the device receiving power sub-optimally for it.

The point seems to hold: we need data to know what the best option to do is. This submission showed one way of DIY'ing that data, but devices could also do better jobs self-reporting, which would let everyone tune better.


I think the bigger win will be cheap charging cables won't corrode as quickly at their contact points with higher voltages.


Unless your 5 GHz spectrum is crowded by other WiFi, you really want to be on channel 36, because that way you do not have DFS at all, see the table on Wikipedia: https://en.wikipedia.org/wiki/List_of_WLAN_channels


The AP still has to send regular beacons for each hidden SSID, taking up air time.


Over all age groups? Definitely not, cardiovascular diseases and cancer get ~everybody in the end: https://ourworldindata.org/grapher/annual-number-of-deaths-b...

You're right for 15-49 year olds, where drug overdoses only recently (around 2015) overtook cancer: https://ourworldindata.org/grapher/causes-of-death-in-15-49-...


Consider applying for YC's Summer 2025 batch! Applications are open till May 13

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

Search: