Skip to content

[stdlib] Default implementation for BinaryInteger._word(at:)#10460

Merged
moiseev merged 1 commit intoswiftlang:masterfrom
moiseev:word-at
Jun 21, 2017
Merged

[stdlib] Default implementation for BinaryInteger._word(at:)#10460
moiseev merged 1 commit intoswiftlang:masterfrom
moiseev:word-at

Conversation

@moiseev
Copy link
Copy Markdown
Contributor

@moiseev moiseev commented Jun 21, 2017

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 21, 2017

@swift-ci Please test

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 21, 2017

/cc @lorentey

@lorentey
Copy link
Copy Markdown
Member

Looks like a fine short-term fix!

Do you want me to try my hand at making a PR for the full thing?

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 21, 2017

@lorentey that would be amazing!

@moiseev moiseev merged commit c34d269 into swiftlang:master Jun 21, 2017
@moiseev moiseev deleted the word-at branch June 21, 2017 22:20
@lorentey
Copy link
Copy Markdown
Member

👍 I'll see what I can do, hopefully tomorrow.

@jrose-apple
Copy link
Copy Markdown
Contributor

Wait, getting a failure at run time about an API you aren't supposed to implement is worse than getting it at compile time.

@jrose-apple
Copy link
Copy Markdown
Contributor

Making a default implementation cycle would be a better short-term fix.

@lorentey
Copy link
Copy Markdown
Member

Right!

I'll submit a PR with _word(at:) implemented in terms of words soon; I just need to track down a tricky case of infinite recursion with integer conversions.

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 22, 2017

@jrose-apple All the built-in types override this method, all the conformances should implement var words without using the _word(at:). How would one get this error at runtime?

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 22, 2017

_word(at:) should not be implemented in terms of words, _word(at:) should cease to exist.

@lorentey
Copy link
Copy Markdown
Member

lorentey commented Jun 22, 2017

Yes, but the problem is that until it becomes possible to explicitly constrain Words to be a Collection of UInts, it doesn't seem feasible to define FixedWidthInteger.init<T: BinaryInteger>(extendingOrTruncating source: T) in terms of words. (Adding the constraint leads to a compiler crash.)

My workaround is to have _word(at:) and _countRepresentedWords remain parts of the internal API for now, and to define them in an extension with the desired constraints.

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 22, 2017

init<T : BinaryInteger>(extendingOrTruncating: T) where T.Words == Words?

@lorentey
Copy link
Copy Markdown
Member

That would work very well! Is it OK to add a constraint like that on the public protocol requirement?

(If so, I'd choose where T.Words: Collection, T.Words.Element == UInt.)

@moiseev
Copy link
Copy Markdown
Contributor Author

moiseev commented Jun 22, 2017

With a FIXIT(ABI), I think it would be better than keeping the underscored APIs. @airspeedswift, @dabrahams what do you think?

@jrose-apple
Copy link
Copy Markdown
Contributor

Ah, if nothing is calling _word(at:) except for words then it should be okay. I was worried that there might be other extensions methods that go directly for _word(at:).

@lorentey
Copy link
Copy Markdown
Member

Sadly the FixedWidthInteger.init<T : BinaryInteger>(extendingOrTruncating: T) initializer does currently call T._word(at:), so external code may indeed run into the runtime error when it tries to initialize a standard integer from a custom BinaryInteger implementation.

@lorentey
Copy link
Copy Markdown
Member

@moiseev, @jrose-apple: I submitted #10558 with a working (if suboptimal) attempt at making words the primary interface.

Adding extra constraints on the conversion initializer requirements quickly turned out to be infeasible in practice -- it lead to frequent difficulties with numeric conversions in generic contexts. (For example, consider numericCasts involving Collection.IndexDistance types.)

That leaves _word(at:) as the viable approach. It seems ideal at first glance, but to define it in terms of words, we need to do index arithmetic that seems difficult/impossible to implement without
relying on numeric casts -- and since the conversions would call call _word(at:), we fall into infinite recursions.

#10558 chooses an alternative API and contains a discussion of some other approaches that may lead to better results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants