Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
On Sun, Jan 15, 2017 at 2:00 AM, Nate Cook via swift-evolution <
swift-evolution@swift.org> wrote:

>
> Link: https://github.com/natecook1000/swift/blob/nc-
> bigint/test/Prototypes/BigInt.swift
>
> This is just a proof of concept BigInt implementation—there's not much in
> the way of optimization going on, and it's a little out of date. It does
> use sign-magnitude, so the word(at:) implementation is O(n) on each call
> due to this bit:
>
> https://github.com/natecook1000/swift/blob/nc-
> bigint/test/Prototypes/BigInt.swift#L571-L576
>
>
> The only other question I have from looking at this again is whether
> perhaps BinaryInteger should have a toString(radix:uppercase:) method,
> since arbitrary precision types may be able to optimize significantly for
> different bases. The prototype at the link doesn't do this, but a hex
> string (or any factor of 2 base?) should be far cheaper to generate than
> the general case that uses repeated division. Without that, a BigInt type
> doesn't have any way to customize the generic String(_:radix:uppercase:)
> initializer.
>

Oh yes, +1 to this idea. (Though for consistency it might be more aptly
named `description(radix:uppercase:)`.)

-Nate
>
>
> I'm glad to see this moving forward.
>
> -Ben Spratling
>
> On Jan 14, 2017, at 2:00 AM, Rien via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> +1
>
> Any change of including “ranged integers”?
> I.e. an integer with a value that must fit in a predefined range?
>
> Regards,
> Rien
>
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Swiftrien
> Project: http://swiftfire.nl
>
>
>
>
> On 13 Jan 2017, at 21:47, Max Moiseev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi everyone,
>
> Back in June 2016 we discussed the new design of the integer types for the
> standard library. It even resulted in acceptance of SE-0104 for Swift 3.
> Unfortunately we were not able to implement it in time for the release.
>
> But it was not forgotten, although, as time went by, a few changes needed
> to be made in order to reflect the current state of the language.
> Without further introduction, please welcome the refined proposal to make
> integers in Swift more suitable for generic programming.
>
> Available in this gist https://gist.github.com/moiseev/
> 62ffe3c91b66866fdebf6f3fcc7cad8c and also inlined below.
>
> Max
>
> Protocol-oriented integers (take 2)
>
>   • Proposal: SE-
>   • Authors: Dave Abrahams, Maxim Moiseev
>   • Review Manager: TBD
>   • Status: Awaiting review
>   • Bug: SR-3196
>   • Previous Proposal: SE-0104
> Introduction
>
> This proposal is an evolution of SE-0104. The goal is still to clean up
> Swifts integer APIs and make them more useful for generic programming.
>
> The language has evolved in ways that affect integers APIs since the time
> the original proposal was approved for Swift 3. We also attempted to
> implement the proposed model in the standard library and found that some
> essential APIs were missing, whereas others could be safely removed.
>
> Major changes to the APIs introduced by this proposal (as compared to
> SE-0104) are listed in a dedicated section.
>
> Motivation
>
> Swift's integer protocols don't currently provide a suitable basis for
> generic programming. See this blog post for an example of an attempt to
> implement a generic algorithm over integers.
>
> The way the Arithmetic protocol is defined, it does not generalize to
> floating point numbers and also slows down compilation by requiring every
> concrete type to provide an implementation of arithmetic operators, thus
> polluting the overload set.
>
> Converting from one integer type to another is performed using the concept
> of the 'maximum width integer' (see MaxInt), which is an artificial
> limitation. The very existence of MaxInt makes it unclear what to do should
> someone implement Int256, for example.
>
> Another annoying problem is the inability to use integers of different
> types in comparison and bit-shift operations. For example, the following
> snippets won't compile:
>
> var x: Int8 = 42
> let y = 1
> let z = 0
>
>
> x
> <<= y   // error: binary operator '<<=' cannot be applied to operands of
> type 'Int8' and 'Int'
> if x > z { ... }  // error: binary operator '>' cannot be applied to
> operands of type 'Int8' and 'Int'
> Currently, bit-shifting a negative number of (or too many) bits causes a
> trap on some platforms, which makes low-level bit manipulations needlessly
> dangerous and unpredictable.
>
> Finally, the current design predates many of the improvements that came
> since Swift 1, and hasn't been revised since then.
>
> Proposed solution
>
> We propose a new model that does not have above mentioned problems and is
> more easily extensible.
>
>   +--+  +-+
>   +-->+  Arithmetic  |  | Comparable  |
>   |   |   (+,-,*,/)  |  | (==,<,>,...)|
>   |   +-++  +---+

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
Given that Arithmetic also provides for multiplication and division, might
it be wise then also to have .multiplicativeIdentity (or .one)?

On Sun, Jan 15, 2017 at 02:47 Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Sat Jan 14 2017, Dave Abrahams  wrote:
>
> > That said, the ability to interpret integer literals as an arbitrary
> > Arithmetic isn't used anywhere in the standard library, so I'd like to
> > consider undoing
> >
> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15d5709eb2be069286c1
> > and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
> > BinaryInteger.
>
> Oh, and I meant to add: maybe the right way for an arbitrary X modeling
> Arithmetic to spell zero (which is needed for negation) is something
> like
>
>X.additiveIdentity
>
> or
>
>X.zero
>
> in other words, via a requirement
>
>static var theNameWeChoose: Self { get }
>
> --
> -Dave
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread Chris Eidhof via swift-evolution
I agree with Dave. To me, building in a limit so that the return type can't
be inferred seems arbitrary.

On Sun, Jan 15, 2017 at 12:41 AM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Fri Jan 13 2017, John McCall  wrote:
>
> > I'm also not sure we'd ever want the element type to be inferred from
> > context like this.  Generic subscripts as I see it are about being
> > generic over *indexes*, not somehow about presenting a polymorphic
> > value.
>
> Actually I *would* want to be able to do that, though I admit it's the
> 1% case (or less).
>
> --
> -Dave
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>



-- 
Chris Eidhof
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread David Sweeris via swift-evolution

> On Jan 15, 2017, at 03:20, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Given that Arithmetic also provides for multiplication and division, might it 
> be wise then also to have .multiplicativeIdentity (or .one)?
> 
>> On Sun, Jan 15, 2017 at 02:47 Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> on Sat Jan 14 2017, Dave Abrahams  wrote:
>> 
>> > That said, the ability to interpret integer literals as an arbitrary
>> > Arithmetic isn't used anywhere in the standard library, so I'd like to
>> > consider undoing
>> > https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15d5709eb2be069286c1
>> > and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
>> > BinaryInteger.
>> 
>> Oh, and I meant to add: maybe the right way for an arbitrary X modeling
>> Arithmetic to spell zero (which is needed for negation) is something
>> like
>> 
>>X.additiveIdentity
>> 
>> or
>> 
>>X.zero
>> 
>> in other words, via a requirement
>> 
>>static var theNameWeChoose: Self { get }

+1

- Dave Sweeris ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread David Sweeris via swift-evolution

> On Jan 14, 2017, at 18:55, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> Responding to both Jacob and Xiaodi here; thanks very much for your
> feedback!
> 
>> on Sat Jan 14 2017, Xiaodi Wu  wrote:
>> 
>> On Sat, Jan 14, 2017 at 1:32 AM, Jacob Bandes-Storch via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> 
>>> Great work, all. I'm not sure I ever commented on SE-0104, so I've read
>>> through this one more carefully. Here are some things that came to mind:
>>> 
>>> *## Arithmetic*
>>> 
>>> Why are ExpressibleByIntegerLiteral and init?(exactly:)
>>> required? I could understand needing access to 0, but this could be
>>> provided by a static property or nullary initializer. It doesn't seem like
>>> all types supporting arithmetic operations would necessarily be convertible
>>> from an arbitrary binary integer.
>>> 
>>> 
>>> I tried to evaluate the Arithmetic protocol by considering what it means
>>> for higher-dimensional types such as CGPoint and CGVector. My use case was
>>> a linear interpolation function:
>>> 
>>>func lerp(from a: T, to b: T, by ratio: T) -> T {
>>>return a + (b - a) * ratio
>>>}
>>> 
>>> If I've read the proposal correctly, this definition works for integer and
>>> floating-point values. But we can't make it work properly for CGVector (or,
>>> perhaps less mathematically correct but more familiar, CGPoint). It's okay
>>> to define +(CGVector, CGVector) and -(CGVector, CGVector), but *(CGVector,
>>> CGVector) and /(CGVector, CGVector) don't make much sense. What we really
>>> want is *(CGVector, *CGFloat*) and /(CGVector, *CGFloat*).
>>> 
>>> After consulting a mathematician, I believe what the lerp function really
>>> wants is for its generic param to be an affine space
>>> . I explored this a bit here:
>>> https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d53b
>>> 03#file-affine-swift-L16-L18
>>> 
>>> This approach is less restrictive and more composable than the proposed
>>> Arithmetic protocol, which can be viewed as a special case with the
>>> following definitions:
>>> 
>>>extension Arithmetic: AffineSpace, VectorSpace {  // not actually
>>> allowed in Swift
>>>typealias Displacement = Self
>>>typealias Scalar = Self
>>>}
>>> 
>>> It'd be great to be able to define a lerp() which works for all
>>> floating-point and integer numbers, as well as points and vectors (assuming
>>> a glorious future where CGPoint and CGVector have built-in arithmetic
>>> operations). But maybe the complexity of these extra protocols isn't worth
>>> it for the stdlib...
>>> 
>> 
>> I think, in the end, it's the _name_ that could use improvement here. As
>> the doc comments say, `Arithmetic` is supposed to provide a "suitable basis
>> for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
>> appropriate? It would make it clear that `CGVector` is not meant to be a
>> conforming type.
> 
> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
> would be appropriate in that case sort of depends on what the implied
> field is, right?

I was under the impression that complex numbers are scalar numbers... although 
maybe not since once you get past, I think quaternions, you start losing 
division and eventually multiplication, IIRC. (I hate it when two of my 
recollections try to conflict with each other.)



> It's true that CGPoint and CGVector have no obvious sensible
> interpretation of "42", and that's unfortunate.  The problem with
> protocols for algebraic structures is that there's an incredibly
> complicated lattice (see figures 3.1, 3.2 in
> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
> shove all of those protocols into the standard library (especially not
> prematurely) but each requirement you add to a more-coarsely aggregated
> protocol like Arithmetic will make it ineligible for representing some
> important type.

My only concern with this is that later on, if we do decide the stdlib should 
have them, does it then become a breaking change to start moving all that stuff 
around? Or would everything be fine as long as the net requirements for the 
"Arithmetic" protocol stay the same regardless of how things get redistributed 
under the hood?


>>> *## FixedWidthInteger*
>>> 
>>> Why is popcount restricted to FixedWidthInteger? It seems like it could
>>> theoretically apply to any UnsignedInteger.
>>> 
>> 
>> You can perfectly legitimately get a popcount for a signed integer. It's
>> just looking at the binary representation and counting the ones. But then
>> with two's complement, it'd have to be restricted to FixedWidthInteger and
>> not BinaryInteger, because the same negative value would have a different
>> popcount depending on the type's bitwidth. 
> 
> Right, or to put it differently, the popcount of a negative BigInt would
> always be inifinite.
> 
>> I'd disagree strongly with removing popcount from signed binary
>> in

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sat Jan 14 2017, Dave Abrahams  wrote:

> That said, the ability to interpret integer literals as an arbitrary
> Arithmetic isn't used anywhere in the standard library, so I'd like to
> consider undoing
> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15d5709eb2be069286c1
> and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
> BinaryInteger.

Oh, and I meant to add: maybe the right way for an arbitrary X modeling
Arithmetic to spell zero (which is needed for negation) is something
like

   X.additiveIdentity

or

   X.zero

in other words, via a requirement

   static var theNameWeChoose: Self { get }

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Anton Zhilin via swift-evolution
What about taking a mathematical approach to numbers?

protocol Group : Equatable {
static var zero: Self { get }
static func + (Self, Self) -> Self
static func += (inout Self, Self)
static func - (Self, Self) -> Self
static func -= (inout Self, Self)
static prefix func - (Self) -> Self
}

protocol Ring : Group {
static var one: Self { get }
static func * (Self, Self) -> Self
static func *= (inout Self, Self)
func tryDivide(by: Self) -> Self?
func tryInvert() -> Self?
}

protocol Field : Ring {
static func / (Self, Self) -> Self
static func /= (inout Self, Self)
var inverted: Self { get }
}

protocol VectorSpace : Group {
associatedtype Scalar : Field
static func * (Self, Scalar) -> Self
static func *= (inout Self, Scalar) -> Self
static func / (Self, Scalar) -> Self
static func /= (inout Self, Scalar) -> Self
static func * (Scalar, Self) -> Self
}

Detalization of mathematical terminology will be determined by what kind of
types we have in the standard library. Integer types are rings (except for
overflow), floating-point types are fields (except for precision), point
types are linear spaces, so I thought the abstractions above are the bare
minimum.

Unfortunately, Swift doesn’t have rename operations for protocol
requirements, so we can’t express groups that use operations other than +
and -. What we can do is to include an adapter to wrap current instance in
an additive group interface:

struct MultiplicativeGroupAdapter : Group {
// ...
}

extension Field {
var multiplicativeGroup: MultiplicativeGroupAdapter
}

​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Code comments that check code validity.

2017-01-15 Thread Amir Michail via swift-evolution

> On Jan 14, 2017, at 8:11 PM, Jay Abbott  wrote:
> 
> I think this would be an anti-feature , here are some reasons why:
> 
>   • If it is code you wrote as an idea for how something might be 
> implemented in the future, then it should be manually tweaked/validated 
> anyway when you put it back in. If things change slightly such that your old 
> commented code breaks when you comment it back in this is a good thing, it 
> forces you to check/amend the old code so that it functions properly in the 
> updated environment that it now inhabits.
>   • If it’s a significant amount of code then it really ought to be 
> structured into something appropriate, like a function or a class, in which 
> case it can happily live uncalled and not commented out. But it’s not a great 
> practice to leave unused code lying around, unless you know it’s going to be 
> used soon.
>   • Commented code is often commented out specifically to make things 
> compile while you tweak/break things somewhere else (i.e. commented out 
> temporarily) - so of course you don’t want it to be compiled.
>   • If you comment out code temporarily then it really should just mean 
> temporarily, i.e. between now and your next commit to test something 
> immediately. Source control means there’s no need for longer-lived commented 
> out code. Unfinished code can live on a branch, old code that you might want 
> to refer to or re-use later is in your source control history, and unused 
> code should probably just be removed.

Other developers may prefer to have some code comments. Solo indie developers 
have more freedom to just do what they want in this respect...

>   • Code that is written and working and intended to be enabled later on 
> should be activated by a feature-toggle (either a compile-time or a run-time 
> one) rather than commented out.
> 
> On Sun, 15 Jan 2017 at 00:04 Amir Michail via swift-evolution 
>  wrote:
> 
>> On Jan 14, 2017, at 6:56 PM, Xiaodi Wu  wrote:
>> 
>> 
>> 
>> On Sat, Jan 14, 2017 at 5:50 PM, Amir Michail  wrote:
>> 
>>> On Jan 14, 2017, at 6:46 PM, Xiaodi Wu  wrote:
>>> 
>>> On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  wrote:
>>> 
>>> > On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
>>> >
>>> > This has been brought up on this list before. The conclusion of the 
>>> > previous thread on this topic was that there is a way to do this:
>>> >
>>> > #if false
>>> > // put your code here
>>> > #endif
>>> >
>>> 
>>> This would not check the code for compilability within the surrounding 
>>> code. This requires more than a syntax check.
>>> 
>>> I can't say I've ever needed that feature; could you share a concrete use 
>>> case?
>>> 
>> 
>> Consider an array of levels for a game where some levels are commented out 
>> for possible future use. It would be nice to have such level entries 
>> continue to compile as the code elsewhere evolves and yet not be included in 
>> the executable.
>> 
>> ```
>> enum Levels: Int {
>>   case foo = 1, bar, baz, boo
>> }
>> 
>> var levels: [Levels] = [
>>   .foo,
>>   .bar,
>> ]
>> 
>> // disabled
>> _ = {
>>   levels += [
>> .baz,
>> .boo,
>> // this won't compile if you add:
>> // .nonExistent,
>>   ]
>> }
>> ```
> 
> That’s helpful thanks! I still think code comments would be nice though.
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Nate Cook  wrote:

> Excited to see this getting closer!
>
>> On Jan 14, 2017, at 7:41 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> on Sat Jan 14 2017, Benjamin Spratling > > wrote:
>> 
>>> I notice the BinaryInteger's func word(at n: Int) -> UInt function
>>> expects a 2's complement representation.  Do you expect that "BigInt"
>>> will be implemented with 2's complement?  
>> 
>> Ah, this is an excellent question, excellently phrased!
>> 
>> We designed it so BigInt could use 2's complement (see
>> DoubleWidth, which works that way), which should be faster than
>> sign-magnitude...
>> 
>> BUT: I hadn't really considered that if existing bignum libraries use
>> sign-magnitude, we'll want to be able to efficiently use their
>> representations, so we need to make sure the protocols don't force those
>> representations to be inefficient.
>> 
>>> As a nonmutating function, I would think any implementation from a 1's
>>> complement big int would result in O(n^2) unless the BigInt were
>>> designed with scratch space where it could store the intermediate
>>> values of that representation.  
>> 
>> Oh... you mean that word(at:) itself would be linear, and thus
>> algorithms that iterate the words linearly would be O(N^2)...  yuck.
>> 
>> So far, the only algorithm we have using word(at:) is this one, and
>> https://github.com/apple/swift/blob/new-integer-protocols/stdlib/public/core/Integers.swift.gyb#L2191
>>  
>> 
>> presumably we could adapt it to sign-magnitude by expanding the
>> BinaryInteger protocol with a static var that indicates which
>> representation is used.
>> 
>>  enum Representation { 
>>twosComplement, signMagnitude, /*onesComplement?*/ 
>>  }
>>  static var representation: Representation { get }
>> 
>> Now, the other algorithms that I can anticipate would use word(at:) are
>> basically... the ones you'd have to implement to build BigInt, so I
>> guess this change would be OK.
>> 
>> Supporting sign-magnitude complicates generic programming with these
>> protocols, though, so I want to be really sure we need to do this before
>> we take the plunge.
>>
>>> I only ask because just last week I was designing an arbitrary-width
>>> float type in 1's complement, well, really I kept the sign bit in a
>>> separate Bool.  
>> 
>> Sounds like sign-magnitude rather than 1's complement if I remember my
>> complements correctly.
>> 
>>> Of course, I recognize the value of being able to write integer init
>>> code from a 2's complement representation, I'm just curious if there's
>>> a way to allow this function to be more efficient for alternate
>>> representations.
>>> 
>>> I love that there's a DoubleWidth type, having coded some arbitrary
>>> precision arithmetic, that's always a downer going from generic code
>>> to having to pick a specific "big enough" result type.
>>> 
>>> I'm glad the % operator got moved.  It really did stand out as not
>>> part of floating points.
>>> 
>>> Trailing zeros looks like a sensible optimization.
>>> 
>>> I agree with moving the shift operators, I like that you've called out
>>> the notion of an infinite shift.  
>> 
>> I don't think we ever meant to say anything about infinite shifts!
>> 
>>> I can't say I fully understood the use of the separate mask vs. smart
>>> shift operators, but I'll take another read in the next few days and
>>> see if I understand why they exist.
>> 
>> You're not alone it appears.  We need to clarify that in the text,
>> obviously.  The smart shift operators are there to give you sensible
>> semantics without undefined behavior or traps in the cases that have
>> logically computable answers.  The masking shifts are there for
>> performance in the rare cases where smart shifting with a non-literal
>> shift amount introduces non-negligible overheads (testing and branching
>> to handle overshifts and negative shift amounts).  
>> 
>> Obviously you have to know that the masking behavior is benign in your
>> use case when using masking shifts in an operation.  I made the mistake
>> of using a masking shift to optimize some code the other day where the
>> shift amount could be equal to the full width of the value being
>> shifted.  I ended up widening the LHS before doing the shift and then
>> truncating back to the width, but that's only because I was writing
>> performance-critical code.  The smart shift would have “just worked.”
>> 
>>> I know this PR does not address the BitInt implementation, but do you
>>> have one?
>> 
>> I know someone that implemented one... using sign-magnitude, actually,
>> and his word(at:) implementation has the linear cost problem.  I'll ask
>> him to post a link.
>
> Link: 
> https://github.com/natecook1000/swift/blob/nc-bigint/test/Prototypes/BigInt.swift
>
> This is just a proof of concept BigInt implementation—there's not much
> in the way of op

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Xiaodi Wu  wrote:

> Given that Arithmetic also provides for multiplication and division, might
> it be wise then also to have .multiplicativeIdentity (or .one)?

I'm always wary of adding requirements that don't have a demonstrated
use-case in a generic algorithm.  What generic algorithm can use this
value?
>
> On Sun, Jan 15, 2017 at 02:47 Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> on Sat Jan 14 2017, Dave Abrahams  wrote:
>>
>> > That said, the ability to interpret integer literals as an arbitrary
>> > Arithmetic isn't used anywhere in the standard library, so I'd like to
>> > consider undoing
>> >
>> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15d5709eb2be069286c1
>> > and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
>> > BinaryInteger.
>>
>> Oh, and I meant to add: maybe the right way for an arbitrary X modeling
>> Arithmetic to spell zero (which is needed for negation) is something
>> like
>>
>>X.additiveIdentity
>>
>> or
>>
>>X.zero
>>
>> in other words, via a requirement
>>
>>static var theNameWeChoose: Self { get }
>>
>> --
>> -Dave
>>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, David Sweeris  wrote:

>> On Jan 14, 2017, at 18:55, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> Responding to both Jacob and Xiaodi here; thanks very much for your
>> feedback!
>
>> 
>>> on Sat Jan 14 2017, Xiaodi Wu  wrote:
>>> 
>>> On Sat, Jan 14, 2017 at 1:32 AM, Jacob Bandes-Storch via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>> 
 Great work, all. I'm not sure I ever commented on SE-0104, so I've read
 through this one more carefully. Here are some things that came to mind:
 
 *## Arithmetic*
 
 Why are ExpressibleByIntegerLiteral and init?(exactly:)
 required? I could understand needing access to 0, but this could be
 provided by a static property or nullary initializer. It doesn't seem like
 all types supporting arithmetic operations would necessarily be convertible
 from an arbitrary binary integer.
 
 
 I tried to evaluate the Arithmetic protocol by considering what it means
 for higher-dimensional types such as CGPoint and CGVector. My use case was
 a linear interpolation function:
 
func lerp(from a: T, to b: T, by ratio: T) -> T {
return a + (b - a) * ratio
}
 
 If I've read the proposal correctly, this definition works for integer and
 floating-point values. But we can't make it work properly for CGVector (or,
 perhaps less mathematically correct but more familiar, CGPoint). It's okay
 to define +(CGVector, CGVector) and -(CGVector, CGVector), but *(CGVector,
 CGVector) and /(CGVector, CGVector) don't make much sense. What we really
 want is *(CGVector, *CGFloat*) and /(CGVector, *CGFloat*).
 
 After consulting a mathematician, I believe what the lerp function really
 wants is for its generic param to be an affine space
 . I explored this a bit here:
 https://gist.github.com/jtbandes/93eeb7d5eee8e1a7245387c660d53b
 03#file-affine-swift-L16-L18
 
 This approach is less restrictive and more composable than the proposed
 Arithmetic protocol, which can be viewed as a special case with the
 following definitions:
 
extension Arithmetic: AffineSpace, VectorSpace {  // not actually
 allowed in Swift
typealias Displacement = Self
typealias Scalar = Self
}
 
 It'd be great to be able to define a lerp() which works for all
 floating-point and integer numbers, as well as points and vectors (assuming
 a glorious future where CGPoint and CGVector have built-in arithmetic
 operations). But maybe the complexity of these extra protocols isn't worth
 it for the stdlib...
 
>>> 
>>> I think, in the end, it's the _name_ that could use improvement here. As
>>> the doc comments say, `Arithmetic` is supposed to provide a "suitable basis
>>> for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
>>> appropriate? It would make it clear that `CGVector` is not meant to be a
>>> conforming type.
>> 
>> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
>> would be appropriate in that case sort of depends on what the implied
>> field is, right?
>
> I was under the impression that complex numbers are scalar
> numbers... 

Well, you can view them as 2d vectors, so I'm not sure.  We need more of
a numerics expert than I am to weigh in here.

> although maybe not since once you get past, I think quaternions, you
> start losing division and eventually multiplication, IIRC. (I hate it
> when two of my recollections try to conflict with each other.)
>
>> It's true that CGPoint and CGVector have no obvious sensible
>> interpretation of "42", and that's unfortunate.  The problem with
>> protocols for algebraic structures is that there's an incredibly
>> complicated lattice (see figures 3.1, 3.2 in
>> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
>> shove all of those protocols into the standard library (especially not
>> prematurely) but each requirement you add to a more-coarsely aggregated
>> protocol like Arithmetic will make it ineligible for representing some
>> important type.
>
> My only concern with this is that later on, if we do decide the stdlib
> should have them, does it then become a breaking change to start
> moving all that stuff around? Or would everything be fine as long as
> the net requirements for the "Arithmetic" protocol stay the same
> regardless of how things get redistributed under the hood?

As far as I know, we don't have a strategy for injecting protocols into
a refinement hierarchy without destablizing ABI.

 *## FixedWidthInteger*
 
 Why is popcount restricted to FixedWidthInteger? It seems like it could
 theoretically apply to any UnsignedInteger.
 
>>> 
>>> You can perfectly legitimately get a popcount for a signed integer. It's
>>> just looking at the binary representation and counting the one

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Anton Zhilin  wrote:

> What about taking a mathematical approach to numbers?
>
> protocol Group : Equatable {
> static var zero: Self { get }
> static func + (Self, Self) -> Self
> static func += (inout Self, Self)
> static func - (Self, Self) -> Self
> static func -= (inout Self, Self)
> static prefix func - (Self) -> Self
> }
>
> protocol Ring : Group {
> static var one: Self { get }
> static func * (Self, Self) -> Self
> static func *= (inout Self, Self)
> func tryDivide(by: Self) -> Self?
> func tryInvert() -> Self?
> }
>
> protocol Field : Ring {
> static func / (Self, Self) -> Self
> static func /= (inout Self, Self)
> var inverted: Self { get }
> }
>
> protocol VectorSpace : Group {
> associatedtype Scalar : Field
> static func * (Self, Scalar) -> Self
> static func *= (inout Self, Scalar) -> Self
> static func / (Self, Scalar) -> Self
> static func /= (inout Self, Scalar) -> Self
> static func * (Scalar, Self) -> Self
> }

The first test for the inclusion of any protocol in the standard library
is: “what generic algorithm that uses this protocol as a constraint
would be appropriate for inclusion in the standard library?”

I don't think we have a use for any of the above directly in the
standard library.  All the generic algorithms I know of that would be
appropriate to those protocols are part of some specialized domain that
should have its own library built on top of the Swift standard lib.

> Detalization of mathematical terminology will be determined by what kind of
> types we have in the standard library. Integer types are rings (except for
> overflow), floating-point types are fields (except for precision), point
> types are linear spaces, so I thought the abstractions above are the bare
> minimum.
>
> Unfortunately, Swift doesn’t have rename operations for protocol
> requirements, so we can’t express groups that use operations other than +
> and -. What we can do is to include an adapter to wrap current instance in
> an additive group interface:
>
> struct MultiplicativeGroupAdapter : Group {
> // ...
> }
>
> extension Field {
> var multiplicativeGroup: MultiplicativeGroupAdapter
> }
>
> ​
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Rob Mayoff via swift-evolution
On Sat, Jan 14, 2017 at 7:41 PM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

> Oh... you mean that word(at:) itself would be linear, and thus
> algorithms that iterate the words linearly would be O(N^2)...  yuck.
>

Couldn't you fix this by replacing `func word(at n: Int) -> UInt` with `var
words: Sequence`, producing the words from least to most significant?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Make nested functions less order-dependent.

2017-01-15 Thread Hoon H. via swift-evolution
I like to suggest relaxing ordering restriction of nested functions. In short, 
just allow nested functions to be defined below its call site. ("Use of local 
variable ‘b’ before its declaration.” error)

Here’s more explanation.

In Swift, we can define nested functions.

func a() {
func b() {
}
func c() {
}
}

It’s quiet flexible, so we actually can call functions regardless order of 
their declaration.

func a() {
func b() {
c() // Calling `c` which is defined below is allowed.
}
func c() {
}
}

This is possible because `c` does not have any order-sensitive dependency.

But unfortunately, calling `b` before its declaration is not allowed. Although 
it has no dependency.

func a() {
b() // Use of local variable ‘b’ before its declaration.
func b() {
c()
}
func c() {
}
}

It doesn’t make sense to me that `b` is disallowed while `c` is allowed. It’d 
be nice if this restriction goes away. Because that allows me to do some code 
“outlining” layout. Please consider this sample.

func work1() {
// Illustrates big outlines first...
bigStep1()
bigStep2()

func bigStep1() {
sharedSmallStep1()
sharedSmallStep2()
}
func bigStep2() {
sharedSmallStep2()
sharedSmallStep3()
}

// Describe details later...
func sharedSmallStep1() {
// Complex and long code...
}
func sharedSmallStep2() {
// Complex and long code...
}
func sharedSmallStep3() {
// Complex and long code...
}
}

Of course you can do this in reverse order, but in that case, we have to read 
them backward — from bottom to top. It’s easier to read if larger outline if on 
top.

I can do this with (1) un-nested free functions, or (2) enum/class/struct 
member functions. But this is still better because nested functions provides 
lexical scopes which can reduce amount of code greatly.

func a(_ v1: Int) { // `v1` is available to all nested scopes.
print(v1)
b(333)
func b(_ v2: Int) { // `v2` is available to all nested scopes.
print(v1 + v2)
c(555)
func c(_ v3: Int) { // `v3` is available to all nested scopes.
print(v1 + v2 + v3)
}
}
}

In the above example, `b` and `c` automatically captures `v1`, so we don’t need 
to pass these values here and there. If `c` was a free function, it should have 
three arguments. Also, this capture does not introduce any extra 
order-dependency.

— Hoon H.





___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Rob Mayoff  wrote:

> On Sat, Jan 14, 2017 at 7:41 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Oh... you mean that word(at:) itself would be linear, and thus
>> algorithms that iterate the words linearly would be O(N^2)...  yuck.
>>
>
> Couldn't you fix this by replacing `func word(at n: Int) -> UInt` with `var
> words: Sequence`, producing the words from least to most significant?


Yeah... I thought about that...

Since Sequence isn't actually a valid type and the words are
multipass, it would actually be either

  // probably too inefficient
  var words: AnyCollection {get} 

or 

  // a bit more complexity than I'd like to have for this purpose
  associatedtype Words : Collection /*where Iterator.Element == UInt*/
  var words: Words {get}

The one algorithm we currently have that uses words generically is
iterating them in reverse order, but I think that's easily
solvable.

Slightly more concerning is that word(at:) was designed so that
algorithms could index beyond countRepresentedWords and get a
mathematically correct answer.  So we'd need to either:

  1. give that up - not a bad choice considering that it currently
 forces a branch into word(at:) that will (probably?) never be used
 if the algorithm is written in the most efficient possible way

  2. keep countRepresentedWords and make words an infinite collection

I guess I'm leaning towards #1.  Exchanging
countRepresentedWords/word(at:) for Words/words is almost an even trade
in overall complexity.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
There _may_ be value in recognizing the distinction between rings and
fields, perhaps? Just as the FP protocols make room for people to implement
their own decimal FP types, and just as you're trying to make Arithmetic
accommodate complex numbers, the distinction would allow someone to write
algorithms generic over rationals and reals (i.e. fields). Being able to
represent exact fractions isn't so terribly niche, and I think the design
wouldn't be terribly complicated by its accommodation:

```
// rename Arithmetic to Ring
// it's acceptable to omit `.one` from Ring, though some may call that a
Pseudoring
// consider omitting division from Ring and pushing it down to
BinaryInteger and Field

protocol BinaryInteger : Ring { ... }

protocol Field : Ring {
  static var one { get }
  static func / (Self, Self) -> Self
  static func /= (inout Self, Self)
  var inverted: Self { get } // default impl: .one / self
}

protocol FloatingPoint : Field { ... }
// rational number types and complex number types
// would also conform to Field
```


On Sun, Jan 15, 2017 at 09:14 Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:



on Sun Jan 15 2017, Anton Zhilin  wrote:



> What about taking a mathematical approach to numbers?

>

> protocol Group : Equatable {

> static var zero: Self { get }

> static func + (Self, Self) -> Self

> static func += (inout Self, Self)

> static func - (Self, Self) -> Self

> static func -= (inout Self, Self)

> static prefix func - (Self) -> Self

> }

>

> protocol Ring : Group {

> static var one: Self { get }

> static func * (Self, Self) -> Self

> static func *= (inout Self, Self)

> func tryDivide(by: Self) -> Self?

> func tryInvert() -> Self?

> }

>

> protocol Field : Ring {

> static func / (Self, Self) -> Self

> static func /= (inout Self, Self)

> var inverted: Self { get }

> }

>

> protocol VectorSpace : Group {

> associatedtype Scalar : Field

> static func * (Self, Scalar) -> Self

> static func *= (inout Self, Scalar) -> Self

> static func / (Self, Scalar) -> Self

> static func /= (inout Self, Scalar) -> Self

> static func * (Scalar, Self) -> Self

> }



The first test for the inclusion of any protocol in the standard library

is: “what generic algorithm that uses this protocol as a constraint

would be appropriate for inclusion in the standard library?”



I don't think we have a use for any of the above directly in the

standard library.  All the generic algorithms I know of that would be

appropriate to those protocols are part of some specialized domain that

should have its own library built on top of the Swift standard lib.



> Detalization of mathematical terminology will be determined by what kind
of

> types we have in the standard library. Integer types are rings (except for

> overflow), floating-point types are fields (except for precision), point

> types are linear spaces, so I thought the abstractions above are the bare

> minimum.

>

> Unfortunately, Swift doesn’t have rename operations for protocol

> requirements, so we can’t express groups that use operations other than +

> and -. What we can do is to include an adapter to wrap current instance in

> an additive group interface:

>

> struct MultiplicativeGroupAdapter : Group {

> // ...

> }

>

> extension Field {

> var multiplicativeGroup: MultiplicativeGroupAdapter

> }

>

> ​

> ___

> swift-evolution mailing list

> swift-evolution@swift.org

> https://lists.swift.org/mailman/listinfo/swift-evolution

>



--

-Dave



___

swift-evolution mailing list

swift-evolution@swift.org

https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
You're quite right. Since the multiplicative inverse of any integer other
than 1 and -1 is not itself an integer, there isn't much one can do...


On Sun, Jan 15, 2017 at 08:41 Dave Abrahams  wrote:

>
>
> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>
>
>
> > Given that Arithmetic also provides for multiplication and division,
> might
>
> > it be wise then also to have .multiplicativeIdentity (or .one)?
>
>
>
> I'm always wary of adding requirements that don't have a demonstrated
>
> use-case in a generic algorithm.  What generic algorithm can use this
>
> value?
>
> >
>
> > On Sun, Jan 15, 2017 at 02:47 Dave Abrahams via swift-evolution <
>
> > swift-evolution@swift.org> wrote:
>
> >
>
> >>
>
> >> on Sat Jan 14 2017, Dave Abrahams  wrote:
>
> >>
>
> >> > That said, the ability to interpret integer literals as an arbitrary
>
> >> > Arithmetic isn't used anywhere in the standard library, so I'd like to
>
> >> > consider undoing
>
> >> >
>
> >>
> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15d5709eb2be069286c1
>
> >> > and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
>
> >> > BinaryInteger.
>
> >>
>
> >> Oh, and I meant to add: maybe the right way for an arbitrary X modeling
>
> >> Arithmetic to spell zero (which is needed for negation) is something
>
> >> like
>
> >>
>
> >>X.additiveIdentity
>
> >>
>
> >> or
>
> >>
>
> >>X.zero
>
> >>
>
> >> in other words, via a requirement
>
> >>
>
> >>static var theNameWeChoose: Self { get }
>
> >>
>
> >> --
>
> >> -Dave
>
> >>
>
> >> ___
>
> >> swift-evolution mailing list
>
> >> swift-evolution@swift.org
>
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> >>
>
>
>
> --
>
> -Dave
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Throws? and throws!

2017-01-15 Thread Haravikk via swift-evolution

> On 12 Jan 2017, at 23:35, Xiaodi Wu via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> On Thu, Jan 12, 2017 at 4:58 PM, Jonathan Hull via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> I really like swift’s error handling system overall. It strikes a good 
> balance between safety and usability.
> 
> There are some cases where it would be nice to throw errors, but errors are 
> rarely expected in most use cases, so the overhead of ‘try’, etc… would make 
> things unusable. Thus fatalError or optionals are used instead.  For example, 
> operators like ‘+’ could never throw because adding ’try’ everywhere would 
> make arithmetic unbearable. But in a few cases it would make my algorithm 
> much cleaner if I just assume it will work and then catch overflow/underflow 
> errors if they happen, and resolve each of them with special cases.  Or 
> perhaps I am dealing with user entered values, and want to stop the 
> calculation and display a user visible error (e.g. a symbol in a spreadsheet 
> cell) instead of crashing.
> 
> Unless I'm mistaken, there is a performance overhead for throwing functions, 
> and thus a much greater barrier to the use cases outlined above is that the 
> performance penalty for '+' would be unacceptable in any case, whatever 
> syntactic sugar you could come up with.

Just wanted to chime in on performance, but since operators should really be 
inlined in most cases anyway I'm not sure there should be any performance 
penalty; the compiler should just optimise it away such that it basically 
becomes what it is now, the only case in which it would add a penalty is if the 
optional try is actually used.


I really like this idea personally; I prefer it to using the addWithOverflow() 
and similar methods, not that they're super burdensome, but error handling 
feels like a better fit IMO.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Jacob Bandes-Storch via swift-evolution
[ proposal link: https://gist.github.com/moiseev/
62ffe3c91b66866fdebf6f3fcc7cad8c ]


On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> Responding to both Jacob and Xiaodi here; thanks very much for your
> feedback!
>
> on Sat Jan 14 2017, Xiaodi Wu  wrote:
> > I think, in the end, it's the _name_ that could use improvement here. As
> > the doc comments say, `Arithmetic` is supposed to provide a "suitable
> basis
> > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
> > appropriate? It would make it clear that `CGVector` is not meant to be a
> > conforming type.
>
> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
> would be appropriate in that case sort of depends on what the implied
> field is, right?
>

I think "scalar" is an appropriate term for any field. The scalar-ness
usually comes into play when it's used in a vector space, but using the
term alone doesn't bother me.


> It's true that CGPoint and CGVector have no obvious sensible
> interpretation of "42", and that's unfortunate.  The problem with
> protocols for algebraic structures is that there's an incredibly
> complicated lattice (see figures 3.1, 3.2 in
> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
> shove all of those protocols into the standard library (especially not
> prematurely) but each requirement you add to a more-coarsely aggregated
> protocol like Arithmetic will make it ineligible for representing some
> important type.
>

Yep, it is quite complicated, and I understand not wanting to address all
that right now; calling it ScalarArithmetic seems appropriate to clarify
the limitations. FieldArithmetic might also be appropriate, but is less
clear (+ see below about quaternions).

Daves Sweeris and Abrahams wrote:

> > I was under the impression that complex numbers are scalar numbers...
although maybe not since once you get past, I think quaternions, you start
losing division and eventually multiplication, IIRC. (I hate it when two of
my recollections try to conflict with each other.)
>
> Well, you can view them as 2d vectors, so I'm not sure.  We need more of
a numerics expert than I am to weigh in here.

But complex numbers have multiplication and division operations defined
(they form a field), unlike regular vectors in R². Meaning you can have a
vector space over the field of complex numbers.

You still have multiplication and division past quaternions, but the
quaternions are *not commutative*. This isn't really a problem in Swift,
since the compiler never allows you to write an expression where the order
of arguments to an operator is ambiguous. This means they are *not a field*,
just a division ring  (a field
is a commutative division ring). (I believe you can't technically have a
vector space over a non-commutative ring; the generalization would be a
module . That's
probably an argument for the name ScalarArithmetic over FieldArithmetic.)

Octonions are furthermore *not associative*, which is more of a problem
since the standard library arithmetic operators are given an associativity.
We can't give that up for regular numeric types, so someone working with
octonions would just have to define their own non-associative operators
(since there's no way for the protocol requirement to specify the operator
associativity).


> That said, the ability to interpret integer literals as an arbitrary
> Arithmetic isn't used anywhere in the standard library, so I'd like to
> consider undoing
> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15
> d5709eb2be069286c1
> and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
> BinaryInteger.
>

+1


>
> >> *## BinaryInteger*
> >>
> >> I'm a little confused by the presence of init(extendingOrTruncating:)
> for
> >> *all* binary integers. Why does it make sense to be able to write
> >> UInt16(extendingOrTruncating: (-21 as Int8)) ? In my mind,
> sign-extension
> >> only has meaning when the source and destination types are both signed.
> >>
> >
> > Here (just IMHO), I disagree. Since any binary integer can be truncated
> and
> > any can be right-shifted, it makes sense for
> `init(extendingOrTruncating:)`
> > to be available for all of them. If I understand the proposal correctly,
> > `Int(extendingOrTruncating: (-1 as Int8))` would give you a different
> > result than `Int(extendingOrTruncating: (255 as UInt8)`.
>
> Yes it would.  But the real justification for this operation is generic
> programming with integers.  It isn't possible, today, to define:
>
>   init(extending:T) where T.isNarrowerThan(Self)
>   init(truncating:T) where T.isWiderThan(Self)
>
> >> Although I would not be against a clamp() function in the standard
> library,
> >> "init(clamping:)" sounds strange to me. What about calling it
> >> "init(nearestTo:)"?  One could also de

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Xiaodi Wu  wrote:

> There _may_ be value in recognizing the distinction between rings and
> fields, perhaps? Just as the FP protocols make room for people to implement
> their own decimal FP types, and just as you're trying to make Arithmetic
> accommodate complex numbers, the distinction would allow someone to write
> algorithms generic over rationals and reals (i.e. fields). Being able to
> represent exact fractions isn't so terribly niche, and I think the design
> wouldn't be terribly complicated by its accommodation:
>
> ```
> // rename Arithmetic to Ring
> // it's acceptable to omit `.one` from Ring, though some may call that a
> Pseudoring
> // consider omitting division from Ring and pushing it down to
> BinaryInteger and Field
>
> protocol BinaryInteger : Ring { ... }
>
> protocol Field : Ring {
>   static var one { get }
>   static func / (Self, Self) -> Self
>   static func /= (inout Self, Self)
>   var inverted: Self { get } // default impl: .one / self
> }
>
> protocol FloatingPoint : Field { ... }
> // rational number types and complex number types
> // would also conform to Field
> ```

What generic algorithms would this enable?  Would they be appropriate
for the standard library (as opposed to some more specialized numerics
library)?

> On Sun, Jan 15, 2017 at 09:14 Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> on Sun Jan 15 2017, Anton Zhilin  wrote:
>
>> What about taking a mathematical approach to numbers?
>
>>
>
>> protocol Group : Equatable {
>
>> static var zero: Self { get }
>
>> static func + (Self, Self) -> Self
>
>> static func += (inout Self, Self)
>
>> static func - (Self, Self) -> Self
>
>> static func -= (inout Self, Self)
>
>> static prefix func - (Self) -> Self
>
>> }
>
>>
>
>> protocol Ring : Group {
>
>> static var one: Self { get }
>
>> static func * (Self, Self) -> Self
>
>> static func *= (inout Self, Self)
>
>> func tryDivide(by: Self) -> Self?
>
>> func tryInvert() -> Self?
>
>> }
>
>>
>
>> protocol Field : Ring {
>
>> static func / (Self, Self) -> Self
>
>> static func /= (inout Self, Self)
>
>> var inverted: Self { get }
>
>> }
>
>>
>
>> protocol VectorSpace : Group {
>
>> associatedtype Scalar : Field
>
>> static func * (Self, Scalar) -> Self
>
>> static func *= (inout Self, Scalar) -> Self
>
>> static func / (Self, Scalar) -> Self
>
>> static func /= (inout Self, Scalar) -> Self
>
>> static func * (Scalar, Self) -> Self
>
>> }
>
> The first test for the inclusion of any protocol in the standard library
>
> is: “what generic algorithm that uses this protocol as a constraint
>
> would be appropriate for inclusion in the standard library?”
>
> I don't think we have a use for any of the above directly in the
>
> standard library.  All the generic algorithms I know of that would be
>
> appropriate to those protocols are part of some specialized domain that
>
> should have its own library built on top of the Swift standard lib.
>
>> Detalization of mathematical terminology will be determined by what kind
> of
>
>> types we have in the standard library. Integer types are rings (except for
>
>> overflow), floating-point types are fields (except for precision), point
>
>> types are linear spaces, so I thought the abstractions above are the bare
>
>> minimum.
>
>>
>
>> Unfortunately, Swift doesn’t have rename operations for protocol
>
>> requirements, so we can’t express groups that use operations other than +
>
>> and -. What we can do is to include an adapter to wrap current instance in
>
>> an additive group interface:
>
>>
>
>> struct MultiplicativeGroupAdapter : Group {
>
>> // ...
>
>> }
>
>>
>
>> extension Field {
>
>> var multiplicativeGroup: MultiplicativeGroupAdapter
>
>> }
>
>>
>
>> ​
>
>> ___
>
>> swift-evolution mailing list
>
>> swift-evolution@swift.org
>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>>
>
> --
>
> -Dave
>
> ___
>
> swift-evolution mailing list
>
> swift-evolution@swift.org
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
On Sun, Jan 15, 2017 at 3:27 PM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>
> > There _may_ be value in recognizing the distinction between rings and
> > fields, perhaps? Just as the FP protocols make room for people to
> implement
> > their own decimal FP types, and just as you're trying to make Arithmetic
> > accommodate complex numbers, the distinction would allow someone to write
> > algorithms generic over rationals and reals (i.e. fields). Being able to
> > represent exact fractions isn't so terribly niche, and I think the design
> > wouldn't be terribly complicated by its accommodation:
> >
> > ```
> > // rename Arithmetic to Ring
> > // it's acceptable to omit `.one` from Ring, though some may call that a
> > Pseudoring
> > // consider omitting division from Ring and pushing it down to
> > BinaryInteger and Field
> >
> > protocol BinaryInteger : Ring { ... }
> >
> > protocol Field : Ring {
> >   static var one { get }
> >   static func / (Self, Self) -> Self
> >   static func /= (inout Self, Self)
> >   var inverted: Self { get } // default impl: .one / self
> > }
> >
> > protocol FloatingPoint : Field { ... }
> > // rational number types and complex number types
> > // would also conform to Field
> > ```
>
> What generic algorithms would this enable?


For one, anything to do with dividing into equal parts could be generic
over floating point, rational, and even complex numbers, but you probably
wouldn't want to include integer types in such an algorithm.


> Would they be appropriate
> for the standard library (as opposed to some more specialized numerics
> library)?
>

The issue is that it's not terribly ergonomic to relegate `Field` to a
specialized library because one cannot retroactively conform
`FloatingPoint` to `Field`.

> On Sun, Jan 15, 2017 at 09:14 Dave Abrahams via swift-evolution <
> > swift-evolution@swift.org> wrote:
> >
> > on Sun Jan 15 2017, Anton Zhilin  wrote:
> >
> >> What about taking a mathematical approach to numbers?
> >
> >>
> >
> >> protocol Group : Equatable {
> >
> >> static var zero: Self { get }
> >
> >> static func + (Self, Self) -> Self
> >
> >> static func += (inout Self, Self)
> >
> >> static func - (Self, Self) -> Self
> >
> >> static func -= (inout Self, Self)
> >
> >> static prefix func - (Self) -> Self
> >
> >> }
> >
> >>
> >
> >> protocol Ring : Group {
> >
> >> static var one: Self { get }
> >
> >> static func * (Self, Self) -> Self
> >
> >> static func *= (inout Self, Self)
> >
> >> func tryDivide(by: Self) -> Self?
> >
> >> func tryInvert() -> Self?
> >
> >> }
> >
> >>
> >
> >> protocol Field : Ring {
> >
> >> static func / (Self, Self) -> Self
> >
> >> static func /= (inout Self, Self)
> >
> >> var inverted: Self { get }
> >
> >> }
> >
> >>
> >
> >> protocol VectorSpace : Group {
> >
> >> associatedtype Scalar : Field
> >
> >> static func * (Self, Scalar) -> Self
> >
> >> static func *= (inout Self, Scalar) -> Self
> >
> >> static func / (Self, Scalar) -> Self
> >
> >> static func /= (inout Self, Scalar) -> Self
> >
> >> static func * (Scalar, Self) -> Self
> >
> >> }
> >
> > The first test for the inclusion of any protocol in the standard library
> >
> > is: “what generic algorithm that uses this protocol as a constraint
> >
> > would be appropriate for inclusion in the standard library?”
> >
> > I don't think we have a use for any of the above directly in the
> >
> > standard library.  All the generic algorithms I know of that would be
> >
> > appropriate to those protocols are part of some specialized domain that
> >
> > should have its own library built on top of the Swift standard lib.
> >
> >> Detalization of mathematical terminology will be determined by what kind
> > of
> >
> >> types we have in the standard library. Integer types are rings (except
> for
> >
> >> overflow), floating-point types are fields (except for precision), point
> >
> >> types are linear spaces, so I thought the abstractions above are the
> bare
> >
> >> minimum.
> >
> >>
> >
> >> Unfortunately, Swift doesn’t have rename operations for protocol
> >
> >> requirements, so we can’t express groups that use operations other than
> +
> >
> >> and -. What we can do is to include an adapter to wrap current instance
> in
> >
> >> an additive group interface:
> >
> >>
> >
> >> struct MultiplicativeGroupAdapter : Group {
> >
> >> // ...
> >
> >> }
> >
> >>
> >
> >> extension Field {
> >
> >> var multiplicativeGroup: MultiplicativeGroupAdapter
> >
> >> }
> >
> >>
> >
> >> ​
> >
> >> ___
> >
> >> swift-evolution mailing list
> >
> >> swift-evolution@swift.org
> >
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> >>
> >
> > --
> >
> > -Dave
> >
> > ___
> >
> > swift-evolution mailing list
> >
> > swift-evolution@swift.org
> >

Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread Jacob Bandes-Storch via swift-evolution
On Sat, Jan 14, 2017 at 3:41 PM, Dave Abrahams via swift-evolution <
swift-evolution@swift.org> wrote:

>
> on Fri Jan 13 2017, John McCall  wrote:
>
> > I'm also not sure we'd ever want the element type to be inferred from
> > context like this.  Generic subscripts as I see it are about being
> > generic over *indexes*, not somehow about presenting a polymorphic
> > value.
>
> Actually I *would* want to be able to do that, though I admit it's the
> 1% case (or less).
>

1%? Wouldn't many JSON libraries, for instance, be eager to take advantage
of this?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
On Sun, Jan 15, 2017 at 3:29 PM, Jacob Bandes-Storch via swift-evolution <
swift-evolution@swift.org> wrote:

> [ proposal link: https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f
> 3fcc7cad8c ]
>
>
> On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> Responding to both Jacob and Xiaodi here; thanks very much for your
>> feedback!
>>
>> on Sat Jan 14 2017, Xiaodi Wu  wrote:
>> > I think, in the end, it's the _name_ that could use improvement here. As
>> > the doc comments say, `Arithmetic` is supposed to provide a "suitable
>> basis
>> > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
>> > appropriate? It would make it clear that `CGVector` is not meant to be a
>> > conforming type.
>>
>> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
>> would be appropriate in that case sort of depends on what the implied
>> field is, right?
>>
>
> I think "scalar" is an appropriate term for any field. The scalar-ness
> usually comes into play when it's used in a vector space, but using the
> term alone doesn't bother me.
>
>
>> It's true that CGPoint and CGVector have no obvious sensible
>> interpretation of "42", and that's unfortunate.  The problem with
>> protocols for algebraic structures is that there's an incredibly
>> complicated lattice (see figures 3.1, 3.2 in
>> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
>> shove all of those protocols into the standard library (especially not
>> prematurely) but each requirement you add to a more-coarsely aggregated
>> protocol like Arithmetic will make it ineligible for representing some
>> important type.
>>
>
> Yep, it is quite complicated, and I understand not wanting to address all
> that right now; calling it ScalarArithmetic seems appropriate to clarify
> the limitations. FieldArithmetic might also be appropriate, but is less
> clear (+ see below about quaternions).
>
> Daves Sweeris and Abrahams wrote:
>
> > > I was under the impression that complex numbers are scalar numbers...
> although maybe not since once you get past, I think quaternions, you start
> losing division and eventually multiplication, IIRC. (I hate it when two of
> my recollections try to conflict with each other.)
> >
> > Well, you can view them as 2d vectors, so I'm not sure.  We need more of
> a numerics expert than I am to weigh in here.
>
> But complex numbers have multiplication and division operations defined
> (they form a field), unlike regular vectors in R². Meaning you can have a
> vector space over the field of complex numbers.
>
> You still have multiplication and division past quaternions, but the
> quaternions are *not commutative*. This isn't really a problem in Swift,
> since the compiler never allows you to write an expression where the order
> of arguments to an operator is ambiguous. This means they are *not a
> field*, just a division ring  (a
> field is a commutative division ring). (I believe you can't technically
> have a vector space over a non-commutative ring; the generalization would
> be a module .
> That's probably an argument for the name ScalarArithmetic over
> FieldArithmetic.)
>

Hmm, the issue is that the integers are not a field. So, if we're going to
have it all modeled by one protocol, maybe neither is the best term.


> Octonions are furthermore *not associative*, which is more of a problem
> since the standard library arithmetic operators are given an associativity.
> We can't give that up for regular numeric types, so someone working with
> octonions would just have to define their own non-associative operators
> (since there's no way for the protocol requirement to specify the operator
> associativity).
>
>
>> That said, the ability to interpret integer literals as an arbitrary
>> Arithmetic isn't used anywhere in the standard library, so I'd like to
>> consider undoing
>> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15
>> d5709eb2be069286c1
>> and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
>> BinaryInteger.
>>
>
> +1
>
>
>>
>> >> *## BinaryInteger*
>> >>
>> >> I'm a little confused by the presence of init(extendingOrTruncating:)
>> for
>> >> *all* binary integers. Why does it make sense to be able to write
>> >> UInt16(extendingOrTruncating: (-21 as Int8)) ? In my mind,
>> sign-extension
>> >> only has meaning when the source and destination types are both signed.
>> >>
>> >
>> > Here (just IMHO), I disagree. Since any binary integer can be truncated
>> and
>> > any can be right-shifted, it makes sense for
>> `init(extendingOrTruncating:)`
>> > to be available for all of them. If I understand the proposal correctly,
>> > `Int(extendingOrTruncating: (-1 as Int8))` would give you a different
>> > result than `Int(extendingOrTruncating: (255 as UInt8)`.
>>
>> Yes it would.  But the real ju

Re: [swift-evolution] Throws? and throws!

2017-01-15 Thread Xiaodi Wu via swift-evolution
On Sun, Jan 15, 2017 at 3:12 PM, Haravikk 
wrote:

>
> On 12 Jan 2017, at 23:35, Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> On Thu, Jan 12, 2017 at 4:58 PM, Jonathan Hull via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I really like swift’s error handling system overall. It strikes a good
>> balance between safety and usability.
>>
>> There are some cases where it would be nice to throw errors, but errors
>> are rarely expected in most use cases, so the overhead of ‘try’, etc… would
>> make things unusable. Thus fatalError or optionals are used instead.  For
>> example, operators like ‘+’ could never throw because adding ’try’
>> everywhere would make arithmetic unbearable. But in a few cases it would
>> make my algorithm much cleaner if I just assume it will work and then catch
>> overflow/underflow errors if they happen, and resolve each of them with
>> special cases.  Or perhaps I am dealing with user entered values, and want
>> to stop the calculation and display a user visible error (e.g. a symbol in
>> a spreadsheet cell) instead of crashing.
>>
>
> Unless I'm mistaken, there is a performance overhead for throwing
> functions, and thus a much greater barrier to the use cases outlined above
> is that the performance penalty for '+' would be unacceptable in any case,
> whatever syntactic sugar you could come up with.
>
>
> Just wanted to chime in on performance, but since operators should really
> be inlined in most cases anyway I'm not sure there should be any
> performance penalty; the compiler should just optimise it away such that it
> basically becomes what it is now, the only case in which it would add a
> penalty is if the optional try is actually used.
>
>
> I really like this idea personally; I prefer it to using the
> addWithOverflow() and similar methods, not that they're super burdensome,
> but error handling feels like a better fit IMO.
>

`addWithOverflow()` gives you both the result and a flag; error handling
would at most give you one of these two. If that's a common use case, it'd
be an argument for a failable addition operator, but not a throwing one,
since there is only one error that happens (overflow).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pattern matching with Arrays

2017-01-15 Thread Jacob Bandes-Storch via swift-evolution
On Tue, Jan 3, 2017 at 10:10 AM, Joe Groff via swift-evolution <
swift-evolution@swift.org> wrote:

>
> On Dec 22, 2016, at 7:43 PM, Robert Widmann 
> wrote:
>
> Do you think there’s room for a more general Pattern Synonyms-like
>  feature that
> could extend this to things that look tuple-y?  We had a short conversation
> on Twitter 'round about the release of Swift 1.2 about Swiftz’s HList
>  
> implementation
> and my desire to be able to destructure them into tuples for native pattern
> matching.
>
>
> My personal favorite design for user-extensible pattern syntax is F#'s
> "active pattern" feature, which lets you declare a set of mutual exclusive,
> total or partial conditions along with a function body that computes which
> condition holds. For the specific case of container patterns, though, I
> feel like it's worth keeping a close association with Collection semantics,
> so that:
>
> - [] matches when the incoming collection's startIndex == endIndex,
> - [, ] fails if startIndex == endIndex, or else
> matches collection[startIndex] against  and recursively matches
> collection[startIndex.advancedBy(1)..]
> - [...] matches the remaining collection against 
>
> -Joe
>

This is really cool. I've never used F#, so thanks for pointing this out.
https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/
active-patterns  Extra points for the name (| "banana clips" |).

I've had something like this on my backburner-wishlist for a while.
Customizable patterns/bindings could be very powerful.

One use case I had in mind: writing parsers for binary formats such as
msgpack . For instance, msgpack encodes a
uint16 as 0xcd + high byte + low byte. If the 0xcd could be given as a
parameter to the "active pattern", you could imagine writing something like

match msgpackStream {  // a raw byte stream

// Scan 3 bytes, the first of which is equal to 0xcd.
// Theoretical syntax allowing a custom stream-scanner object to fill in
the two variable bindings
// by reading bytes from the stream. If the first byte were not 0xcd, the
match would fail.
case [0xcd, let hi, let lo]:
return UInt16(hi) << 8 | UInt16(lo)
...
}
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Jacob Bandes-Storch via swift-evolution
On Sun, Jan 15, 2017 at 2:42 PM, Xiaodi Wu  wrote:

> On Sun, Jan 15, 2017 at 3:29 PM, Jacob Bandes-Storch via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> [ proposal link: https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f
>> 3fcc7cad8c ]
>>
>>
>> On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>>
>>> Responding to both Jacob and Xiaodi here; thanks very much for your
>>> feedback!
>>>
>>> on Sat Jan 14 2017, Xiaodi Wu  wrote:
>>> > I think, in the end, it's the _name_ that could use improvement here.
>>> As
>>> > the doc comments say, `Arithmetic` is supposed to provide a "suitable
>>> basis
>>> > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
>>> > appropriate? It would make it clear that `CGVector` is not meant to be
>>> a
>>> > conforming type.
>>>
>>> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
>>> would be appropriate in that case sort of depends on what the implied
>>> field is, right?
>>>
>>
>> I think "scalar" is an appropriate term for any field. The scalar-ness
>> usually comes into play when it's used in a vector space, but using the
>> term alone doesn't bother me.
>>
>>
>>> It's true that CGPoint and CGVector have no obvious sensible
>>> interpretation of "42", and that's unfortunate.  The problem with
>>> protocols for algebraic structures is that there's an incredibly
>>> complicated lattice (see figures 3.1, 3.2 in
>>> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
>>> shove all of those protocols into the standard library (especially not
>>> prematurely) but each requirement you add to a more-coarsely aggregated
>>> protocol like Arithmetic will make it ineligible for representing some
>>> important type.
>>>
>>
>> Yep, it is quite complicated, and I understand not wanting to address all
>> that right now; calling it ScalarArithmetic seems appropriate to clarify
>> the limitations. FieldArithmetic might also be appropriate, but is less
>> clear (+ see below about quaternions).
>>
>> Daves Sweeris and Abrahams wrote:
>>
>> > > I was under the impression that complex numbers are scalar numbers...
>> although maybe not since once you get past, I think quaternions, you start
>> losing division and eventually multiplication, IIRC. (I hate it when two of
>> my recollections try to conflict with each other.)
>> >
>> > Well, you can view them as 2d vectors, so I'm not sure.  We need more
>> of a numerics expert than I am to weigh in here.
>>
>> But complex numbers have multiplication and division operations defined
>> (they form a field), unlike regular vectors in R². Meaning you can have a
>> vector space over the field of complex numbers.
>>
>> You still have multiplication and division past quaternions, but the
>> quaternions are *not commutative*. This isn't really a problem in Swift,
>> since the compiler never allows you to write an expression where the order
>> of arguments to an operator is ambiguous. This means they are *not a
>> field*, just a division ring
>>  (a field is a commutative
>> division ring). (I believe you can't technically have a vector space over a
>> non-commutative ring; the generalization would be a module
>> . That's
>> probably an argument for the name ScalarArithmetic over FieldArithmetic.)
>>
>
> Hmm, the issue is that the integers are not a field. So, if we're going to
> have it all modeled by one protocol, maybe neither is the best term.
>

Eurgh. That's true. Appropriate mathematical terms go out the window when
"division" doesn't actually produce a multiplicative inverse.

BasicArithmetic?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread David Sweeris via swift-evolution

> On Jan 15, 2017, at 17:19, Jacob Bandes-Storch via swift-evolution 
>  wrote:
> 
> 
>> On Sun, Jan 15, 2017 at 2:42 PM, Xiaodi Wu  wrote:
>>> On Sun, Jan 15, 2017 at 3:29 PM, Jacob Bandes-Storch via swift-evolution 
>>>  wrote:
>> 
>>> [ proposal link: 
>>> https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c ]
>>> 
>>> 
 On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution 
  wrote:
 
 Responding to both Jacob and Xiaodi here; thanks very much for your
 feedback!
 
 on Sat Jan 14 2017, Xiaodi Wu  wrote:
 > I think, in the end, it's the _name_ that could use improvement here. As
 > the doc comments say, `Arithmetic` is supposed to provide a "suitable 
 > basis
 > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
 > appropriate? It would make it clear that `CGVector` is not meant to be a
 > conforming type.
 
 We want Arithmetic to be able to handle complex numbers.  Whether Scalar
 would be appropriate in that case sort of depends on what the implied
 field is, right?
>>> 
>>> I think "scalar" is an appropriate term for any field. The scalar-ness 
>>> usually comes into play when it's used in a vector space, but using the 
>>> term alone doesn't bother me.
>>>  
 It's true that CGPoint and CGVector have no obvious sensible
 interpretation of "42", and that's unfortunate.  The problem with
 protocols for algebraic structures is that there's an incredibly
 complicated lattice (see figures 3.1, 3.2 in
 ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
 shove all of those protocols into the standard library (especially not
 prematurely) but each requirement you add to a more-coarsely aggregated
 protocol like Arithmetic will make it ineligible for representing some
 important type.
>>> 
>>> Yep, it is quite complicated, and I understand not wanting to address all 
>>> that right now; calling it ScalarArithmetic seems appropriate to clarify 
>>> the limitations. FieldArithmetic might also be appropriate, but is less 
>>> clear (+ see below about quaternions).
>>> 
>>> Daves Sweeris and Abrahams wrote:
>>> 
>>> > > I was under the impression that complex numbers are scalar numbers... 
>>> > > although maybe not since once you get past, I think quaternions, you 
>>> > > start losing division and eventually multiplication, IIRC. (I hate it 
>>> > > when two of my recollections try to conflict with each other.) 
>>> >
>>> > Well, you can view them as 2d vectors, so I'm not sure.  We need more of 
>>> > a numerics expert than I am to weigh in here.
>>>  
>>> But complex numbers have multiplication and division operations defined 
>>> (they form a field), unlike regular vectors in R². Meaning you can have a 
>>> vector space over the field of complex numbers.
>>> 
>>> You still have multiplication and division past quaternions, but the 
>>> quaternions are not commutative. This isn't really a problem in Swift, 
>>> since the compiler never allows you to write an expression where the order 
>>> of arguments to an operator is ambiguous. This means they are not a field, 
>>> just a division ring (a field is a commutative division ring). (I believe 
>>> you can't technically have a vector space over a non-commutative ring; the 
>>> generalization would be a module. That's probably an argument for the name 
>>> ScalarArithmetic over FieldArithmetic.)
>> 
>> Hmm, the issue is that the integers are not a field. So, if we're going to 
>> have it all modeled by one protocol, maybe neither is the best term.
> 
> Eurgh. That's true. Appropriate mathematical terms go out the window when 
> "division" doesn't actually produce a multiplicative inverse.
> 
> BasicArithmetic?

I was thinking something similar... Could we just rename Int/UInt to 
Counter/UnsignedCounter, and leave all these "mathematically correct" protocols 
and types to mathematically correct numeric libraries?

- Dave Sweeris___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread John McCall via swift-evolution
> On Jan 14, 2017, at 6:41 PM, Dave Abrahams via swift-evolution 
>  wrote:
> on Fri Jan 13 2017, John McCall  wrote:
> 
>> I'm also not sure we'd ever want the element type to be inferred from
>> context like this.  Generic subscripts as I see it are about being
>> generic over *indexes*, not somehow about presenting a polymorphic
>> value.
> 
> Actually I *would* want to be able to do that, though I admit it's the
> 1% case (or less).

Would you actually want the value type to be inferred, or you would just want 
it to be allowed to vary according to the index type?  Because the former 
sounds like a huge usability issue.

John.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread John McCall via swift-evolution
> On Jan 13, 2017, at 9:33 PM, Brent Royal-Gordon  
> wrote:
>> On Jan 13, 2017, at 9:50 AM, John McCall via swift-evolution 
>>  wrote:
>> 
>> I'm also not sure we'd ever want the element type to be inferred from 
>> context like this.  Generic subscripts as I see it are about being generic 
>> over *indexes*, not somehow about presenting a polymorphic value.
> 
> I think I have a pretty good use case for generic element types: you may want 
> an index to carry the type of its element. For example, suppose you want to 
> have a sort of dictionary whose keys are unique instances of a key class, and 
> whose value type depends on the key instance:

Oh, sorry, I didn't mean to suggest that the value type shouldn't be allowed to 
depend on the subscript's type parameters at all, just that it should probably 
be determinable from the index type.  I'm not sure that I have a specific 
technical concern, though, as long as it's a given that any particular access 
assigns a single type to the value; but I'll need to think about it.

John.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
"Mathematically correct" integers behave just like Int in that there is not
a multiplicative inverse. What we're trying to do here is to determine how
much of what we know about mathematics is usefully modeled in the standard
library. The answer is not zero, because there is more than just counting
that people do with integers.


On Sun, Jan 15, 2017 at 17:54 David Sweeris  wrote:

>
> On Jan 15, 2017, at 17:19, Jacob Bandes-Storch via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Sun, Jan 15, 2017 at 2:42 PM, Xiaodi Wu  wrote:
>
> On Sun, Jan 15, 2017 at 3:29 PM, Jacob Bandes-Storch via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> [ proposal link:
> https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f3fcc7cad8c ]
>
>
> On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> Responding to both Jacob and Xiaodi here; thanks very much for your
> feedback!
>
> on Sat Jan 14 2017, Xiaodi Wu  wrote:
> > I think, in the end, it's the _name_ that could use improvement here. As
> > the doc comments say, `Arithmetic` is supposed to provide a "suitable
> basis
> > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
> > appropriate? It would make it clear that `CGVector` is not meant to be a
> > conforming type.
>
> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
> would be appropriate in that case sort of depends on what the implied
> field is, right?
>
>
> I think "scalar" is an appropriate term for any field. The scalar-ness
> usually comes into play when it's used in a vector space, but using the
> term alone doesn't bother me.
>
>
> It's true that CGPoint and CGVector have no obvious sensible
> interpretation of "42", and that's unfortunate.  The problem with
> protocols for algebraic structures is that there's an incredibly
> complicated lattice (see figures 3.1, 3.2 in
> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
> shove all of those protocols into the standard library (especially not
> prematurely) but each requirement you add to a more-coarsely aggregated
> protocol like Arithmetic will make it ineligible for representing some
> important type.
>
>
> Yep, it is quite complicated, and I understand not wanting to address all
> that right now; calling it ScalarArithmetic seems appropriate to clarify
> the limitations. FieldArithmetic might also be appropriate, but is less
> clear (+ see below about quaternions).
>
> Daves Sweeris and Abrahams wrote:
>
> > > I was under the impression that complex numbers are scalar numbers...
> although maybe not since once you get past, I think quaternions, you start
> losing division and eventually multiplication, IIRC. (I hate it when two of
> my recollections try to conflict with each other.)
> >
> > Well, you can view them as 2d vectors, so I'm not sure.  We need more of
> a numerics expert than I am to weigh in here.
>
> But complex numbers have multiplication and division operations defined
> (they form a field), unlike regular vectors in R². Meaning you can have a
> vector space over the field of complex numbers.
>
> You still have multiplication and division past quaternions, but the
> quaternions are *not commutative*. This isn't really a problem in Swift,
> since the compiler never allows you to write an expression where the order
> of arguments to an operator is ambiguous. This means they are *not a
> field*, just a division ring  (a
> field is a commutative division ring). (I believe you can't technically
> have a vector space over a non-commutative ring; the generalization would
> be a module .
> That's probably an argument for the name ScalarArithmetic over
> FieldArithmetic.)
>
>
> Hmm, the issue is that the integers are not a field. So, if we're going to
> have it all modeled by one protocol, maybe neither is the best term.
>
>
> Eurgh. That's true. Appropriate mathematical terms go out the window when
> "division" doesn't actually produce a multiplicative inverse.
>
> BasicArithmetic?
>
>
> I was thinking something similar... Could we just rename Int/UInt to
> Counter/UnsignedCounter, and leave all these "mathematically correct"
> protocols and types to mathematically correct numeric libraries?
>
> - Dave Sweeris
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, John McCall  wrote:

>> On Jan 14, 2017, at 6:41 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> on Fri Jan 13 2017, John McCall  wrote:
>> 
>>> I'm also not sure we'd ever want the element type to be inferred from
>>> context like this.  Generic subscripts as I see it are about being
>>> generic over *indexes*, not somehow about presenting a polymorphic
>>> value.
>> 
>> Actually I *would* want to be able to do that, though I admit it's the
>> 1% case (or less).
>
> Would you actually want the value type to be inferred, or you would
> just want it to be allowed to vary according to the index type?
> Because the former sounds like a huge usability issue.

Both.  Usability-wise, it's no worse than f() -> T, which has its
(rare) uses today and doesn't cause a problem when it's not used.
Ideally I'd like to be able to guide deduction to pick a sensible
default for T when there's insufficient type context, but that's a
separable feature.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Jacob Bandes-Storch  wrote:

> On Sat, Jan 14, 2017 at 3:41 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> on Fri Jan 13 2017, John McCall  wrote:
>>
>> > I'm also not sure we'd ever want the element type to be inferred from
>> > context like this.  Generic subscripts as I see it are about being
>> > generic over *indexes*, not somehow about presenting a polymorphic
>> > value.
>>
>> Actually I *would* want to be able to do that, though I admit it's the
>> 1% case (or less).
>>
>
> 1%? Wouldn't many JSON libraries, for instance, be eager to take advantage
> of this?

Y'all brought up plenty of examples I hadn't thought of, so 1% might be
too low.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread David Sweeris via swift-evolution



Sent from my iPhone
> On Jan 15, 2017, at 18:02, Xiaodi Wu  wrote:
> 
> "Mathematically correct" integers behave just like Int in that there is not a 
> multiplicative inverse. What we're trying to do here is to determine how much 
> of what we know about mathematics is usefully modeled in the standard 
> library. The answer is not zero, because there is more than just counting 
> that people do with integers.

It's an interesting problem... When I was in school, "integer" division 
"returned" a "quotient and remainder", a "fraction" (which, occasionally, could 
be simplified to just an integer), or a "real". We never talked about division 
in the context of "(Int, Int) -> Int", though. OTOH, I never took any math 
classes past Differential Equations or Linear Algebra, either... I'm aware of 
areas of math where you formally restrict yourself to the kind of "(Int, Int) 
-> Int" operations we're doing here, but I don't really know much about it. Is 
division even well-defined in that context?

- Dave Sweeris___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread John McCall via swift-evolution
> On Jan 15, 2017, at 7:22 PM, Dave Abrahams  wrote:
> on Sun Jan 15 2017, John McCall  wrote:
> 
>>> On Jan 14, 2017, at 6:41 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> on Fri Jan 13 2017, John McCall  wrote:
>>> 
 I'm also not sure we'd ever want the element type to be inferred from
 context like this.  Generic subscripts as I see it are about being
 generic over *indexes*, not somehow about presenting a polymorphic
 value.
>>> 
>>> Actually I *would* want to be able to do that, though I admit it's the
>>> 1% case (or less).
>> 
>> Would you actually want the value type to be inferred, or you would
>> just want it to be allowed to vary according to the index type?
>> Because the former sounds like a huge usability issue.
> 
> Both.  Usability-wise, it's no worse than f() -> T, which has its
> (rare) uses today and doesn't cause a problem when it's not used.

Well, I'm assuming you would like to be able to do things like call mutating 
methods on these things.  Maybe not in the use case you're thinking of, though?

> Ideally I'd like to be able to guide deduction to pick a sensible
> default for T when there's insufficient type context, but that's a
> separable feature.

Yes, defaulting would fix the usability problem.

John.

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Jacob Bandes-Storch  wrote:

> [ proposal link: https://gist.github.com/moiseev/
> 62ffe3c91b66866fdebf6f3fcc7cad8c ]
>
> On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> Responding to both Jacob and Xiaodi here; thanks very much for your
>> feedback!
>>
>> on Sat Jan 14 2017, Xiaodi Wu  wrote:
>> > I think, in the end, it's the _name_ that could use improvement here. As
>> > the doc comments say, `Arithmetic` is supposed to provide a "suitable
>> basis
>> > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
>> > appropriate? It would make it clear that `CGVector` is not meant to be a
>> > conforming type.
>>
>> We want Arithmetic to be able to handle complex numbers.  Whether Scalar
>> would be appropriate in that case sort of depends on what the implied
>> field is, right?
>>
>
> I think "scalar" is an appropriate term for any field. 

Yes, but IIUC complex numbers are not scalars in every field.

> The scalar-ness usually comes into play when it's used in a vector
> space, but using the term alone doesn't bother me.
>
>> It's true that CGPoint and CGVector have no obvious sensible
>> interpretation of "42", and that's unfortunate.  The problem with
>> protocols for algebraic structures is that there's an incredibly
>> complicated lattice (see figures 3.1, 3.2 in
>> ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
>> shove all of those protocols into the standard library (especially not
>> prematurely) but each requirement you add to a more-coarsely aggregated
>> protocol like Arithmetic will make it ineligible for representing some
>> important type.
>
> Yep, it is quite complicated, and I understand not wanting to address all
> that right now; calling it ScalarArithmetic seems appropriate to clarify
> the limitations. 

I don't see why we should do that, as opposed to moving integer literal
convertibility down the refinement hierarchy and adding an additive
identity.  The latter seems like it makes a sensible API for average
programmers while still accomodating vector types.

If we can define the semantics properly (not sure if that's possible),
it could even cover SIMD types.

> FieldArithmetic might also be appropriate, but is less clear (+ see
> below about quaternions).
>
> Daves Sweeris and Abrahams wrote:
>
>> > I was under the impression that complex numbers are scalar numbers...
> although maybe not since once you get past, I think quaternions, you start
> losing division and eventually multiplication, IIRC. (I hate it when two of
> my recollections try to conflict with each other.)
>>
>> Well, you can view them as 2d vectors, so I'm not sure.  We need more of
>> a numerics expert than I am to weigh in here.
>
> But complex numbers have multiplication and division operations defined
> (they form a field), unlike regular vectors in R². Meaning you can have a
> vector space over the field of complex numbers.

Yes, I know.  I'm just not clear enough on the meaning of “scalar” to
know whether it's appropriate to call complex numbers scalars
independent of knowing the field in which they are scalars.  Does
https://www2.clarku.edu/~djoyce/complex/mult.html describe a field,
where the complex numbers are treated as 2d vectors?  I haven't done the
analysis.

> You still have multiplication and division past quaternions, but the
> quaternions are *not commutative*. This isn't really a problem in Swift,
> since the compiler never allows you to write an expression where the order
> of arguments to an operator is ambiguous. This means they are *not a field*,
> just a division ring  (a field
> is a commutative division ring). (I believe you can't technically have a
> vector space over a non-commutative ring; the generalization would be a
> module . That's
> probably an argument for the name ScalarArithmetic over FieldArithmetic.)
>
> Octonions are furthermore *not associative*, which is more of a problem
> since the standard library arithmetic operators are given an associativity.
> We can't give that up for regular numeric types, so someone working with
> octonions would just have to define their own non-associative operators
> (since there's no way for the protocol requirement to specify the operator
> associativity).

I think syntactic associativity of operators might be a totally
orthogonal thing to semantic associativity of binary functions, so I'm
not sure this is an issue.

>> That said, the ability to interpret integer literals as an arbitrary
>> Arithmetic isn't used anywhere in the standard library, so I'd like to
>> consider undoing
>> https://github.com/apple/swift/commit/de5b03ddc41be9c5ca5e15
>> d5709eb2be069286c1
>> and moving ExpressibleByIntegerLiteral down the protocol hierarchy to
>> BinaryInteger.
>>
>
> +1
>
>>
>> >> *## BinaryInteger*
>> >>
>> >> I'm a little conf

Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
On Sun, Jan 15, 2017 at 7:24 PM, Dave Abrahams  wrote:

>
> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>
> > On Sun, Jan 15, 2017 at 6:42 PM, David Sweeris 
> wrote:
> >
> >>
> >>
> >>
> >>
> >> On Jan 15, 2017, at 18:02, Xiaodi Wu  wrote:
> >>
> >> "Mathematically correct" integers behave just like Int in that there is
> >> not a multiplicative inverse. What we're trying to do here is to
> determine
> >> how much of what we know about mathematics is usefully modeled in the
> >> standard library. The answer is not zero, because there is more than
> just
> >> counting that people do with integers.
> >>
> >>
> >> It's an interesting problem... When I was in school, "integer" division
> >> "returned" a "quotient and remainder", a "fraction" (which,
> occasionally,
> >> could be simplified to just an integer), or a "real". We never talked
> about
> >> division in the context of "(Int, Int) -> Int", though. OTOH, I never
> took
> >> any math classes past Differential Equations or Linear Algebra,
> either...
> >> I'm *aware* of areas of math where you formally restrict yourself to the
> >> kind of "(Int, Int) -> Int" operations we're doing here, but I don't
> >> really know much about it. Is division even well-defined in that
> context?
> >>
> >> - Dave Sweeris
> >>
> >
> > I'm no mathematician, and I'm not sure how to tackle the question of
> > "well-defined." Hopefully someone who is more knowledgable can chime in
> > here.
> >
> > But I'll have a go at replying to your point as it relates to the
> practical
> > issue here. Two Int values can be "divided" to produce another Int, and
> > that gives a predictable and well-understood result. It's an operation
> > that's always going to be there--first, because it'd be insane to remove
> it
> > since much working code relies on it, and second, because we're only
> > re-designing integer protocols and not the concrete types. However, it
> _is_
> > true that such an operation has very different semantics from division as
> > you learned it in math.
> >
> > This is why I'm advocating for perhaps another look at the top of this
> > integer protocol hierarchy. At the moment, `Arithmetic` offers reasonable
> > semantic guarantees for a lot of things, but `/` has different semantics
> > for integer types and floating point types
>
> Well, that really depends on how closely you look.  From one
> point-of-view, floating point division and integer division *both*
> produce approximate results.
>

Yes, from a certain point of view. I remember we did discuss this at one
point on the list; I asked whether FloatingPoint was meant to model only
the countable set of representable values or whether it was meant to model
the uncountable set of reals. The answer was that here in Swift-land we're
trying to model the latter, and the approximate result is an artifact of
the imperfect modeling. Integer division, however, is not such an artifact,
but fundamentally a different operation.


> > and is really closer to just syntax. Other mathematical types--which
> > certainly the stdlib doesn't have to offer, but the stdlib protocol
> > hierarchy shouldn't preclude their conformance to relevant protocols
> > if it's possible--such as fractions and complex numbers, share with
> > floating point types the semantics of `/` that qualify these types as
> > fields. Dave A's question as to practical uses can probably best be
> > answered in this way: to the extent that any generic algorithm relies
> > on `/` having semantics and can be applied to fractions and real
> > numbers, it would be useful to distinguish such an operation from
> > integer "division."
>
> That's not a bad answer.  Ruminating on this...
>
> --
> -Dave
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, John McCall  wrote:

>> On Jan 15, 2017, at 7:22 PM, Dave Abrahams  wrote:
>> on Sun Jan 15 2017, John McCall  wrote:
>> 
 On Jan 14, 2017, at 6:41 PM, Dave Abrahams via swift-evolution 
 
> wrote:
 on Fri Jan 13 2017, John McCall  wrote:
>
 
> I'm also not sure we'd ever want the element type to be inferred from
> context like this.  Generic subscripts as I see it are about being
> generic over *indexes*, not somehow about presenting a polymorphic
> value.
 
 Actually I *would* want to be able to do that, though I admit it's the
 1% case (or less).
>>> 
>>> Would you actually want the value type to be inferred, or you would
>>> just want it to be allowed to vary according to the index type?
>>> Because the former sounds like a huge usability issue.
>> 
>> Both.  Usability-wise, it's no worse than f() -> T, which has its
>> (rare) uses today and doesn't cause a problem when it's not used.
>
> Well, I'm assuming you would like to be able to do things like call
> mutating methods on these things.  

Yes.  That's already *possible* even without a default:

func mutate(_ x: inout T, applying body: (inout T)->R) -> R {
  return body(&x)
}

mutate(&thingWithGenericSubscript[3]) { 
  (a: inout X)->() in a.mutatingMethod() // deduce X
}

Obviously this is awful.  The default mentioned below helps eliminate
the awfulness.

But not all subscripts are, or need to be, get/set, and even without the
default, the feature would be useful with get-only subscripts.

> Maybe not in the use case you're thinking of, though?
>
>> Ideally I'd like to be able to guide deduction to pick a sensible
>> default for T when there's insufficient type context, but that's a
>> separable feature.
>
> Yes, defaulting would fix the usability problem.
>
> John.

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Xiaodi Wu  wrote:

> On Sun, Jan 15, 2017 at 6:42 PM, David Sweeris  wrote:
>
>>
>>
>>
>> 
>> On Jan 15, 2017, at 18:02, Xiaodi Wu  wrote:
>>
>> "Mathematically correct" integers behave just like Int in that there is
>> not a multiplicative inverse. What we're trying to do here is to determine
>> how much of what we know about mathematics is usefully modeled in the
>> standard library. The answer is not zero, because there is more than just
>> counting that people do with integers.
>>
>>
>> It's an interesting problem... When I was in school, "integer" division
>> "returned" a "quotient and remainder", a "fraction" (which, occasionally,
>> could be simplified to just an integer), or a "real". We never talked about
>> division in the context of "(Int, Int) -> Int", though. OTOH, I never took
>> any math classes past Differential Equations or Linear Algebra, either...
>> I'm *aware* of areas of math where you formally restrict yourself to the
>> kind of "(Int, Int) -> Int" operations we're doing here, but I don't
>> really know much about it. Is division even well-defined in that context?
>>
>> - Dave Sweeris
>>
>
> I'm no mathematician, and I'm not sure how to tackle the question of
> "well-defined." Hopefully someone who is more knowledgable can chime in
> here.
>
> But I'll have a go at replying to your point as it relates to the practical
> issue here. Two Int values can be "divided" to produce another Int, and
> that gives a predictable and well-understood result. It's an operation
> that's always going to be there--first, because it'd be insane to remove it
> since much working code relies on it, and second, because we're only
> re-designing integer protocols and not the concrete types. However, it _is_
> true that such an operation has very different semantics from division as
> you learned it in math.
>
> This is why I'm advocating for perhaps another look at the top of this
> integer protocol hierarchy. At the moment, `Arithmetic` offers reasonable
> semantic guarantees for a lot of things, but `/` has different semantics
> for integer types and floating point types 

Well, that really depends on how closely you look.  From one
point-of-view, floating point division and integer division *both*
produce approximate results.

> and is really closer to just syntax. Other mathematical types--which
> certainly the stdlib doesn't have to offer, but the stdlib protocol
> hierarchy shouldn't preclude their conformance to relevant protocols
> if it's possible--such as fractions and complex numbers, share with
> floating point types the semantics of `/` that qualify these types as
> fields. Dave A's question as to practical uses can probably best be
> answered in this way: to the extent that any generic algorithm relies
> on `/` having semantics and can be applied to fractions and real
> numbers, it would be useful to distinguish such an operation from
> integer "division."

That's not a bad answer.  Ruminating on this...

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Jacob Bandes-Storch  wrote:

> On Sun, Jan 15, 2017 at 2:42 PM, Xiaodi Wu  wrote:
>
>> On Sun, Jan 15, 2017 at 3:29 PM, Jacob Bandes-Storch via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> [ proposal link: https://gist.github.com/moiseev/62ffe3c91b66866fdebf6f
>>> 3fcc7cad8c ]
>>>
>>>
>>> On Sat, Jan 14, 2017 at 4:55 PM, Dave Abrahams via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>

 Responding to both Jacob and Xiaodi here; thanks very much for your
 feedback!

 on Sat Jan 14 2017, Xiaodi Wu  wrote:
 > I think, in the end, it's the _name_ that could use improvement here.
 As
 > the doc comments say, `Arithmetic` is supposed to provide a "suitable
 basis
 > for arithmetic on scalars"--perhaps `ScalarArithmetic` might be more
 > appropriate? It would make it clear that `CGVector` is not meant to be
 a
 > conforming type.

 We want Arithmetic to be able to handle complex numbers.  Whether Scalar
 would be appropriate in that case sort of depends on what the implied
 field is, right?

>>>
>>> I think "scalar" is an appropriate term for any field. The scalar-ness
>>> usually comes into play when it's used in a vector space, but using the
>>> term alone doesn't bother me.
>>>
>>>
 It's true that CGPoint and CGVector have no obvious sensible
 interpretation of "42", and that's unfortunate.  The problem with
 protocols for algebraic structures is that there's an incredibly
 complicated lattice (see figures 3.1, 3.2 in
 ftp://jcmc.indiana.edu/pub/techreports/TR638.pdf) and we don't want to
 shove all of those protocols into the standard library (especially not
 prematurely) but each requirement you add to a more-coarsely aggregated
 protocol like Arithmetic will make it ineligible for representing some
 important type.

>>>
>>> Yep, it is quite complicated, and I understand not wanting to address all
>>> that right now; calling it ScalarArithmetic seems appropriate to clarify
>>> the limitations. FieldArithmetic might also be appropriate, but is less
>>> clear (+ see below about quaternions).
>>>
>>> Daves Sweeris and Abrahams wrote:
>>>
>>> > > I was under the impression that complex numbers are scalar numbers...
>>> although maybe not since once you get past, I think quaternions, you start
>>> losing division and eventually multiplication, IIRC. (I hate it when two of
>>> my recollections try to conflict with each other.)
>>> >
>>> > Well, you can view them as 2d vectors, so I'm not sure.  We need more
>>> of a numerics expert than I am to weigh in here.
>>>
>>> But complex numbers have multiplication and division operations defined
>>> (they form a field), unlike regular vectors in R². Meaning you can have a
>>> vector space over the field of complex numbers.
>>>
>>> You still have multiplication and division past quaternions, but the
>>> quaternions are *not commutative*. This isn't really a problem in Swift,
>>> since the compiler never allows you to write an expression where the order
>>> of arguments to an operator is ambiguous. This means they are *not a
>>> field*, just a division ring
>>>  (a field is a commutative
>>> division ring). (I believe you can't technically have a vector space over a
>>> non-commutative ring; the generalization would be a module
>>> . That's
>>> probably an argument for the name ScalarArithmetic over FieldArithmetic.)
>>>
>>
>> Hmm, the issue is that the integers are not a field. So, if we're going to
>> have it all modeled by one protocol, maybe neither is the best term.
>>
>
> Eurgh. That's true. Appropriate mathematical terms go out the window when
> "division" doesn't actually produce a multiplicative inverse.
>
> BasicArithmetic?

“Basic” adds nothing AFAICT, which is why the proposed name is
“Arithmetic”

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
On Sun, Jan 15, 2017 at 6:42 PM, David Sweeris  wrote:

>
>
>
> Sent from my iPhone
> On Jan 15, 2017, at 18:02, Xiaodi Wu  wrote:
>
> "Mathematically correct" integers behave just like Int in that there is
> not a multiplicative inverse. What we're trying to do here is to determine
> how much of what we know about mathematics is usefully modeled in the
> standard library. The answer is not zero, because there is more than just
> counting that people do with integers.
>
>
> It's an interesting problem... When I was in school, "integer" division
> "returned" a "quotient and remainder", a "fraction" (which, occasionally,
> could be simplified to just an integer), or a "real". We never talked about
> division in the context of "(Int, Int) -> Int", though. OTOH, I never took
> any math classes past Differential Equations or Linear Algebra, either...
> I'm *aware* of areas of math where you formally restrict yourself to the
> kind of "(Int, Int) -> Int" operations we're doing here, but I don't
> really know much about it. Is division even well-defined in that context?
>
> - Dave Sweeris
>

I'm no mathematician, and I'm not sure how to tackle the question of
"well-defined." Hopefully someone who is more knowledgable can chime in
here.

But I'll have a go at replying to your point as it relates to the practical
issue here. Two Int values can be "divided" to produce another Int, and
that gives a predictable and well-understood result. It's an operation
that's always going to be there--first, because it'd be insane to remove it
since much working code relies on it, and second, because we're only
re-designing integer protocols and not the concrete types. However, it _is_
true that such an operation has very different semantics from division as
you learned it in math.

This is why I'm advocating for perhaps another look at the top of this
integer protocol hierarchy. At the moment, `Arithmetic` offers reasonable
semantic guarantees for a lot of things, but `/` has different semantics
for integer types and floating point types and is really closer to just
syntax. Other mathematical types--which certainly the stdlib doesn't have
to offer, but the stdlib protocol hierarchy shouldn't preclude their
conformance to relevant protocols if it's possible--such as fractions and
complex numbers, share with floating point types the semantics of `/` that
qualify these types as fields. Dave A's question as to practical uses can
probably best be answered in this way: to the extent that any generic
algorithm relies on `/` having semantics and can be applied to fractions
and real numbers, it would be useful to distinguish such an operation from
integer "division."
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Xiaodi Wu  wrote:

> On Sun, Jan 15, 2017 at 3:27 PM, Dave Abrahams via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>>
>> > There _may_ be value in recognizing the distinction between rings and
>> > fields, perhaps? Just as the FP protocols make room for people to
>> implement
>> > their own decimal FP types, and just as you're trying to make Arithmetic
>> > accommodate complex numbers, the distinction would allow someone to write
>> > algorithms generic over rationals and reals (i.e. fields). Being able to
>> > represent exact fractions isn't so terribly niche, and I think the design
>> > wouldn't be terribly complicated by its accommodation:
>> >
>> > ```
>> > // rename Arithmetic to Ring
>> > // it's acceptable to omit `.one` from Ring, though some may call that a
>> > Pseudoring
>> > // consider omitting division from Ring and pushing it down to
>> > BinaryInteger and Field
>> >
>> > protocol BinaryInteger : Ring { ... }
>> >
>> > protocol Field : Ring {
>> >   static var one { get }
>> >   static func / (Self, Self) -> Self
>> >   static func /= (inout Self, Self)
>> >   var inverted: Self { get } // default impl: .one / self
>> > }
>> >
>> > protocol FloatingPoint : Field { ... }
>> > // rational number types and complex number types
>> > // would also conform to Field
>> > ```
>>
>> What generic algorithms would this enable?
>
> For one, anything to do with dividing into equal parts 

For example...?

> could be generic over floating point, rational, and even complex
> numbers, but you probably wouldn't want to include integer types in
> such an algorithm.
>
>> Would they be appropriate
>> for the standard library (as opposed to some more specialized numerics
>> library)?
>>
>
> The issue is that it's not terribly ergonomic to relegate `Field` to a
> specialized library because one cannot retroactively conform
> `FloatingPoint` to `Field`.

I don't think this is an important enough concern to justify adding
protocols to the standard library.  The number of types one has to
individually make conform to Field is probably going to remain small.

Show-me-the-mone^Walgorithms-ly y'rs,

-- 
-Dave
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Generic Subscripts

2017-01-15 Thread John McCall via swift-evolution

> On Jan 15, 2017, at 8:32 PM, Dave Abrahams  wrote:
> 
> 
> on Sun Jan 15 2017, John McCall  wrote:
> 
>>> On Jan 15, 2017, at 7:22 PM, Dave Abrahams  wrote:
>>> on Sun Jan 15 2017, John McCall  wrote:
>>> 
> On Jan 14, 2017, at 6:41 PM, Dave Abrahams via swift-evolution 
> 
>> wrote:
> on Fri Jan 13 2017, John McCall  wrote:
>> 
> 
>> I'm also not sure we'd ever want the element type to be inferred from
>> context like this.  Generic subscripts as I see it are about being
>> generic over *indexes*, not somehow about presenting a polymorphic
>> value.
> 
> Actually I *would* want to be able to do that, though I admit it's the
> 1% case (or less).
 
 Would you actually want the value type to be inferred, or you would
 just want it to be allowed to vary according to the index type?
 Because the former sounds like a huge usability issue.
>>> 
>>> Both.  Usability-wise, it's no worse than f() -> T, which has its
>>> (rare) uses today and doesn't cause a problem when it's not used.
>> 
>> Well, I'm assuming you would like to be able to do things like call
>> mutating methods on these things.  
> 
> Yes.  That's already *possible* even without a default:
> 
>func mutate(_ x: inout T, applying body: (inout T)->R) -> R {
>  return body(&x)
>}
> 
>mutate(&thingWithGenericSubscript[3]) { 
>  (a: inout X)->() in a.mutatingMethod() // deduce X
>}
> 
> Obviously this is awful.  The default mentioned below helps eliminate
> the awfulness.

Right.  I described it as a usability problem, not an expressiveness barrier. :)

> But not all subscripts are, or need to be, get/set, and even without the
> default, the feature would be useful with get-only subscripts.

True.  And like I've said, it's possible that this isn't a big problem.

John.

> 
>> Maybe not in the use case you're thinking of, though?
>> 
>>> Ideally I'd like to be able to guide deduction to pick a sensible
>>> default for T when there's insufficient type context, but that's a
>>> separable feature.
>> 
>> Yes, defaulting would fix the usability problem.
>> 
>> John.
> 
> -- 
> -Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Xiaodi Wu via swift-evolution
One example: earlier, it was demonstrated that a genetic lerp would not
accommodate vector types. However, it _does_ work fine for any scalar (i.e.
field) type; however, with the currently proposed integer protocols, one
would constrain it to Arithmetic types, yet the algorithm would be bogus
for integers.


On Sun, Jan 15, 2017 at 19:21 Dave Abrahams  wrote:

>
>
> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>
>
>
> > On Sun, Jan 15, 2017 at 3:27 PM, Dave Abrahams via swift-evolution <
>
> > swift-evolution@swift.org> wrote:
>
> >
>
> >>
>
> >> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>
> >>
>
> >> > There _may_ be value in recognizing the distinction between rings and
>
> >> > fields, perhaps? Just as the FP protocols make room for people to
>
> >> implement
>
> >> > their own decimal FP types, and just as you're trying to make
> Arithmetic
>
> >> > accommodate complex numbers, the distinction would allow someone to
> write
>
> >> > algorithms generic over rationals and reals (i.e. fields). Being able
> to
>
> >> > represent exact fractions isn't so terribly niche, and I think the
> design
>
> >> > wouldn't be terribly complicated by its accommodation:
>
> >> >
>
> >> > ```
>
> >> > // rename Arithmetic to Ring
>
> >> > // it's acceptable to omit `.one` from Ring, though some may call
> that a
>
> >> > Pseudoring
>
> >> > // consider omitting division from Ring and pushing it down to
>
> >> > BinaryInteger and Field
>
> >> >
>
> >> > protocol BinaryInteger : Ring { ... }
>
> >> >
>
> >> > protocol Field : Ring {
>
> >> >   static var one { get }
>
> >> >   static func / (Self, Self) -> Self
>
> >> >   static func /= (inout Self, Self)
>
> >> >   var inverted: Self { get } // default impl: .one / self
>
> >> > }
>
> >> >
>
> >> > protocol FloatingPoint : Field { ... }
>
> >> > // rational number types and complex number types
>
> >> > // would also conform to Field
>
> >> > ```
>
> >>
>
> >> What generic algorithms would this enable?
>
> >
>
> > For one, anything to do with dividing into equal parts
>
>
>
> For example...?
>
>
>
> > could be generic over floating point, rational, and even complex
>
> > numbers, but you probably wouldn't want to include integer types in
>
> > such an algorithm.
>
> >
>
> >> Would they be appropriate
>
> >> for the standard library (as opposed to some more specialized numerics
>
> >> library)?
>
> >>
>
> >
>
> > The issue is that it's not terribly ergonomic to relegate `Field` to a
>
> > specialized library because one cannot retroactively conform
>
> > `FloatingPoint` to `Field`.
>
>
>
> I don't think this is an important enough concern to justify adding
>
> protocols to the standard library.  The number of types one has to
>
> individually make conform to Field is probably going to remain small.
>
>
>
> Show-me-the-mone^Walgorithms-ly y'rs,
>
>
>
> --
>
> -Dave
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread David Sweeris via swift-evolution

> On Jan 15, 2017, at 19:24, Dave Abrahams  wrote:
> 
> 
>> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>> 
>>> On Sun, Jan 15, 2017 at 6:42 PM, David Sweeris  wrote:
>>> 
>>> 
>>> 
>>> 
>>> 
>>> On Jan 15, 2017, at 18:02, Xiaodi Wu  wrote:
>>> 
>>> "Mathematically correct" integers behave just like Int in that there is
>>> not a multiplicative inverse. What we're trying to do here is to determine
>>> how much of what we know about mathematics is usefully modeled in the
>>> standard library. The answer is not zero, because there is more than just
>>> counting that people do with integers.
>>> 
>>> 
>>> It's an interesting problem... When I was in school, "integer" division
>>> "returned" a "quotient and remainder", a "fraction" (which, occasionally,
>>> could be simplified to just an integer), or a "real". We never talked about
>>> division in the context of "(Int, Int) -> Int", though. OTOH, I never took
>>> any math classes past Differential Equations or Linear Algebra, either...
>>> I'm *aware* of areas of math where you formally restrict yourself to the
>>> kind of "(Int, Int) -> Int" operations we're doing here, but I don't
>>> really know much about it. Is division even well-defined in that context?
>>> 
>>> - Dave Sweeris
>>> 
>> 
>> I'm no mathematician, and I'm not sure how to tackle the question of
>> "well-defined." Hopefully someone who is more knowledgable can chime in
>> here.
>> 
>> But I'll have a go at replying to your point as it relates to the practical
>> issue here. Two Int values can be "divided" to produce another Int, and
>> that gives a predictable and well-understood result. It's an operation
>> that's always going to be there--first, because it'd be insane to remove it
>> since much working code relies on it, and second, because we're only
>> re-designing integer protocols and not the concrete types. However, it _is_
>> true that such an operation has very different semantics from division as
>> you learned it in math.
>> 
>> This is why I'm advocating for perhaps another look at the top of this
>> integer protocol hierarchy. At the moment, `Arithmetic` offers reasonable
>> semantic guarantees for a lot of things, but `/` has different semantics
>> for integer types and floating point types 
> 
> Well, that really depends on how closely you look.  From one
> point-of-view, floating point division and integer division *both*
> produce approximate results.

Yeah, but integer division tends to be so "approximate" that the answer can 
easily be useless without also calculating x%y. Floating point division will 
generally give you at least a few correct digits, won't it?

- Dave Sweeris
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Stephen Canon via swift-evolution
Responding to the thread in general here, not so much any specific email:

“Arithmetic” at present is not a mathematically-precise concept, and it may be 
a mistake to make it be one[1]; it’s a mathematically-slightly-fuzzy “number” 
protocol. FWIW, if I had to pick a mathematical object to pin it to, I would 
make it a [non-commutative] ring, which give it:

addition, subtraction, multiplication, IntegerLiteralConvertible, and 
an inverse: T? property.

Note that this would make division go out the window, but we would *preserve* 
int literal convertible (because there’s a unique map from Z to any ring — Z is 
the initial object in the category of rings). I think that it’s quite important 
to keep that for writing generic code.

Vectors and points are not “numbery” in this sense, so they should not conform 
to this protocol, which is why it’s OK that multiplication and int literals 
don’t make sense for them. They’re property a vector space or module built over 
a scalar type.

I would be OK with moving division out of the Arithmetic protocol, as the 
division operator is fundamentally different for integers and floating-point, 
and you want to have separate left- and right- division for quaternions and 
matrices. I would be pretty strongly opposed to removing integer literals; they 
rightfully belong here.

I think the name “Arithmetic” is sound. It is deliberately *not* one of the 
standard mathematical abstractions, reserving those names for folks who want to 
build a precise lattice of algebraic objects. Vectors don’t belong in this 
protocol, though.

– Steve

[1] We don’t want to make a semester course in modern algebra a prerequisite to 
using Swift, as much as I would enjoy building a tower of formalism as a 
mathematician.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Jacob Bandes-Storch via swift-evolution
On Sun, Jan 15, 2017 at 6:13 PM, Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> One example: earlier, it was demonstrated that a genetic lerp would not
> accommodate vector types. However, it _does_ work fine for any scalar (i.e.
> field) type; however, with the currently proposed integer protocols, one
> would constrain it to Arithmetic types, yet the algorithm would be bogus
> for integers.
>

I wouldn't say lerp is bogus (the results aren't wrong), just much
less useful.

On the other hand:

extension Collection where Iterator.Element: Arithmetic {
func mean() -> Iterator.Element {
return self.reduce(Iterator.Element(), +) /
Iterator.Element(count)  // assuming these initializers exist
}
}

Now [6, 7].mean() returns 6, and *that* I would call bogus.

Of course, there are some alternative ways to implement this which avoid
the issue:

- Implement it only for Iterator.Element: FloatingPoint.
- Implement it as mean() -> T, reducing by { $0 + T($1) }
or whatever the appropriate conversion initializer is, or simply converting
to floating point once *after* taking the sum.


>
> On Sun, Jan 15, 2017 at 19:21 Dave Abrahams  wrote:
>
>>
>>
>> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>>
>>
>>
>> > On Sun, Jan 15, 2017 at 3:27 PM, Dave Abrahams via swift-evolution <
>>
>> > swift-evolution@swift.org> wrote:
>>
>> >
>>
>> >>
>>
>> >> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>>
>> >>
>>
>> >> > There _may_ be value in recognizing the distinction between rings and
>>
>> >> > fields, perhaps? Just as the FP protocols make room for people to
>>
>> >> implement
>>
>> >> > their own decimal FP types, and just as you're trying to make
>> Arithmetic
>>
>> >> > accommodate complex numbers, the distinction would allow someone to
>> write
>>
>> >> > algorithms generic over rationals and reals (i.e. fields). Being
>> able to
>>
>> >> > represent exact fractions isn't so terribly niche, and I think the
>> design
>>
>> >> > wouldn't be terribly complicated by its accommodation:
>>
>> >> >
>>
>> >> > ```
>>
>> >> > // rename Arithmetic to Ring
>>
>> >> > // it's acceptable to omit `.one` from Ring, though some may call
>> that a
>>
>> >> > Pseudoring
>>
>> >> > // consider omitting division from Ring and pushing it down to
>>
>> >> > BinaryInteger and Field
>>
>> >> >
>>
>> >> > protocol BinaryInteger : Ring { ... }
>>
>> >> >
>>
>> >> > protocol Field : Ring {
>>
>> >> >   static var one { get }
>>
>> >> >   static func / (Self, Self) -> Self
>>
>> >> >   static func /= (inout Self, Self)
>>
>> >> >   var inverted: Self { get } // default impl: .one / self
>>
>> >> > }
>>
>> >> >
>>
>> >> > protocol FloatingPoint : Field { ... }
>>
>> >> > // rational number types and complex number types
>>
>> >> > // would also conform to Field
>>
>> >> > ```
>>
>> >>
>>
>> >> What generic algorithms would this enable?
>>
>> >
>>
>> > For one, anything to do with dividing into equal parts
>>
>>
>>
>> For example...?
>>
>>
>>
>> > could be generic over floating point, rational, and even complex
>>
>> > numbers, but you probably wouldn't want to include integer types in
>>
>> > such an algorithm.
>>
>> >
>>
>> >> Would they be appropriate
>>
>> >> for the standard library (as opposed to some more specialized numerics
>>
>> >> library)?
>>
>> >>
>>
>> >
>>
>> > The issue is that it's not terribly ergonomic to relegate `Field` to a
>>
>> > specialized library because one cannot retroactively conform
>>
>> > `FloatingPoint` to `Field`.
>>
>>
>>
>> I don't think this is an important enough concern to justify adding
>>
>> protocols to the standard library.  The number of types one has to
>>
>> individually make conform to Field is probably going to remain small.
>>
>>
>>
>> Show-me-the-mone^Walgorithms-ly y'rs,
>>
>>
>>
>> --
>>
>> -Dave
>>
>>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution


Sent from my moss-covered three-handled family gradunza

> On Jan 15, 2017, at 5:29 PM, Xiaodi Wu  wrote:
> 
>> On Sun, Jan 15, 2017 at 7:24 PM, Dave Abrahams  wrote:
>> 
>> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>> 
>> > On Sun, Jan 15, 2017 at 6:42 PM, David Sweeris  wrote:
>> >
>> >>
>> >>
>> >>
>> >>
>> >> On Jan 15, 2017, at 18:02, Xiaodi Wu  wrote:
>> >>
>> >> "Mathematically correct" integers behave just like Int in that there is
>> >> not a multiplicative inverse. What we're trying to do here is to determine
>> >> how much of what we know about mathematics is usefully modeled in the
>> >> standard library. The answer is not zero, because there is more than just
>> >> counting that people do with integers.
>> >>
>> >>
>> >> It's an interesting problem... When I was in school, "integer" division
>> >> "returned" a "quotient and remainder", a "fraction" (which, occasionally,
>> >> could be simplified to just an integer), or a "real". We never talked 
>> >> about
>> >> division in the context of "(Int, Int) -> Int", though. OTOH, I never took
>> >> any math classes past Differential Equations or Linear Algebra, either...
>> >> I'm *aware* of areas of math where you formally restrict yourself to the
>> >> kind of "(Int, Int) -> Int" operations we're doing here, but I don't
>> >> really know much about it. Is division even well-defined in that context?
>> >>
>> >> - Dave Sweeris
>> >>
>> >
>> > I'm no mathematician, and I'm not sure how to tackle the question of
>> > "well-defined." Hopefully someone who is more knowledgable can chime in
>> > here.
>> >
>> > But I'll have a go at replying to your point as it relates to the practical
>> > issue here. Two Int values can be "divided" to produce another Int, and
>> > that gives a predictable and well-understood result. It's an operation
>> > that's always going to be there--first, because it'd be insane to remove it
>> > since much working code relies on it, and second, because we're only
>> > re-designing integer protocols and not the concrete types. However, it _is_
>> > true that such an operation has very different semantics from division as
>> > you learned it in math.
>> >
>> > This is why I'm advocating for perhaps another look at the top of this
>> > integer protocol hierarchy. At the moment, `Arithmetic` offers reasonable
>> > semantic guarantees for a lot of things, but `/` has different semantics
>> > for integer types and floating point types
>> 
>> Well, that really depends on how closely you look.  From one
>> point-of-view, floating point division and integer division *both*
>> produce approximate results.
> 
> Yes, from a certain point of view. I remember we did discuss this at one 
> point on the list; I asked whether FloatingPoint was meant to model only the 
> countable set of representable values or whether it was meant to model the 
> uncountable set of reals. The answer was that here in Swift-land we're trying 
> to model the latter, and the approximate result is an artifact of the 
> imperfect modeling. Integer division, however, is not such an artifact, but 
> fundamentally a different operation.

That's right.  Thanks for keeping us honest and reminding us of our guiding 
stars. 👌🏻


>> > and is really closer to just syntax. Other mathematical types--which
>> > certainly the stdlib doesn't have to offer, but the stdlib protocol
>> > hierarchy shouldn't preclude their conformance to relevant protocols
>> > if it's possible--such as fractions and complex numbers, share with
>> > floating point types the semantics of `/` that qualify these types as
>> > fields. Dave A's question as to practical uses can probably best be
>> > answered in this way: to the extent that any generic algorithm relies
>> > on `/` having semantics and can be applied to fractions and real
>> > numbers, it would be useful to distinguish such an operation from
>> > integer "division."
>> 
>> That's not a bad answer.  Ruminating on this...
>> 
>> --
>> -Dave
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution


Sent from my moss-covered three-handled family gradunza

> On Jan 15, 2017, at 6:46 PM, Jacob Bandes-Storch  wrote:
> 
>> On Sun, Jan 15, 2017 at 6:13 PM, Xiaodi Wu via swift-evolution 
>>  wrote:
> 
>> One example: earlier, it was demonstrated that a genetic lerp would not 
>> accommodate vector types. However, it _does_ work fine for any scalar (i.e. 
>> field) type; however, with the currently proposed integer protocols, one 
>> would constrain it to Arithmetic types, yet the algorithm would be bogus for 
>> integers.
> 
> I wouldn't say lerp is bogus (the results aren't wrong), just much less 
> useful.
> 
> On the other hand:
> 
> extension Collection where Iterator.Element: Arithmetic {
> func mean() -> Iterator.Element {
> return self.reduce(Iterator.Element(), +) / 
> Iterator.Element(count)  // assuming these initializers exist
> }
> }
>  
> Now [6, 7].mean() returns 6, and that I would call bogus.
> 
> Of course, there are some alternative ways to implement this which avoid the 
> issue:
> 
> - Implement it only for Iterator.Element: FloatingPoint.
> - Implement it as mean() -> T, reducing by { $0 + T($1) } 
> or whatever the appropriate conversion initializer is, or simply converting 
> to floating point once after taking the sum.

You really want this to work for any field, though. Rational numbers, for 
example, would be excluded by those constraints

>> 
>> 
>>> On Sun, Jan 15, 2017 at 19:21 Dave Abrahams  wrote:
>>> 
>>> 
>>> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>>> 
>>> 
>>> 
>>> > On Sun, Jan 15, 2017 at 3:27 PM, Dave Abrahams via swift-evolution <
>>> 
>>> > swift-evolution@swift.org> wrote:
>>> 
>>> >
>>> 
>>> >>
>>> 
>>> >> on Sun Jan 15 2017, Xiaodi Wu  wrote:
>>> 
>>> >>
>>> 
>>> >> > There _may_ be value in recognizing the distinction between rings and
>>> 
>>> >> > fields, perhaps? Just as the FP protocols make room for people to
>>> 
>>> >> implement
>>> 
>>> >> > their own decimal FP types, and just as you're trying to make 
>>> >> > Arithmetic
>>> 
>>> >> > accommodate complex numbers, the distinction would allow someone to 
>>> >> > write
>>> 
>>> >> > algorithms generic over rationals and reals (i.e. fields). Being able 
>>> >> > to
>>> 
>>> >> > represent exact fractions isn't so terribly niche, and I think the 
>>> >> > design
>>> 
>>> >> > wouldn't be terribly complicated by its accommodation:
>>> 
>>> >> >
>>> 
>>> >> > ```
>>> 
>>> >> > // rename Arithmetic to Ring
>>> 
>>> >> > // it's acceptable to omit `.one` from Ring, though some may call that 
>>> >> > a
>>> 
>>> >> > Pseudoring
>>> 
>>> >> > // consider omitting division from Ring and pushing it down to
>>> 
>>> >> > BinaryInteger and Field
>>> 
>>> >> >
>>> 
>>> >> > protocol BinaryInteger : Ring { ... }
>>> 
>>> >> >
>>> 
>>> >> > protocol Field : Ring {
>>> 
>>> >> >   static var one { get }
>>> 
>>> >> >   static func / (Self, Self) -> Self
>>> 
>>> >> >   static func /= (inout Self, Self)
>>> 
>>> >> >   var inverted: Self { get } // default impl: .one / self
>>> 
>>> >> > }
>>> 
>>> >> >
>>> 
>>> >> > protocol FloatingPoint : Field { ... }
>>> 
>>> >> > // rational number types and complex number types
>>> 
>>> >> > // would also conform to Field
>>> 
>>> >> > ```
>>> 
>>> >>
>>> 
>>> >> What generic algorithms would this enable?
>>> 
>>> >
>>> 
>>> > For one, anything to do with dividing into equal parts
>>> 
>>> 
>>> 
>>> For example...?
>>> 
>>> 
>>> 
>>> > could be generic over floating point, rational, and even complex
>>> 
>>> > numbers, but you probably wouldn't want to include integer types in
>>> 
>>> > such an algorithm.
>>> 
>>> >
>>> 
>>> >> Would they be appropriate
>>> 
>>> >> for the standard library (as opposed to some more specialized numerics
>>> 
>>> >> library)?
>>> 
>>> >>
>>> 
>>> >
>>> 
>>> > The issue is that it's not terribly ergonomic to relegate `Field` to a
>>> 
>>> > specialized library because one cannot retroactively conform
>>> 
>>> > `FloatingPoint` to `Field`.
>>> 
>>> 
>>> 
>>> I don't think this is an important enough concern to justify adding
>>> 
>>> protocols to the standard library.  The number of types one has to
>>> 
>>> individually make conform to Field is probably going to remain small.
>>> 
>>> 
>>> 
>>> Show-me-the-mone^Walgorithms-ly y'rs,
>>> 
>>> 
>>> 
>>> --
>>> 
>>> -Dave
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Code comments that check code validity.

2017-01-15 Thread Step Christopher via swift-evolution
These (maintaining a clean codebase, using source control, branching) are good 
practices for solo developers as much as anyone else. 

> El ene. 15, 2017, a las 2:24 PM, Amir Michail via swift-evolution 
>  escribió:
> 
> 
>> On Jan 14, 2017, at 8:11 PM, Jay Abbott  wrote:
>> 
>> I think this would be an anti-feature , here are some reasons why:
>> 
>>• If it is code you wrote as an idea for how something might be 
>> implemented in the future, then it should be manually tweaked/validated 
>> anyway when you put it back in. If things change slightly such that your old 
>> commented code breaks when you comment it back in this is a good thing, it 
>> forces you to check/amend the old code so that it functions properly in the 
>> updated environment that it now inhabits.
>>• If it’s a significant amount of code then it really ought to be 
>> structured into something appropriate, like a function or a class, in which 
>> case it can happily live uncalled and not commented out. But it’s not a 
>> great practice to leave unused code lying around, unless you know it’s going 
>> to be used soon.
>>• Commented code is often commented out specifically to make things 
>> compile while you tweak/break things somewhere else (i.e. commented out 
>> temporarily) - so of course you don’t want it to be compiled.
>>• If you comment out code temporarily then it really should just mean 
>> temporarily, i.e. between now and your next commit to test something 
>> immediately. Source control means there’s no need for longer-lived commented 
>> out code. Unfinished code can live on a branch, old code that you might want 
>> to refer to or re-use later is in your source control history, and unused 
>> code should probably just be removed.
> 
> Other developers may prefer to have some code comments. Solo indie developers 
> have more freedom to just do what they want in this respect...
> 
>>• Code that is written and working and intended to be enabled later on 
>> should be activated by a feature-toggle (either a compile-time or a run-time 
>> one) rather than commented out.
>> 
>>> On Sun, 15 Jan 2017 at 00:04 Amir Michail via swift-evolution 
>>>  wrote:
>>> 
>>> On Jan 14, 2017, at 6:56 PM, Xiaodi Wu  wrote:
>>> 
>>> 
>>> 
 On Sat, Jan 14, 2017 at 5:50 PM, Amir Michail  wrote:
 
 On Jan 14, 2017, at 6:46 PM, Xiaodi Wu  wrote:
 
 On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  wrote:
 
> On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
> 
> This has been brought up on this list before. The conclusion of the 
> previous thread on this topic was that there is a way to do this:
> 
> #if false
> // put your code here
> #endif
> 
 
 This would not check the code for compilability within the surrounding 
 code. This requires more than a syntax check.
 
 I can't say I've ever needed that feature; could you share a concrete use 
 case?
 
>>> 
>>> Consider an array of levels for a game where some levels are commented out 
>>> for possible future use. It would be nice to have such level entries 
>>> continue to compile as the code elsewhere evolves and yet not be included 
>>> in the executable.
>>> 
>>> ```
>>> enum Levels: Int {
>>>  case foo = 1, bar, baz, boo
>>> }
>>> 
>>> var levels: [Levels] = [
>>>  .foo,
>>>  .bar,
>>> ]
>>> 
>>> // disabled
>>> _ = {
>>>  levels += [
>>>.baz,
>>>.boo,
>>>// this won't compile if you add:
>>>// .nonExistent,
>>>  ]
>>> }
>>> ```
>> 
>> That’s helpful thanks! I still think code comments would be nice though.
>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Throws? and throws!

2017-01-15 Thread Russ Bishop via swift-evolution
I’m not sure I like this specific proposal, but the idea of having the option 
of catching a certain class of runtime errors is appealing.

I don’t think it makes sense to abort a server process (potentially dropping X 
threads and thousands of connections on the ground) because one stray thread 
performed an overflowing addition… one could always require use of 
addWithOverflow I suppose, but auditing code for “+” is a different kind of 
pain than auditing for UnsafeMutablePointer. For servers the operation is 
almost always bounded by a single request, so unwinding any transactions and 
aborting the thread is sufficient to recover. There will also be cases where 
cleanup on fatalError() is absolutely required; if Swift leaves dangling 
database transactions on abort it is not usable for a large number of scenarios 
(speaking from direct experience). 

Rust takes an interesting approach with panic and catch_unwind… at compile time 
you can make a policy decision that all panics are aborts or that 
non-catastrophic panics can be handled, but only by the parent thread. In our 
terminology that would be saying that precondition ends the current dispatch 
work item and only the parent queue can handle the failure. This gets very 
tricky to even describe because it doesn’t map cleanly to libDispatch and we 
don’t have the compiler support to enforce cross-queue boundaries right now, so 
there is the potential to leak memory (which is OK for infrequent panics) or 
corrupt memory (unacceptable).

My guess is we could do something like this and in fact will need to do 
something like this, but only when we have a good concurrency story enforced by 
the compiler.

Russ

> On Jan 12, 2017, at 2:58 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I really like swift’s error handling system overall. It strikes a good 
> balance between safety and usability.
> 
> There are some cases where it would be nice to throw errors, but errors are 
> rarely expected in most use cases, so the overhead of ‘try’, etc… would make 
> things unusable. Thus fatalError or optionals are used instead.  For example, 
> operators like ‘+’ could never throw because adding ’try’ everywhere would 
> make arithmetic unbearable. But in a few cases it would make my algorithm 
> much cleaner if I just assume it will work and then catch overflow/underflow 
> errors if they happen, and resolve each of them with special cases.  Or 
> perhaps I am dealing with user entered values, and want to stop the 
> calculation and display a user visible error (e.g. a symbol in a spreadsheet 
> cell) instead of crashing.
> 
> I would like to propose adding ‘throws?’ and ‘throws!’ variants to ‘throws’.
> 
> These would be used for cases where error handling is not the default desired 
> behavior, but having it as an option is desired occasionally.  Essentially, 
> the user would no longer have to preface the call with ‘try’, as the compiler 
> would implicitly add ‘try?’ or ‘try!’ respectively.
> 
> Thus, the function would act like a non-throwing function (either trapping or 
> returning an optional in the case of error), but the user could add ‘try’ to 
> the call to override that behavior and deal with the error more explicitly.
> 
> Another example would be bounds checking on arrays.  If subscripting arrays 
> was marked as ‘throws!’ then it would have the same default behavior it does 
> now (trapping on bounds error).  But a user could add ‘try?’ to return nil 
> for a bounds error in cases where they explicitly want that, or they could 
> add ‘try’ to deal with it as an error using do-catch.
> 
> I think this would really increase the availability of error handling in 
> areas where it is impractical right now…
> 
> Thanks,
> Jon
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Dave Abrahams via swift-evolution

on Sun Jan 15 2017, Stephen Canon  wrote:

> Responding to the thread in general here, not so much any specific email:
>
> “Arithmetic” at present is not a mathematically-precise concept, and
> it may be a mistake to make it be one[1]; it’s a
> mathematically-slightly-fuzzy “number” protocol. FWIW, if I had to
> pick a mathematical object to pin it to, I would make it a
> [non-commutative] ring, which give it:
>
>   addition, subtraction, multiplication, IntegerLiteralConvertible, and 
> an inverse: T?
>   property.
>
> Note that this would make division go out the window, but we would
> *preserve* int literal convertible (because there’s a unique map from
> Z to any ring — Z is the initial object in the category of rings). I
> think that it’s quite important to keep that for writing generic code.
>
> Vectors and points are not “numbery” in this sense, so they should not
> conform to this protocol, which is why it’s OK that multiplication and
> int literals don’t make sense for them. They’re property a vector
> space or module built over a scalar type.
>
> I would be OK with moving division out of the Arithmetic protocol, as
> the division operator is fundamentally different for integers and
> floating-point, and you want to have separate left- and right-
> division for quaternions and matrices. I would be pretty strongly
> opposed to removing integer literals; they rightfully belong here.
>
> I think the name “Arithmetic” is sound. It is deliberately *not* one
> of the standard mathematical abstractions, reserving those names for
> folks who want to build a precise lattice of algebraic
> objects. Vectors don’t belong in this protocol, though.

OK, suppose we move division, and state in the documentation that models
of Arithmetic should have the mathematical properties of a
(non-commutative) Ring?

> – Steve
>
> [1] We don’t want to make a semester course in modern algebra a
> prerequisite to using Swift, as much as I would enjoy building a tower
> of formalism as a mathematician.

Indeedy.

-- 
-Dave

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Code comments that check code validity.

2017-01-15 Thread Pierre Monod-Broca via swift-evolution
Amir's idea is interesting to me.
But I like Xiadi's solution with unused closure, and I don't see a reason to 
put more effort into this.

It works well with simple and complex cases, and anyhow, for complex cases, 
feature switches and/or branches are already suitable, like said before.

Pierre

> Le 16 janv. 2017 à 06:39, Step Christopher via swift-evolution 
>  a écrit :
> 
> These (maintaining a clean codebase, using source control, branching) are 
> good practices for solo developers as much as anyone else. 
> 
>> El ene. 15, 2017, a las 2:24 PM, Amir Michail via swift-evolution 
>>  escribió:
>> 
>> 
>>> On Jan 14, 2017, at 8:11 PM, Jay Abbott  wrote:
>>> 
>>> I think this would be an anti-feature , here are some reasons why:
>>> 
>>>   • If it is code you wrote as an idea for how something might be 
>>> implemented in the future, then it should be manually tweaked/validated 
>>> anyway when you put it back in. If things change slightly such that your 
>>> old commented code breaks when you comment it back in this is a good thing, 
>>> it forces you to check/amend the old code so that it functions properly in 
>>> the updated environment that it now inhabits.
>>>   • If it’s a significant amount of code then it really ought to be 
>>> structured into something appropriate, like a function or a class, in which 
>>> case it can happily live uncalled and not commented out. But it’s not a 
>>> great practice to leave unused code lying around, unless you know it’s 
>>> going to be used soon.
>>>   • Commented code is often commented out specifically to make things 
>>> compile while you tweak/break things somewhere else (i.e. commented out 
>>> temporarily) - so of course you don’t want it to be compiled.
>>>   • If you comment out code temporarily then it really should just mean 
>>> temporarily, i.e. between now and your next commit to test something 
>>> immediately. Source control means there’s no need for longer-lived 
>>> commented out code. Unfinished code can live on a branch, old code that you 
>>> might want to refer to or re-use later is in your source control history, 
>>> and unused code should probably just be removed.
>> 
>> Other developers may prefer to have some code comments. Solo indie 
>> developers have more freedom to just do what they want in this respect...
>> 
>>>   • Code that is written and working and intended to be enabled later on 
>>> should be activated by a feature-toggle (either a compile-time or a 
>>> run-time one) rather than commented out.
>>> 
 On Sun, 15 Jan 2017 at 00:04 Amir Michail via swift-evolution 
  wrote:
 
 On Jan 14, 2017, at 6:56 PM, Xiaodi Wu  wrote:
 
 
 
> On Sat, Jan 14, 2017 at 5:50 PM, Amir Michail  wrote:
> 
> On Jan 14, 2017, at 6:46 PM, Xiaodi Wu  wrote:
> 
>> On Sat, Jan 14, 2017 at 5:35 PM, Amir Michail  wrote:
>> 
>> On Jan 14, 2017, at 6:28 PM, Xiaodi Wu  wrote:
>> 
>> This has been brought up on this list before. The conclusion of the 
>> previous thread on this topic was that there is a way to do this:
>> 
>> #if false
>> // put your code here
>> #endif
>> 
> 
> This would not check the code for compilability within the surrounding 
> code. This requires more than a syntax check.
> 
> I can't say I've ever needed that feature; could you share a concrete use 
> case?
> 
 
 Consider an array of levels for a game where some levels are commented out 
 for possible future use. It would be nice to have such level entries 
 continue to compile as the code elsewhere evolves and yet not be included 
 in the executable.
 
 ```
 enum Levels: Int {
 case foo = 1, bar, baz, boo
 }
 
 var levels: [Levels] = [
 .foo,
 .bar,
 ]
 
 // disabled
 _ = {
 levels += [
   .baz,
   .boo,
   // this won't compile if you add:
   // .nonExistent,
 ]
 }
 ```
>>> 
>>> That’s helpful thanks! I still think code comments would be nice though.
>>> 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution