Is there some option/builtin to disable "error: unused function parameter" in some cases?

My viewpoint is that I accept that the compiler is going to give very opinionated errors, no warnings, etc, and I appreciate the consistency. Also, it seems obvious that not everyone will agree on all that, because people have different workflows, they may want warnings vs errors, and they may want different errors/warnings at different phases of development.

In all other languages I know, there are linters to handle these differences in people’s needs and to check for things the compiler does not check. To me it seems obvious that linters will eventually exist for Zig.

In the case of unused vars, you can’t suppress (and will probably never be able to) the compiler errors. So the question is: how can they be customized somehow using a linter? The only thing I can think of is to have a tool that does configurable, automatic insertion of the discard statements, and that can distinguish between automatically inserted discards and those manually added – with that, it would be possible customize the errors for your workflow. Linters that I know of don’t insert code automatically, but perhaps a Zig linter will need that capability to handle this case.

This sounds pretty bad, now that I’ve written it down, but I can’t think of a better solution. Any other ideas?

Edit: I guess with tools like the VSCode tool mentioned, that inserts discards when you don’t use a variable, you could disable the compiler errors completely. And then add a linter that detects unused vars in the way you’d like for your workflow.

Linters is not a useful comparison. In other languages, unused parameters is a “warning”. What hordes of people have found is that “ignoring warnings is a troublingly easy way to introduce errors and defects”. Generally, all greenfield programs should be written with -wall -werror.

This is an especially weird one cause it’s honestly a complete non-issue.

1 Like

It’s not bogus, it’s instruction for you what to do next. I very much welcome it. In fact, I’d love if Zig did the same file-level consts (imports). Only pub consts should be allowed to be unused.

4 Likes

Agree. It would be nice to cleanup forgotten pub consts / vars.
I like the strictness.

This has a cure which is worse than the disease, so it’s probably not a good idea.

What I mean is “import is never used” flashes on the screen, I’m in a hurry, I say "drat’ (except more vulgar) and I tag it pub.

Then later I’m wondering why the heck (except more vulgar) this thing is pub, is that load-bearing, am I going to do a “breaking change” to downgrade it, it’s a mess.

3 Likes

Hmm, that’s an excellent point, but then maybe Zig does need a linter.

2 Likes

What I mean is “import is never used” flashes on the screen, I’m in a hurry, I say "drat’ (except more vulgar) and I tag it pub.

Gee, if only we had some kind of a concept that allowed you to have an error that you can ignore and resolve it later, at a time of your choosing, like an adult?


Zig’s lack of warnings looks to me like a PTSD overreaction to working with bad code or a bad environment.

Code that is a work in progress is a thing, it has unused names that are intended to be used later. It seems such an obvious fact, so much that it doesn’t have to be stated.

It is trivial to make your editor to highlight unused variables, and better than sticking _ = x; 100 lines down at the bottom of your function, just to convince the compiler it’s explicitly ignored for now (I know it’s silly to put it far away, but hey, you can).

Warnings are good.

Warnings being good doesn’t mean I want to see other people’s code filled with ignored warnings, it means I decide when to tidy. Great software can be developed in imperfect steps (and always is, because humans are imperfect). People who want to treat unused variables as errors can always do it as a personal choice, with a compiler flag, or just mentally never let a warning be ignored. The reverse is not true though, since an error stops your progress until it’s resolved.

I am really pulling my hair every time this is discussed. “always error no matter the context” is such a bad take… It holds back this language that does have some good and interesting ideas.

2 Likes

Here’s an idea: let’s make it an error to discard a variable in a place other than right below its declaration.

Just kidding.

Or am I? :smirking_face:

Zig needs at least one linter. I’m not convinced it should come with the compiler.

2 Likes

It will happen, one way or another. Some people are already doing their own thing for special cases, and such things will evolve over time:

Warnings are terrible!
I remember my C# and Delphi days. Ok… Delphi did a better job than C#. Most warnings were useful.
In C# it is utterly impossible to write a warningless program unless you disable most of them.
Certainly with their new constructors and nullable stuff, let alone their naming conventions.
No… I love the Zig strictness and I hope there never will be gray zone warnings.
It prevents you from writing a totally crappy “imperfect in development” thing. Who cares if you have to spend an extra minute in the ocean of programming time to do the _ = x;

5 Likes

I agree and I also like strict checking. But adding the discard statement is not a problem, it’s remembering to go back and remove it later (when that’s your intent). For right now, the only way is to append a FIXME-style comment and have some sort of process to grep for it before releasing, as someone suggested. And there is currently no way to disable the errors, for those who want a different workflow. We can probably do better. This isn’t a critical issue for me right now, but I think it is a situation that can be improved.

Why? (I didn’t use it… in the last decade anyway)

I don’t understand why anyone would care about the process of how other people want to work. Is it unreasonable to comment out a block of code just to test something out, without worrying about some variable becoming “not used”? I’m not interested in this speed bump (even if a “speed bump” is all it is).

I’m also not interested in the editor inserting the _ = x; stuff for me. It is simply useless noise – except for when it’s the final thought I want to express and commit. The editor should just highlight the unused variables differently to make it clear they are unused (I’m thinking of function scope here, in namespaces it’s maybe a more tricky question in Zig because of the lazy compilation etc).

The correct place to check there are no warnings is only at the point you decide you care. Many people here might argue that the right time is every time you compile (which is not a surprising position if you use Zig), but I will argue that making a mess can be ACTUALLY GOOD! You can make changes and experiment more easily, and tidy when you finish.

If someone works in a project with well defined standards, and they let the code just exist for long time with warnings in it, the problem is not the language… it’s the programmers who let it be that way. It is very easy to address with basic CI.

1 Like

Zig’s design is like that: it does push people in the direction of making code readable and reliable, even if the particular style it imposes may be an uncommon one. It’s a reflection of how strongly the designers feel about readability and reliability. So even though I understand why this particular issue is a problem for people, a counterpoint is that I have adjusted to it over time and appreciate the benefits of it.

Actually not a problem! The compiler will error out with a “pointless discard” error.

Which I think it actually a lot of people’s snapping point on the whole rigamarole. First it tells you to discard, and then you do, and then it tells you nope, gotta un-discard! Analogous behavior in a human will reliably provoke resentment, I get it.

I think the language is actually needlessly provocative. Try referring to someone’s behavior as “pointless” without them getting at least irritated, good luck. “var is used [here] so it cannot be discarded” would convey the point without getting everyone’s back up.

The behavior itself I support, for all the known reasons. But it’s controversial, and making the compiler be abrasive about it strikes me as, frankly, immature.

4 Likes

Sorry, I should have said the problem is remembering to go back and finish the code that should be using the variable. This is for the case where people want to create things in a partially working state and then go back and complete it in pieces.

1 Like

FWIW that was clear to me from your comment.

Warnings for this case are like a free TODO list you don’t have to manually manage.

Intentionally leaving things for later is fine and good. (as long as you actually go back and fix it at the appropriate time, of course)

I didn’t track “remove it later” as “finish the code” at all, no. That’s fine though, discourse is not an exact science.

I tend to use these ones:

fn newFn(a: A, b: B, c: C) !D {
    _ = .{ a, b, c };
}

That lets me prototype a function I need, without much mental effort, and then get back to writing the other function which needs to call it.

I said in the Docs writeup that I would support the Zig compiler generating ‘pointless discard’ messages for this formula also, but after writing the Zitron generator, I’ve changed my mind. Generated code is an edge case, but an important one.

I wonder sometimes if the way people code influences how irritating they find this. Probably a topic for another thread, but the Vim school moves around very fluidly, so hopping back to add that variable I need, but only when I’m ready to use, it is no sweat. I mostly only discard for function prototypes (as above) and for captures, and with captures I need something to hold the braces open anyway so it really isn’t a big deal.

1 Like

For me it’s not at all about the amount of “text editing work”, but rather that you have to care at all. I use neovim btw.

There are these desired states in my mind:

  1. Variable is used.
  2. Variable explicitly discarded.
  3. Variable not used, causing a warning (but not an error).

Because Zig has no warnings, I am forced into (2) where (3) is desired. So in practice I will have to write a comment as well, just in order to not conflate a (3) with a (2): e.g. _ = x; // autofix or “temporary ignore”. And then when I do use it, the extra work to remove the discard.

If you are commenting out blocks of code temporarily, for example as a sanity check if it does what you expect at runtime, you may have to add/remove all these pointless discards constantly.

Regarding the code generation use case, yeah, it is a special case. In Rust you would simply slap a #[allow(unused)] on the relevant function or module and call it a day. It should not be a big deal or require much thought. It’s scoped, so it only affects the relevant part of the code.

1 Like

Discards are a code smell, generally.

Unavoidable with the sloppy way many C APIs are written. This is one of the reasons why using wrappers to keep the C stink away from your Zig is good. Writing to the bare C APIs tends to let that bad stuff infect your code.