(&v != &v) for function parameter

Not directly related to this, but I think it’s worth mentioning that the Carbon language is implementing arguments that cannot have it’s address taken. While Zig tries to optimize parameter passing by making all arguments const and letting the compiler decide between passing by value or reference, Carbon has value parameters and reference parameters. This is supposed to make it easier for the compiler to pass arguments in registers. Foonathan has nice article about it.
It’s curious to think that parameter passing is one the most basic things we do as programmers, and yet we have not found the optimal way of doing it.

5 Likes

I think what @LucasSantos91 posted here is the most compelling insight I’ve heard so far.

Here’s the thing… with what is being proposed, the address operator will have side effects - it still creates a singular copy instead of a new copy for each one. I agree this is a step in the right direction but there’s a bigger discussion behind all this.

There’s two ways you can go here - the implicit or explicit route. The implicit route potentially has a rule like “if you take the address of the parameter, the compiler now has to do x to make it behave according to the average programmer’s expectations”. This is a fine approach and introduces very little cognitive overhead.

The other way to do it is to make the programmer be very explicit about things and make the compiler’s job easier. Now the expectations are aligned but you have a bigger cognitive burden for an issue that most people don’t tend to notice.

At this point, I imagine the first option will be taken (if this gets changed) because the syntax around parameters is fairly well established by now.

1 Like

You are right. I used a sloppy language. It is deterministic. But it is an address operator with side-effects such that (&v == &v) is true for var and const, and false for function parameters (passed both by value or by reference).

2 Likes

Right, it’s inconsistent and that’s definitely annoying - I’m glad we have people advocating for higher standards with our programming languages such as yourself. I’ll definitely watch the issue on Git and throw in my two cents because I’d like to see this resolved, too.

2 Likes

This is what C compilers do. The moment you take address of a variable compiler makes it an l-value and puts one-and-only-one copy on the stack.

If your team is in charge of critical production systems, it might be too early for you to use Zig.

Zig is v0 precisely because it’s unfinished work. You need to keep your expectations aligned with the current state of the project (and its current development trajectory), otherwise you will build up expectations that the Zig project won’t be able to meet.

In this instance, you are describing this bug as one of “dire importance”, but that’s not the same level of priority for the Zig project because we have limited manpower and a very large scope to cover, which means that there are plenty of other bugs of comparable severity (see the whole RLS vs PRO thing for example, or miscompilations) .

More importantly, for the Zig project the goal is not to create a maximally usable v0.11.x Zig, but to have a smooth developer experience in order to create a maximally usable Zig v1. This does mean keeping Zig usable in the short term, but work prioritization follows the needs of those who do the work, not the needs of some “beta” users.

That said, some companies have invested in Zig and we do care about not regressing their use cases. Uber for example has a support contract with the ZSF that does make us prioritize bugs that they report.

(we also have something vaguely similar for relevant Zig projects, but that seems a bit outside the scope of this discussion)

So this is my advice wrt advocating for Zig in your company:

  1. Make abundantly clear to everybody involved that Zig is unstable software. It is usable, but it is not yet a battle tested, reliable tool. Using Zig seriously means being willing to participate in its development process one way or another (eg by reporting bugs).
  2. Learn how development of Zig happens, our financial structure and design philosophy.
  3. (optional) Setup a meeting between your team and me so I can answer any question that the materials available on the internet can’t.
  4. If your company vibes with the way we do things and concludes that it has more to gain than to lose by using Zig in its current incomplete state, then consider asking the ZSF for a support contract in order to further de-risk your technological choice.

This, in my opinion, is the only correct way of bringing a v0 technology to a company. Anything else is a highway to disappointment.

9 Likes

No, it is not for a critical production system but for greenfield proof-of-concept projects. Still the goal is to deploy in production for internal use.

I think this whole discussion has brought up a more interesting issue that I’ll make a post about regarding how to be an advocate for a language that is still heavily under development.

3 Likes

Yes, please! Looking forward to reading it. Rust was in these shoes few short years ago. I hope Zig can repeat its success. Moreover, Zig has advantage of much flatter learning curve.

3 Likes

I’m curious if this information - bugs reported by Uber and terms of their contract, is open to the general public.

In general it’s the bugs reported by motiejus on GitHub. The terms of the contract are not public but basically boil down to “we promise to look into your report right away, but we decide if it is a bug and how to fix it”.

3 Likes

More and more I think about (&v != &v) for function parameters, more I come to realization that Zig can follow Carbon language approach and ban taking address of function parameters making it a compile-time error. If I am writing a function where I need an address of an object passed into the function as a parameter I can always redefine function’s signature and pass this object by pointer (constant or mutable). Not needing to deal with parameter addresses makes (future) escape analysis some what simpler – one less pointer class to consider. I am curious was it ever considered?

5 Likes

I wonder if there are legitimate cases where you would want to know address of a parameter… Parameters are const, so you’re not supposed to mutate them anyway.

As I said in my comment if you want an address of an object pass it as a pointer. Pointer has an address as its value.

I don’t argue with that.
It’s just that I’m trying to imagine a situation where you would legitimately need to know parameter’s address, and I can’t find any so far.

1 Like

Neither could I. I do not see any sense in taking an address of a function argument.

1 Like

There many such cases. To name the few: (1) detecting aliasing. (2) If two objects equal by value are in reality the same object (the same address). The list goes on …

But we are talking about parameters. If function’s parameters are objects (as opposed to pointers, references, etc.), then they’re distinct objects by definition. Their contents may be the same (they’re equal, so to say), but they are not at the same location in memory.

Or am I missing something here?

1 Like

You can easily have multiply(M,M) to compute square of a matrix M. It is the same M for both arguments. The same as in the ‘same address’. You want to know whether you are multiplying the same matrix with itself or two different matrixes that happen to have the same matrix elements. You can think of other cases outside of numerical computing when identity of two objects plays a role in addition to their value equality.

They would have different addresses, as you passed them by value.

1 Like