Iteration works as expected if you respect the con...
# language-proposals
k
Iteration works as expected if you respect the contracts of
Iterator
.
v
I think @mikehearn means that side-effects of a loop were not run when lopped over an empty colection
k
I'm still having trouble imagining a useful scenario where this is a problem. Something like
Copy code
var a = 3
for (c in emptyList()) a = 5
println(a)
maybe?
I'd be interested in seeing an example.
m
The actual cases where this came up are more complex than small code snippets. Think: a plugin loading mechanism is supposed to register classes of a particular type, and there is meant to be at least one in a real deployment, but if it doesn't happen then the feature the plugin provides just silently vanishes.
you really want an ability to say, "give me a list of plugins and oh by the way, *there is supposed to always be at least one*" in the type signature.
and have the compiler generate the right assertions
Now, some smart alec is going to come along and say, but you can't do that without immutable lists because a thread could change it concurrently.... but I don't really care about that. Iterating over a list that another thread is changing is broken already. So it's OK if the compiler assumes the list won't change between check(isNotEmpty()) and usage.
k
For
varargs
I've done things like
fun max(first: Int, varargs rest: Int) = ...
, not sure if that's possible in your use case.
m
yes that works for varargs. but not for general collections.
✔️ 1
c
@mikehearn Just to clarify: you already have implemented such lists and wondering if it could be added to the stdlib?
m
Yes I have them, but I'd rather it be in the type system more natively so as to avoid wrapper types
(with value types it may not matter at all)
p
@mikehearn Value types cannot really do it. You want typestate as: https://www.cs.cmu.edu/~aldrich/papers/onward2009-state.pdf
Although in the pattern of http://pcwalton.github.io/blog/2012/12/26/typestate-is-dead/ it may be able to use a generic parameter with state enums for a subset of it (an enumerable amount of states, not something like the actual amount of elements in a list).
m
Well, you can pull it off today with wrapper classes and some extension functions. It's just kind of ugly and inefficient.
i've tried to implement type state in the kotlin compiler actually 🙂 well, i say "implement" ... i abused the internal contracts feature and commented out an error check that was getting in my way, before getting stuck because of course flow typing does not expect types to change exactly, only be narrowed. but it was a fun experiment.
but yes, you can use that approach if you don't care about the safety check poking out into the code.