Is this stated somewhere? A simple search online yields nothing, and just testing it out on godbolt the compiler does inline at least simple async functions as mentioned in the article.
Not having a required input, say when you try to reproduce a previous build of a package, is a separate issue to an input silently changing when you go to rebuild it. No build system can ensure a link stays up, only that what's fetched hasn't changed. The latter is what the hash in nix is for. If it tries to fetch a file from a link and the hash doesn't match, the build fails.
Flakes, then, run in a pure evaluation mode, meaning you don't have access to stuff like the system triple, the current time, or env vars and all fetching functions require a hash.
Buildkit has the same caching model. That's what I'm saying.
It doesn't force you to give it digests like nix functions often do but you can (and should).
That doesn't really make sense since memory safety is a property of a language. You can have code that is unsafe (read unsound), but that is a separate issue.
For a language to be memory safe it means there must be no way to mishandle a function or use some object wrong that would result in an "unsafe" operation (for Rust, that means undefined behavior).
That is to say the default is safe, and you are given an escape hatch. While in something like c/c++ the default is unsafe.
I'd also like to add that program correctness is another separate concept from language safety and code safety, since you could be using an unsafe language writing unsafe ub code and still have a correct binary.
I've only heard of this concept in academic languages, I don't feel knowledgeable enough to recommend any specific one. In terms of mainstream languages, I think an analogous concept is the use-before-initialization analysis that languages like Rust employ, e.g. if I have a variable defined like this:
let x: u8;
I can't actually do anything with this variable:
foo(x); // error
Except I can apply the initialization operator:
x = 42;
And now I can do things with this variable as usual.
But consider that the type of x hasn't changed as a result of the initialization. Beforehand it was a u8, and afterward it was still a u8, and yet something about the state of the variable changed my ability to use it in various contexts. I believe that typestate is something like this, generalized to allow variables to flow through states (like a compile-time state machine) to ensure that things happen in the correct order.
> I could disable autoadding files, but life will be worse that way.
```
[snapshot]
auto-track = 'none()'
```
This is what I do, and I don't think it is worse. I prefer not having all my ignored files auto-tracked when I accidentally go back to a commit without them in the .gitignore
Some other solutions (which aren't simple at all):
- Remove specific files from auto-track
- Have a private commit with changes to the .gitignore and work on top of a merge commit
- Like last one, have a private commit with the files you don't want to push (+ merge)
I have it setup where any commit with a description that starts with "IGNORE:" is private.
snippet from my config:
```
[git]
private-commits = '''
description(regex:"(?x)
# (?x) enables the x flag (verbose mode) allowing comments and ignores whitespace
# see: https://docs.rs/regex/latest/regex/#grouping-and-flags
# Ignores commits starting with:
# (case-insensitive) PRIV: or PRIVATE:, or IGNORE:
^(?i:PRIV(ATE)?):
| ^IGNORE:
")
> `enum` is a "true" enum, while an `enum class` somehow isn't?
No. Enums are used in both cases. The difference there is in the types the enums are applied to. In one case, a basic integer-based type. In the other, a class.
This differs from Rust. Rust does not use enums. It relies on the type itself to carry all the information. C++ enum classes could have done the same, so it is not clear why they chose to use enums, but perhaps for the sake of familiarity or backwards compatibility with the regular enum directive?
> I mean more in the sense of "where did you get this definition from."
In other words, you want to have a conversation with someone else by proxy? If that's the case, why not just go talk the other people you'd really prefer to talk to?
> I'm still not seeing a difference
There is no difference. I recant what I said. This (strangely, undocumented in the above link) functionality does, in fact, provide use of enums.
Curious addition to the language. Especially when you consider how unsafe enums are. When would you ever use it? It is at least somewhat understandable in C++ as it may be helpful to "drop down" to work with the standard enum construct in some migratory situations, but when do you use it in Rust?
> Why not just go talk the other people you'd really prefer to talk to?
sorry, I didn't mean to be so argumentative or negative. (The "You'll have to ask the Rust community. Rust lacks enums." did get me a little annoyed :p)
> This (strangely, undocumented in the above link) functionality does, in fact, provide the use of enums.
I assume (like you said for c++) a good reason would be for c/c++ interoperate, but it also probably makes things like serialization easier. Sometimes you just need a number (e.g. indexing an array) and it's simpler to be able to cast then have a function that goes from enum -> int.
> Especially when you consider how unsafe enums are.
Do note though, going from int -> enum is an unsafe op which would require `std::mem::transmute`.
> sorry, I didn't mean to be so argumentative or negative.
Thanks, but I had no reason to think that the output of software has human qualities.
> That link was from "the rust book" which is primarily is for learning rust.
Learn Rust by keeping features of the language a secret? Intriguing.
> a good reason would be for c/c++ interoperate
I'm not sure that's a good reason. C++ doing it is questionable to begin with, but at least you can understand how a bad idea might have made it in many years ago when we didn't know any better.
> it also probably makes things like serialization easier.
It would, except you would never want to serialize the product of an enum as it means your program becomes forever dependent on the structure of the code. I mean, sure, you can remove the enum later if you are to change the code, so you're not truly stuck, but that kind of defeats the purpose. You may as well do it right the first time.
Enums are inherently unsafe. That you have to be explicit about converting the union to an integer at least gives some indication that you are doing something unsafe. It is not so unusual that Rust allows some kind of "escape hatch" to get at the actual memory. What is interesting, though, is that it also allows manipulation of what values are assigned by the enumerator as a first-class feature, which suggests that it promotes this unsafe behaviour. This is what is surprising and what doesn't seem to serve a purpose.
Is this stated somewhere? A simple search online yields nothing, and just testing it out on godbolt the compiler does inline at least simple async functions as mentioned in the article.
reply