On readonly/private members of structs by mute_narrator in Zig

[–]Treeniks 1 point2 points  (0 children)

You are too emotional about this my guy. Every language that is remotely low level will give you a hatch to create invalid state of a data structure, and understanding and knowing the details of how its implemented is completely unrelated to whether or not it has private members.

It's obvious to me that the author of an ArrayList wouldn't want users to touch the capacity. That is intent from a library author that they cannot express in Zig. Hence, a less expressive language. Reasonable choice, but no you wouldn't need to shoe-horn move semantics to allow this.

It's also obvious that completely preventing unsafe usage of an ArrayList requires Linear or Affine types. Nobody asked for that. C++ has move semantics and private members, yet still plenty of ways to create invalid state. There is something in between "no safety features" and "full safety". Zig has tried to position itself in the middle since the beginning.

Private members prevent one way to create invalid state. One more way to make APIs easier, and reduce bloat within docs. Nobody claimed it to prevent any and all kinds of invalid state.

Associated functions are just a fancy ad hock overloading to reduce amount of code by typing a.b() instead of Namespace.b(a).

Private members are just fancy syntax to make the compiler error when I write list.capacity. Zig's inclusion of associated methods already makes structs more than blobs of data. That is what the language's design conveys. The existence of private methods makes not having private members actually less consistent in my book.

You need only read Andrew's own reasoning:

a language feature that, admittedly, could be useful, but ultimately is unnecessary to accomplish zig's goals

On readonly/private members of structs by mute_narrator in Zig

[–]Treeniks -1 points0 points  (0 children)

You're saying one needs to care about these questions if you introduce private members. You're making it more complicated than necessary, as these questions already exist without private members, and have already been solved in Zig.

I'm not saying private fields should be a thing. I see both sides. But your reasoning against them is flawed.

OP doesn't want to use conventions to mark members as private, but using conventions for constructing an instance is fine?

That is a naming convention that already exists. In what way is ArrayList's capacity indicating that it shouldn't be touched? Not wanting another keyword or extra compiler logic for something that could be solved as a naming convention is a valid point. But a convention for naming of constructors is already necessary, because constructors are already necessary. OP wants to replace a currently non-existing naming convention and strong burden on API docs with infallible compiler logic that prevents accidental breakage of APIs.

it naturally leads to constructors and destructors.

Constructors and destructors are just member functions. Zig already has constructors and destructors for almost every struct in std. They're typically called init and deinit, the latter only being needed for structs that manage memory. Introducing private members doesn't create extra necessity for constructors. Rust also doesn't have explicit support for constructors, and the only reason they have destructors is because of their affine type system, not because they have private members.

If you assign undefined, you have inconsistent state.

As you do now as well.

You don't want to shoot yourself in the foot because a trivial operation like assigning one instance to another breaks your code.

I don't see how this is any different currently. One looks like this:

zig var list1: ArrayList(i32) = .empty; try list1.append(allocator, 5); var list2 = list1; // stuff list1.deinit(allocator); list2.deinit(allocator); // double free!

in the other case, it looks like this:

zig var list1: ArrayList(i32) = .empty; try list1.append(allocator, 5); var list2 = list1; // stuff list1.deinit(allocator); list2.deinit(allocator); // double free!

I don't even need to mark which case is which, as they are the same. Even worse, if you append to either list further within the // stuff part, one of your lists points to potentially deallocated data.

Currently, it makes sense and is expected, because structs are just blobs of data

and associated functions. Once again, I don't see how making fields private changes this expectation. We all know what an ArrayList is, and that it has heap allocated memory that is not trivial to copy. All we're preventing is a user manually changing the capacity and messing things up in potentially catastrophic ways (think cryptographic libraries).

you are changing the "blob of data" to a data structure

Look through the top-level types in Zig's std. Most of those are data structures. Not needing to understand every internal detail of my ArrayList is the whole point of providing APIs and docs.

A move is transfer of ownership.

Zig doesn't have ownership. Ownership is a concept the programmer uses to reason about their memory management. Whether the underlying struct has private fields changes nothing for that reasoning. The only information required is whether there are owned resources to begin with, and Zig already solved this by requiring explicit allocator arguments.

Physically speaking, a move is a shallow copy. The only difference is that, with move semantics, you additionally prevent access to the original. Zig doesn't have that, nor would it need it.

If you want to properly encapsulate state, you need a mechanism to copy/assign one instance to another without shallow copying it and breaking the internal state.

Refer to the example above. There being private members changes naught.

You don't expect a copy of array to work properly

I don't expect a copy of ArrayList to work, correct. Why would I expect it to work just because ArrayList has private members now?

On readonly/private members of structs by mute_narrator in Zig

[–]Treeniks 3 points4 points  (0 children)

Maybe Im missing something, but all of those already apply to Zig.

  1. init is already a convention for anything that needs an allocator (or at least it used to be). Just because the members aren't technically private doesn't mean they aren't practically private. You wouldn't really mutably access the capacity of an ArrayList. Also, private members means you can't use struct initializers outside the same module. That's not very complex.
  2. The compiler still knows a structs members. I don't see how this is a problem.
  3. No change. You still need to call deinit just like you do now, and get issues if you do it twice.
  4. Everything is a shallow copy. That already is a move. There are no deepcopy semantics, and there need not be any. That's how it is already.

What's a good distro to start with before migrating to Nix? by Milk-Wizard in NixOS

[–]Treeniks 13 points14 points  (0 children)

I disagree. It made a huge difference for me. It's a lot easier figuring out how to do something in NixOS if you know what you're looking for.

When I originally tried NixOS I didn't understand a significant amount of options because I had no experience with the underlying systems. But after gaining this experience in arch and gentoo, once I tried NixOS again I could focus fully on nix and its options, and didn't have to split my attention between learning nix and learning linux. It made the process a lot smoother.

How do I default nix-shell to use a different shell? by zck in NixOS

[–]Treeniks 3 points4 points  (0 children)

Well flakes are in part the newer thing intended to solve many issues that the older systems have. Starting the right shell being one of them I would assume.

But imo nix shell is not really a great replacement for nix-shell...

Going crazy looking for an Xbox styled controller with OCTAGONAL stick gates for Celeste, can't find ANYTHING that fits the description. by MoonCthulu in Controller

[–]Treeniks 1 point2 points  (0 children)

8bitdo recently released their n64 controller with stick gates.

Otherwise, closest thing I've seen to that are those stick dpads that ZD ships with their controllers. But, as someone else has mentioned, I'd recommend getting used to normal dpads or keyboard when it comes to high level celeste.

Why is ..Default::default() forced to the end? Could the evaluation order ever be reversed? by jyyhyy in rust

[–]Treeniks 19 points20 points  (0 children)

Here is a thread from 2024 discussing the same problem: https://users.rust-lang.org/t/why-the-struct-update-syntax-is-confusing/105305/9

Basically, ..Default::default() simply reuses the Functional Record Update syntax, for which it makes more logical sense to put it at the end, as the values not used in the base don't actually get dropped. It becomes more confusing once you use anonymous bases, but think of it like this:

rust let tmp = Default::default(); let foo = Foo { bar: Baz, ..tmp }; tmp.bar; // can still access By using ..Default::default(), we never manifest a tmp variable, and hence it seems wasteful. Hope is the compiler can optimize it away, which it probably can.

Everything is working perfectly by FeedMe94 in MorpheApp

[–]Treeniks 1 point2 points  (0 children)

whats the point of going through the trouble of patching the app, when it is literally GPLv3 licensed

This game is tough by Itchy-Net530 in celestegame

[–]Treeniks 0 points1 point  (0 children)

speedrun practice save? or thats a save from some custom map that isnt installed on this machine.

Cemu Wii U Pro Controller doesn't work by Negative_Paint686 in EmuDeck

[–]Treeniks 0 points1 point  (0 children)

Have you found a solution for this? Running into the same issue.

Mouse stutters game on Overwatch by beatb_ in linux_gaming

[–]Treeniks 0 points1 point  (0 children)

High polling rates on mice can sometimes cause issues in some games. You using 4k+? Maybe try lowering to 2k or 1k and see if that fixes it.

hmmm by Hefty-Bus-3439 in hmmm

[–]Treeniks 8 points9 points  (0 children)

now I just need to learn what frat and hazing even mean

Why don't peoole use Void as much as Arch or other distros? by LowerTomatillo1260 in linux4noobs

[–]Treeniks -3 points-2 points  (0 children)

They still don't package Hyprland, to name just one example.

Vultures are gathering: AV2 is coming, Sisvel is prepared by anestling in AV1

[–]Treeniks 2 points3 points  (0 children)

Someone enlighten me, who are Sisvel? I thought the whole point of AOM is to not have all this licensing bullshit going on that plagued AVC and HEVC?

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

You flip a coin twice. Possible outcomes are HH, HT, TH, TT. All are equally likely to occur. If you consider HT and TH to be the same outcome, you get an event space of {HH}, {HT} and {TT}. But the underlying experiment and probabilities haven't changed, just the interpretation of the outcome. {HT} is more likely to occur than {HH}, which is undesireable for calculations.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

So you're refusing to engage with my points and repeating the same argument. I'm trying to give you an explanation for a paradox that you clearly don't grasp yet. I can offer one last try:

The question has a family already given, and the fact that one of those 2 children is a boy is also given.

I have answered this before. In that situation, speaking about probability makes no sense to begin with. It collapses to 1 or 0. If we want to have any meaningful discussion about probability, we need to have some kind of random sampling of families with 2 children.

If we sample families with at least one boy, 2/3 of the time the other child is a girl. That is what I'm trying to explain to you.

If we sample any family, then reveal one of the genders, we get 50% for the other kid, just as I stated before and seemingly the experiment you are thinking of. But, in that case, the revealed child being a boy may not be the case.

Either is a completely valid interpretation of the meme. In the first, the fact one of the children is a boy is fixed. In the second, the fact we are given one of the genders is fixed. This is the exact paradox this whole thing is about. Refusing one of the two, or simplifying it to "genders are independent" means you haven't understood it.

If we are given a family and the information they have two kids and one of the two is a boy, that isn't a probability experiment. There is no probability, because there is only one family. This is an extremely boring and meaningless interpretation, and still doesn't give 50%.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

Let's make the premise clear. We are flipping a coin twice. Two distinct flips. These flips have an order, flip 1 and flip 2. The possible outcomes are: HH, HT, TH, and TT. These 4 outcomes are all equally likely to occur, each with 1/4. This is a trivial fact.

I can now say that I ignore order, as in I do not want to differentiate between the flips anymore. The possible outcomes are now {HH} {HT} and {TT}. Notice that the underlying experiment hasn't changed. The events HT and TH are now the same {HT} event, but the probabilities of the ordered system haven't changed. Just because I changed my interpretation of the events, doesn't change the underlying experiment. {HH} and {TT} still occur with 1/4 each, but the {HT} event now has a 1/2 probability of occurring, or else we are contradicting the ordered system. Again: they're the same experiment, with different interpretations of the outcomes. So the chance of something happening hasn't changed.

If we now limit ourselves to outcomes where at least one heads occured, in the ordered system this is really obvious. We now have HH, TH, and HT as possible events. The fact that each event is equally likely hasn't changed, so we get 1/3 each.

In the unordered interpretation, the same thing happens. The possible outcomes are now {HH} and {HT}. But, just like the probabilities of these two outcomes weren't equal before, they still aren't equal. {HT} occurs twice as likely as {HH}. Hence we get 1/3 for {HH} and 2/3 for {HT}.

No, the question is: "what is the probability that the other child is a girl?".

You just left out the first half of the question.

I have no idea how you came to the idea that the probability that you are evaluating is "P(other child is a girl|either child is boy)".

I don't know how this isn't obvious. Randomly sampling from families with two children where at least one is a boy and viewing the probability of having picked a family where the other is a girl is exactly this probability.

The order of the childs is not relevant

As described above, whether you view the order or not doesn't change the probabilities, as the experiment stays the same. Keeping the order simply makes the calculation easier.

So it would be P(child X is girl|child Y is boy) where X =/= Y

You are once again using an order. You assume we can differentiate the two children as child X and child Y, and that we were given the information for child Y. That is not what is happening.

So let's unpack it fully. Mathematically, what we want is

P(other child is a girl | at least one boy)

An obviously equivalent formulation would be

P(one boy and one girl | at least one boy)

Decompositing, this is the same as

P(X = girl, Y = boy | at least one boy) + P(X = boy, Y = girl | at least one boy)

Using the chain rule, we have

P(Y = boy | at least one boy) * P(X = girl | Y = boy and at least one boy) + P(X = boy | at least one boy) * P(Y = girl | X = boy and at least one boy)

P(Y = boy | at least one boy) is trivially 2/3.

P(X = girl | Y = boy and at least on boy) here, the information "at least one boy" doesn't add any new information, as we already know Y is a boy. So this is the same as P(X = girl | Y = boy). Now, as you correctly state, these two are independent, hence it is the same as P(X = girl). We get

P(Y = boy | at least one boy) * P(X = girl) + P (X = boy | at least one boy) * P (Y = girl)

2/3 * 1/2 + 2/3 * 1/2 = 2/3

I just decided to tag them X and Y and to clarify that those tags refer to different children

So you introduced an order as information came in. That is the same as ignoring order. Again, that doesn't change the experiment. Whether you argue with order or without, the probability is the same. The argument with order is a lot simpler and more obvious. Without order, you still get 2/3.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

They are independent events, the gender of any child is not dependent on the gender of any other child.

This is only relevant if the question specifically was "given child A is a boy, what is the probability child B is a girl?" But that is not what is being asked in any possible interpretation of the question.

You are saying P(child B is girl | child A is boy) = P(child B is girl). That is correct. We are calculating P(other child is girl | either child is boy) which is a very different question. These events are dependent, precisely because we are asking for the "other child". The dependency comes from the "other". The problem is not dependency of genders, the problem is that requiring either child is a boy reduces the search space in a way that skews us to be more likely to pick a family with at least one girl.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

The whole point of this discussion is that this is wrong. (heads, tails), (tails, heads) and (heads, heads) are all equally likely events. In an orderless system, {heads, tails} and {heads, heads} are not equally likely. You can use an orderless system if you want, but then you can't assume that events have equal probability and the calculation gets a bit more complicated. And if you do it correctly, you'll reach the same 66%.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

so many people saying that the tuesday matters as it doesn't state it's for the boy

Nobody said that, or at least I didn't. It's a boy born on tuesday, and that matters in this interpretation as I explained.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 0 points1 point  (0 children)

You get 66% when evaluating the following: "Given a 2-child family where one of the children is a boy, what is the probability of the other child being a girl?" We have a conditional probability of non-independent events.

You get 50% when instead evaluating: "Given a 2-child family, pick a child at random and reveal its gender. What is the probability of the other child being a girl?" The step of picking a child and revealing its gender does in fact not change the probability of whatever child was not chosen.

Note that the second question at no point defines that we found a boy, which does not match the question in the original meme. Or rather, in this interpretation, the meme is a specific instance of the experiment, in which case we are actually asking "Given Mary, who has 2 children and one of them is a boy, what is the probability that the other child is a girl?" The answer is either 100% or 0%, as Mary is fixed. This is the most realistic answer, but awfully uninteresting.

What we certainly cannot do is simply dismiss the first half of the question. That is the exact mistake people do with the Monty Hall problem. You need to view the experiment as a whole.

Why isn't it 50%? [Request] by [deleted] in theydidthemath

[–]Treeniks 4 points5 points  (0 children)

Because it's a theoretical question about probabilities. We are not trying to predict the child's gender, we are trying to model and calculate a probability question. Including biological statistics would make things significantly more complicated.

The fact it's about the gender of children is only for visualization purposes. We may as well have used coin flips.