4 ms·
Broken is a very loaded word. So i don't agree with this as written. If by broken you mean "does not compile or pass tests", then fine, sure. If by broken you m
by DannyBee 5y ago
Broken is a very loaded word. So i don't agree with this as written.
If by broken you mean "does not compile or pass tests", then fine, sure.
If by broken you mean "there are likely some hard issues in there", then no, i don't agree.
I've watched plenty of really good software where the dev process amounts to:
1. Integrate code that is more experimental into the
development trunk
2. Let people discover what is wrong with it
3. Fix and iterate it
4. Release.
The approach on some open source projects amount to:
1. Refuse to integrate code until every conceivable thing is thought out and dealt with. Burn through and push away tons of contributors in the process
2. Integrate code (or sometimes just give up and throw it away!)
3. Discover there were bugs in it anyway, because no code is perfect. Fix them.
4. Release
I would put money the releases put out by projects that spend years arguing to get PR's "correct" are not of any higher quality (by bug rate, etc) than the ones that accepted more experimental code and iterated it in the codebase. In fact, i'll put money they are worse.
One (of many) reasons is that the former process is one where people are expected to fix bugs and issues after integration, and that their job does not end when the code is integrated. This matches reality - bugs will be found, issues will be discovered, etc.
The latter process often makes people feel like once it's "ready", it's "ready", and it's done. That just doesn't end up true in practice unless it's a remarkably simple system. (or you have highly verifiable systems/process)
- zozbot234 5y ago> 1. Integrate code that is more experimental into the development trunk > 2. Let people discover what is wrong with it > 3. Fix and iterate it This kind of experimentation can be done on a separate branch. There's no need to involve whoever maintains the "main" development branch until the code is reasonably OK for release. In some cases, it can be acceptable to merge code that's clearly marked as experimental into the main trunk if it's a totally separate feature that can be ensured to not affect normal use of the project. You can see this, e.g. with "nightly" Rust features, which are opt-in and clearly separate from the "stable" language. But this is not very feasible in something like a terminal emulator, for obvious reasons.
- DannyBee 5y agoYeah, that's the party line for sure, but the end effectiveness of waiting until "it's okay for release" is low. You will never reach that point. Most experimental branches basically see no use outside of who is developing them. So a lot of time you are only really getting them to the point they pass existing tests, and maybe whatever additional testing the person writing the code is doing. As a result it's really rare that code got enough testing on that branch that it was "ready for release" when it was integrated. Show me software done this way, and i'll show you software released with lots of bugs and point releases :) One of these development processes admits that's true and integrates it at some earlier point and accepts it will take more work despite that. I'm also not sure what "no need to involve whoever maintains the main branch" means. Software development is a team sport. If you don't want it to be, don't accept contributions (no judgement, i'm serious).
- abstract_put 5y agoAcknowledging my bias towards correctness first (or a harness for explicitly experimenting), I think your step 3 ("3. Fix and iterate it") is rarely ever done and that absence puts people off. In the corporate environments I work in, the PR sets the standard for what is acceptable and there's vanishingly little motivation to fix anything that isn't blowing up a high profile client. Basically mini tragedy of the commons. I wouldn't be surprised if an aspect of this is "I don't trust you'll iterate and fix this, and I don't want to, so please make sure this is correct". I would expect a contributor with a long/trust-filled relationship to the maintainer to have much more leeway for not-exactly-perfect contributions.
- DannyBee 5y agoMy bias is from watching a lot of smart people experiment well. I think you are not wrong in the limit, but it's a bit more complex than that: 1. You need to set expectations up front of what it means to contribute. 2. You need to be willing to spend time to help ensure people know how to iterate it, etc. Check in with them, etc. We often expect people to just figure out what you want or be completely self-sufficient. Especially with folks who have never interacted with your project, how could they possibly know how to do it well? We often motivate (positively or negatively). But we often suck at training people at things they aren't used to. Training goes a long way. etc Again, this will never work 100% of the time. You will find people who in fact, will just want to get it in and run away. I'm just trying to get that percent to say 5-10%, rather than 80% :) I agree with the aspect you see - people are not always willing to trust. This often turns into "you are all helping me with my software" rather than "we are all working together to produce software". In practice - the process i gave is also one of the only good ways i know to build long term trust and contributor relationships. You trust them to work on their code once added, and to care. They trust you to help them. That is how you start to build good team relationships. They will be good at things you are not, you will be good at things they are not. I'm not sure how you ever build a trust or community relationship if you say "i don't want to trust you to do anything, please drop it on me in a perfect state so i don't have to trust you"
- cma 5y agoA terminal emulator has security implications.
- DannyBee 5y agoSo? Lots of things do. Good programming practice would be to carefully segregate the security parts of it from the non, and keep that part small and carefully thought out.
- nyanpasu64 5y agoQuoting woodruffw: > The `nix` crate is a cornerstone of the Rust development ecosystem: if you do anything that requires POSIX or various nix-specific APIs beyond those wrapped by the standard library, then `nix` most likely provides a high-level and safe wrapper for them. Perfectionism is a virtue in this context, one that keeps large parts of the Rust ecosystem from accidentally consuming buggy code. I think "refuse to integrate code until every conceivable thing is thought out and dealt with" is the right* approach when contributing unsafe code to Rust projects, especially to a foundational crate. Rust is designed around the separation of safe code (which allows non-expert programmers to write code with the speed of C and the safety of Java), and safe APIs around unsafe code (exposing a interface around dangerous primitives, constrained so non-expert programmers can't misuse the API to achieve undefined behavior, use-after-free, dereferencing wild pointers, reading uninitialized memory, etc.). To ensure that safe Rust is actually safe (can't achieve segfaults), third-party libraries which expose safe APIs around unsafe code (like nix) should be proven/provable to never use-after-free, write to wild pointers, expose uninitialized data, etc. This is a high bar to clear, and takes dedicated learning to develop the necessary expertise. But not doing so would expose users of the library to possible segfaults when users "hold the API wrong", which is the failure mode of C++ that Rust exists to avoid. Sadly, the compiler and standard library itself has some unsoundness bugs (described as the "worst kind of bug") which allow convoluted code constructions to result in segfaults despite not containing `unsafe` blocks . These are tracked at https://github.com/rust-lang/rust/issues?q=label%3AI-unsound https://github.com/rust-lang/rust/issues?q=label%3AI-unsound.) On the topic of application-level code quality (rather than foundational libraries), I believe that for native applications, code which can't be proven to be memory-safe (either because the program's author doesn't know C++ and the libraries well enough, or because they accept poorly written code from outside contributors) is a significant factor towards the instability of C++ apps I've used. I'm not sure how to best develop this knowledge; perhaps newbies creating/maintaining codebases could be mentored by more experienced developers (who hopefully have prior experience with the app or problem domain)? Perhaps managed/GC'd languages make it easier to write approximately-correct code, since they don't require global architectural knowledge and flawless reasoning to avoid segfaults. However it still takes global architectural knowledge and flawless reasoning to avoid race conditions. Even though I value code quality over velocity, and despite how incorrect memory-management and threading inevitably results in broken programs, I hate to admit that that gatekeeping code quality and user-facing experience (perhaps architectural design?) could result in more stress, less progress and contributors, and a worse end result.