RFC: Rename int/uint to intp/uintp, intm/uintm or imem/umem

This RFC proposes that we rename the pointer-sized integer types int/uint to intp/uintp, intm/uintm or imem/umem, so as to avoid misconceptions and misuses.
This is yet another attempt to rename int/uint. See A tale of two’s complement for reasons of the rejection of the previous proposal.
After community disscussions, this RFC has undergone a major revision and the originally proposed intx/uintx have lost favour.
Rendered View.

@liigo, in computer science, pointer is usually short for memory pointer as the context allows us to omit the "memory" part. But there are other kinds of pointers.
That said, I agree the connection between imem/umem and "memory pointers" is not obvious. But once one read the documentation, I believe this interpretation is not hard to internalize, especially when compared to "for memory-related things".
@ben0x539, I like ix/ux as suffixes too, it is unfortunate that x is too vague.

@liigo, in computer science, pointer is usually short for memory pointer as the context allows us to omit the "memory" part. But there are other kinds of pointers.
That said, I agree the connection between imem/umem and "memory pointers" is not obvious. But once one read the documentation, I believe this interpretation is not hard to internalize, especially when compared to "for memory-related things".
@ben0x539, I like ix/ux as suffixes too, it is unfortunate that x is too vague.

I added iptr/uptr to the candidates, it seemed strange when we had intp/uintp, imem/umem, intm/uintm as candidates in the RFC but not iptr/utr.
The text has been revised again, and I hope it is more coherent as a result.
I believe that we should nail down our general integer types/coercions/data structure indexing policies, as discussed in Restarting the int/uint Discussion, before deciding which names to rename int/uint to.

I added iptr/uptr to the candidates, it seemed strange when we had intp/uintp, imem/umem, intm/uintm as candidates in the RFC but not iptr/utr.
The text has been revised again, and I hope it is more coherent as a result.
I believe that we should nail down our general integer types/coercions/data structure indexing policies, as discussed in Restarting the int/uint Discussion, before deciding which names to rename int/uint to.

it really should be changed to something else. Anything else.

it really should be changed to something else. Anything else.

@CloudiDust thanks so much for your persistence with this issue!
The discussion is leaning heavily in the direction of a renaming like the one you're suggesting. Would you mind re-incorporating isize/usize as potential names, however? Perhaps with the pros/cons outlined here as well as your thoughts here?
(Personally, I tend to agree with glaebhoerl that all of the names are problematic in various ways, but these read fairly well and fit into existing language tradition.)
Also re: unresolved questions, after the current discussion I think we should probably move forward with some variant of this RFC, and then separately address:

Conventions regarding which integer sizes to pick. @valloric gave an excellent start on the thread, and I plan to post an RFC more formally codifying these.

Ergonomics, based on the evolving thread here. I think it's pretty clear that we'll want to make some improvements here, but it's not clear which, and we can add them backwards-compatibly. I think we should pursue this discussion vigorously after alpha is released next week.

Some more (summarized) comments about the names:

https://github.com/rust-lang/rfcs/pull/464#issuecomment-62957564
https://github.com/rust-lang/rfcs/pull/464#issuecomment-63882759

They are greatly aggregated by @1fish2: https://github.com/rust-lang/rfcs/blob/180cda6a41ce6320f3f6668651872bac0bd882ac/active/0000-int-name.md
+1 for imem/umem
cc rust-lang/rust-guidelines#24
cc rust-lang/rust#16446

@aturon, will do.
The problem here is that the actual semantics of int/uint has nothing to do with (container) sizes. It's simply that we preferred them (for now) as container sizes. And if having default int types is not desirable, maybe having default size types (in the "favoured in the names" sense) is not either?
But on the other hand, if the types can get rid of the "storing casted pointers" use case and focus on container-related usages, then idiff/usize can be fine choices. (Not isize because ssize_t in C/C++ is not for offsets.)

Rust isn't C / C++.

The maximum theoretical object size is int::MAX, not uint::MAX.

So I added discussions about idiff/usize to the RFC.
I think if no single pair of names can be satisfactory, then it may be a signal that we should indeed have aliases in the language. One possible solution is to rename int/uint to iptr/uptr, but also provide idiff/usize as aliases that are used in container method signatures.
Or we can have iptr/uptr and idiff/usize be different types with the same underlying representations. (For idiff/usize, the fact that they are pointer-sized will be but an implementation detail.)

@thestinger Yes, Rust is not C/C++, but if we are to use names that may remind people of C/C++, we'd better not do too surprising things.
That said I still agree with you on preferring imem/umem. Failing that, I now prefer having both iptr/uptr and idiff/usize and use them for different use cases.
We can also have a warning when people want to force a pointer value into idiff/usize.

I think we need to settle on a name that actually describes what it is to someone who hasn’t seen it before. iptr, for example, barely suggests it’s an integer at all, and sounds a lot more like it is a pointer type. The only thing it has going for it is that it’s similar to C’s intptr_t. ix and ip do not describe themselves at all, and if someone new to Rust read code using ix or ip I cannot possibly imagine how they could understand what it meant, other than possibly connecting the dots between that name and i8, i16, etc.. imem isn’t much better: it sounds like a type that represents… memory? That doesn’t really mean much. The i (as with every name) gives a slight hint, but I honestly don’t think it helps much, as it’s just a single letter. isize is a little better: it can represent the size of any type, but that’s probably not the main use of int today. I’d guess the main use would be indices, but I don’t think that means we should use a name like index/offset—it still hides the fact that it can be used for other things.
I’d really like to see a suggestion for a name that describes itself well. If you permit very long names, ptrsizedint is descriptive, but not practical.  index and offset are close, but perhaps don’t describe the full range of uses for the type.

Thank you, @wycats and @aturon for reconsidering this issue!
These types are for indexing and offsetting into blocks of memory, and for sizing blocks of memory, which is why I think the names imem/umem (or intm/uintm) are most helpful.
The names isize/usize are also good. A number good for sizing a memory block is obviously large enough to index into it, so the "sizing" purpose doesn't make the "indexing" purpose out of place.
There are indeed many kinds of pointers: absolute hardware addresses, virtual memory addresses, base pointers, relative pointers, scaled pointers, ... Names like iptr/uptr, intp/uintp, intptr suggest that the purpose of these values is to hold a pointer, and that's not it at all.
Thank you, @l0kod for digging up pointers [there's that term again] to those previous posts.

BTW the experiment using imem looks very appealing to me (other than some additional names that also need to change like AtomicInt). (The isize experiment has web server errors.)
Whether imem creates a barrier for newcomers is easy to test, but surely small compared to the misconceptions about int for newcomers from C/C++, Objective C, C#, Java, and even Swift.
Renaming int and uint is also an excellent opportunity to find misuses of those types.

@P1start, would having both iptr/uptr and idiff/usize be better than desperately trying to find a single pair of names that can satisify most people, which seems not to actually exist given the discussions?
@1fish2, I didn't consider the "many kinds of pointers" angle, thanks for mentioning them. But I believe people would expect the ptr in iptr/uptr to be the same as the ptr in C/C++ intptr_t/uintptr_t, which is fine if iptr/uptr are used only for the same use cases as intptr_t/uintptr_t..

@P1start we'd all love to find a self-describing name.
This concept is hard to name because it's not a common software concept. It does not match the use of int in other languages. It's a workaround for the problem of using bounded integers to index & size memory blocks that span 14 orders of magnitude without making 16- and 32-bit machines pay for 64-bit indexing or even limiting the language to 64-bit indexing.
Any name for the "pointer sized integer" concept is not self-descriptive. Why use a "pointer sized integer" for these purposes? We must explain: It's an integer type that can span the address space and therefore is sufficient to index into or size a memory block, while not taking up excess space on machines with smaller address spaces. That's hairy, and it glosses the part about signed integers only spanning half the address space.
I think it's an easier story to explain imem, intm, isize, or intsize. But not ideal.
@CloudiDust, the leap from C/C++ intptr_t to Rust intptr or intp or even iptr is not far but, as you noted, that type is for totally different uses.
I fear that aliasing the basic integer types would be more confusing than picking one-sided names, but this can be tested with a brief usability test.

What's the thinking behind the name idiff? Every subtraction yields a difference.

@1fish2, idiff comes from standard C/C++ ptrdiff_t, which is the preferred type for representing pointer/index offsets. The problem with isize is that people may confuse them with C/C++ ssize_t which is not for offsets according to the POSIX standard, though often misused as such.

The types aren't defined the same way as the C / C++ types though.

ptrdiff_t doesn't provide the guarantee that a pointer offset within an object will not overflow (pointer offsets outside of object bounds are invalid in C, so that doesn't matter)

It is also worth mentioning that by introducing iptr/uptr/idiff/usize, Rust's int type names would become quite in line with C99 (But not any other additional platform-specific standards like POSIX.) Which can be a plus from the familiarity point of view.

I don't see the point in introducing types with identical use cases and definitions. Mixing types will cause concern about potential problems when there should be none.

@thestinger, agreed, but keeping this distinction may be better than using uptr for container sizes or usize for casted pointers. Wanted or not, people already have (incorrect in various ways in the context of Rust) expectations for types with names that are similar to C/C++ ones.
Still if possible imem/umem should be chosen.

I feel like an opinion has been left by the wayside from the discussion, which is disappointing. I disagreed fervently with having a widely available non-warning/error isize outside of unsafe blocks. Some others expressed at least some agreement.
I will also say that I heartily disagree with isize and imem, they are both confusing, and could lead to widespread use of the types, which I think everyone agrees is undesirable. For that reason, I think intptr and uintptr are better names.
There are a few reasons:

Any short named 'automatically sized' integer is bound to be used more frequently than ones that have specific sizes. If Rust gives the option for people to forego thinking, that's what will happen. I dogmatically believe the only 'automatically sized' integer, if ever there is one, should be a bigint. Especially if it's something short like imem. Why would I ever use i32 again?

These pointer-sized ints when used will infect structs, resulting in portability issues with serialization. Very fast (Cap'n'proto-esque) serialization systems will introduce errors in serialization, or have to extensively guard against it. With names like intptr, there should be no confusion. It is an int that is a pointer, and one ought to be very careful doing anything with it.

These pointer-sized ints will infect public APIs, and could cause subtle issues when doing RPC/IPC, as above.

Ultimately, there's just no good reason to ever use a pointer-sized integer unless you intend to (a.) index an object exactly as large as your system memory can hold, or (b.) intend to do pointer arithmetic.

With reason 4a, the first is not a good reason: there is no collection in Std that could be reasonably expected to handle more than 4 billion elements. Systems using collections with indexes that large will design their own collections, because that's what they do on every platform where their data sizes are that large. Slices I think are the only exception, they should accept any integer size because they could theoretically represent a large, mmapped buffer. But since slices are a builtin type, what's the problem with making slices accept any integer type as an index input? Bounds checking could cause a panic to occur if the size of the index type is smaller than the slice. That is, index into a 257 element slice with a u8? Panic. Yeah, it could hide problems in small systems, but in my opinion any attempt to index into a slice with an integer that's too small is a hazard. Perhaps using any size 16-bits or lower could be a warning disabled by something like #[allow(small_index)].
Since I firmly believe you should only be able to work with pointer-sized integers inside unsafe blocks, I think it should be an error to use them outside of unsafe blocks.
And the name should be longer than any of the other integer types by a significant amount, to deter users from thinking it's for anything other than working with pointers. Given this, the only sensible names are something such as uintptr or intptr. It makes it clear: I am working with integers that are pointers.
I don't think a diff or size type is necessary for Rust, because raw pointers are so verboten that anyone working with them should be able to do so safely in an unsafe block. If a newtype is used to seperate a diff from a size, I would understand that, but the only conceivable situation that would be used would be FFI or low level systems code.

@AaronFriel, the reason this is left out of the disscussion is because,this RFC is for name bikeshedding, the general integer type policies are discussed here.
This RFC is based on the assumption that, a pair of pointer-sized integer types is to be left in core Rust, and we do not want int/uint as their names.
This aside, I find it a bit suprising that you believe imem to be a beautiful name that people will abuse. imem is specially chosen because it is foreign (so people will not default to it) and actually requires manual-reading to be understandable. I'll prefer i32 to imem if I can get away with it.
Also, there will be no diff or size types, but maybe idiff and usize, and they are different. (But as you do not like pointer-sized integers outside unsafe blocks, I can see why you don't want idiff/usize either.)

I feel like an opinion has been left by the wayside from the discussion, which is disappointing.

Most people understand why these types are valuable. I find it very reassuring that this is a minority view because it would harm the language.

Any short named 'automatically sized' integer is bound to be used more frequently than ones that have specific sizes. If Rust gives the option for people to forego thinking, that's what will happen.

These are fixed size integers with clear use cases, not "automatically sized" integers for people who don't want to think about the size. It's not clear from the current names, but it would be very clear if it was changed to imem / umem. It's not a balanced way of framing the issue.

I will also say that I heartily disagree with isize and imem, they are both confusing, and their brevity could lead to widespread use of the types, which I think everyone agrees is undesirable. For that reason, I think intptr and uintptr are better names.

I don't see why they're confusing. The types should be widely used, just not where pointer-size integers aren't appropriate. They are currently used way more than they should be but there's no reason to take things to another extreme.

These pointer-sized ints when used will infect structs, resulting in portability issues with serialization. Very fast (Cap'n'proto-esque) serialization systems will introduce errors in serialization, or have to extensively guard against it.

These don't cause any unique problems. Pointers of various kinds infect structs, as do all kinds of other opaque platform-specific data structures. I'm not sure where you think these are going to introduce errors. A statement like this isn't going to be taken at face value without any elaboration on what makes this a problem.

These pointer-sized ints will infect public APIs, and could cause subtle issues when doing RPC/IPC, as above.

Same as above. X needs to be portable. Y varies across platforms. Y is not guaranteed to be a significant problem for X. You have to connect the dots or it's just negative rhetoric.

Ultimately, there's just no good reason to ever use a pointer-sized integer unless you intend to (a.) index an object exactly as large as your system memory can hold, or (b.) intend to do pointer arithmetic.

Fixed-size integers are useful in cases where the bounds are guaranteed to be within the range. The possible values certainly don't have to fill the whole range for it to be useful. These types are useful for counting anything bounded by the number of bytes in the address space. It makes sense to use them for object counters like reference counts or collection lengths. It also makes sense to use the signed type for distances within types, whether directly in terms of addresses or another unit like the distance between two indices in a vector. Both the overhead and dynamic failure cases from overflow in smaller integer types are avoided by doing it this way. Large amounts of memory can be handled, which is important in this world of 64-bit computing.

With reason 4a, the first is not a good reason: there is no collection in Std that could be reasonably expected to handle more than 4 billion elements.

There are plenty of use cases for it within the standard libraries. 640k is not enough for everyone.

Systems using collections with indexes that large will design their own collections, because that's what they do on every platform where their data sizes are that large.

No, it's really not. It's 2014, and people use very large data structures in the real world. Crippling the types in the standard library and forcing people to roll their own without any good reason would be insane.

Slices I think are the only exception, they should accept any integer size because they could theoretically represent a large, mmapped buffer.

How is it not important for anything else like slices: ring buffers, vectors, hash tables, and more? I don't see why it's unimportant for trees or reference counted smart pointers either. There are use cases for managing lots of data, and you're haven't made an argument for why dropping support for that gives Rust anything in return.

But since slices are a builtin type, what's the problem with making slices accept any integer type as an index input? Bounds checking could cause a panic to occur if the size of the index type is smaller than the slice. That is, index into a 257 element slice with a u8? Panic. Yeah, it could hide problems in small systems, but in my opinion any attempt to index into a slice with an integer that's too small is a hazard.

Another dynamic failure case is bad for performance and bad for robustness. I don't understand why indexing with a smaller type than the one used to store the size would be a problem anyway. There is no possibility for an overflow.

Since I firmly believe you should only be able to work with pointer-sized integers inside unsafe blocks, I think it should be an error to use them outside of unsafe blocks.

The definition of unsafe blocks is very clear. It is a boundary between memory unsafe code and not good. It has nothing to do with good practices and bad practices. People look at the unsafe feature with glee because they see it as a way to force their subjective style choices on other people. This is a language that already has a lot of friction.

And the name should be longer than any of the other integer types by a significant amount, to deter users from thinking it's for anything other than working with pointers.

It's pointer-size, but that doesn't mean that it's just for pointers. Using fixed-size integers means careful thought about the lower and upper bounds. In many cases, the address space imposes a clear upper bound and these types are the correct choice.

It makes it clear: I am working with integers that are pointers.

The types can hold addresses, but they're not limited to that. In fact, it's a niche usage of these types rather than a prominent one. You're essentially arguing against those names by stating that you think they are misleading.

I don't think a diff or size type is necessary for Rust, because raw pointers are so verboten that anyone working with them should be able to do so safely in an unsafe block.

These types are important for far more than raw pointer arithmetic. Even if they were only useful for pointer arithmetic, you're going to have to accept that this is a systems language and there's not much more important than those use cases.

If a newtype is used to seperate a diff from a size, I would understand that, but the only conceivable situation where that would be used would be FFI or low level systems code.

Rust is a language for writing low-level systems code.

@AaronFriel It sounds like you're unaware of some key, non-obvious background, and as a result the term "pointer-sized integer" has led you astray. (This demonstrates a usability problem.)

Rust is a systems programming language that aims to bring memory safety and other software engineering benefits to everything from large programs that require 64-bit address spaces to (hopefully) embedded 16-bit safety-critical devices.
Currently, Rust only has bounded-sized integers. So we have to be careful about overflow/underflow (unlike higher level languages like Python and Dart). Rust pays for array bounds checking for the sake of memory safety but mostly skips integer overflow checking for the sake of competing with C++ performance. (See A tale of two's complement for the current plan on overflow checking.)
Rust uses target-dependent, "pointer-sized" integer types named int and uint for array indexing and memory allocation sizing to fully support large 64-bit programs without making 32- or 16-bit machines pay for 64-bit indexes or even limiting Rust to 64-bit address spaces. These integer types scale with the size of the address space so computations that are bounded by the number of bytes in memory will rarely overflow. (It's a clever workaround.) Consequently these types are used for many related things that can scale with the size of the address space like reference counts and collection indexes, and thus they appear in many places in the library APIs.
Rust currently does no automatic conversions between integer types. That means that when using i32 or u32 for (portable) data, we must explicitly convert to uint to use it as an array index or pass it to any of the mentioned APIs. Thus int and uint get widely used in code and APIs. (Fortunately, @glaebhoerl  started a discussion about automatic widening and conversion for array indexing.)
Unfortunately the names int and uint lead us to misuse these types as "default" or "go to" integer types, which they are not suitable for because they're non-portable.

@thestinger I think you severely misunderstand me. When I say "automatically sized", I mean that they are sized dependent on the machine, but fixed-size in a given binary.

I don't see why they're confusing. The types should be widely used, just not where pointer-size integers aren't appropriate.

I find this perplexing. Why would you want pointer-sized integers to be widely used? They make any binary protocol more fragile and the result is inevitably that when the Rust program interfaces with the outside world, a cast will be necessary. And the number of casts will simply grow as the pointer-sized type becomes more common. Those casts are all points where overflow or other incorrect behavior could occur, and so I think encouraging in any way for people to use pointer-sized types is a mistake. This is how I read "should be widely used", anyhow. And I disagree with that.

These don't cause any unique problems. Pointers of various kinds infect structs, as do all kinds of other opaque platform-specific data structures. I'm not sure where you think these are going to introduce errors. A statement like this isn't going to be taken at face value without any elaboration on what makes this a problem.

It's a serialization/platform portability issue. Write a file to disk? Well, if you used imem or whatever it is decided to be called, you will have invisibly encoded an error in the representation of your file. I think the only reason to use pointer-sized integers is when working with pointers. Otherwise, you're better off using a portable integer.

Fixed-size integers are useful in cases where the bounds are guaranteed to be within the range. The possible values certainly don't have to fill the whole range for it to be useful. These types are useful for counting anything bounded by the number of bytes in the address space. It makes sense to use them for object counters like reference counts or collection lengths. It also makes sense to use the signed type for distances within types, whether directly in terms of addresses or another unit like the distance between two indices in a vector. Both the overhead and dynamic failure cases from overflow in smaller integer types are avoided by doing it this way. Large amounts of memory can be handled, which is important in this world of 64-bit computing.

But these use-cases are limited exclusively to counting things that are exactly bounded by the size of your address space. Filesystems, databases, the internet (IPv6) and the world at large demonstrate that using pointer-sized types is either too large or too small in an overwhelming number of cases. The cost of using pointer-sized types is a lack of portability and potentially hidden bugs.

There are plenty of use cases for it within the standard libraries. 640k is not enough for everyone.

I should have been more clear. I should only be talking about Vec, VecMap, RingBuf and their kin, excluding any collections that doesn't rely on contiguous memory. And Vec does not scale well to very large sizes. A very large Vec will have abysmal performance for a very large number of operations, with very long pauses during copies which can occur as a result of many of the methods present.
To fix this, Vec would have to be rewritten and not be a contiguous piece of memory anymore. An efficient, very large vector would have to take advantage of things that are currently beyond the scope of Vec. Any user who writes code that takes 10 billion items into memory and then clones or pushes a Vec of them around is going to be chastised for not using the appropriate data structure. Almost certainly a rope like structure, a trie, a discontiguous vector, a B-Tree, or a litany of other types would better serve their needs and be vastly more performant.

How is it not important for anything else like slices: ring buffers, vectors, hash tables, and more? I don't see why it's unimportant for trees or reference counted smart pointers either. There are use cases for managing lots of data, and you're haven't made an argument for why dropping support for that gives Rust anything in return.

I have amended my claims to include RingBuf with Vec, but it's not the same as a slice. You don't index into hash tables with pointer-sized types. That would be silly, because if you did that you would be better off with a radix trie, b-tree, Julia tree, or something like that. Because if your index into a hashtable is a pointer-sized integer, you are better off skipping the hashing process.

Another dynamic failure case is bad for performance and bad for robustness. I don't understand why indexing with a smaller type than the one used to store the size would be a problem anyway. There is no possibility for an overflow.

Because there is a possibility for hidden failures if you index into an object that contains 1 million elements with a 16-bit integer. That's all.

The definition of unsafe blocks is very clear. It is a boundary between memory unsafe code and not good. It has nothing to do with good practices and bad practices. People look at the unsafe feature with glee because they see it as a way to force their subjective style choices on other people. This is a language that already has a lot of friction.

And I think pointer-sized integers ought to be considered memory unsafe, because there's only one good purpose for them. You disagree, but I think almost every case where you say your next statement I disagree with.

It's pointer-size, but that doesn't mean that it's just for pointers. Using fixed-size integers means careful thought about the lower and upper bounds. In many cases, the address space imposes a clear upper bound and these types are the correct choice.

This is our primary point of contention I think. In almost no case that I can think of do you intentionally want a data structure to be capped to 32-bits on one platform and 64-bit on another. Not all data structures work directly with things in memory, and pointer-sized types introduce friction not just when Rust interfaces with other Rust code, but with the entire outside world. Other users have mentioned data structures that use files as a backing store, databases, any networking code, etc, you do not want to use pointer-sized integers. Any time you use a pointer-sized integer, you will have to eventually cast it to a fixed size to interact with the rest of the universe or introducing bugs when two programs with different integer sizes interact.

The types can hold addresses, but they're not limited to that. In fact, it's a niche usage of these types rather than a prominent one. You're essentially arguing against those names by stating that you think they are misleading.

I beg to differ, where are they appropriately used other than for interacting with memory? Because as you said, the only use case for pointer sized integers is when the upper bound is explicitly the size of memory. There's only one thing in the entire universe that has the same size as the amorphous concept of "the size of the current machine's memory".

@1fish2 I am aware of most, if not all of what you wrote, but it's helpful to have an explicit description of the demands of Rust. Still, though, I disagree. I still fervently disagree.
I don't think anything in my proposal, whether just for bikeshedding names or for restricting the pointer-sized integers to unsafe blocks, is unreasonable in accomplishing the goals you mention. If anything, my proposal only strengthens portability of code between 16-bit and 64-bit platforms. That is, by restricting the pointer-sized stuff to the very smallest use case, everything else is more portable by default. Even 16-bit embedded platforms often deal with data stores that might require 32-bit integers. To paraphrase @thestinger, "65,536 items is not enough for everyone". That is, making the decision to exclusively pointer sized stuff in one case hurts other use cases tremendously. To believe that a program on a 16-bit system will never need to count higher than 65,536 is, well, ignorant. And having Vec be indexable by different sized integers doesn't impose any additional cost on the Vec. In fact, my proposal is only buttressed by the fact that existing Rust code that works with pointers is littered with unsafe!
RingBuf:
http://doc.rust-lang.org/src/collections/ring_buf.rs.html#41-52
50 references to unsafe!
Vec:
http://doc.rust-lang.org/src/collections/vec.rs.html#41-52
57 reference to unsafe!
These low level data structures already hide a lot of platform complexity behind an API.
To use trendy CS terms, pointer-sized integers are a leaky abstraction. If you let them run wild, you end up with C/C++ and their style guides strictly encouraging users to be explicit about what size types they want, or forcing a choice on everyone for the good of mankind (as with making int 32-bit).
No language has escaped this, pointer sized integers are like playing with fire.  This is why I think they should be relegated to unsafe blocks, because there is no better place for them.

There's no other reasonable size for things like the size of Vec or the count of an Rc. You cannot have a dynamic array bigger than the size of the address space. You cannot have more references to an object than the number of addressable locations in memory. Getting rid of memory-sized integers will just force them to be reintroduced through cfg for these sorts of use cases- big enough not to overflow, small enough not to waste cache space.
Also, using unsafe in data structures has absolutely nothing to do with the size of the integers they use. It has everything to do with the fact that things like Vec are implementing low-level abstractions that in other safe languages are just baked into the language and are thus entirely unsafe.

@AaronFriel I basically agree and would love to see an RFC for banishing pointer-sized integers to the very rare intptr_t cases. It's not easy since they're a very convenient hack. The type is workable for any use that's constrained to be less (or much less) than the address space. What type should a function like len() return?
Non-portable integers are a leaky abstraction that quickly leaks out [sorry] into other uses. They should certainly not be used beyond main memory, and lint checks should check where feasible. I've been trying to plug some leaks but if you can drain the swamp, please do.
My point about 16-bit machines is that int (in library code et al) will fail nearly everywhere it leaks into non-address-space-constrained uses. (When writing Google Maps for PalmOS, I had to banish int which is 16-bits. That meant bucking the style guide and code reviewers.)

So I know we've been talking about these names to death, but FWIW, here's how I currently see it:
imem/umem
Pros

The name pretty closely reflects the underlying concept (a measurement of the extent of some memory on this system). It is not biased toward any particular usage (for pointers or for container indexes)
Fits well into our general naming scheme, reasonable suffixes.
The names are new, which means that people are more likely to search for documentation about them, and can be directed to our guidelines etc.

Cons

The lack of familiarity of these types may turn people away from Rust.
There's possible ambiguity about the meaning of mem here, but I don't think that's a significant worry personally. (In particular, it's still closer to the intended meaning than many alternatives)

isize/usize
Mostly like imem/umem, except that the names are somewhat less directly evocative of the intended meaning and more suggestive of a particular use. On the other hand, the names are possibly more friendly.
offset/size
Pros

Much friendlier-seeming names. They describe one typical use (container measurement) well -- and this use is the one more commonly encountered by newcomers writing safe code.

Cons

They do not describe the intrinsic meaning of the types as well as imem/umem for example.
They uses they describe don't cover all uses of the types.
They don't fit into the current integer naming scheme.
Suffixes?

intptr, iptr, intp
In Rust, ptr generally refers to raw pointers, making it would be easy to confuse these for pointer types.
For intp, you don't have the ptr confusion, but I don't see much advantage of these over imem/umem, personally: they seem equally unfamiliar, but their names carry less of the direct meaning than imem/umem. Like the size variants, they are biased toward a particular use of the type.

I like isize/usize the most if you can claim that the size part refers to the width of pointers, not its use as a "size" of anything. It's basically a contraction of integer_pointer_size_bits like i32 is a contraction of integer_32_bits.
If you're going to go with intptr might as well just make it iptr_size to be REALLY clear.
imem/umem is I guess my second choice because it's something vague about memory. But I don't have as clear of a mnemonic for it to explain to other people why it's mem.

I like iptr_size too. I don't like iptr, imem, isize, or even size. The first two are confusing, the latter two appear to define the size of all things forever-more. And that's wrong because APIs will adopt those to represent sizes incorrectly, and suddenly your 16-bit embedded devices don't work with libraries and public APIs. (Although this is obviated if my suggestion to restrict these types to use in unsafe blocks.)

So one thing that's been driving me crazy is trying to understand the use case for signed "size" types.
Specifically, while a signed size type is usable as a negative offset, that type cannot be used to
reference the top of the theoretically available address space.
Presumably the reason we care about the unsigned size type in the first place is that we want to
make sure that we can talk about 2 ** 63 + 1 bytes of memory, and any method that takes a signed
size type is making that  impossible.
I reviewed the standard library and the use-cases for ssize_t and it seems to me:

It's used in the unsafe offset method, which is talking about literal memory offsets, and where
the 2s-complement representation makes it happen to do the right thing.
It's used in POSIX to reserve -1 for the error case, and presumably people aren't too bothered
about the fact that you can ask pread for a size in bytes that the return value of pread can't
represent?

In general, it seems that this type is extremely unusual, frequently incorrect, and used in Rust
today to talk about literal memory offsets. Am I missing something?
(If this is the case, I think it might be ok to use size for the type in Vec etc. and use something
more obscure like mem::isize or libc::ssize_t to refer to the much-less-commonly-used type).

@wycats I believe you're correct, int is only used meaningfully used offset methods.

The i* and u* conventions are very nice and I wouldn’t like to abandon them just for size, which means usize gets my vote. I find it OK to move the signed variant out of core language, especially because it can be added later backwards-compatibly if need arises.
It doesn’t look like we will ever come to any kind of consensus until some kind of vote is made.

@wycats I think you're right.
I don't agree with using a pointer sized integer for collections though. It will cause the std collections to be unsuitable for many purposes. Certainly for sparse data structures, their size-ish type should be possibly much larger than the pointer size. That's certainly true for 16-bit systems, and often the case for 32-bit systems. For contiguous data structures like Vec, their size will be strictly less than the pointer size, true, but some people seem to suggest that they should be designed such that they safely work up to that size. A Vec is the wrong structure to use for many billions of elements, and anyone with a massive system storing 2^40 elements in a Vec would be rightly chastised by the community for expecting that code to work with no performance issues as they perform the standard operations on it.
This is akin to people using the list data type incorrectly in Haskell. There are a number of collection types easily accessible in Haskell, but it isn't anticipated they will scale to every possible use case. Just because you can store a billion elements in a list and just because you can index into a list, doesn't mean it's a reasonable thing to do, nor should the simplicity of the standard list type be taken away to satisfy consumers who demand that it scale from the largest to the smallest use case. That is absurd. It is bonkers. It is the prose of a madman who writes in such a way.
If this machine-sized integer, imem or usize or whatever infects the language as a standard type that anyone can use anywhere, expect it to be misused. People will use it for reading from databases, reading files, it will be used for interacting with the outside world. And coming from doing a lot of Haskell development, that feels a lot like unsafeperformio. It's wrong, it's bad. Using usize projects the constraints of the current binary onto the rest of the world. That's wrong.

@iopq, we can say that mem means "memory-pointer-sized". This interpretation is not vague, though not obvious either. (But we expect people to read the doc.)
isize/usize don't say which "size" they have if we don't consider them variants of C's size_t, and they are actually more like intx/uintx then, i.e. the size suffix would be too vague. But if we consider them size_t's variants, then they favor specific use cases over others.
@AaronFriel, iptr_size is clear but too long. However if the intention is purely to discourage its usage, that will be fine. However we don't really want to discourage its usage too much. (Which I believe we are in disagreement with.)

There is no reason to use a non-portable integer and have it leak out into consuming code.
This is a systems-programming language. People expect need to know the underlying Vec semantics, it would be surprising if it wasn't indexed using a uint. See C++ where this is also the case for std::vector and std::string.

@wycats, ssize_t is in the POSIX standard but not the C standard, and it actually means "a size type that can represent -1", it is not for offsets according to the standard because the availability of other negative values is not guaranteed. But in practice it is often used as offsets.
The correct standard C99 type for index/pointer offsets is ptrdiff_t. I think C doesn't distinguish between index offsets and pointer offsets because C arrays are more closely related to pointers.
This is also why I am against isize but fine with idiff as usize's counterpart. (We don't really need a size type that can represent -1, but we need a type that can represent index offsets.)

@wycats: It's only valid to perform pointer arithmetic within a single object. Rust defines the maximum object size as int::MAX so it is always usable for this without overflows. This information is provided in the manual and has been restated many times here. It helps to read the existing discussion before throwing in your two cents, or you'll just be contributing noise.

@AaronFriel
I've sometimes thought the same thing about e.g. Vec -- it's unusable at very large sizes. But I always run into trouble with slices, which are a common way of working with vectors. A slice is just a hunk of memory with a size. Since it's certainly reasonable for a hunk of memory to be very large (sized > 4gb), you can't reasonably limit the size/indexing/other APIs for slices to e.g. u32. And trying to make slices generic over the size type doesn't seem to work out very well either, for many reasons.
Have you thought about this aspect of changing the nature of vector indexing away from pointer-sized integers?

@wycats: Pointer-arithmetic overflow is not defined as being two's complement wrapping in either C or Rust. It is not even well-defined to index outside of an object, let alone wrapping around the address space. There's a reason that compilers and robust C library implementations like musl enforce PTRDIFF_MAX as the upper bound on object size. The operation ptr2 - ptr could be undefined within large objects if objects larger than PTRDIFF_MAX bytes were permitted.

@aturon: The Vec type is hardly unusable at large sizes. The throughput remains just as good as it gets very large even without reserving memory, and there is always the possibility of reserving the necessary memory up-front. There are similar types like chunked lists where latency doesn't suffer when the types get larger.

@thestinger

@aturon: The Vec type is hardly unusable at large sizes. The throughput remains just as good as it gets very large even without reserving memory, and there is always the possibility of reserving the necessary memory up-front. There are similar types like chunked lists where latency doesn't suffer when the types get larger.

My comment may have been too glib, but what I meant is that at sizes that require >32bits to measure, you probably want to be using a data structured more tailored to your use case. (Though I take your point that there are some particular uses of Vecs at that size that may be reasonable, which is further evidence that tying the size measurement to the address space is the right move.)

@aturon: If you aren't considered with latency, using Vec at very large sizes even without reserving space is perfectly fine. The geometric growth is there for exactly this reason - so throughput doesn't suffer at all as it grows larger. In fact, the existence of mremap means that the throughput can increase at large sizes.

@CloudiDust: C considers dynamic allocations and scalar values to be array objects in the sections covering pointer arithmetic. Pointer arithmetic is defined in terms of array indices. There is a distinction between pointer-sized integers, pointer-difference integers and size integers in C but it's not sensible to bring it up in the context of Rust. Rust does not and will not support segmented memory models. It's as simple as that.

@1fish2, I believe "pointer-sized integer" is the only sane (in the "saner than all others" sense, the others being any fixed size integer or "nothing") default indexing type for the core data structures. But on the other hand, I agree the core data structures can be parameterized by indexing types, which hopefully can be a backwards-compatiable extension.

@thestinger, yes, Rust doesn't have this distinction in semantics and this is all the more reason to abandon any type name that can remind us of C types, which leaves us imem/umem. (Actually iptr_size or iptr_sized is clearer, but is long, irregular, and feels out of place.)
OTOH, as a fallback plan which I am increasingly unwilling to fallback to, if we do use C-like names, we should surprise people as little as possible.

@aturon

I've sometimes thought the same thing about e.g. Vec -- it's unusable at very large sizes. But I always run into trouble with slices, which are a common way of working with vectors. A slice is just a hunk of memory with a size. Since it's certainly reasonable for a hunk of memory to be very large (sized > 4gb), you can't reasonably limit the size/indexing/other APIs for slices to e.g. u32. And trying to make slices generic over the size type doesn't seem to work out very well either, for many reasons.

I somewhat disagree. There are legitimate use cases when it might be useful to restrict slices on a 64-bit system to only containing a hundred elements, and a slice indexed by u8 would be better and more ergonomic. Anyone seeking to do otherwise would have to have a number of casts or waste memory and cache. There's no reason slices should be restricted to only taking the machine-sized type, and it'd be nice not to get an error if you didn't.
Even better, would it be possible to have indexes be linted/warned against if the same identifier is accessed with different-sized index values? That way if you consistently use u8 throughout your code, it's clear you meant to do so. If you consistently use u16, likewise.

@AaronFriel: There's no benefit from storing the internal length in a different format than a pointer-sized type. It has to be padded to that length anyway. Permitting indexing with other types is entirely orthogonal to the internal storage type. I think it would make more sense to allow integer extension without casting rather than hard-coding it for anything taking a fixed-size integer... if it doesn't make sense across the board, I don't see why it makes sense in isolated cases.

Even better, would it be possible to have indexes be linted/warned against if the same identifier is accessed with different-sized index values? That way if you consistently use u8 throughout your code, it's clear you meant to do so. If you consistently use u16, likewise.

I don't see why this warning would be helpful. It's not a correctness issue at all. The smaller integer types can successfully index all values they can hold. If there's an overflow occurring, it is not caused by the indexing or slicing operations.

@AaronFriel

There are legitimate use cases when it might be useful to restrict slices on a 64-bit system to only containing a hundred elements, and a slice indexed by u8 would be better and more ergonomic.

I didn't mean to dismiss the use cases, but rather to say that if you try to work out the details of what the world looks like with generics-sized slices, you run into many problems. You need to adjust the type notation. You need to make many, many slice-manipulating functions generic over the size type, if you want to benefit from the flexibility (a nontrivial complexity and code bloat cost). If you interact with multiple slices with generic sizes, you have to equate their size types. Basically, it risks making one of the most basic types in Rust much more complex to work with idiomatically. (There are more problems, but hopefully that gives you some idea of the concerns I have in mind.)
Generics over the index can improve some ergonomics locally, as you say, but implicit widening or overloaded indexing helps with some of that problem; see this discussion. (It's not the full story, though, because len and position and so on still hand you usize values.)
It might be worth separately talking about whether there's benefit to making Vec optionally generic over the index type (with a default of usize), however.
But overall to me it's clear that usize (or whatever we call it) is going to be an important/common type -- not just for unsafe code -- because of its fundamental role in types like slices among others.

@thestinger:

There's no benefit from storing the internal length in a different format than a pointer-sized type. It has to be padded to that length anyway.

There are with cache and memory, given the ability to store lots of indices to a small number of elements. Yes, it has to be padded when used as a pointer, but other things have to be done to it anyway to use it as a pointer: multiplication by the object size and adding it to the base index. I don't know assembly well enough, but I don't think there's a significant cost here.

I don't see why this warning would be helpful. It's not a correctness issue at all. The smaller integer types can successfully index all values they can hold. The programmer may only want to index into the initial portion of the slice or a subset of it that's known to be small. Either way, there's no possibility of an overflow from using a smaller integer type for indexing or slicing. The overflow would need to occur elsewhere - by the time it is being used for indexing nothing can go wrong.

I think you're misunderstanding me, and that's why I'm not using the term overflow. In a sense, in a very abstract sense, you risk the opposite of overflow when using an index parameter that's too small and is not overflow checked.
For example, suppose you have some code using u8 indices because you have an array you know will only contain a few hundred elements. Or suppose you're working with ASCII data and you have tokenization tables, or whatever the case may be. Now in that case, u8 indices make a lot of sense. Suppose now you're modifying your code to work with larger data, and u16 indices make sense, and so you begin the refactoring project.
Now under the hypothetical regime of always having to case to usize, your code would initially look like this:
  let idx: u8 = expr as u8;
  let elem = array[idx as usize];
```

As you slowly change your code, it looks like this:

let idx: u16 = expr as u16;
let elem = array[idx as usize];

Notice however, that if at some point you were inconsistent in your conversion, if you left an `as u8`/`as usize` pairs in your code, you would be truncating your indices.

That's an issue I have with this `imem`/`usize` business. The explicit casts everywhere mean anyone optimizing their data structures for cache reasons and storing smaller indices will have hidden truncation bugs laying in wait.

That's why I propose this instead:

let idx: u16 = expr;
let elem = array[idx];

Now, accessing `array` should be an error if the size of the index is not large enough to cover the entire array, and the programmer needs to be **explicit** that they want a truncated value:

let idx: u16 = expr; //where expr is already u16
let elem = array[(idx as u64) % 65536];

That is very explicit. The integer casts disappear, and so too do any issues of silent truncation by the compiler.

And to aide this, a lint pass could be added such that this would become a warning:

let idx16: u16 = expr; //where expr is already u16
let elem = array[idx];
...
let idx8: u8 = expr8;
let elem8 = array[idx8];

@AaronFriel:

There are with cache and memory, given the ability to store lots of indices to a small number of elements. Yes, it has to be padded when used as a pointer, but other things have to be done to it anyway to use it as a pointer: multiplication by the object size and adding it to the base index. I don't know assembly well enough, but I don't think there's a significant cost here.

As I sad, there's no benefit to storing the internal length in slices as a smaller integer type. You are free to do what you want elsewhere, but there's nothing to gain by changing it there.

@thestinger I thought by internal you meant in structs and arrays of indices, but I see what you mean. There might be some benefit if you had say, a Vec<Vec<...>> in performance! In which case, there would be a small perf win for making it generic in the index size.

@aturon:
I agree, the ergonomics of making slices generic seems like it would be terrible, and unappealing for consumers. But I think auto-widening and hiding the pointer-sized integer type actually has huge ergonomic wins. Look at my reply to @thestinger above the one immediately prior. Without auto-widening, the excessive casts can hide truncation when users do write any performance-sensitive code and try to use smaller indices. The truncation occurs because single or double casts would be ubiquitous, and the compiler is unable to differentiate between an intentional desire to truncate a value to a smaller int or an unintentional truncation.
If slices were indexed by uptr_size and inputs were both automatically widened and a warning pass verified that a given identifier was accessed using a common denominator size, I think the ergonomics and safety are vastly improved. Truncation becomes something explicitly and intentionally done, never hidden by redundant casts, and the compiler can verify your accesses to a slice are internally consistent in their size parameter.

Thanks for all the replies. It seems to me that there are two types under consideration here, but that one is used orders of magnitude more frequently.
In particular, the usize variant is used in lots of Vec (and [T] / &[T] / Box<[T]>) operations. In contrast, the isize variant is used almost exclusively when working with pointer offsets (like std::instrinsics::offset) and usually fed an argument cast from today's uint.
Given this large discrepancy in uses (std::intrinsics::offset is only used in unsafe code), we could consider relegating the far-less-commonly used version to mem. In light of that, I would propose that we use size for the more-regularly-used type (it reads reasonably well as "address space size", "vector size" and "index"), and mem::offset as the type meant to be used with functions like std::instrinsics::offset. I think this would aid in both clarity and friendliness.

I would expect the two to have i/u prefixes for consistency. Even if one of them is only used in unsafe code.

It's not just use for pointer arithmetic. It's usable for any distance operations within collections. It wouldn't make much sense to use two different names for types that are defined as signed / unsigned versions of the same thing. The unsigned version is not much more than an optimization to make operations like bounds checks at API boundaries simpler.

@iopq: Both types have a wide range of use cases in both safe and unsafe code. The signed version covers all valid object sizes in bytes as positive numbers. This makes it usable for performing operations like taking the difference between sizes.

How about inum/unum (number)? idef/udef (default)?
-1 to imem/umem for its meaninglessness. Memory means everything, so it
also means nothing!

@liigo: It's not a default (that's i32) and neither def or num is clearer than int about the fact that these are pointer-size integers.

@alfie ptr is misleading because it's not actually a pointer type, just an integer type which happens to have the size of a pointer. And what would signed and unsigned pointer mean?

I have another proposal. If we want something that's mostly going to hold addresses, why not "addr"? We can then ditch the i/u prefix seeing as negative memory addresses are meaningless.

@alfie

I have another proposal. If we want something that's mostly going to hold addresses, why not "addr"? We can then ditch the i/u prefix seeing as negative memory addresses are meaningless.

Part of what's emerged from this discussion is that the type is also destined for heavy use representing vector/slice indexes, not just addresses.
I think usize (or size) may be the best compromise between clarity (since it can be understood equally as container size and memory address space size, and it's used for both) and friendliness (in comparison to something like umem).

+1 for the i/u convention, therefore usize and isize. I don't care either way where isize lives, but I think the symmetry here is important. (in previous discussions, there has always been pretty much broad support for the i/u prefixes).

@nick29581

I think the symmetry here is important.

Can you elaborate on why you think the symmetry outweighs other concerns? I agree that other things being equal, following the convention is good, but I also try to think hard about the newcomer experience to Rust. There are lots of things to learn in Rust, so the fewer barriers we throw up, the better.
Specifically, my worry is that when first working with vecs/slices -- a fundamental type -- you encounter usize everywhere and end up having to dig into the details there before you can go on learning. Whereas something like size is a little easier to gloss over at first and come back to later.
Further, isize forces you to make sense of a "negative size", whereas size alone seems (to me) obviously unsigned, while offset does not immediately imply unsigned.
Anyway, I realize these are somewhat hypothetical arguments, but I'm curious to hear yours in turn!

@glaebhoerl @1fish2 I'd appreciate your thoughts on this final bit of bikeshedding as well.

@aturon Another way to put what you just said is that when a user first encounters a size (as distinct from an integer), they're already encountering a new concept. It's pretty easy to tell them "it's the size of a Vec; we'll get back to it later".
It gets harder to move on if the size is prefixed with a "signedness" and you have to explain why you might have a signed size. In my experience, trying to hand-wave multiple new concepts at once doesn't work very well.
The unsigned size type leaks very readily, since it's the return type of things like len and pos, and the yielded value of enumerations. Since sizes leak so readily (and are therefore very common across all ranges of experience), but signed sizes are much less common, I would like to optimize for friendliness here (a size type and a less friendly place or name for the signed variant).
(FWIW: the int type already didn't follow the i and u prefix conventions)

Symmetry outweighs other concerns because while we can see the benefits of being closer to C or having more descriptive names, from the outside asymmetrical names seem like bad design. A newcomer is not going to go through old RFCs to actually discover the discussion behind all of the choices, it will seem arbitrary and "Rust has a million integer types" type of thing will come up among people who have mostly Java experience. Indeed, having isize/usize seems like ONE additional type with a prefix.
So something like:

Signed
Unsigned

i32
u32

isize
usize

vs.

Signed
Unsigned

i32
u32

N/A
size

offset
N/A

It seems like having a table of integers with blank spaces in them is inconsistent

@aturon, @wycats I see it as a tradeoff - you either make it easier to teach about arrays or easier to teach about numbers. If you go the size/mem::offset, you have to explain all that when teaching numbers, rather than two simple rules. I would think that you don't even need to use that type in the first few lessons - foo[42] will just work. You can teach the usize stuff after you teach numbers, and at the stage, the usize/isize thing should be clear. Furthermore, the array stuff is annoying once, the lack of symmetry is annoying forever.
Basically, I think symmetry is important the same reason conventions are important elsewhere - remembering fewer rules is easer than remembering more rules. I think one problem with the mess of C types, and one reason I liked Rust numeric types when I learnt Rust is that the Rust ones are so much more regular than C.
I also think the marginal cost of one more integer in the global namespace is tiny. So, even if it is not used too much, having isize as built-in does not really cost us anything.
I realise the negative size thing is odd. It is one reason I didn't like size when it was first proposed, but I think it is one negative mark where the other proposals have many more.
(uint/int are close enough to the convention and iint would be ridiculous, so I think that is just nit picking.)

@wycats

Given this large discrepancy in uses (std::intrinsics::offset is only used in unsafe code), we could consider relegating the far-less-commonly used version to mem. In light of that, I would propose that we use size for the more-regularly-used type (it reads reasonably well as "address space size", "vector size" and "index"), and mem::offset as the type meant to be used with functions like std::instrinsics::offset. I think this would aid in both clarity and friendliness.

I agree completely with this, that is, not forcing the i/u prefixing. This was what I was going to propose back when there were less than 10 comments on this RFC but I forgot about it.  It's much more apparent what a non-prefixed one may mean, and doesn't allude to anything about conventional integer types and so doesn't involve the potential confusion that has been mentioned before.

(uint/int are close enough to the convention and iint would be ridiculous, so I think that is just nit picking.)

Would you feel the same way about size / isize?

It seems like having a table of integers with blank spaces in them is inconsistent.

Signed
Unsigned

i32
u32

offset
size

There. No more blank spaces.

@blaenk that doesn't follow the i/u convention, so the criticism now is the table is not regular. Not only is it irregular in the slight sense like int/uint, it has full-blown suppletivism akin to English "good"/"better". This is all right for words that are very frequently used, but in natural languages words that are rarer tend to confuse the speakers more if they are not regular. For example, people in English sometimes say "snuck" instead of "sneaked" because it is not that common of a word compared to "worse". They apply the pattern of "sing"/"sung" and other verbs to "sneak".
So when you have something that's not very common, people are more likely to make mistakes and try the more regular option. I would argue it would make more sense to have types like int and nat for unsigned because they are so common that learning those two wouldn't take any time. You would see them fairly frequently. But offset is will be not used as commonly and will be more easily forgotten / needing to be looked up.

@wycats short answer no, but I would not feel bad either.
Long answer: int/uint fit the pattern of u/i, because they begin with those letters, size doesn't being with u. Or to put it another way, in my head u32 means (in my head) "an Unsigned integer with width 32 bits" and i32 means "an Integer with width 32 bits". Likewise, int means "an Integer [waves hands about width]" and isize means "an Integer with width enough to hold the size of any array". That, I think is why I prefer the consistent prefixes and why I prefer isize, imem etc. to int. It is also somewhat just post-hoc rationalisation of my slightly OCD sense of aesthetics:
u8    i8
u16   i16
u32   i32
u64   i64
size  isize   // IT BURNS!

A more rational opposition to size (vs usize) is that underflow is a classic problem and marking the type explicitly as unsigned is (I think) a good reminder to programmers that the type is unsigned and can easily underflow. (I have been personally caught out like this using size_t in C++ and caught the same bug reviewing others' code).

All fixed int types don't have any additional semantics besides their signedness and sizes in the names. In particular, they do not suggest any use case. Suggesting use cases can be a problem especially when not all use cases are covered by the names.
Besides negating other use cases and the actual semantics of int/uint, offset/size are commonly used as variable names, not type names.

I think @CloudiDust has a good point that I hadn't thought of in favour of uszie/isize - they are unlikely to be used by programmers for anything else, but size and offset are likely to be used (note however, that using them for the int names doesn' preclude them being used for other things, but it does make it confusing, sometimes).

@nick29581, the problem with isize/usize is that they still look like C size_t/ssize_t which suggests specific use cases. (People would assume that they are size_t/ssize_t with "Rustified" names.)
Also I'd like to argue that, names that suggest use cases (idiff/isize/usize/size/offset) may have the same problem with int/uint - They tempt people to default to them without much consideration, without understanding the actual semantics and pitfalls.
Familiarity is a double-edged sword.
On the other hand we have imem/umem which don't tempt people to make incorrect assumptions, but do seem strange when first encountered. (Some may find them too strange that even after realising the "memory-pointer-sized integers" interpretation, they don't see them as natural names.)
I still prefer the unfamiliarity of imem/umem though.

@CloudiDust

@nick29581, the problem with isize/usize is that they still look like C size_t/ssize_t which suggests specific use cases. (People would assume that they are size_t/ssize_t with "Rustified" names.)

Can you say more about what specifically you are worried about people assuming that would be incorrect?

@aturon My thoughts are still largely as here, and in other comments.
I think the priorities are:

Making it obvious that they are integer types
Avoiding the specific names int and uint
Giving a good intuition about the meaning or purpose of the types

with 3. being extremely difficult to impossible in such limited space.
The first point rules out, for me, any names which don't start with an 'i' and a 'u'. (size, for example, could just as easily have a geometric meaning.) It also makes me prefer "int" and "uint" with a given single-letter suffix to a given word with 'i' and 'u' prefixes.
I think 3. is less important comparatively; the overwhelming priority is merely to avoid moments of total incomprehension and confusion when someone stumbles upon some source code written in Rust. Beyond that point, for the precise definition and recommendations surrounding these types, one would have to end up consulting the documentation anyways. That said, I'm completely unconcerned about mismatches on the finer points relative to C types: a person with enough expertise to be familiar with the precise definition and pitfalls of ssize_t is unlikely to be someone we need to worry about. (I was not, for instance.)

@CloudiDust The thing that really put me off *mem was this example (and similar things):
fn slice_or_fail<'b>(&'b self, from: &umem, to: &umem) -> &'b [T]

The umems here just don't suggest anything numeric to me and suggest too much something pointer-ish. Sorry to make such a subjective argument.
I think that, as a first approximation, equating usize with size_t is not so bad. Indeed it is a connotation that puts me in favour of the name due to familiarity.

@glaebhoerl

The first point rules out, for me, any names which don't start with an 'i' and a 'u'.

I don't see why you think that usize has obvious meaning as an integer type. The first time I saw it, that certainly wasn't obvious to me.

@wycats, like "they are only for indices/sizes", "they are not suitable for storing casted pointers", "when I want to represent sizes, I should use them as much as possible" or "I don't need to care about which container indexing type to use". (The latter two becomes bigger problems with custom data structures.)
Also, when I first learned C++, I incorrectly used size_t for all kinds of sizes, container-related or not.

I don't see why you think that usize has obvious meaning as an integer type. The first time I saw it, that certainly wasn't obvious to me.

At least it has the shared prefix convention, making it less non-obvious. But yes, this is why I now prefer intp/uintp, or something of that sort.

@glaebhoerl

The first point rules out, for me, any names which don't start with an 'i' and a 'u'. (size, for example, could just as easily have a geometric meaning.) It also makes me prefer "int" and "uint" with a given single-letter suffix to a given word with single-letter 'i' and 'u' prefixes.

The point about size here seems to ignore that these types will be encountered in specific contexts. In particular, the first encounter will almost certainly be when interacting with vectors/slices. If you see a len function returning a size, I think inferring that it's an unsigned integer type is pretty reasonble. (I personally think the same argument applies to usize.)

I agree with @nick29581 and @glaebhoerl : The built-in integer type names had better be uniform (few rules to remember) and start with i and u or ordinary programmers like me with much in our mental working memory won't remember that they're integers and which one is unsigned. I'd have trouble remembering whether size is signed, and unsigned integers are risky without everyday underflow checking (which is why the Google C++ style guide recommends against them). Also, unadorned terms "offset" and "size" are too general purpose. Hence isize/usize, imem/umem, intp/uintp, or intm/uintm. And please don't move one off to a package that we'll forget where to look in.
The scientific approach is usability testing. The alternate branches using imem/umem32 and isize/usize are a good start if one fixes the page load problems of the latter, adds a tour of where to look (I didn't see slice_or_fail), and conducts two quick experiments: One to test learnability for newbies and the other to test for portability errors and signed/unsigned errors in the midst of a difficult programming problem. (Does Mozilla have a usability tester? @steveklabnik is an excellent writer & teacher. He'd probably be a good at this.)
BTW the renaming is the ideal time to fix mis-uses of int and uint that are not limited by the address space and thus not portable to 16-bit CPUs. Also there are some derived names to fix or delete like AtomicInt.

@1fish2 Thanks for weighing in!
I agree about usability testing, but sadly I don't think we have the time or resources for that -- we are planning to release the alpha version of Rust 1.0 on Jan 9th (see this post) and really need to know what the new names will be before then.

BTW the renaming is the ideal time to fix mis-uses of int and uint that are not limited by the address space and thus not portable to 16-bit CPUs. Also there are some derived names to fix or delete like AtomicInt.

Agreed completely. The plan (assuming this RFC is accepted) is to introduce the new names for alpha, but keep the old ones in deprecated form. During alpha we will perform exactly this audit, and remove all uses of int/uint in favor of the new types or of fixed-size types. By beta we hope to be able to drop the old names outright.

@nick29581, yeah though I personally don't feel that way, I can see why this line can be annoying.
@glaebhoerl, would intm/uintm be better than   intp/uintp as they don't suggest intptr_t/uintptr_t? (For some reason I tend to interprete intm as i + ntm, but don't quite see intp as i + ntp though.)

@aturon

The point about size here seems to ignore that these types will be encountered in specific contexts. In particular, the first encounter will almost certainly be when interacting with vectors/slices. If you see a len function returning a size, I think inferring that it's an unsigned integer type is pretty reasonble.

Quite possibly, but also quite possibly not: I bet there's a long tail. And if you have an existing expectation about what kind of type len() presumably returns, it's going to help you whatever the type is called.
@CloudiDust I don't really mind either way. Both are fine. (I don't think suggesting intptr_t/uintptr_t is bad; int* and uint* are more worrying. At the same time, for whatever reason I'm not fantastically enthused about the whole "mem" thing. So it's a wash.)

@aturon Thanks for asking!
It might help to just collect together some key API and code snippets, apply the candidate renamings, and show it to some core team members and newbies. Also ask Steve to draft the doc that'll explain these types and their uses & abuses. That should be revealing.

@nick29581, I think intm/uintm can be a middle ground. They are definitely int types if the reader knows where to split the words, and nonsense if they do not. (Which is a plus.)
They have most advantages of imem/umem, but are less regular and less pretty, being the only types that have int in the names if accepted.

@glaebhoerl, the mem part admittedly is a desperate attempt to escape from the exact words ptr but still mean it.
I think I am wrong about imem/umem or intm/uintm not suggesting use cases. They do suggest "memory-related things", but this is vague enough (but not too vague) that it covers all of the types' main use cases.
From this POV, imem/umem or intm/uintm can be said to discourage the usage of these types in "non-memory-related" cases, where the data "leaves the memory", like in serializations, persistence, and network communications.

To add some levity and check for connotation goofs, here's what Google & Google Translate say:

isize, usize: "help" in Zulu (actually "usizo")
imem
umem: "i can" in Bosnian (actually "ja mogu"); University of Maryland School of Medicine
intp: "INTP" in Myers Briggs type indicators, Awesome famous INTPs
uintp
intm: Italia's Next Top Model
uintm

I guess you can't just abbreviate ONE word to make it mean "pointer-sized integer", so why not use an initialism?
irtfm/urtfm: Resized Type For Memory
this should cover all the objections ;)

Among the candidates other than imem/umem, I think isize/usize are the most pleasent on the eyes (though I don't like the incorrect assumptions that people will be tempted to make, it is possible that I am worrying too much).
intp/uintp and intm/uintm are awkward, as they don't strictly follow the i/u + {size} pattern, are of different lengths, and the more frequently used type uintp(uintm) has a longer name. Granted, this problem already exists with int/uint, but those two are names that everyone is familiar with.

@iopq, another crazy idea, what about isiz/usiz?
People will go "what's the point in omitting e?" and read the manual.
I hope I am not serious. Oh I am half serious actually.

@glaebhoerl @nick29581
If the point is to stop people from making incorrect assumptions and tempt them to read the manual, while at the same time take advantage of familarity, isiz/usiz are actually not bad.
"usiz is for container sizes, try read it, but hey there is a reason why it isn't called usize, and no, it is not (only) for saving a keystroke."

Since this is the thread that never ends, might as well weigh in:  keeping to the theme of 'exactly what it says on the tin', what about iptrsz/uptrsz?

The main problem with usiz/isiz are:

They don't reflect the fact that they are pointer-sized. (But there is a reason that they are not usize/isize.)
Some may think that they are "unprofessional". (But, C's creat is professional, no?)

Overall a good balance.
I'll add this one to the RFC.

@jfager, iptrsz/uptrsz are a bit too long (but better than iptr_size I think).
Definitely worth considering.

That's their drawback, but they're the same as size_t and shorter than
ssize_t and ptrdiff_t.  Also the same length as, for instance, Option
or Result, which while not being primitives are almost certainly more
common.
On Monday, January 5, 2015, Richard Zhang<EMAIL_ADDRESS>wrote:

@jfager https://github.com/jfager, iptrsz/uptrsz are a bit too long
(but better than iptr_size I think).
Definitely worth considering.
—
Reply to this email directly or view it on GitHub
https://github.com/rust-lang/rfcs/pull/544#issuecomment-68680611.

@wycats
isize is not rare and is used not only for low level pointer offsets
Here's a snippet roughly translated from my C++ code
fn getWordForm(sent: &Sentence, abs_pos: usize, shift: isize) -> String
{
      let mut form = String::from_str("*");
      let pos = abs_pos as isize + shift;
      if (pos >= 0 && pos as uint < sent.len()) form = sent[pos as uint].form();
      form
}

isize here is just a signed counterpart of usize
The symmetric naming with i/u also accentuates this meaning and improves readability in this case.

@jfager, yeah, and with many opposing imem/umem, I think iptrsz/uptrsz can be the new champion of camp "semantics-over-familarity", while isiz/usiz can be the new champion of camp "familarity-over-semantics".
I tried with @nick29581's example and find that I like isiz/usiz better, which may or may not be a problem as the type names are pleasent to use.
iptrsz/uptrsz still make me wonder "what is a pointer doing here?" But certainly to a much less extent than iptr/uptr.

@jfager, ipsz/upsz?

It is interesting that ipsz/upsz are similiar to isiz/usiz. ipsz/upsz are my favourites now.

@aturon @nick29581 @wycats,
I dare say we have a winner here thanks to the inspiration from @jfager.
ipsz/upsz reflect the correct semantics right in the names,  without stressing the "pointer" parts. Actually if anything they stress the "size" parts, which makes them natural to use in our common use cases.
Win-Win.

Except ipsz/upsz looks like letter soup. I think at that point it's just bikeshedding, I think the core team should just decide on the naming (or maybe make a poll if they want to be democratic about it, although personally I would be perfectly fine with an unilateral decision at that point).

@simias, this RFC and this comment thread are all about bikeshedding. But I agree this has taken a long time and is getting tiring. So let's finish it. :)
I'll update this RFC hopefully for the last one time.

@CloudiDust oh it's been a very interesting discussion IMO, thanks for making this RFC. Now it seems almost everybody agrees that int needs to be renamed, and that's the important part.
The actual renaming however is more of a subjective choice, I think if there was a perfect name that would get a consensus we'd have found it by now. There have been plenty of good suggestions for the core team to chose from.

ipsz/upsz are completely unreadable. Much better to have a sensible word that might be slightly off the intended meaning when you think about it than to have a non-word that's technically more accurate when you look it up in the documentation.

It took me a minute to realize that ipsz is meant to stand for int pointer size, and I've been following this conversation. I think it's exceedingly likely that most users will have no idea what they stand for or what they should be used for until they are told, which is very non-ideal.

I'm also -1 on ipsz/upsz.  They look more like ip_sz and up_sz than i_psz and u_psz, and even if they did group right 'psz' is still fairly cryptic.
The point of iptrsz/uptrsz was to leverage common abbreviations that would read pretty directly as 'pointer size'.  If brevity is the highest good then I would strongly prefer imem/umem or intp/uintp to ipsz/upsz.

@rpjohnst @reem
So I backed down from promoting ipsz/upsz. I think I've been thinking too much about this whole renaming thing that anything is going to make sense in one way or another. I need some rest. ;)

@jfager, I agree now. I actually have just written in the RFC that uptrsz/iptrsz can be better than upsz/ipsz in the "clarity" regard. :)

I think this whole thread makes it clear that they need to be renamed. I don't think what they are renamed to is that important, as long as it is rid from the "default" implications of int and uint

Are y'all sure we can't get away with calling them iword and uword?

@ben0x539 No, we can't get away like this, because these integers aren't necessarily word-sized.

@tbu- yeah but pointers are sort of like words, no one really cares what words are exactly, and it conveys the meaning better than most proposals

@ben0x539 Would you expect iword to be 64 bit on a 64-bit CPU? If so, this proposal is confusing, because iword will not necessarily have 64 bit there (E.g. x32).

The core team met this morning to coordinate on the alpha release and to finalize a decision here. The discussion on this thread, on discuss, and elsewhere has been vigorous and dug deep; thanks everyone who participated!
Summarizing the discussion
I won't try to fully summarize everything that has been said, but single out the most salient points:

@Valloric laid out a vivid description of Google's guidelines: use i32 for numbers "laughably smaller" than 4 billion; otherwise use i64. We will need to tweak these guidelines to also cover our pointer-sized types, but they greatly clarified that having a "default" int type is problematic.

The discussion on this thread has covered the pros/cons of various renamings of int/uint. This is a difficult question at the intersection of clarity, learnability, and friendliness to newcomers.

Of course, many many other interesting points were made along the way, and I encourage those interested in the topic to read back through the threads for more.
The decision
In the end we chose isize/usize, partly due to arguments summarized by @1fish2: keeping the i/u prefixes makes it easier to understand that they are part of Rust's family of integer types and follow the same rules. Similarly, @iopq's point that "having isize/usize seems like ONE additional type with a prefix" makes a compelling argument against size/offset, which appear to say that the two types have a different relationship than our other prefixed types.
On the other hand, seeing usize in the context of slice indexing or as the return of the len function is unlikely to lead to too much surprise for newcomers. A type like umem, on the other hand, is likely to raise eyebrows. Since "size" is general enough to refer to both the size of the address space and the size of a container and its indexes (which are, of course, closely related), and reasonably intuitive, we feel it is the best choice.
The plan
Here's what needs to happen next:

@CloudiDust, can you please update the RFC a final time, giving isize/usize as the "Detailed design" and leaving the others as alternatives? Once that's done, I will merge the RFC.

We will introduce isize/usize before the alpha release, and deprecate int/uint.

I will very soon post an RFC proposing formal conventions around integers, based partly on @Valloric's comment above. These do not need to be approved before alpha, but should be approved ASAP.

During the alpha cycle, we will revisit all uses of int/uint and change to a specific integer type based on the conventions above. This is one of the few places where we anticipate changes to #[stable] APIs during alpha. (The broader story about the alpha cycle will be detailed in the upcoming alpha announcement.)

By the beta release, we should be ready to remove int/uint.

Separately, we should consider ergonomic improvements to ease the pain of having no "default" integer type. See this thread for early discussion of a number of ideas. These changes are backwards-compatible and can be made more slowly over time.

We should just use the full type name for the suffix, since that's what the other numeric types do.

agreed with @ben0x539

@aturon, will do.
@ben0x539, I agree about the suffixes.

@aturon Big thanks to you and the rest of the core team for a reasonable decision here. isize and usize are fine, and so are the suffixes. Thanks for continuing to listed to community feedback on this matter even after making an initial decision; this continues the exemplary pattern of the core team changing past designs after more feedback has been received and not categorically closing ranks behind "a decision has been reached" mentality.
Keep up the awesome work!

I'm really happy with this decision! Thanks for reconsidering after your original decision.
I'd prefer for the suffixes to be the same as the type names. That's consistent with the rest of the numeric types, and since the suffixes can be inferred most of the time, the 3 extra characters (isize vs is) shouldn't be a problem on the rare occasion you need to include the suffix.

@aturon, I suggest that we try isize/usize as suffixes first, and if this proves painful, we then go with is/us.
is/us are actual words, and is is a keyword in many languages. So this is a -1 for is/us.
OTOH, we can treat 42is and 42 is as different things if is becomes a keyword, though it feels a bit hack-ish.
P.S. I don't have access to an internet-enabled computer until tonight (local time of course), so sorry about not being able to update the RFC now. (My understanding is that we wish to merge this ASAP.)

@CloudiDust we already do treat 42is and 42 is differently, for exactly this sort of reason.

(In particular, all literal suffixes are reserved, and whitespace is required around literals to separate them from other tokens)

@cmr, 42is is would be a bit funny if it ever becomes a thing. :)
But my main concern is that is/us may be too pleasant, 42is vs 42i32 vs 42isize?

@aturon, done.

Thanks @CloudiDust for your tireless effort! I'm going to merge this RFC.

Merged. Tracking issue.

An after-note for register-sized types. As @thestinger and others pointed out, they are not synonymous with isize/usize. These types may be useful for optimization, but using them in a public interface is probably not a good idea for the reasons thoroughly discussed here and in other places. So it's not important whether they are distinct from any other built-in integer types. ireg/ureg (or whatever color you want this bikeshed painted in) may be defined as machine-dependent aliases, similar to the libc types.

#573 has been filed to discuss the suffixes. That RFC proposes isz/usz as a compromise between isize/usize and is/us. (Both isz/usz and isize/usize are fine in my eyes.) Comments are welcomed.


Add i2c-dev to modules to load with modprobe

Need to modprobe i2c-dev to work without restarting

Feel free to also submit this to maintained fork:
https://github.com/abandonware/node-i2c


Can't Widen Wordlist Column

Hi Damien. Thanks for doing this project.
In the Input tab, Word lists, there is the Word lists table. The header of each column has a single meaning. I can hover over the divider between columns, and the cursor changes into a double-headed horizontal arrow, indicating that I can widen the column. That's what I want, because some of the meanings are too wide right now, and I can't tell the difference between a couple of them. So I click and hold to widen the column. The column won't widen for me.
If you need me to add a screen shot, let me know.

Thanks for trying out Cog. Which version are you using? This was an issue that was fixed in 1.1.1, which is the latest version.

I got v. 1.1.0. not more than a month ago.
Thanks again for working on this. I have an intricate language/dialect
situation here I'm trying to sort out.
Steve
On 10/6/2015 13:37, Damien Daspit wrote:

Thanks for trying out Cog. Which version are you using? This was an
issue that was fixed in 1.1.1, which is the latest version.
—
Reply to this email directly or view it on GitHub
https://github.com/sillsdev/cog/issues/30#issuecomment-145733867.

Yeah, I released 1.1.1 not too long ago. Let me know if you need any more help.


Release 2.4.0

I just realized it's been 9 months since our last release! Definitely time for a new one.
There's a pull request in flight, but otherwise I think we're not really waiting on anything. Let me know if there's something you think should be addressed before the release, though!
Otherwise I'll probably do a release in the next week or so.

Done!
https://github.com/openseadragon/openseadragon/releases/tag/v2.4.0
https://twitter.com/openseadragon/status/1020352639832338432


Error running tune.py

Hi
I ran the first part of NFVDeep successfully (Experiments/script.py).
But in executing the second part(Hyperparameter Optimization/tune.py) , I encounter the following error:
_File "C:\Users\98913\Documents\Python\NFVdeep-main\tune.py", line 158, in
search_alg=AxSearch(ax_client),
File "C:\Simulate\lib\site-packages\ray\tune\suggest\ax.py", line 173, in init
self._setup_experiment()
File "C:\Simulate\lib\site-packages\ray\tune\suggest\ax.py", line 197, in setup_experiment
raise ValueError(
ValueError: Please specify the mode argument when initializing the AxSearch object or pass it to tune.run().
I spent many hours fixing it but did not get the result.Please help me fix this error.

The error message ("or pass it to tune.run()") doesn't really make sense to me since you do pass it to tune.run() in the corresponding line if you didn't change the tune.py script.
Either way, you could try setting mode="max" as extra argument inside the AxSearch constructor. Not sure if this will work. Let me know.

The error message ("or pass it to tune.run()") doesn't really make sense to me since you do pass it to tune.run() in the corresponding line if you didn't change the tune.py script.
Either way, you could try setting mode="max" as extra argument inside the AxSearch constructor. Not sure if this will work. Let me know.

I did what you said first (mode="max" inside the AxSearch) ,but it made the same error again.
The error was related to the my requirements and was fixed.
Thanks

Can the number of nodes be changed for each experiment? If so, where should it be done?
Please help me

Do you mean nodes of the underlying computer network topology? You need to define the network topology in a separate file. There are examples here: https://github.com/CN-UPB/NFVdeep/tree/main/data
You can then pass the network file as input when you run the algorithm.
But keep in mind that this is not an official implementation of NFVdeep and that we could not reproduce the results of the paper. Just so you know before you invest too much time.

Do you mean nodes of the underlying computer network topology? You need to define the network topology in a separate file. There are examples here: https://github.com/CN-UPB/NFVdeep/tree/main/data You can then pass the network file as input when you run the algorithm.
But keep in mind that this is not an official implementation of NFVdeep and that we could not reproduce the results of the paper. Just so you know before you invest too much time.

Yes, "nodes of the underlying computer network topology"
Thanks
Sincerely yours

The error message ("or pass it to tune.run()") doesn't really make sense to me since you do pass it to tune.run() in the corresponding line if you didn't change the tune.py script.
Either way, you could try setting mode="max" as extra argument inside the AxSearch constructor. Not sure if this will work. Let me know.

I did what you said first (mode="max" inside the AxSearch) ,but it made the same error again. The error was related to requirements and was fixed. Thanks
I also did this. But an error message "TypeError: 'AxClient' object is not iterable" came. Please tell me how you deal with it? Or can you give me some other advice?


hn unit testing

Description
-small test for two functions
-will need help from @proful on how to test a function which is calling multiple functions and function mocking
Attach Screenshot

Note 2 code reviewer approval needed. Approach in twitter group & discord channel.

Good start


Add water control as possible DD column

Description
So users can see at a glance the new required field values.

Tests

add and remove column
check default by deleting local storage

thoughts on placing it next to "Sample Type" in the list?

thoughts on placing it next to "Sample Type" in the list?

Good question. It's true that it is next to sample type in upload. On the other hand there is no apparent order in the add columns list. Is there?

I see yeah, seems fine to me


feat(configuration): support hjson in the configuration by default

:tada: This PR is included in version 1.17.0 :tada:
The release is available on:

v1.17.0
GitHub release

Your semantic-release bot :package::rocket:


Any introduction to the principles related to clustering?

Hello, do you have an introduction to the principles related to clustering? Is the state of all nodes consistent? What kind of data does the Raft protocol synchronize?

You may refer to the Raft algorithm.
In the RMQTT's Raft cluster implementation, the connection status and subscription relationships of each node are synchronized.


Prep for 0.6.0 stable

Prep for stable release. What has to be done:

[ ] Assets with macro
[ ] head::Link components
[ ] Proper suspense
[ ] Proper ErrorBoundaries


Content correctness

[Enter feedback here]
Can you please review,
Can a reader role at subscription level enable traffic analytics?

Document Details
⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

ID: 6a3b799a-7429-813c-c630-e6242c39b77f
Version Independent ID: 8ad04d57-6370-c8dd-1049-1826a823bd12
Content: Azure traffic analytics frequently asked questions
Content Source: articles/network-watcher/traffic-analytics-faq.yml
Service: network-watcher
GitHub Login: @damendo
Microsoft Alias: damendo

@varunrom, Thanks for the feedback! We are taking a look into this and will get back to you soon.

@varunrom , We have assigned this to the content owner/author for review.
@damendo , please review this as it has been reported in https://github.com/MicrosoftDocs/azure-docs/issues/75373

As advised by my manager @jyothisuri, closing the issues that are older than a year.
#please-close


Upgrade to Ruby 2.3.0

Ruby 2.2.3 has known vulnerabilities, and 2.3.0 seems to work fine, so let's jump straight to the latest version of Ruby.

LGTM

LGTM. We have new docker image ready to be used but need to merge your changes first :)