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

As an Englishman that has been transplanted to another country, I find myself making them more in Germany than I ever made them back home.

But that's because my wife requests it.

It would never occur to me to up the egg ratio so high to reach into that void though. My wife manages to mess up the proportions every time though, so maybe we'll unwittingly explore that region one day.


Oh interesting!

I'm also overseas these days, in Australia with my English partner, and have rarely thought of the English pancake in some time. Even when I'm making breakfast pancakes they're usually American style and I'm supposed to be watching my weight and cholesterol these days so that's become a lot less frequent too.


I want every commit to represent a buildable state in which I have confidence automated tests pass. Bisecting is made unnecessarily difficult otherwise, and it's nice to be able checkout any commit and just build something for testing.

This constraint is usually enforced by code review.

On Github, the unit of code review is the PR.

Therefore, I prefer squashing.


>On Github, the unit of code review is the PR.

It is, and that is some bullshit. The only sensible way to work with that is to break up larger features into several PRs - which is often positive anyway, but sometimes it doesn't fit the nature of the change.


I am not a fan of Github's interface.

But my point is, is that I believe the important thing to preserve in history is whatever your unit of review is. If you could stack PRs and each were subject to the individual review, I would not combine and squash those (just the individual commits within each PR).


>I believe the important thing to preserve in history is whatever your unit of review is

I do not share that belief, but this thread (your posts and others) gave me an idea about code reviews. They became commonplace when I'd been working in software for a while already and, while I see the benefits, I never really felt like I handled them well. I guess one of the ingredients for handling them better is to center the workflow around them - an area in which I have never noticed major changes in an existing project, although they are visible when looking from the right angle: Long-lived, large feature branches have become noticeably less common.


Reading through, something small caught me by surprise.

https://c3-lang.org/language-common/arrays/#fixed-size-multi...

Multi dimensional arrays are not declared in the same way they are accessed; the order of dimensions is reversed.

Accessing the multi-dimensional fixed array has inverted array index order to when the array was declared.

That is, the last element of 'int[3][10] x = {...}' is accessed with 'x[9][2]'.

This seems bizarre to me. What am I missing? Are there other languages that do this?


Please consider a variable `List{int}[3] x`, this is an array of 3 List{int} containing List{int}. If we do `x[1]` we will get an element of List{int}, from the middle element in the array. If we then further index this with [5], like `x[1][5]` we will get the 5th element of that list.

If we look at `int*`, the dereference will peel off the `*` resulting in `int`.

So, the way C3 types are declared is the most inside one is to the left, the outermost to the right. Indexing or dereferencing will peel off the rightmost part.

C uses a different way to do this, we place `*` and `[]` not on the type but on the variable, in the order it must be unpacked. So given `int (*foo) x[4]` we first dereference it (from inside) int[4], then index from the right.

If we wanted to extract a standalone type from this, we'd have `int(*)[4]` for a pointer to an array of 4 integers. For "left is innermost", the declaration would instead be `int[4]*`. If left-is-innermost we can easily describe a pointer to an array of int pointers (which happens in C3 since arrays don't implicitly decay) int*[4]*. In C that be "int*(*)[4]", which is generally regarded as less easy to read, not the least because you need to think of which of * or [] has priority.

That said, I do think that C has a really nice ordering to subscripts, but it was unfortunately not possible to retain it.


Thanks for pointing out what I was missing.

Please consider a variable `List{int}[3] x`, this is an array of 3 List{int} containing List{int}. If we do `x[1]` we will get an element of List{int}, from the middle element in the array. If we then further index this with [5], like `x[1][5]` we will get the 5th element of that list.

I get that motivation. In C++ it's an odd case that where `std::vector<int> x[4]` is "reversed" in a sense compared to `int x[4][100]`. And this quirk is shared with other languages (Java, C#).

But in my experience, mixing generic datatypes like this with arrays is quite rare, and multi-dimensional array like structures with these types is often specified via nesting (`std::vector<std::vector>>`) which avoids confusion.

The argument re. pointers is more convincing though.


File it with the footgun of the two different array slicing syntaxes: https://c3-lang.org/language-common/arrays/#slicing-arrays

I have already opened a discussion about this with the author, and I must say I agree to disagree that a language needs arr[start..end] (inclusive) as well as arr[start:len] (up to len-1) and if you use the wrong one, you’ve now lost a foot and your memory is corrupted.


The closed intervals for slices caught my eye as well, but I simply filed that under 'that's a weird quirk' rather than 'wtf?'.

It would require more thinking on my end to change that to either 'this is an acceptable choice' or 'this is a terrible idea'.

But the array indices being reversed on declaration? I cannot think of an upside to that at all.


Looking at those in my extended family that have reached retirement, this does not appear to be a given.

End of life care* is highly variable in duration and costs and many people do not adequately prepare for expensive endings.

* this is true of more than just care post retirement


Plus most of what needs to be done is highly informal and unstructured. Money can only buy so much. It can't buy someone who is going to actually represent your interests, rather than charging gobs of money for the illusion.


An unfortunate reality is that you're never going to have such services until there are children for them to service.

Decline like this is difficult to reverse, but that doesn't mean we shouldn't try.


I doubt it would make much of a difference. Children growing up in rural communities typically move to a bigger city as soon as they can, which is where they then find mates and start their own families. I suspect not many young people are going to give up the social opportunities to stay in a small town or move back there.


But when they want the family, they have the option to go someplace to build it. That's the point. Right now the people meet in the city and stay in the city because they're tethered there.


Your real commit history is irrelevant. I don't care too much about how you came to a particular state.

The overall project history though, the clarity of changes made, and that bisecting reliably works are important to me.

Or another way; the important unit is whatever your unit of code review is. If you're not reviewing and checking individual commits, they're just noise in the history; the commit messages are not clear and I cannot reliably bisect on them (since nobody is checking that things build).


It's sometimes nice to be deterministic.

I don't often care about a specific order, only that I get the same order every time.


Thinking about this upfront for me, I am actually wondering why this is useful outside of equality comparisons.

Granted, I live and work in TypeScript, where I can't `===` two objects but I could see this deterministic behavior making it easier for a language to compare two objects, especially if equality comparison is dependent on a generated hash.

The other is guaranteed iteration order, if you are reliant on the index-contents relationship of an iterable, but we're talking about Dicts which are keyed, but extending this idea to List, I see this usefulness in some scenarios.

Beyond that, I'm not sure it matters, but I also realize I could simply not have enough imagination at the moment to think of other benefits


I work on a build system (Bazel), so perhaps I care more than most.

But maybe it does all just come down to equality comparisons. Just not always within your own code.


Being able to parse something into a dict and then serialise it back to the same thing is a bit easier. Not a huge advantage, though.


Open source projects? Maybe less so.

But there are definitely companies that use Bazel in a major way.


At least in British English usage, there is no distinction between Jail, Gaol, and Prison other than at least one of these is a dated word.

I believe only the US has a strong distinction between Prison and Jail.


Part 4c (this is quite a long series) goes into some detail here. https://acoup.blog/2025/09/12/collections-life-work-death-an...

My own interpretation is that it's difficult to precisely compare how peasants were exploited to modern taxation regimes in the developed world. Perhaps more as an unfavorable relationship with the only employer in town?


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

Search: