Skip to content
This repository was archived by the owner on Dec 22, 2021. It is now read-only.
This repository was archived by the owner on Dec 22, 2021. It is now read-only.

Remove empty parameter list from iterator() #520

Closed
@NthPortal

Description

@NthPortal

There was a discussion on https://gitter.im/scala/collection-strawman about whether or not IterableOnce.iterator()/Iterable.iterator() should have an empty parameter list, or none at all. I will do my best to record the main points of the discussion below.


(mostly quotes from Gitter)

I ask "Why does IterableOnce.iterator() have an empty parameter list, rather than no parameter list?"

@szeiger and @julienrf suggest it is because iterator() is a side-effecting method, in that two returned Iterators have distinct identities, so the method is not referentially transparent.

@martijnhoekstra notes that "If everything that's not referentially transparent is a side effect, obtaining an iterator is a side-effect".

I ask "What about toArray? The Arrays are mutable, so while initially they would be equivalent, you could modify them so they are not".

@szeiger: "Indeed, if you go by referential transparency a lot more methods would need an empty argument list. What about size? When used on a mutable collection it's not referentially transparent. Of course, nothing is. The distinction doesn't make any sense there. So what about List.size? It is referentially transparent but that's not good enough because substituting such calls has huge performance implications. In a pure functional language the compiler can help you with that but Scala can't."

@SethTisue: "My intuition likes the 'initially they would be equivalent' side of your way of phrasing it, @NthPortal. But I'm having trouble backing up my intuition with a convincing argument [...] I think my intuition is something like, require the () if it introduces mutation or side effects into a program that wouldn't otherwise have it. And toArray doesn't do that, because you are free to write code that uses Array but never mutates an array".

@martijnhoekstra: "Neither does iterator() though - provided you never call next() [...] There is a lot less you can do with an iterator without modifying it than you can do with an Array without modifying it though".

@SethTisue: "In Scala through 2.12, .iterator has no parameter lists and the compiler says 'Iterator[...] does not take parameters' if you write .iterator(). So somebody made a different decision on this years ago. Just leaving it like it was doesn't feel terrible to me. Even if you buy the argument that it ought to have the (), I'm not sure it's worth annoying people with the change, especially since (as Stefan has pointed out) the change will become more annoying when future Scala requires the ()".

@Ichoran says that "My intuition is that () as a way to denote referential transparency is not a good idea anyway. Instead, () is useful as a marker for things that observably mutate the object on which the method is called. That is, for some method bar, the behavior of x.bar will be different after x.foo()." @SethTisue likes this intuition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions