Closed vi closed 3 years ago
A suggestion for option name: --exploratory
Sorry for bikeshedding, but the topic came up on Discord a while back and someone said that "Zig is currently not great for exploratory code", or something to that effect, so that's where it comes from. :)
Sometimes, you just don't know exactly what you're building, or how you want to do it, so you're "exploring" how to write the code. (Especially true for people new to Zig.) Having to handle for example allocation errors when you "know" they won't happen slows you down more than it helps in this particular stage.
Related: #68
The main issue with this idea (in my mind at least) is that it'll almost certainly result in people forgetting to turn the feature off, and then having to clean up a giant mess of code when they go to e.g. submit to a Zig package repository.
I think this idea is definitely workable, but it might need a tad more thought.
Another more minor issue: I don't think downgrading things like unreachable code to warnings is the best idea - that I think should show up as an even lower priority, as otherwise too many warnings could stack up quickly, making it hard to find what you're actually looking for. On the other hand, having it show up as a warning means there's a greater incentive to fix it, to clean up the warnings list even in --sloppy
mode.
This definitely needs a lot more thought, though I do think it has merit.
I don't think downgrading things like unreachable code to warnings is the best idea - that I think should show up as an even lower priority, as otherwise too many warnings could stack up quickly, making it hard to find what you're actually looking for.
Obviously, in the sloppy mode warning classes should also be ignorable.
For non-sloppy-mode usage, warnings should be ignorable on case-by-case basis, when unreachable code is by design due usage of to generic (comptime
) tricks.
people forgetting to turn the feature off, and then having to clean up a giant mess of code when they go to e.g. submit to a Zig package repository.
That's inevitable. It is also inevitable that sloppy-only libs that only live on Github, not on the official repository will apear.
But I assume there are many projects that don't come to the phase where it is reasonable to publish them (i.e. experiments). Pre-publishing cleanup (during which README, documentation, tests, etc. may be written) is simply not needed for them. Requiring clean code for everything (including one-off throw-away code) may be suboptimal.
Jonathan Blow just tweeted a thread (how timely! :) ) related to this: https://twitter.com/Jonathan_Blow/status/1194289482469502976
More of my perspective: I tend to always work in "full" warnings/warnings as error-mode in C/C++, so I appreciate releasing things where the code doesn't have hidden bugs or whatever.
But I agree with Blow here, and it probably needs to be more granular than on a project/build-wide setting? Like let's say you're working on a game and you're working on a subsystem that you want to fiddle with a bit before deciding on the final implementation, it makes sense to be able to mark that as sloppy, in some sense. I'm not sure if that can be easily solved in practice though... :)
And like @vi said, sometimes you work on something that you never have time to finish as a "proper" project, but that may still be valuable to people. Here's one of mine, https://github.com/Srekel/the-worldinator, it's not done yet and not sure if it ever will be, but I imagine someone might learn something from it.
More of my perspective: I tend to always work in "full" warnings/warnings as error-mode in C/C++, so I appreciate releasing things where the code doesn't have hidden bugs or whatever.
hidden bugs or whatever
Some warnings are not about hidden bugs, but about maintainability. Notably unused code warnings (including unused imports and unused mutability). Those warnings are most often triggered by something being unfinished (although sometimes they point to a bug as well, but rarer).
For example, when I start doing things in Rust, I typically add #[allow(unused)]
as soon as I see first of such warnings. Eventually this annotation goes away, as module stabilizes. It may reappear when heavy refactoring is undergoing. Something similar can happen in Zig projects. Start in exploratory mode, then go to normal mode. When reogranisation/refactoring happenning, switch the project back to exploratory mode for a while. For this it may be worth supporting specifying --sloppy
both on command line (quick debugging sessions spanning minutes/hours) and inside source code (project reorg spanning days/a week).
"proper" project, but that may still be valuable to people
Nobody forbids publishing unuploadable-to-official-repository code to a github.
Also related: https://github.com/ziglang/zig/issues/335 (proposal to add more errors for unused/unreachable things - these should be reduced to warnings in sloppy mode)
Instead of a command-line option, I would suggest some type of configuration inside the source code. If code is written in this sloppy mode
, then it's not really a command-line "option" that you can enable or disable, it's a feature of the code itself. The code is either written in "sloppy" mode or it's not, so the code should declare what mode it's written in.
Allowing each source file to declare this also allows you to compile multiple modules with sloppy mode enabled/disabled on a per-module basis without having to invoke zig multiple times to enable/disable it for each one.
After reading more about this it actually may make more sense to make it a command-line option. I thought this was a permanent type of mode for zig source code, but it looks like it's just a temporary switch to aid in faster refactoring/development.
@marler8997 , I think it should primairly command-line switch, but also triggerable from build.zig
(making it permanent-ish for a project).
Production-oriented version of Zig compiler may reject both.
Production-oriented version of Zig compiler may reject both.
I think that's a good idea.
Related: #224
This very useful for one off things or proof of concept. I suggest to make it as annoying so it is used sparing. I suggest avoid adding features but instead downgrading several errors to warning if they are related to safety or code maintenance. So if want to test a new method to do something as a proof of concept, I could test spend more time to test if the idea works.
the only material change to the language this proposal proposes is Errors about unreachable code, as well as other non-critical errors are downgraded to warnings
which would be a very very bad idea. Zig already has plenty of ways to make it so userland code can ignore errors if it so chooses.
one large barrier making Zig less "hacking-friendly" imo is needing to always having an allocator handy, but I don't think there are any plans to change that. and it's not that big of a mental change to need to add one extra property to your structs.
if someone doesn't like the ethos that Zig is going for, I would hypothesize that they are more than welcome to use another language.
The more I think about this proposal, the less I like it.
Additional built-in and library functions may be available. Example: #3296
The specific issue linked could be solved in userspace. More generally, the idea of adding functionality in such a mode seems quite problematic.
Errors about unreachable code (and similar), as well as other non-critical errors are downgraded to warnings. Such warnings may be hidden. Similar for ignoring errors, missing switch cases and so on.
This seems like a bad idea. There's a reason these are errors. My general rule for this is that if something indicates a problem with the code, it should be an error and not a warning.
A warning may be emitted just for mere enabling --sloppy mode, as an eye sore reminding that it is not supposed to be permanently enabled.
People are used to ignoring warnings in other languages (especially C). Adding one for this won't accomplish anything.
Mere turning on --sloppy without modifying source code should not affect program behaviour. Comptime functions may check for sloppy mode and @compileError if it is not enabled. The reverse should not be idiomatic.
These two points are contradictory. If it's possible to check, at comptime, whether sloppy mode is enabled, some functionality will be written to depend on it - and quite likely to change behavior based on it. Being able to check for sloppy mode at all seems like a bad idea, given the stated intent.
Fundamentally, this proposal means creating a compilation mode which ignores the Zen of Zig. It explicitly is intended to favor writing code over reading code, it replaces compile errors with both runtime crashes and bugs, and it prioritizes short-term developer convenience.
Another critical point: we intend to have a language server embedded in stage2 at some point. This should make refactoring painless anyways. I believe any other use cases for a sloppy mode can be addressed similarly - instead of making it possible to disable the language's safety features, we should work on making it so that you won't want to.
Overall, this seems to me to provide some short-term benefits at the expense of long-term code quality, and to make matters worse it requires complicating the compiler. Accordingly, I've changed my vote for to a vote against this proposal.
It is inevitable that sloppy-only libs that only live on Github, not on the official repository will apear.
This is only inevitable if we make it an option.
But I assume there are many projects that don't come to the phase where it is reasonable to publish them (i.e. experiments). Pre-publishing cleanup (during which README, documentation, tests, etc. may be written) is simply not needed for them. Requiring clean code for everything (including one-off throw-away code) may be suboptimal.
Requiring clean code for everything may be suboptimal.
This is my fundamental issue with this proposal. This proposal will result in bad code being written and published - and, realistically, used as-is.
Some warnings are not about hidden bugs, but about maintainability. Notably unused code warnings (including unused imports and unused mutability). Those warnings are most often triggered by something being unfinished (although sometimes they point to a bug as well, but rarer).
This is why we don't have those warnings in Zig.
I think that if there are places where Zig is currently inconvenient to write, we should focus on fixing that without simply giving up and encouraging bad practices.
I think that this line of complaint is avoiding the original point, that this is a opt-in flag, which will be added in a way (to be determined) that makes it clear that it's only for use in the thick of development. We're not proposing to "add warnings". And if people are able to post or paste online code that only builds in sloppy mode, who cares? They can also publish code that doesn't compile at all. Or code that only compiles on an old version of Zig.
I don't think people are going to take a third party library seriously if it only compiles in sloppy mode. You as the application developer will most likely be using those libraries in source form, and you are the one setting sloppy mode or not.
Tabs vs space is a hangup for some people, this is a hangup for me. It's extremely annoying to get unreachable code or unused variable errors when you are trying to debug something and commenting out 10 different regions of code in turn. (And I don't agree with having to rely on IDE features to smooth this out.)
And I don't think invoking "Zen of Zig" is valid in itself. If it says that Zig is supposed to favor readability over writeability, you can interpret that to any degree you want. Why are we going to have a live reloading incremental compiler? That's pure writeability.
Disclaimer: I might be arguing for a smaller subset of the sloppy feature than was originally proposed here.
They can also publish code that doesn't compile at all. Or code that only compiles on an old version of Zig.
Code that doesn't compile won't be given attention. "Old versions of zig" becomes irrelevant post-1.0, sloppy code doesn't.
I don't think people are going to take a third party library seriously if it only compiles in sloppy mode. You as the application developer will most likely be using those libraries in source form, and you are the one setting sloppy mode or not.
Sloppy libraries will probably result in the application developer turning on sloppy code too.
Tabs vs space is a hangup for some people, this is a hangup for me. It's extremely annoying to get unreachable code or unused variable errors when you are trying to debug something and commenting out 10 different regions of code. (And I don't agree with having to rely on IDE features to smooth this out.)
Refactoring wouldn't be an IDE feature, it'd be built into the compiler.
And I don't think invoking "Zen of Zig" is valid in itself. If it says that Zig is supposed to favor readability over writeability, you can interpret that to any degree you want. Why are we going to have a live reloading incremental compiler? That's pure writeability.
Incremental compilation has no affect on readability, and is not favoring writability over readability as a resuly. Sloppy code is less readable as a direct cost of the improved writability, which does.
Disclaimer: I might be arguing for a smaller subset of the sloppy feature as originally proposed here.
A smaller subset I'd likely be fine with, I'm against the proposal as outlined in the OP.
Ok, rereading the issue there is a lot more going on here than I had in mind. To me, sloppy mode should just suppress lint-like errors like unreachable code, unused variables, using var where you could have used const, declarations being required to be in a certain order, etc. That's it. I definitely don't support the idea of letting code check if sloppy mode is enabled, adding sloppy-only library functions, and stuff like that.
we intend to have a language server embedded in stage2 at some point. This should make refactoring painless anyways
This pushes the language into Java-esque IDE-only mode and detracts from text editor-based flow.
Sloppy libraries will probably result in the application developer turning on sloppy code too.
I don't thing that would happen in masse if typical Zig user values good code (and I expect average Zig user mindset to be different compared to baseline).
This pushes the language into Java-esque IDE-only mode and detracts from text editor-based flow.
No it doesn't require IDE's at all. It only sets the minimum above notepad(++). Vim, VS Code, and any text editors that support basic extension would support a zig extension that is capable of automatically running zls
and zig fmt
Zig already has plenty of ways to make it so userland code can ignore errors if it so chooses.
It is proposed to introduce a compile error if you create a var
that you never modify (#224) or never read from (#2304).
I don't know of any way for userland (the code being compiled) to "ignore" this compile error (short of employing a custom preprocessor).
If for this reason alone, I am in support of a --sloppy
flag.
EDIT: I've since found out we already have an error for unused block labels. That one seems even less sensical, but at least block labels aren't quite as common (at least in my code) as variables, so it evens out.
using const
where available is objectively better for performance and security over using var
/let
. how would pushing users to write better code be a bad thing? and why can't they use another language if this is a hard point for them?
Because this
It's extremely annoying to get unreachable code or unused variable errors when you are trying to debug something and commenting out 10 different regions of code in turn.
I don't think "use another language" is a very constructive response. This is an ergonomic detail, not some essential piece of the language.
Some reasons to use var
even though the value isn't modified:
* const T
, but those const
s are implementation details, not interface details, and you are semantically modifying the contents in a way that may require the interface to change to *T
in the future.This third bullet is surprisingly common. Here's one case:
const slice: []const u8 = ...;
var substr_index = 0;
const substr = slice[0..substr_index];
const ptr = @as([]const u8, substr).ptr;
In this example, changing substr_index
from var
to const
makes it comptime known, which changes the third line from a runtime substring to a comptime sub-array. When substr_index
is runtime-known, the type of substr
is []const u8
and it has a valid pointer. Therefore the value of ptr
is well defined. But if substr_index
is comptime-known, its type changes to *[0]const u8
, which is zero-sized and does not have a valid pointer. Therefore ptr
becomes undefined. Pretty much any use of ptr
after this point will trigger UB, but only if substr_index
is const
.
And here's another:
var i: u32 = 4;
const array = &[_]u32{ i };
array[0] = 4;
Here, i
is never modified. However, i
being runtime-known means that the array literal expression [_]u32{ i }
is not comptime known. This makes it a stack local variable, meaning that @TypeOf(array)
in the above code is *[1]u32
, and therefore the line after is allowed to assign to it. But if i
is changed to const
, it's now comptime known. Which means that the array literal is comptime known and goes in the constants section. This makes @TypeOf(array)
turn out to be *[1]const u32
, which causes the line after to fail to compile.
That said, my personal opinion here is that we should un-accept #224 instead of accepting this. I'm strongly against the idea of creating two versions of the language.
I'm strongly against the idea of creating two versions of the language.
In Rust world it seems to work ("nightly" vs "stable") - production users typically use stable. "nightly" for hacking + "stable" on CI is often a good combo, providing access to additional tools in development environment while keeping things in check for production environment.
Why wouldn't that work for Zig?
IMO it's different because Zig aims to be a language that doesn't change often. As I understand it, Rust's nightly contains features which are planned for addition to the language but may not be available yet or may change, so beware. This seems like the primary reason that CIs tend not to allow nightly - it's likely to suddenly stop working at some point. But with Zig, the language doesn't change. So we have two separate dialects that are just as stable as each other, but one is more permissive than the other. Making a codebase compliant with the strict subset of Zig will be thought about the same way we think about converting html into xhtml. It's great if you are super strict about it but not worth it in almost all cases.
Nobody asked for it, but here's a fun idea for making absolutely sure --sloppy
mode is not used in production: Give it a timestamp argument and auto-deactivate it after some time (f.e. one hour).
zig build --sloppy="2020-11-07-00:10"
Error: Your sloppy time is up! Current time: 2020-11-07-01:12
(Yes, you can write a script, but you can also just patch out errors from the compiler, and it's easy enough to adjust by hand.) (And I'm only half-serious. But also only half-joking.)
Trying to write the code that contains no unused things that are caught by Zig's "errors" is like trying to build a house while keeping construction site tidy and clean at all times.
Construction sites are typically messy and not pleasant to be in (at least in clean clothing without a hard hat). Cleaning up and removing all the garbage (in programming language case: unused things and dead code) typically happens near the end of construction process.
Give it a timestamp argument and auto-deactivate it after some time (f.e. one hour).
Maybe a better idea is to allow only one Zig source file/module to be sloppy at a time: --sloppy=src/workinprogress.zig
.
Trying to write the code that contains no unused things that are caught by Zig's "errors" is like trying to build a house while keeping construction site tidy and clean at all times.
I think you may be overestimating what Zig will count as a compile error. Unused or unreachable code can't possibly be standard compile errors. The entire conditional compilation system is built with the assumption that there will be very large amounts of both of these.
The only issue this proposal mentions that is actually accepted is #224, and even that is susceptible to major conditional compilation problems. The other two, #2304, and #335, can only possibly be validated with multibuilds (#3028), which will be optional. build-exe
is never going to fail because of either of these rules. Other checks you might want to turn off in sloppy mode, like #282, #952, #2654, and #5208 are all only enabled with multibuilds.
The only thing left is removing the requirement that switches handle all cases. But I don't think it's worth a whole separate compilation mode to avoid typing else => {}
.
build-exe
is never going to fail because of either of these rules.
Is multi-build being stricter than regular build a design choice or just an implementation detail that may change as Zig compiler gets more clever (i.e. detecting that a thing is obviously unused regardless of various flags because of it is mentioned in the source code exactly once)?
Will there be "open" multi-build mode where Zig should check things for specified list of targets, but not assume that the specified set is complete (so some things can still dangle around)?
In presense of multi-build, will simpler modes like build-exe
be still always available or there will be multibuild-exclusive features that lock projects to only building all targets at once?
My assumption was that multibuilds will act more like a linter than a compiler, but I might be wrong about that.
Is multi-build being stricter than regular build a design choice or just an implementation detail
Before 1.0 there will be a language spec that defines exactly what the boundaries are for what does and does not compile. It will err on the side of simplicity, so "clever" checks that are difficult to describe in a specification will likely not be allowed to cause compilation failure, unless they are deemed to be really valuable (like maybe some cases of returning pointer to stack var).
Will there be "open" multi-build mode
Some form of this must certainly exist. The standard library contains code that only compiles on windows, but not all projects which import the standard library will have windows as a target. It would be ridiculous for this to be a compile error. That said, it could be that the plan is to only run multibuild on the "root" package, and not validate external packages. In that case there would be a simple workaround would be to make your root package a stub that references "sloppy" code, but that's a simple enough hole that it will probably make sense to make an open build mode. Additionally, multi-builds inherently require a decent amount of configuration, so I think there will probably always be a simple alternative way to say "build this zig file into an exe and don't do the multibuild validation".
All that said, I haven't actually talked to Andrew about his specific plans for multibuilds, so I might be wrong about the plan here.
What I don't want is the Go problem, in which the programmer has to write dead code that the compiler allows, so that way the compiler doesn't flag the dead code that it doesn't allow as dead code:
package main
import "fmt"
func main() {
_=fmt.Println // important
}
Got here via: https://www.reddit.com/r/Zig/comments/ooknzg/lament_for_the_unused_parameter/
What if --sloppy mode would compile (parse, syntax check, etc) but not write code to disk? Well, might have to be a bit more clever to allow 'zig run' to work: write it to a tempfile, run it, then immediately delete it. The point is: if the worry is about (accidentally or otherwise) putting code built with --sloppy enabled into production - just never allow that code to hit (accessible) disk.
Or maybe there's a way to get the language server to suggest workarounds as potential fixes? eg. "Error: unused parameter 'foo' in function 'bar'. Remove it or add 'var __foo = foo;' to the top of the function." That would at least let people copy/paste fixes.
Here's a way to think about unused locals and unused parameter errors: The Zig language is designed to prevent bugs by making strategic use of friction. For example this is why coercing a u16
to a u32
works without any syntax at all, yet to go the other way requires the friction of @intCast
. @intCast
does not mean your code is wrong; it documents code that correlates with a higher chance of bugs.
Likewise, Zig supports unused parameters and unused locals. However such things are indeed correlated with a higher chance of there being a bug, so you have to confirm that the non-use is intentional with additional syntax, just like with @intCast
.
Friction is, by nature, uncomfortable, and people seek comfort, meaning that people seek to program in a way the language does not induce friction. Making use of all variables and parameters even while experimenting corresponds with the principle of YAGNI, which is a programming style unfamiliar to some. To those who already have taken YAGNI to heart, it will feel like the language is guiding you down the path you already wanted to go. For those who do not program this style, it will feel like the language is fighting you. For young programmers, it will shape their preferences as they develop their own programming style.
The Zig language is opinionated. There is one canonical way to do things. There will be no sloppy mode, and no divergence of compile errors from debug to release.
For those who find their own programming style to be in conflict with the language, I do have a suggestion, which is tooling. It would be reasonable to make a command line tool that you run and it "fixes" all unused parameter errors by adding _ = foo;
in the appropriate place, and automatically removing them when unneeded. IDEs could have this as a button you press to automatically do this for you. Eclipse has had this for ages with organizing Java imports and frankly it's perfect. You want a sloppy mode? That's fine, but it's not an officially recognized concept in the Zig language; what is sloppy is very personal and belongs in an individual's development experience.
Final point I want to make, the first priority of the Zig language design goals is the ability for a person to quickly and comprehensively peruse an unfamiliar codebase, and really understand it completely, holding it all in their head, confidently able to maintain it without worrying about unknown unknowns. Not allowing shadowing, not allowing unused variables, and requiring the use of const are all part of achieving this goal. Making writing code from scratch "fun" was never a goal of the Zig language. Personally, I think it's fun to make great software, but what's fun has to do with the application and end user experience, rather than minutiae about the language. A carpenter might have fun building something out of wood using a hammer and nails, but they don't use a "fun hammer". They just want an effective hammer, and the fun part is the part where you build something.
There will be no sloppy mode, and no divergence of compile errors from debug to release.
If this is some principled position then maybe respective entry should be added to zig zen
?
For those who find their own programming style to be in conflict with the language, I do have a suggestion, which is tooling. It would be reasonable to make a command line tool ...
Shall "annoyed by some language detail - write a tool to handle" be official position? Shall zig toolchain include means for making such tools relatively stable and simple enough?
Making writing code from scratch "fun" was never a goal of the Zig language.
Ignoring programmer's comfort too much can lead to workarounds that are even uglier, as demonstrated by Go example in a comment above. Such kludges are also sometimes seen in Java code (e.g. to evade unreachable code detection).
So completely ignoring code writer's needs for advancing code reader's needs can backfire. Some helpers should be available, be it inside Zig language/compiler or as a separate (but more or less popular and/or officialy supported) tool.
This sounds like a false dichotomy. I don't want to remove unused var errors, they are good and I think most people agree. We can have unused var errors and still make it easy to write/triage/debug code in Zig.
The unused vars case is interesting because it demonstrates a case where we have Zig code that can be compiled but that the compiler thinks could be a bug so it refuses to do so. The compiler is taking on multiple roles, that of a compiler and a static code analyzer. This is a great feature because it helps find more bugs at compile-time, but this particular use case is at odds with code as it is being developed since there are times when vars aren't used because the code hasn't been written yet, or its been commented out for triage/debug. It's at this time where we don't want the static code analyzer, we just want the compiler. Note that this occurs not only when code is being written, but also when it's being triaged/debugged which falls into the "reading code" camp as well.
If we think this issue is big enough to address, I think it would be best to classify errors based on whether they affect compilation or whether they just "look like they might be bugs".
A command-line option that tells the compiler to temporarily stop looking for "potential bugs" and just compile the code could solve this issue. I'll add that my confidence that this is an issue that could justify added complexity has increased since experiencing what it's like to write new code with this new analysis enabled. If this is an issue worthy of concern, then I expect everyone else will start to feel the same annoyance and we can talk about potential solutions then.
The compiler is taking on multiple roles, that of a compiler and a static code analyzer.
This is an incredible *feature* of Zig and raises the standard of all Zig code. I am firmly against there being a sloppy mode or a way to disable certain compile errors. As both a user of Zig code applications, libraries, and maintainer of a few libraries I absolutely love the assurances that we get for everyone by default with these errors.
Other languages struggle and go through great lengths to come up with an extensive collection of linting tools. With them being in the compiler itself, you can *know* that if you run zig build
and you actually get a program out on the other side, then *all* the code that went into producing that artifact is being held to the Zig standard.
That's more fun to me than writing code will ever bring.
Zig is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
Remember, Zig offers many a great developer features such as comptime, strong but lazy typing, etc, etc, but we (as developers) were never the main priority from the start. Zig's not for when you're writing code. Its for when you or someone else is trying to update or run your code weeks, months, or years in the future.
Together we serve the users.
Wow, bikeshedding in this issue is colossal. Just because of that I don't want the flag. If add the flag, the only thing it should do is turn off the "unused variable" errors. Suggesting the flag would be used not only at the moment of code modification is ridiculous.
If all this was about was unused variables, why not just --allow-unused-variables
? I'm not personally a big fan of the idea in the first place, but might as well through that out there.
--allow-unused-variables
There may be similar rule about unused mutability (var
where const
would also do). So it may make sense to have just --allow-unused
(either instead or in addition to fine-grained warning controls).
@andrewrk
A carpenter might have fun building something out of wood using a hammer and nails, but they don't use a "fun hammer". They just want an effective hammer,
Sure thing. But Go and Zig seem to be the hammer that makes your hand hurt while using it, which you only ever use when the other hammers you have don't do the job well.
Due to opinionated stuff like this (which are bad opinions, in my opinion), I only use Go when a library is only available in that language, and I only use Zig for its C/C++ compiler. Great job on that part of Zig, by the way! I only wish Zig itself would be better to use so I wouldn't have as much of an use for C/C++.
Since the lack of a "sloppy" mode actively prevents me from compiling and working, and breaks me out of my workflow to write bugs, Zig is actively trying to not be an effective hammer. If a hammer constantly gives me pain and forces me to readjust my grip, it's gonna be less effective than the hammer that just lets me use it to work.
and the fun part is the part where you build something.
These "features" make building something hard, frustrating, and seem to be specifically designed to make it not fun. It makes it so that when something finally gets built, it feels like it got built despite the language, not thanks to it.
Is explicit, documented refusal to implement dev/permissive mode better than endless postponing of it? It may promote creation of some separate, independent project to make Zig development easier. Such as:
Zig development proper may then focus on providing hooks and features for various language tools (not just "sloppificator', but also static analyzers, code tranformations, checking interpreteres, etc.), leaving implementation of convenient editing mode to the community.
Taking my first steps with zig at the moment, and immediately ran into this. How do people meaningfully iterate on code when the compiler complains any time what I'm writing isn't completed yet? Eg, I wrote this as a start to my program:
pub fn main() !void {
var g = Graph.init(std.testing.allocator);
}
But my program won't compile. Do I need to delete some of my code (the var g
) so I can test some other code, and then add it back again afterwards? Apparently I can't use _g
like I can in rust, to assure the compiler that my variable is unused. Do I need to write a useless dummy function just so I can test things? (Eg fn drop(x) {}
?)
This is a horrible experience.
And for what? To "force" me to "always write good code"? I'm not your wayward child. How utterly patronizing.
Do I need to delete some of my code (the
var g
) so I can test some other code, and then add it back again afterwards? Apparently I can't use_g
like I can in rust, to assure the compiler that my variable is unused. Do I need to write a useless dummy function just so I can test things? (Egfn drop(x) {}
?)
No, you can use _ = g;
for marking as "yes compiler i know its unused", and for mutability errors, just replace the var with const (there is _ = &g;
, but its kind-of a hack, and you should probably just temporarily set it as const).
the first is done automatically by ZLS' autosave feature, but the second you have to do yourself
As far as I understand, Zig places great emphasis on code maintainability.
Unfortunately, restrictions required for it are at conflict with ease of development, debugging and prototyping.
I suggest to have a special Zig mode that trades code maintainability for short-term ease, ergonimics and speed of hacking. Command-line option may be
--sloppy
or--devmode
or--lax
.Proposed rules for such mode:
--sloppy
as a minimal acceptance test.--sloppy
mode code.switch
cases and so on.--sloppy
mode, as an eye sore reminding that it is not supposed to be permanently enabled.--sloppy
without modifying source code should not affect program behaviour.@compileError
if it is not enabled. The reverse should not be idiomatic.--sloppy
mode. Master builds may be required.