that you said was okay
Really? There were example somewhere close, but never close enough.
I am really stopped digging more, once found how Linus Torvalds doing
I was literally felt stupid that Linus was able to do something in C, but I can't do same without Java, and then I've found improvised vtable on structs, so it got me back on my feet 
For instance, is it valid to make a Collection that returns -1 for size.
Don't bother about such exception case. I was pushing more to not use size of iterator, so I've used that example of infinite iterators which very often. Regarding Collection, I can't remember any example of infinite collection, but it can be enormously if it is proxy collection over database.
You've talked about having a Collection that proxies a database with no iterator and just size, so I imagine this is similar and requires a way to return errors too.
Also if an iterator isn't intended to provide size, why is the abstract implementation using it.
Rust implementation of Iterator has size as property. I am not really criticizing that rust already included that property there.
But if speak about clean minimalistic design, this is what Iterator meant to be:
fn process<I: Iterator>(mut iterator: I) {
while let Some(value) = iterator.next() {
// process value here
}
}
Many people tried to hack through Iterator::count and perhaps it could be a valid solution for real-life problem in rust coding, but this question more about software design, let's do it without hacks like Iterator::count, just use Iterator to iterate only, what it meant to be at first place.
I think Rust land is resistant to this type of development, you would instead spend time refactoring and specifying your code and updating constraints.
That's what I am thinking too... Initially I wanted to make that post on internal.rust-lang where people more focused on discussion how they see future of rust.
This is a little bit outside of scope for this Collection question, but here is the concrete problem that I see specifically for rust. I think you know that trait From in rust, very convenient one, and I am using a lot in my code.
Let's say I am designing similar trait MyFrom:
pub trait MyFrom<T>: Sized {
fn from(value: T) -> Self;
}
// Obviously Blanket implementation is usefull here:
// if F can be created from &T,
// then F can also be created from T.
impl<T, F> MyFrom<T> for F
where
F: for<'a> MyFrom<&'a T>,
{
fn from(value: T) -> Self {
MyFrom::from(&value)
}
}
Now if I will try to put concrete implementation from &A -> B:
impl<'a> MyFrom<&'a MyConcreteTypeA> for MyConcreteTypeB {
fn from(value: &'a MyConcreteTypeA) -> Self {
MyConcreteTypeB { value: value.value }
}
}
I will get an error:
1. error[E0119]: conflicting implementations of trait `MyFrom<&MyConcreteTypeA>` for type `MyConcreteTypeB`
--> src/main.rs:26:1
But the point is that, even if I've already made a generic defintion that any implementation for MyFrom<&T> should make blanked implementation for MyFrom<T>, I still should be able to override that blanked implementation with my concrete implementation MyFrom<T>, if I need so.
impl<T, F> MyFrom<T> for F
where
F: for<'a> MyFrom<&'a T> { ... }
Shouldn't go into conflict with:
impl MyFrom<MyConcreteTypeA> for MyConcreteTypeB {...}
Just most concrete implementation should be chosen, such feature is know in C++ as specialization. Java doing something very similar during method overloading. In C++ specialization is actively used together with templates, I think Rust just missing the proper implementation here, it doesn't even requires classical OOP, and I guess rust will stop resisting.
This example is just the tip of the iceberg, but I think there is a lot more to explore here.
And what's important, we don't even need to re-invent the wheel, we just need to learn how it is done in other languages.
but it's worth remembering that the kernel is a not an 'open' system
Linux kernel is monolithic but it is open system:
You can even load and unload kernel modules dynamically. I think Linux worth learning how to build complex software.
if I wanted to change the kernel to allow higher precision clock measurements.
I guess you are speaking about some very core functionality, where Linux heavily depended on that? I think there was demand to modularize that driver for that hardware, it would be possible through kernel modules, just was never necessity for that. In many places where something needs to be modularized, Linux is extensible.
I would be expected to modify all interfaces and code that uses the clocks.
Backward compatibility is hard, no-one demands that. And by the way, that's why I am saying that property Iterator::size is example of bad design, once you add that property into core API, you can't simply remove it from there, now you need to support it in every possible places.
So this java Iterator definition:
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
And this is rust Iterator:
pub trait Iterator {
type Item;
fn next(&mut self) -> Option<Self::Item>;
fn next_chunk<const N: usize>(
&mut self,
) -> Result<[Self::Item; N], array::IntoIter<Self::Item, N>>
where
Self: Sized,
{ ... }
fn size_hint(&self) -> (usize, Option<usize>) { ... }
fn count(self) -> usize
where
Self: Sized,
{ ... }
fn last(self) -> Option<Self::Item>
where
Self: Sized,
{ ... }
fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>> { ... }
fn nth(&mut self, n: usize) -> Option<Self::Item> { ... }
...
// and who knows how many more methods goes here....
}
If you need to make your concrete implementation for Iterator rust trait or java interface, which one would be easier to maintain?
From this conversation here, I've learned that people expecting that when they doing Iterator::count, you will provide something optimal from computation complexity, not just O(n) to iterate through entire sequence how it is done by default.
Java designed many time with a mind, that they offer you some framework, but literally for everything you can do you own implementation. If we take Iterator as example, it is literally three method, where one of that method is optional. Except next and hasNext that used for iteration. You can tell me that java offers Iterator::remove() as excess, however it is hard to argue against that without that Iterator::remove(), java collection API would be complete.