Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-21 Thread Dave Abrahams via swift-evolution

on Thu Apr 21 2016, Thorsten Seitz  wrote:

> I totally agree with you. 
>
> But I think that the suggested Summable with zero fits the bill of
> your citation quite nicely as it actually is a very generic concept
> which is widely useful.

Sure, that's Monoid.  My main objection is to adding a "Multiplicative"
that doesn't actually have two operations with the right relationships.

I'm trying to explain general principles here, not pick on Summable
specifically.  The main reason not to add Summable is that once you
attach numeric semantics to the operation of Monoid, there are no useful
models I know of that can't also satisfy some much richer protocols such
as Arithmetic.

> FWIW I had chosen the name Summable instead of Monoid for two reasons: (1) 
> there
> has been reluctance by some people on this list to add algebraic types to the
> standard library

Yeah, we're reluctant because we want to do it right and that's hard.

> and (2) Summable is one concrete instance of Monoid for numbers (with
> respect to addition) just as my other suggestion Multiplicative is
> another instance of Monoid for numbers (with respect to
> multiplication).

Yeah... having a system where some things conform to the same protocol
in multiple ways is a whole 'nother kettle of fish that needs its own
language features
(c.f. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2098.pdf)

> If we want to add Monoid (and other algebraic types) to the standard
> library (I would welcome that), you are certainly right that we should
> design this well.  

We should design it well even if we're going to stick to numerical
subsets of Monoid ;^)

> The above actually suggests that summable and multiplicative instances
> for numbers might just be that: (singleton?)  instances of Monoid with
> an associated type of Number (instead of protocols) so that they can
> be passed around more easily.  

I don't know what you have in mind here.

> On the other hand we could borrow some ideas from Eiffel to solve the
> (semantic) diamond problem via renaming and choosing defaults. Like
> the early work about generics you found, 

I don't mean to be a pedant, but what I pointed you about is not about
generics, which is a collection language features.  Generics had been
around for years in Ada and C++ when that was written.  That paper is
about *generic programming*, which I won't define here because the paper
does a much better job than I can.

> Eiffel's solution sadly is ignored in most language designs (and
> interfaces thought of as a solution of the diamond problem... they are
> not). Not too long ago I wrote a lenghty mail on this list about that
> in the Mixin thread IIRC.
>
> I'm not sure I'm adding anything by saying this, but one problem with
> creating protocols that satisfy the absolute minimum requirements for a
> particular algorithm is that you end up without any meaningful
> abstractions.
>
> I think Dave Sweeris' example is not about creating Addable a.k.a
> Summable just because it satisfies the algorithm but rather it happens
> that Monoid *is* such a useful abstraction that it naturally pops up
> in many algorithms.

Why do you think that?  It seemed pretty well focused around addition to
me.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-21 Thread Thorsten Seitz via swift-evolution
I totally agree with you. 

But I think that the suggested Summable with zero fits the bill of your 
citation quite nicely as it actually is a very generic concept which is widely 
useful. 

FWIW I had chosen the name Summable instead of Monoid for two reasons: (1) 
there has been reluctance by some people on this list to add algebraic types to 
the standard library and (2) Summable is one concrete instance of Monoid for 
numbers (with respect to addition) just as my other suggestion Multiplicative 
is another instance of Monoid for numbers (with respect to multiplication).

If we want to add Monoid (and other algebraic types) to the standard library (I 
would welcome that), you are certainly right that we should design this well. 
The above actually suggests that summable and multiplicative instances for 
numbers might just be that: (singleton?) instances of Monoid with an associated 
type of Number (instead of protocols) so that they can be passed around more 
easily. 
On the other hand we could borrow some ideas from Eiffel to solve the 
(semantic) diamond problem via renaming and choosing defaults. Like the early 
work about generics you found, Eiffel's solution sadly is ignored in most 
language designs (and interfaces thought of as a solution of the diamond 
problem... they are not). Not too long ago I wrote a lenghty mail on this list 
about that in the Mixin thread IIRC.

> I'm not sure I'm adding anything by saying this, but one problem with
> creating protocols that satisfy the absolute minimum requirements for a
> particular algorithm is that you end up without any meaningful
> abstractions.

I think Dave Sweeris' example is not about creating Addable a.k.a Summable just 
because it satisfies the algorithm but rather it happens that Monoid *is* such 
a useful abstraction that it naturally pops up in many algorithms.

-Thorsten 

> Am 21.04.2016 um 20:36 schrieb Dave Abrahams via swift-evolution 
> :
> 
> 
> on Wed Apr 20 2016, davesweeris-AT-mac.com wrote:
> 
>>> On Apr 20, 2016, at 1:15 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
 on Tue Apr 19 2016, Thorsten Seitz  wrote:
 
 I'd like to have something like Summable with 'add', 'adding' and 'zero' 
 being a
 separate protocol as well as somthing like Multiplicative with 'multiply',
 'multiplied' and 'one' being a separate protocol, because these are 
 universally
 interesting for other cases, e.g. Summable would be useful for defining 
 path
 lengths in a graph library.
 
 Would you mind adding that to the proposal?
>>> 
>>> I suspect you may be headed into the realm of
>>> protocols-as-bags-of-syntax.
>> 
>> You say that like it’s a bad thing… 
> 
> Indeed!
> 
>> Am I missing the point? (NOT a rhetorical question)
> 
> I don't know, but I'll try to help answer...
> 
>> Speaking only for myself, I want stuff broken up into many simpler
>> protocols (which `Arithmetic` and such conform to) because there are
>> many algorithms which only require small parts of the larger
>> protocol. What if I wanted to add a function that sums all the
>> elements in a collection?
>> 
>> extension CollectionType where Generator.Element: Arithmetic {
>>func sum() -> Generator.Element {
>>var s = Generator.Element()
>>for e in self {
>>s.add(e)
>>}
>>return s
>>}
>> }
>> 
>> Yeah, it works, but if I want to get the sum of a collection of some custom 
>> type, I
>> have to implement *all* of `Arithmetic`, as opposed to just the two
>> parts of it (`init()` and `.add(:)`) that the algorithm actually
>> uses. It’d be both simpler for the users and *more to the point of the
>> function*, if it could be written like this:
>> 
>> extension CollectionType where Generator.Element: Addable { // "Addable" 
>> instead of "Arithmetic"
>>... // No change here
>> }
> 
> This method is undocumented.  What does it *do*, given an arbitrary
> element type conforming to Addable?  The answer needs to be a
> description of the semantics that doesn't require me to effectively
> execute the source of the function in my head.  How can I test that the
> method does the right thing?  To answer these questions, you have to
> attach some semantics to Addable so that it's more than a mere bag of
> syntax.  For example, for the above to produce the usual semantics of
> summing, the Element's init() method needs to produce the additive
> identity element.
> 
> Choosing the granularity of protocols is something of an art.  Lots has
> been written about generic programming's “requirement minimization
> principle,” in which the more requirements you add, the less reusable
> algorithms become.  Almost nothing has been written about the other side
> of the coin, but...
> 
> After much googling I came up with a reference to one of Alexander
> Stepanov and James Dehnert's early papers on generic programming (it
> sometimes amazes me how many of the key insights can only be found in
>

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-21 Thread Dave Abrahams via swift-evolution

on Wed Apr 20 2016, davesweeris-AT-mac.com wrote:

>> On Apr 20, 2016, at 1:15 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Tue Apr 19 2016, Thorsten Seitz  wrote:
>> 
>>> I'd like to have something like Summable with 'add', 'adding' and 'zero' 
>>> being a
>>> separate protocol as well as somthing like Multiplicative with 'multiply',
>>> 'multiplied' and 'one' being a separate protocol, because these are 
>>> universally
>>> interesting for other cases, e.g. Summable would be useful for defining path
>>> lengths in a graph library.
>>> 
>>> Would you mind adding that to the proposal?
>> 
>> I suspect you may be headed into the realm of
>> protocols-as-bags-of-syntax.
>
> You say that like it’s a bad thing… 

Indeed!

> Am I missing the point? (NOT a rhetorical question)

I don't know, but I'll try to help answer...

> Speaking only for myself, I want stuff broken up into many simpler
> protocols (which `Arithmetic` and such conform to) because there are
> many algorithms which only require small parts of the larger
> protocol. What if I wanted to add a function that sums all the
> elements in a collection?
>
> extension CollectionType where Generator.Element: Arithmetic {
> func sum() -> Generator.Element {
> var s = Generator.Element()
> for e in self {
> s.add(e)
> }
> return s
> }
> }
>
> Yeah, it works, but if I want to get the sum of a collection of some custom 
> type, I
> have to implement *all* of `Arithmetic`, as opposed to just the two
> parts of it (`init()` and `.add(:)`) that the algorithm actually
> uses. It’d be both simpler for the users and *more to the point of the
> function*, if it could be written like this:
>
> extension CollectionType where Generator.Element: Addable { // "Addable" 
> instead of "Arithmetic"
> ... // No change here
> }

This method is undocumented.  What does it *do*, given an arbitrary
element type conforming to Addable?  The answer needs to be a
description of the semantics that doesn't require me to effectively
execute the source of the function in my head.  How can I test that the
method does the right thing?  To answer these questions, you have to
attach some semantics to Addable so that it's more than a mere bag of
syntax.  For example, for the above to produce the usual semantics of
summing, the Element's init() method needs to produce the additive
identity element.

Choosing the granularity of protocols is something of an art.  Lots has
been written about generic programming's “requirement minimization
principle,” in which the more requirements you add, the less reusable
algorithms become.  Almost nothing has been written about the other side
of the coin, but...

After much googling I came up with a reference to one of Alexander
Stepanov and James Dehnert's early papers on generic programming (it
sometimes amazes me how many of the key insights can only be found in
that early work):

http://www.stepanovpapers.com/DeSt98.pdf

  We call the set of axioms satisfied by a data type and a set of
  operations on it a concept. Examples of concepts might be an integer
  data type with an addition operation satisfying the usual axioms; or a
  list of data objects with a first element, an iterator for traversing
  the list, and a test for identifying the end of the list. **The critical
  insight which produced generic programming is that highly reusable
  components must be programmed assuming a minimal collection of such
  concepts, and that the concepts used must match as wide a variety of
  concrete program structures as possible**. Thus, successful production
  of a generic component is not simply a matter of identifying the
  minimal requirements of an arbitrary type or algorithm – it requires
  identifying the common requirements of a broad collection of similar
  components. The final requirement is that we accomplish this without
  sacrificing performance relative to programming with concrete
  structures. A good generic library becomes a repository of highly
  efficient data structures and algorithms, based on a small number of
  broadly useful concepts, such that a library user can combine them and
  his own components in a wide variety of ways.

(emphasis mine).

I'm not sure I'm adding anything by saying this, but one problem with
creating protocols that satisfy the absolute minimum requirements for a
particular algorithm is that you end up without any meaningful
abstractions.

“*The* critical insight,” wow.  And it's so easily overlooked.

HTH,

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-21 Thread Thorsten Seitz via swift-evolution
I totally agree with Dave Sweeris. He has put the issue quite nicely.

Being able to add protocol conformance to a protocol would indeed solve this 
problem (having well designed protocols in the standard library would still be 
nice, though, so many thanks for the pointers, Dave A, that looks really 
interesting!).

-Thorsten

> Am 20.04.2016 um 23:23 schrieb Dave via swift-evolution 
> :
> 
> 
>> On Apr 20, 2016, at 1:15 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> on Tue Apr 19 2016, Thorsten Seitz  wrote:
>> 
>>> I'd like to have something like Summable with 'add', 'adding' and 'zero' 
>>> being a
>>> separate protocol as well as somthing like Multiplicative with 'multiply',
>>> 'multiplied' and 'one' being a separate protocol, because these are 
>>> universally
>>> interesting for other cases, e.g. Summable would be useful for defining path
>>> lengths in a graph library.
>>> 
>>> Would you mind adding that to the proposal?
>> 
>> I suspect you may be headed into the realm of
>> protocols-as-bags-of-syntax.
> You say that like it’s a bad thing… Am I missing the point? (NOT a rhetorical 
> question)
> 
> Speaking only for myself, I want stuff broken up into many simpler protocols 
> (which `Arithmetic` and such conform to) because there are many algorithms 
> which only require small parts of the larger protocol. What if I wanted to 
> add a function that sums all the elements in a collection?
> extension CollectionType where Generator.Element: Arithmetic {
> func sum() -> Generator.Element {
> var s = Generator.Element()
> for e in self {
> s.add(e)
> }
> return s
> }
> }
> 
> Yeah, it works, but if I want to get the sum of a collection of some custom 
> type, I have to implement *all* of `Arithmetic`, as opposed to just the two 
> parts of it (`init()` and `.add(:)`) that the algorithm actually uses. It’d 
> be both simpler for the users and *more to the point of the function*, if it 
> could be written like this:
> extension CollectionType where Generator.Element: Addable { // "Addable" 
> instead of "Arithmetic"
> ... // No change here
> }
> 
> Now, if Swift allowed you to add protocol conformance to protocols:
> protocol Addable {
> ... // Relevant subset of `Arithmetic`
> }
> #for T in Arithmetic { // "#for" because this is clearly macro-ish, and # 
> seems to be what we've settled on for that
> extension T : Addable {} // Don't need anything here since `Arithmetic` 
> already has everything in `Addable`
> }
> … then this all becomes a somewhat moot point. If some generic function only 
> needs a subset of a protocol’s functionality, said function’s author could do 
> this “#for T …” song & dance, and their function would be defined with the 
> minimum constraints.
> 
> 
>> Look at pages 14 and 24 of
>> —which does the job
>> right for C++—and you'll see why.
> COOL!!! Thanks for posting that, it looks like it’ll be a great read! :-D
> 
> - Dave Sweeris
> ___
> 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] [Proposal draft] Enhanced floating-point protocols

2016-04-20 Thread Dave via swift-evolution

> On Apr 20, 2016, at 1:15 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Apr 19 2016, Thorsten Seitz  wrote:
> 
>> I'd like to have something like Summable with 'add', 'adding' and 'zero' 
>> being a
>> separate protocol as well as somthing like Multiplicative with 'multiply',
>> 'multiplied' and 'one' being a separate protocol, because these are 
>> universally
>> interesting for other cases, e.g. Summable would be useful for defining path
>> lengths in a graph library.
>> 
>> Would you mind adding that to the proposal?
> 
> I suspect you may be headed into the realm of
> protocols-as-bags-of-syntax.
You say that like it’s a bad thing… Am I missing the point? (NOT a rhetorical 
question)

Speaking only for myself, I want stuff broken up into many simpler protocols 
(which `Arithmetic` and such conform to) because there are many algorithms 
which only require small parts of the larger protocol. What if I wanted to add 
a function that sums all the elements in a collection?
extension CollectionType where Generator.Element: Arithmetic {
func sum() -> Generator.Element {
var s = Generator.Element()
for e in self {
s.add(e)
}
return s
}
}

Yeah, it works, but if I want to get the sum of a collection of some custom 
type, I have to implement *all* of `Arithmetic`, as opposed to just the two 
parts of it (`init()` and `.add(:)`) that the algorithm actually uses. It’d be 
both simpler for the users and *more to the point of the function*, if it could 
be written like this:
extension CollectionType where Generator.Element: Addable { // "Addable" 
instead of "Arithmetic"
... // No change here
}

Now, if Swift allowed you to add protocol conformance to protocols:
protocol Addable {
... // Relevant subset of `Arithmetic`
}
#for T in Arithmetic { // "#for" because this is clearly macro-ish, and # seems 
to be what we've settled on for that
extension T : Addable {} // Don't need anything here since `Arithmetic` 
already has everything in `Addable`
}
… then this all becomes a somewhat moot point. If some generic function only 
needs a subset of a protocol’s functionality, said function’s author could do 
this “#for T …” song & dance, and their function would be defined with the 
minimum constraints.


> Look at pages 14 and 24 of
> —which does the job
> right for C++—and you'll see why.
COOL!!! Thanks for posting that, it looks like it’ll be a great read! :-D

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-20 Thread Dave Abrahams via swift-evolution

on Tue Apr 19 2016, Thorsten Seitz  wrote:

> I'd like to have something like Summable with 'add', 'adding' and 'zero' 
> being a
> separate protocol as well as somthing like Multiplicative with 'multiply',
> 'multiplied' and 'one' being a separate protocol, because these are 
> universally
> interesting for other cases, e.g. Summable would be useful for defining path
> lengths in a graph library.
>
> Would you mind adding that to the proposal?

I suspect you may be headed into the realm of
protocols-as-bags-of-syntax.  I'm guessing Summable should probably be
Monoid  and the Multiplicative
one, likely Ring .

Creating and using a lattice of Swift protocols for Algebraic Structures
 is a research
project.  Look at pages 14 and 24 of
—which does the job
right for C++—and you'll see why.  That level of complexity probably
shouldn't appear at the top level of the standard library, and really
needs a family of generic algorithms to justify it.  Ideally, all of
this would be researched and developed outside the standard library and
possibly incorporated when it is established existing practice.  IMO
it's definitely not a realm the standard library should enter casually
by throwing in a couple of protocols based around addition and
multiplication.

Cheers,
Dave

> Am 15.04.2016 um 01:55 schrieb Stephen Canon via swift-evolution
> :
>
> Enhanced floating-point protocols
>
> * Proposal: SE-
> * Author(s): Stephen Canon
> * Status: Awaiting review
> * Review manager: TBD
>
> SVG ImageIntroduction
>
> The current FloatingPoint protocol is quite limited, and provides only a
> small subset of the features expected of an IEEE 754 conforming type. This
> proposal expands the protocol to cover most of the expected basic
> operations, and adds a second protocol, BinaryFloatingPoint, that 
> provides a
> number of useful tools for generic programming with the most commonly used
> types.
>
> SVG ImageMotivation
>
> Beside the high-level motivation provided by the introduction, the 
> proposed
> prototype schema addresses a number of issues and requests that we've
> received from programmers:
>
> * FloatingPoint should conform to Equatable, and Comparable
> * FloatingPoint should conform to FloatLiteralConvertible
> * Deprecate the % operator for floating-point types
> * Provide basic constants (analogues of C's DBL_MAX, etc.)
> * Make Float80 conform to FloatingPoint
>
> It also puts FloatingPoint much more tightly in sync with the work that is
> being done on protocols for Integers, which will make it easier to 
> provide a
> uniform interface for arithmetic scalar types.
>
> SVG ImageDetailed design
>
> A new protocol, Arithmetic, is introduced that provides the most basic
> operations (add, subtract, multiply and divide) as well as Equatable and
> IntegerLiteralConvertible, and is conformed to by both integer and 
> floating-
> point types.
>
> There has been some resistance to adding such a protocol, owing to
> differences in behavior between floating point and integer arithmetic. 
> While
> these differences make it difficult to write correct generic code that
> operates on all "arithmetic" types, it is nonetheless convenient to 
> provide
> a single protocol that guarantees the availability of these basic
> operations. It is intended that "number-like" types should provide these
> APIs.
>
> /// Arithmetic protocol declares methods backing binary arithmetic 
> operators,
> /// such as  `+`, `-` and `*`; and their mutating counterparts.  These methods
> /// operate on arguments of the same type.
> ///
> /// Both mutating and non-mutating operations are declared in the protocol, 
> but
> /// only the mutating ones are required.  Should conforming type omit
> /// non-mutating implementations, they will be provided by a protocol 
> extension.
> /// Implementation in that case will copy `self`, perform a mutating operation
> /// on it and return the resulting value.
> public protocol Arithmetic: Equatable, IntegerLiteralConvertible {
>   /// Initialize to zero
>   init()
>
>   /// The sum of `self` and `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `add` operation.
>   @warn_unused_result
>   func adding(rhs: Self) -> Self
>
>   /// Adds `rhs` to `self`.
>   mutating func add(rhs: Self)
>
>   /// The result of subtracting `rhs` from `self`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `subtract` operation.
>   @warn_unused_result
>   func subtracting(rhs: Self) -> Self
>
>   /// Subtracts `rhs` from `self`.
>   mutating func subtract(rhs: Self)
>
>   /// The product of `self` and `r

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-20 Thread Dave Abrahams via swift-evolution

on Mon Apr 18 2016, Greg Parker  wrote:

>> On Apr 14, 2016, at 10:07 PM, Stephen Canon via swift-evolution 
>>  wrote:
>> 
>>> On Apr 14, 2016, at 8:34 PM, Brent Royal-Gordon  
>>> wrote:
>>> 
 Stephen Canon wrote:
 
 public protocol Arithmetic
>>> 
>>> Is there a rationale for the name "Arithmetic"? There's probably
>>> nothing wrong with it, but I would have guessed you'd use the name
>>> "Number”.
>> 
>> Dave A. came up with the name, though I think it’s a good one.  Number isn’t 
>> bad either.
>
> Does Number hew too close to Foundation's NSNumber name?
>
> `Arithmetic` provides a beautiful hook for grammar pedants: as a
> protocol name it ought to be pronounced as the adjective "arithMEtic"

Yes, or for those less excited by the idea, arith-MEH-tic.

> and not the noun "aRITHmetic". Complaining about that sounds like fun
> to me, but naming the protocol `Arithmetical` would avoid that issue
> if others disagree.

Point taken, but... blick.

-- 
Dave

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-19 Thread Thorsten Seitz via swift-evolution
I'd like to have something like Summable with 'add', 'adding' and 'zero' being 
a separate protocol as well as somthing like Multiplicative with 'multiply', 
'multiplied' and 'one' being a separate protocol, because these are universally 
interesting for other cases, e.g. Summable would be useful for defining path 
lengths in a graph library.

Would you mind adding that to the proposal?

-Thorsten 

> Am 15.04.2016 um 01:55 schrieb Stephen Canon via swift-evolution 
> :
> 
> Enhanced floating-point protocols
> Proposal: SE-
> Author(s): Stephen Canon
> Status: Awaiting review
> Review manager: TBD
> Introduction
> 
> The current FloatingPoint protocol is quite limited, and provides only a 
> small subset of the features expected of an IEEE 754 conforming type. This 
> proposal expands the protocol to cover most of the expected basic operations, 
> and adds a second protocol, BinaryFloatingPoint, that provides a number of 
> useful tools for generic programming with the most commonly used types.
> 
> Motivation
> 
> Beside the high-level motivation provided by the introduction, the proposed 
> prototype schema addresses a number of issues and requests that we've 
> received from programmers:
> 
> FloatingPoint should conform to Equatable, and Comparable
> FloatingPoint should conform to FloatLiteralConvertible
> Deprecate the % operator for floating-point types
> Provide basic constants (analogues of C's DBL_MAX, etc.)
> Make Float80 conform to FloatingPoint
> It also puts FloatingPoint much more tightly in sync with the work that is 
> being done on protocols for Integers, which will make it easier to provide a 
> uniform interface for arithmetic scalar types.
> 
> Detailed design
> 
> A new protocol, Arithmetic, is introduced that provides the most basic 
> operations (add, subtract, multiply and divide) as well as Equatable and 
> IntegerLiteralConvertible, and is conformed to by both integer and floating- 
> point types.
> 
> There has been some resistance to adding such a protocol, owing to 
> differences in behavior between floating point and integer arithmetic. While 
> these differences make it difficult to write correct generic code that 
> operates on all "arithmetic" types, it is nonetheless convenient to provide a 
> single protocol that guarantees the availability of these basic operations. 
> It is intended that "number-like" types should provide these APIs.
> 
> /// Arithmetic protocol declares methods backing binary arithmetic operators,
> /// such as  `+`, `-` and `*`; and their mutating counterparts.  These methods
> /// operate on arguments of the same type.
> ///
> /// Both mutating and non-mutating operations are declared in the protocol, 
> but
> /// only the mutating ones are required.  Should conforming type omit
> /// non-mutating implementations, they will be provided by a protocol 
> extension.
> /// Implementation in that case will copy `self`, perform a mutating operation
> /// on it and return the resulting value.
> public protocol Arithmetic: Equatable, IntegerLiteralConvertible {
>   /// Initialize to zero
>   init()
> 
>   /// The sum of `self` and `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `add` operation.
>   @warn_unused_result
>   func adding(rhs: Self) -> Self
> 
>   /// Adds `rhs` to `self`.
>   mutating func add(rhs: Self)
> 
>   /// The result of subtracting `rhs` from `self`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `subtract` operation.
>   @warn_unused_result
>   func subtracting(rhs: Self) -> Self
> 
>   /// Subtracts `rhs` from `self`.
>   mutating func subtract(rhs: Self)
> 
>   /// The product of `self` and `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `multiply` operation.
>   @warn_unused_result
>   func multiplied(by rhs: Self) -> Self
> 
>   /// Multiplies `self` by `rhs`.
>   mutating func multiply(by rhs: Self)
> 
>   /// The quotient of `self` dividing by `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `divide` operation.
>   @warn_unused_result
>   func divided(by rhs: Self) -> Self
> 
>   /// Divides `self` by `rhs`.
>   mutating func divide(by rhs: Self)
> }
> 
> /// SignedArithmetic protocol will only be conformed to by signed numbers,
> /// otherwise it would be possible to negate an unsigned value.
> ///
> /// The only method of this protocol has the default implementation in an
> /// extension, that uses a parameterless initializer and subtraction.
> public protocol SignedArithmetic : Arithmetic {
>   func negate() -> Self
> }
> The usual arithmetic operators are then defined in terms of the 
> implementation hooks provided by Arithmetic and SignedArithmetic, so 
> providing those operations are all that is necessary for a type to present a 
> "number-like" interface.
> 
> The FloatingPoint protocol 

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Greg Parker via swift-evolution

> On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
>   /// `true` iff the signbit of `self` is set.  Implements the IEEE 754
>   /// `signbit` operation.
>   ///
>   /// Note that this is not the same as `self < 0`.  In particular, this
>   /// property is true for `-0` and some NaNs, both of which compare not
>   /// less than zero.
>   //  TODO: strictly speaking a bit and a bool are slightly different
>   //  concepts.  Is another name more appropriate for this property?
>   //  `isNegative` is incorrect because of -0 and NaN.  `isSignMinus` might
>   //  be acceptable, but isn't great.  `signBit` is the IEEE 754 name.
>   var signBit: Bool { get }
> 
>   init(signBit: Bool, exponent: Int, significand: Self)
These do feel a bit awkward. Perhaps something over-engineered to handle the 
typical cases more readably?

  public protocol FloatingPoint: SignedArithmetic, Comparable {
enum Sign { 
  case Plus
  case Minus
  init(bit: Bool) { return bit ? .Minus : .Plus }
  var bit: Bool { get { return self == Minus } }
}
  
var sign: Sign { get }
var signBit: Bool { get }
  
init(sign: Sign, exponent: Int, significand: Self)
init(signBit: Bool, exponent: Int, significand: Self)
  
…
  }

…and perhaps each sign/signBit pair would provides one as a default 
implementation that calls the other.

Then we can often write something more readable than signBit: 

  let x = Float(sign: .Plus, exponent: 2, signficand: 2)
  if x.sign == .Plus { … }

Alternatively or additionally, perhaps signBit ought to be an Int because the 
people writing code using signBit would probably prefer to use literal 1 and 0 
instead of true and false. (Hasn't the distinction between Bit and Bool come up 
before?)


-- 
Greg Parker gpar...@apple.com Runtime Wrangler


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Greg Parker via swift-evolution

> On Apr 14, 2016, at 10:07 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
>> On Apr 14, 2016, at 8:34 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> Stephen Canon wrote:
>>> 
>>> public protocol Arithmetic
>> 
>> Is there a rationale for the name "Arithmetic"? There's probably nothing 
>> wrong with it, but I would have guessed you'd use the name "Number”.
> 
> Dave A. came up with the name, though I think it’s a good one.  Number isn’t 
> bad either.

Does Number hew too close to Foundation's NSNumber name?

`Arithmetic` provides a beautiful hook for grammar pedants: as a protocol name 
it ought to be pronounced as the adjective "arithMEtic" and not the noun 
"aRITHmetic". Complaining about that sounds like fun to me, but naming the 
protocol `Arithmetical` would avoid that issue if others disagree.


-- 
Greg Parker gpar...@apple.com Runtime Wrangler


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Howard Lovatt via swift-evolution
+1 `prefix -=`, it logically follows :)

  -- Howard.

On 19 April 2016 at 09:02,  wrote:

> "prefix -=“?
>
> (I’m not sure if I’m serious)
>
> - Dave Sweeris
>
> On Apr 18, 2016, at 5:57 PM, Howard Lovatt 
> wrote:
>
> I think `prefix -` works for `negated` (non-mutating form) but not
> `negate` (mutating form). IE `-=` is the mutating form of `infix -` and
> there is no equivalent in C-like languages for `negated` :(
>
>   -- Howard.
>
> On 19 April 2016 at 08:28,  wrote:
>
>> On Apr 16, 2016, at 6:12 PM, Howard Lovatt via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> For the Arithmetic protocol how about changing it to:
>>
>> protocol Arithmetic {
>> func + (lhs: Self, rhs: Self) -> Self
>> mutating func += (rhs: Self) -> Self
>> ...
>> }
>>
>> That way naming issues are largely avoided, except for `mutating func
>> negate()` which has no operator and would therefore have to be a normal,
>> non-operator, func.
>>
>> “prefix -" works for negate, at least off the top of my head.
>>
>> I think.
>>
>> - Dave Sweeris
>>
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Dave via swift-evolution
"prefix -=“?

(I’m not sure if I’m serious)

- Dave Sweeris

> On Apr 18, 2016, at 5:57 PM, Howard Lovatt  wrote:
> 
> I think `prefix -` works for `negated` (non-mutating form) but not `negate` 
> (mutating form). IE `-=` is the mutating form of `infix -` and there is no 
> equivalent in C-like languages for `negated` :(
> 
>   -- Howard.
> 
> On 19 April 2016 at 08:28, mailto:daveswee...@mac.com>> 
> wrote:
>> On Apr 16, 2016, at 6:12 PM, Howard Lovatt via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> For the Arithmetic protocol how about changing it to:
>> 
>> protocol Arithmetic {
>> func + (lhs: Self, rhs: Self) -> Self
>> mutating func += (rhs: Self) -> Self
>> ...
>> }
>> 
>> That way naming issues are largely avoided, except for `mutating func 
>> negate()` which has no operator and would therefore have to be a normal, 
>> non-operator, func. 
> “prefix -" works for negate, at least off the top of my head.
> 
> I think.
> 
> - Dave Sweeris
> 

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Howard Lovatt via swift-evolution
I think `prefix -` works for `negated` (non-mutating form) but not `negate`
(mutating form). IE `-=` is the mutating form of `infix -` and there is no
equivalent in C-like languages for `negated` :(

  -- Howard.

On 19 April 2016 at 08:28,  wrote:

> On Apr 16, 2016, at 6:12 PM, Howard Lovatt via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> For the Arithmetic protocol how about changing it to:
>
> protocol Arithmetic {
> func + (lhs: Self, rhs: Self) -> Self
> mutating func += (rhs: Self) -> Self
> ...
> }
>
> That way naming issues are largely avoided, except for `mutating func
> negate()` which has no operator and would therefore have to be a normal,
> non-operator, func.
>
> “prefix -" works for negate, at least off the top of my head.
>
> I think.
>
> - Dave Sweeris
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Dave via swift-evolution
> On Apr 16, 2016, at 6:12 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> For the Arithmetic protocol how about changing it to:
> 
> protocol Arithmetic {
> func + (lhs: Self, rhs: Self) -> Self
> mutating func += (rhs: Self) -> Self
> ...
> }
> 
> That way naming issues are largely avoided, except for `mutating func 
> negate()` which has no operator and would therefore have to be a normal, 
> non-operator, func. 
“prefix -" works for negate, at least off the top of my head.

I think.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Dave Abrahams via swift-evolution

on Thu Apr 14 2016, Stephen Canon  wrote:

> Hi Howard, thanks for the feedback.
>
> On Apr 14, 2016, at 6:05 PM, Howard Lovatt  
> wrote:
>
> +1 great addition.
>
> Would suggest the naming could be more consistent, in particular:
>
> 1 Anything returning Self could be named xxxed. In the current proposal 
> this
>   naming convention is sometimes used, e.g. divided, and sometimes not, 
> e.g.
>   subtracting. Suggest all unified with the xxxed convention.
>
> The names in the Arithmetic protocol are Dave A’s creation, but I think 
> they’re
> a reasonable compromise given the constraints placed on us. While consistency
> would be nice, I think that clarity at use site is more important, under the
> rationale that code is read more often than written. Also, keep in mind that 
> in
> practice, “everyone” will use the operators for arithmetic. Dave may have more
> to say on the subject.
>
> 1 Anything returning Bool could be named isXxx. In some cases this is 
> used,
>   e.g. isUnordered, but not others, e.g. totalOrder.

FWIW, that is a much more restrictive constraint than what our API guidelines
specify.  They say the usage should read as an assertion about the
receiver, e.g.

person.hasTooManyCats
waterSupply.containsUnsafeLevelsOfLead

are fine.

>
>
> That’s a reasonable point. isTotallyOrdered(with: ) is simple, but I’m not 
> sure
> how I would handle totalOrderMagnitude( ) under this scheme. Thoughts?
>
> Thanks,
> – Steve
>
> ___
> 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] [Proposal draft] Enhanced floating-point protocols

2016-04-18 Thread Dave Abrahams via swift-evolution

on Fri Apr 15 2016, Brent Royal-Gordon  wrote:

>>> Are there potential conforming types which aren't Comparable?
>> 
>> Not at present, but I expect there to be in the future.  Modular integers 
>> and complex numbers come to mind as the most obvious examples.
>
> Ooh, those are great examples. That is definitely the right decision, then.
>
> (One thing I've been vaguely concerned with is dimensional analysis. A
> strong type system opens up the possibility of marking numbers with
> units, or at least dimensions, so that the type system can catch when
> you try to pass a Second> to a call that's expecting a
> Second>. Doing this properly requires more freedom in the
> multiplication and division operators' parameters and return
> values—but of course, it also requires higher-kinded types to
> construct the right return values, so it's out of reach for Swift 3
> anyway.)
>
 /// NaN `payloads`.  `FloatingPoint` types should either treat inadmissible
 /// payloads as zero, or mask them to create an admissible payload.
 static func nan(payload payload: RawSignificand, signaling: Bool) -> Self
>>> 
>>> This seems unusually tolerant of bad inputs. Should this instead be
>>> a precondition, and have an (elidable in unchecked mode) trap if
>>> it's violated?
>> 
>> I don’t think that it’s a particularly useful error to detect,
>
> Maybe it's just my lack of knowledge, but I feel like, if you are
> calling this method, you probably care about getting that payload into
> the resulting NaN. Otherwise you would be using the `nan`
> property. (There is no `signalingNan` property, but there could be.)
>
> What do people use NaN payloads for? Are there a lot of cases where
> the payload is a nice-to-have, but it's okay to destroy or even mangle
> it?

Another option: trap the precondition violation only in debug builds.

>> and different floating point types may differ greatly in what
>> payloads they support (if any), because they might choose to reserve
>> those encodings for other purposes.
>
> If the data you can actually get into a NaN varies so much from one
> type to another, is this API a useful one to offer on the protocol? Is
> it something you can reliably use on "any floating-point type" without
> knowing which type it is?
>
> (It also now occurs to me that this might be better off as an initializer: 
> `init(nanWithPayload:signaling:)`.)
>
>>> Reading these, I find the use of "least" a little bit misleading—it seems 
>>> like they should be negative.
>> 
>> Magnitudes are strictly positive.  In fairness, that may not be immediately 
>> obvious to all readers.
>
> It does make sense now that you've said so! It might be a good doc comment 
> note, though.
>
>>> static var positiveNormals: ClosedRange { get }
>>> static var positiveSubnormals: ClosedRange { get }
>>> 
>>> Double.positiveNormals.upperBound   // DBL_MAX
>>> Double.positiveNormals.lowerBound   // DBL_MIN
>>> Double.positiveSubnormals.upperBound// 
>>> Self.positiveNormals.lowerBound.nextDown
>>> Double.positiveSubnormals.lowerBound// 0.nextUp
>> 
>> This seems wildly over-engineered to me personally.  Every language
>> I surveyed provides (a subset of) these quantities as simple scalar
>> values.
>
> Well, I am rather prone to wild over-engineering. :^)
>
> One place where a range like FloatingPoint.positives would be useful is in 
> random number generation. Suppose you have:
>
>   protocol Randomizer {
>   …
>   mutating func choice(from choices: 
> ClosedRange) -> T
>   …
>   }
>
> Which lets you say:
>
>   rng.choice(from: 0...1)
>
> It would then be nice to say something like:
>
>   rng.choice(from: Double.positives)
>   rng.choice(from: Float.finites)
>   // etc.
>
> Of course, the set of ranges useful for that purpose is probably different 
> from these more technical things, so that might not be the best design anyway.
>
 public protocol FloatingPoint: SignedArithmetic, Comparable {
 func isLess(than other: Self) -> Bool
 func totalOrder(with other: Self) -> Bool
>>> 
>>> Swift 2's Comparable demands a strict total order. However, the
>>> documentation here seems to imply that totalOrder is *not* what you
>>> get from the < operator. Is something getting reshuffled here?
>> 
>> The Swift 2 Comparable documentation is probably overly specific.
>> The requirement should really be something like a strict total order
>> on non-exceptional values.
>
> Okay.
>
> (While I was waiting for your reply, I was thinking about a rework of
> `Comparable` which had a sort-oriented `totalOrder(_:)` as a
> requirement and `isLess(_:)`, `isGreater(_:)`, et. al. which defaulted
> to using `totalOrder(_:)`, but could be overridden for types like
> FloatingPoint with exceptional values. I should just wait for answers
> sometimes.)

We're still interested in doing something like that.

>
>
>>> Also, since `init(_:)` is los

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-16 Thread Howard Lovatt via swift-evolution
For the Arithmetic protocol how about changing it to:

protocol Arithmetic {
func + (lhs: Self, rhs: Self) -> Self
mutating func += (rhs: Self) -> Self
...
}

That way naming issues are largely avoided, except for `mutating func
negate()` which has no operator and would therefore have to be a normal,
non-operator, func.

On Saturday, 16 April 2016, Nicola Salmoria via swift-evolution <
swift-evolution@swift.org> wrote:

> > Oh, a couple more things I just thought of:
> >
> > > public protocol Arithmetic: Equatable, IntegerLiteralConvertible {
> > If your goals include supporting complex numbers, how is
> IntegerLiteralConvertible going to fit in there?
> >
> > > /// Initialize to zero
> > > init()
> > 0 is valuable as the additive identity. Should there also be a way to
> get 1, the multiplicative identity? If you need both, should these be
> static properties instead of initializers?
>
> Interestingly, these two questions are related.
>
> If you expose the multiplicative identity, you automatically expose a
> natural way to convert from an integer N: just add `one` to itself N times.
> If N is negative, take the opposite.
>
> For complex numbers the multiplicative identity is 1 + 0i, so this means
> that Complex(N) = N + 0i.
>
> As an aside, a default generic implementation of IntegerLiteralConvertible
> would run in O(log N) steps, using the “double-and-add” algorithm:
>
> https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Double-and-add
> .
> Though I don’t think this is particularly useful for our use case :-)
>
> —
> Nicola
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution
>


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-16 Thread Nicola Salmoria via swift-evolution
> Oh, a couple more things I just thought of:
> 
> > public protocol Arithmetic: Equatable, IntegerLiteralConvertible {
> If your goals include supporting complex numbers, how is 
> IntegerLiteralConvertible going to fit in there?
> 
> > /// Initialize to zero
> > init()
> 0 is valuable as the additive identity. Should there also be a way to get 1, 
> the multiplicative identity? If you need both, should these be static 
> properties instead of initializers?

Interestingly, these two questions are related.

If you expose the multiplicative identity, you automatically expose a natural 
way to convert from an integer N: just add `one` to itself N times.
If N is negative, take the opposite.

For complex numbers the multiplicative identity is 1 + 0i, so this means that 
Complex(N) = N + 0i.

As an aside, a default generic implementation of IntegerLiteralConvertible 
would run in O(log N) steps, using the “double-and-add” algorithm:
https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Double-and-add.
Though I don’t think this is particularly useful for our use case :-)

—
Nicola

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread William Dillon via swift-evolution


> On Apr 15, 2016, at 11:15, Erica Sadun via swift-evolution 
>  wrote:
> 
> Finally, it's Swift. Isn't it time for π and 𝜏 as well as Pi and Tau?

Yes! I was waiting to bring up tau.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Brent Royal-Gordon via swift-evolution
Oh, a couple more things I just thought of:

> public protocol Arithmetic: Equatable, IntegerLiteralConvertible {

If your goals include supporting complex numbers, how is 
IntegerLiteralConvertible going to fit in there?

>   /// Initialize to zero
>   init()

0 is valuable as the additive identity. Should there also be a way to get 1, 
the multiplicative identity? If you need both, should these be static 
properties instead of initializers?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephan Tolksdorf via swift-evolution

On 2016-04-15, 18:58, Stephen Canon wrote:


but the documentation for Equatable and Comparable states that == and
< must implement an equivalence relation and a strict total order,
which is incompatible with the default IEEE-754 implementation of
these operators when NaN values are involved. How do you resolve this
conflict?


That’s a documentation bug; it should be relaxed by appending something
like “… on non-exceptional values.”

I’ll quote Dave A. to put it a bit more formally:


To be clear, the semantic conformance of floating point types to
Comparable depends on treating NaN as a "singular value”, i.e. outside
the domain of valid arguments to < /for the purposes of Comparable/.
 That doesn’t mean we can’t nail down what < does for floating point
types when it does get a NaN.


Thanks for the clarification!

- Stephan

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Erica Sadun via swift-evolution

> On Apr 15, 2016, at 12:22 PM, Stephen Canon  wrote:
> 
>> 
>> On Apr 15, 2016, at 11:14 AM, Erica Sadun > > wrote:
>> That said, I use M_PI_4 a lot because it's really handy for sample code. I'm 
>> one of the
>> outlier users whose use is not reflective of this quick check.
> 
> M_PI_2 and M_PI_4 are interesting cases; they date back to a time when 
> compilers couldn’t be trusted to constant-fold computations like M_PI / 2.  
> Since Swift quite reliably does this transformation, I would prefer to simply 
> use the more explicit .pi / 2.  How does that strike you as a user?
> 
> – Steve

I cannot really defend my use other than to say they are comfortable constants, 
ones that I read easily. 
Should Swift eliminate them I do not believe my code would suffer beyond muscle 
memory. Newer 
users don't necessarily resonate to them the same way, either.

I do think that adding both .pi and .π and using .π/4.0 would be the most 
readable expression of intent.

-- E

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution
On Apr 15, 2016, at 11:05 AM, Guillaume Lessard via swift-evolution 
 wrote:

> I don’t see why this is needed; there isn't an AdditivelyInvertible protocol

That’s precisely SignedArithmetic, just under a different name.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution

> On Apr 15, 2016, at 11:14 AM, Erica Sadun  wrote:
> 
> On Apr 15: 2016: at 11:56 AM: Joe Groff via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Apr 15: 2016: at 8:20 AM: Stephen Canon via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> “e” is a great bike-shedding example.  While it would definitely allow a 
>>> fluent style if you know what you’re looking at: I worry a little bit about 
>>> readability of `Float.e` or `.e` in source.  Most programmers are at least 
>>> passingly familiar with pi: but that familiarity doesn’t necessarily extend 
>>> to e.  IDEs and docstrings make this palatable: of course.
>> 
>> It's also questionable to me how often `e` itself is interesting independent 
>> of an exp() or log() operation.
> 
> I'm sure it gets used but I'd imagine it would be at an order of magnitude or 
> more less than PI. Quick gist count:
> 
> M_E: 109
> M_LOG2E: 23
> M_LOG10E: 19
> M_LN2: 24
> M_LN10: 10
> M_PI: 2,231
> M_PI_2: 255
> M_PI_4: 54
> M_1_PI: 27
> M_2_PI: 25
> M_2_SQRTPI: 23
> M_SQRT2: 31
> M_SQRT1_2: 26
> 
> That said, I use M_PI_4 a lot because it's really handy for sample code. I'm 
> one of the
> outlier users whose use is not reflective of this quick check.

M_PI_2 and M_PI_4 are interesting cases; they date back to a time when 
compilers couldn’t be trusted to constant-fold computations like M_PI / 2.  
Since Swift quite reliably does this transformation, I would prefer to simply 
use the more explicit .pi / 2.  How does that strike you as a user?

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Erica Sadun via swift-evolution
On Apr 15: 2016: at 11:56 AM: Joe Groff via swift-evolution 
mailto:swift-evolution@swift.org>> wrote:
> 
> 
>> On Apr 15: 2016: at 8:20 AM: Stephen Canon via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> “e” is a great bike-shedding example.  While it would definitely allow a 
>> fluent style if you know what you’re looking at: I worry a little bit about 
>> readability of `Float.e` or `.e` in source.  Most programmers are at least 
>> passingly familiar with pi: but that familiarity doesn’t necessarily extend 
>> to e.  IDEs and docstrings make this palatable: of course.
> 
> It's also questionable to me how often `e` itself is interesting independent 
> of an exp() or log() operation.

I'm sure it gets used but I'd imagine it would be at an order of magnitude or 
more less than PI. Quick gist count:

M_E: 109
M_LOG2E: 23
M_LOG10E: 19
M_LN2: 24
M_LN10: 10
M_PI: 2,231
M_PI_2: 255
M_PI_4: 54
M_1_PI: 27
M_2_PI: 25
M_2_SQRTPI: 23
M_SQRT2: 31
M_SQRT1_2: 26

That said, I use M_PI_4 a lot because it's really handy for sample code. I'm 
one of the
outlier users whose use is not reflective of this quick check.

* With M_PI at 2,231 and M_E at 109, I think you can conclude that some 
constants really are used more
often than others.
* As my personal case reflects, less popular constants are sometimes heavily 
used in niche cases

Finally, it's Swift. Isn't it time for π and 𝜏 as well as Pi and Tau?

-- E

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Erica Sadun via swift-evolution
On Apr 15: 2016: at 11:56 AM: Joe Groff via swift-evolution 
 wrote:
> 
> 
>> On Apr 15: 2016: at 8:20 AM: Stephen Canon via swift-evolution 
>>  wrote:
>> 
>> “e” is a great bike-shedding example.  While it would definitely allow a 
>> fluent style if you know what you’re looking at: I worry a little bit about 
>> readability of `Float.e` or `.e` in source.  Most programmers are at least 
>> passingly familiar with pi: but that familiarity doesn’t necessarily extend 
>> to e.  IDEs and docstrings make this palatable: of course.
> 
> It's also questionable to me how often `e` itself is interesting independent 
> of an exp() or log() operation.

I'm sure it gets used but I'd imagine it would be at an order of magnitude or 
more less than PI. Quick gist count:

M_E: 109
M_LOG2E: 23
M_LOG10E: 19
M_LN2: 24
M_LN10: 10
M_PI: 2,231
M_PI_2: 255
M_PI_4: 54
M_1_PI: 27
M_2_PI: 25
M_2_SQRTPI: 23
M_SQRT2: 31
M_SQRT1_2: 26

That said, I use M_PI_4 a lot because it's really handy for sample code. I'm 
one of the
outlier users whose use is not reflective of this quick check.

* With M_PI at 2,231 and M_E at 109, I think you can conclude that some 
constants really are used more
often than others.
* As my personal case reflects, less popular constants are sometimes heavily 
used in niche cases

Finally, it's Swift. Isn't it time for π and 𝜏 as well as Pi and Tau?

-- E

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Guillaume Lessard via swift-evolution

> On 15 avr. 2016, at 00:48, Nicola Salmoria via swift-evolution 
>  wrote:
> 
> It might make sense to also have a
> 
> public protocol InvertibleArithmetic : Arithmetic {
>  func inverted() -> Self
> }
> 
> FloatingPoint would conform to this protocol, returning 1/x, while integer 
> types would not.

I don’t see why this is needed; there isn't an AdditivelyInvertible protocol, 
why have MultiplicativelyInvertible? Are there (schoolbook arithmetic) types 
for which a terse inversion operation (i.e. `-num` or `1/num`) is not defined? 
For what it’s worth, “inverse” has so many definitions that “reciprocal” might 
be better if this must be defined; it has many fewer definitions.

Cheers,
Guillaume Lessard

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Ted F.A. van Gaalen via swift-evolution
Hi Stephen


> Hi Erica, thanks for the feedback.
> 
>> On Apr 14, 2016, at 6:29 PM, Erica Sadun > > wrote:
>> 
>> * I do use % for floating point but not as much as I first thought before I 
>> started searching through my code after reading your e-mail. But when I do 
>> use it, it's nice to have a really familiar symbol rather than a big word.
> 
Agreeing completely with Erica here.

> 
>> What were the ways that it was used incorrectly? Do you have some examples?
> 
> As it happens, I have a rationale sitting around from an earlier (internal) 
> discussion:
> 
> While C and C++ do not provide the “%” operator for floating-point types, 
> many newer languages do (Java, C#, and Python, to name just a few).  
> Superficially this seems reasonable, but there are severe gotchas when % is 
> applied to floating-point data, and the results are often extremely 
> surprising to unwary users.
What is your definition of unwary users? Programmers that usually don’t work 
with floating point data? 
No gotchas or total flabbergasting astonishment with day to day floating point 
usage.

>  C and C++ omitted this operator for good reason.  Even if you think you want 
> this operator, it is probably doing the wrong thing in subtle ways that will 
> cause trouble for you in the future.
I don’t share this opinion at all.
> 
> The % operator on integer types satisfies the division algorithm axiom: If b 
> is non-zero and q = a/b, r = a%b, then a = q*b + r.  This property does not 
> hold for floating-point types, because a/b does not produce an integral value.
The axiom is correct of course, but only in a perfect world with perfect 
numbers. Not in real life.   **
Floats never represent integral values, if so then they were Integers.

>  If it did produce an integral value, it would need to be a bignum type of 
> some sort (the integral part of DBL_MAX / DBL_MIN, for example, has over 2000 
> bits or 600 decimal digits).
Impossible. E.g. one would need a planet covered completely 
with memory (even holographic quantum) units and even then 
you would not have enough storage to store (one) PI with all its decimals.
By the way most of PIs decimals are unknown as you know.
It could even be that memory units on all the planets in (this) 
the universe are even not enough to satisfy the storage need 
for just one PI.
 * Please read the Hitchhikers Guide To The Galaxy for more info on this 
interesting subject :o)
Of course, the last decimals of PI are …42. Dolphins know that, but they left 
long ago in the future *  
> 
> Even if a bignum type were returned, or if we ignore the loss of the division 
> algorithm axiom, % would still be deeply flawed.  
   % is not flawed. It’s just the real life precision limitations of the 
floating point type. Live with it.


> Whereas people are generally used to modest rounding errors in floating-point 
> arithmetic, because % is not continuous small errors are frequently 
> enormously magnified with catastrophic results:
> 
>   (swift) 10.0 % 0.1
>// r0 : Double = 0.0995 // What?!
As I have tried to explain in more detail before:
This is perfectly normal, acceptable  and expected, because,
whether you like it or not, that is the exactly? the nature of 
floating point numbers stored in a computer
(well, at least in this age)  they’re not precise,
but in context precise enough voor most purposes in scientific 
and engineering applications.
If you want to work with exact values e.g. for representing money,
then use an appropriate numerical type 
or roll your own, make a struct for it.

Swift is poor in this because it only offers Integer and Floating point 
numerical types,
not Fixed Decimal (Like e.g. in PL/1 and C#) 
also its Ranges and iterations are with Integers only and
going in one direction only.
 
> 
> [Explanation: 0.1 cannot be exactly represented in binary floating point; the 
> actual value of “0.1” is 
> 0.155511151231257827021181583404541015625.  Other than that 
> rounding, the entire computation is exact.]
no, it's not. or at least you can’t count on that. especially when intermediate 
expressions (with floats) are involved.

** (to all, not meant cynically here, and with all due respect:
If you don’t value floats and understand their purpose and place,
please go programming for a half year or so in an industrial/engineering 
workshop.
You’ll notice that these precision issues you are writing about are mostly 
irrelevant.
E.g. You could theoretically calculate the length of a steel bar for a bridge 
(the hardware one :o)
exactly to 0.0001 or so,  but the bar in question would only 
coincidentally have
this exact value. For instance thermal expansion will be much larger. 
http://www.engineeringtoolbox.com/thermal-expansion-metals-d_859.html 

It’s all a matter of magnitude in the context/domain of what one is calculating.
  
> 
> Pro

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Joe Groff via swift-evolution

> On Apr 15, 2016, at 8:20 AM, Stephen Canon via swift-evolution 
>  wrote:
> 
> “e” is a great bike-shedding example.  While it would definitely allow a 
> fluent style if you know what you’re looking at, I worry a little bit about 
> readability of `Float.e` or `.e` in source.  Most programmers are at least 
> passingly familiar with pi, but that familiarity doesn’t necessarily extend 
> to e.  IDEs and docstrings make this palatable, of course.

It's also questionable to me how often `e` itself is interesting independent of 
an exp() or log() operation.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Chris Lattner via swift-evolution
On Apr 15, 2016, at 8:20 AM, Stephen Canon  wrote:
>> 
>> Incidentally, if you make pi and e be static members of the type, we should 
>> get a pretty fluent style, along the lines of:
>> 
>>  let x = someDouble * 2 * .pi
>> 
>> I agree that there is a concern about deciding “which” constants to include. 
>>  I’ll let you and the numeric elite figure that out :-)
> 
> “e” is a great bike-shedding example.  While it would definitely allow a 
> fluent style if you know what you’re looking at, I worry a little bit about 
> readability of `Float.e` or `.e` in source.  Most programmers are at least 
> passingly familiar with pi, but that familiarity doesn’t necessarily extend 
> to e.  IDEs and docstrings make this palatable, of course.
> 
> I wonder if maybe we shouldn’t expose `.pi` directly, but tuck other 
> constants behind something like `.math.e`.

Yes, I think this is a great approach.  In my (totally limited and arbitrary) 
experience, Pi is used orders of magnitude more commonly than other non-trivial 
constants.

This is another situation where I wish we had real submodules and generic 
properties already.  At that point, we could these constants defined in the 
Math submodule, and even give them unicode aliases like π.  Then you’d get this 
sort of behavior:

let _ = 2*.pi*b// works everywhere.
let _ = y + Math.e + .pi  // works everywhere, for all the weird constants you 
want to dump into the math module.
let _ = 2 * Math.π * b// works everywhere.

func doMathStuff() {   // some local scode
  import Math
  let _ = y + e + .pi // works because we imported Math.
  let _ = 2 * π * b// works because we imported Math.
}

That said, we don’t have those features, so perhaps the discussion should be 
scoped to just adding the pi member for swift 3.

> The other question is how these play with arbitrary-precision types, if 
> someone wants to write one that conforms to Floating Point.  Usually in 
> arbitrary-precision libraries, these would be functions (desiredPrecision: 
> Int) -> Self, but they could also be implemented as a future that gets 
> evaluated to the desired precision when used or something similar.  If we add 
> these to the protocols, I wouldn’t want to constrain the design space 
> arbitrarily.  The most conservative approach would be to just add them to the 
> concrete types.  We could also put them in a FixedWidthFloatingPoint protocol 
> for now if necessary.

It would be unfortunate if these weren’t supported by (e.g.) the binary FP 
protocol at least, since that would defeat code trying to use type-generic FP 
algorithms.

Does the rest of your design scale to arbitrary precision types?  Is arbitrary 
precision FP used in any common or important domain?  If not, it seems worth 
throwing under the bus to get better utility for the types that non-specialists 
actually use in practice. 

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Joe Groff via swift-evolution
The floating-point API design looks great. However, I'm concerned about 
providing a generic Arithmetic protocol:

> On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
> A new protocol, Arithmetic, is introduced that provides the most basic 
> operations (add, subtract, multiply and divide) as well as Equatable and  
> IntegerLiteralConvertible, and is conformed to by both integer and floating- 
> point types.
> 
> There has been some resistance to adding such a protocol, owing to 
> differences in behavior between floating point and integer arithmetic. While 
> these differences make it difficult to write correct generic code that 
> operates on all "arithmetic" types, it is nonetheless convenient to provide a 
> single protocol that guarantees the availability of these basic operations. 
> It is intended that "number-like" types should provide these APIs.

There are many other things we could do because they're "convenient", but we 
don't because they're wrong or mislead users into design cul-de-sacs. For 
example, we could provide integer indexing into strings, which would certainly 
be convenient, but we don't do that because it would lead to misguided 
accidentally-quadratic algorithms all over the place. This feels like a similar 
accommodation—while convenient, it makes it too easy for users to write naive 
real-number-arithmetic code and apply it blindly to numeric representations 
with very different error and overflow behavior. By including "divides" in the 
protocol, you're also implying a common abstraction over two *completely 
different* operations—integer quotient and floating-point division don't share 
many properties other than unfortunately sharing an operator in C.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution
> On Apr 15, 2016, at 9:52 AM, Stephan Tolksdorf via swift-evolution 
>  wrote:
> 
> but the documentation for Equatable and Comparable states that == and < must 
> implement an equivalence relation and a strict total order, which is 
> incompatible with the default IEEE-754 implementation of these operators when 
> NaN values are involved. How do you resolve this conflict?

That’s a documentation bug; it should be relaxed by appending something like “… 
on non-exceptional values.”

I’ll quote Dave A. to put it a bit more formally:

> To be clear, the semantic conformance of floating point types to Comparable 
> depends on treating NaN as a "singular value”, i.e. outside the domain of 
> valid arguments to < for the purposes of Comparable.  That doesn’t mean we 
> can’t nail down what < does for floating point types when it does get a NaN.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephan Tolksdorf via swift-evolution


Hi Stephen,

You write


  * FloatingPoint should conform to Equatable, and Comparable


but the documentation for Equatable and Comparable states that == and < 
must implement an equivalence relation and a strict total order, which 
is incompatible with the default IEEE-754 implementation of these 
operators when NaN values are involved. How do you resolve this conflict?


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread William Dillon via swift-evolution
> 
> Ultimately, we may want to have a finer-grained classification of numeric 
> protocols, but “schoolbook arithmetic” is a pretty reasonable set of 
> operations while we’re picking just one.
> 
> – Steve
> 

The only thing I want to add to this fantastic discussion is that, while 
"schoolbook arithmetic" should have priority above all else, I'm dreaming about 
using well-designed language features for quaternions, complex math, matrices, 
and galiois fields. :)

- Will

> 
> ___
> 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] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution

> On Apr 14, 2016, at 11:48 PM, Nicola Salmoria  
> wrote:
> 
>>  /// The quotient of `self` dividing by `rhs`.
>>  //  Arithmetic provides a default implementation of this method in terms
>>  //  of the mutating `divide` operation.
>>  @warn_unused_result
>>  func divided(by rhs: Self) -> Self
>> 
>>  /// Divides `self` by `rhs`.
>>  mutating func divide(by rhs: Self)
> 
> When dealing with integer arithmetic, I often find useful a `divmod` function 
> which produces a (quotient, remainder) pair.
> It could be argued that such a pair is the primary result of division on 
> integers. It would be great to have such a function included in the design.

I believe that it’s present in the latest draft of the Integer protocols.

>> /// SignedArithmetic protocol will only be conformed to by signed numbers,
>> /// otherwise it would be possible to negate an unsigned value.
>> ///
>> /// The only method of this protocol has the default implementation in an
>> /// extension, that uses a parameterless initializer and subtraction.
>> public protocol SignedArithmetic : Arithmetic {
>>  func negate() -> Self
>> }
> 
> It might make sense to also have a
> 
> public protocol InvertibleArithmetic : Arithmetic {
>  func inverted() -> Self
> }
> 
> FloatingPoint would conform to this protocol, returning 1/x, while integer 
> types would not.

That’s a very reasonable suggestion (and one that can easily be added 
separately if it doesn’t make it into this batch of changes).

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution
> On Apr 15, 2016, at 7:23 AM, plx via swift-evolution 
>  wrote:
> 
> One is if there’s any ETA or similar for a glimpse at the “complete picture” 
> of Swift’s revised numeric protocols; these floating-point protocols look 
> really, really good, but this is also (I think) the first glimpse at the new 
> `Arithmetic` protocol, and there’s also a new “Integer” protocol coming…and 
> it’d be nice to get a sense of the complete vision here.

I don’t want to speak for the Apple standard library team, who are doing the 
Integer protocol work, but I’ve seen a reasonably complete draft, so I believe 
the answer is “soon”.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution
> On Apr 14, 2016, at 10:47 PM, daveswee...@mac.com wrote:
> 
> In general, I think this is fantastic. In particular, I *really* like the 
> notion that `BinaryFloatingPoint` conforms to `FloatingPoint`. I would do a 
> few things differently, though:
>> On Apr 14, 2016, at 6:55 PM, Stephen Canon via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> public protocol FloatingPoint: SignedArithmetic, Comparable {
>>   ...
>>   /// The greatest finite number.
>>   ///
>>   /// Compares greater than or equal to all finite numbers, but less than
>>   /// infinity.  Corresponds to the C macros `FLT_MAX`, `DBL_MAX`, etc.
>>   /// The naming of those macros is slightly misleading, because infinity
>>   /// is greater than this value.
>>   static var greatestFiniteMagnitude: Self { get }
>>   ...
>> }
> 
> Why put this in FloatingPoint? The concept is valid for any real type (IMHO, 
> it’s valid for rectangular Complex/Quaternion/etc types as well... I’m not 
> sure if it is for the various polar formats, though). I think a better place 
> for it is either in `Arithmetic`, or another protocol to which `Arithmetic` 
> conforms:
> 
> protocol HasMinAndMaxFiniteValue {
> static var maxFinite: Self {get} // I think “max”/“min" are clear enough 
> (especially if the docs are explicit), but I understand the objection
> static var minFinite: Self {get} // 0 for unsigned types
> }

As mentioned in reply to Brent, there may very well be Arithmetic types without 
a real notion of magnitude (modular integers).  There’s also a complication 
that the magnitude of a Complex shouldn’t be complex, but rather real, and 
also isn’t usually representable as a T (the one exception is polar forms, 
where it *is* representable =).

> This would unify the syntax for getting a numeric type’s min or max finite 
> value across all the built-in numeric types (this means that `Int.max` would 
> become `Int.maxFinite`). Similarly, IMHO infinity shouldn’t be tied to 
> floating point types. While it’s true that the *native* integer types don’t 
> support infinity, arbitrary precision integer types might.
> 
> protocol HasInfinity {
> static var infinity: Self {get}
> }

I think that integer max and min behave sufficiently differently from the 
FloatingPoint quantities that it’s not particularly useful to unify their 
names.  Most obviously, all integers between min and max are representable for 
integers, and this is very much not the case for floating point types.

> I’d restructure this a bit:
> protocol Arithmetic { //AFAIK *all* numeric types should be able to do these
> init()
> func adding(rhs: Self) -> Self
> mutating func add(rhs: Self)
> func subtracting(rhs: Self) -> Self
> mutating func subtract(rhs: Self)
> }
> protocol ScalarArithmetic : Arithmetic { //These can be iffy for non-scalar 
> types
> func multiplied(by rhs: Self) -> Self
> mutating func multiply(by rhs: Self)
> func divided(by rhs: Self) -> Self
> mutating func divide(by rhs: Self)
> }
> 
> Multiplication isn't always defined for any two arbitrarily-dimensioned 
> matrices (plus, there are so many reasonable matrix “subtypes” that there's 
> no guarantee that the return type should always be the same), and I don’t 
> think there’s a generally agreed-upon meaning for matrix division at all.

There’s a natural tension of exactly what structure in the hierarchy of 
semigroups, groups, rings, etc is the baseline to be “numbery”.  While it’s not 
totally obvious that division should be required, neither is it obvious that it 
should be excluded.

I should note that for non-scalar types, multiplication and division are 
frequently more reasonable than addition and subtraction.  E.g. the orthogonal 
matrix groups and unitary quaternions are closed under multiplication but not 
addition.

Ultimately, we may want to have a finer-grained classification of numeric 
protocols, but “schoolbook arithmetic” is a pretty reasonable set of operations 
while we’re picking just one.

– Steve


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution

> On Apr 14, 2016, at 10:12 PM, Erica Sadun  wrote:
> 
> 
>> On Apr 14, 2016, at 10:36 PM, Stephen Canon > > wrote:
>> 
>> Hi Erica, thanks for the feedback.
>> 
>>> On Apr 14, 2016, at 6:29 PM, Erica Sadun >> > wrote:
>>> 
>>> * I do use % for floating point but not as much as I first thought before I 
>>> started searching through my code after reading your e-mail. But when I do 
>>> use it, it's nice to have a really familiar symbol rather than a big word. 
>>> What were the ways that it was used incorrectly? Do you have some examples?
>> 
>> As it happens, I have a rationale sitting around from an earlier (internal) 
>> discussion:
>> 
> 
> Thanks. That makes plenty of sense although I do still think the name is long 
> and hard to discover compared to fmod[1] and %.

I completely agree.  I don’t expect the fmod free function to go away anytime 
soon, FWIW (and I would oppose removing it unless we had a more discoverable 
name for this method).

>>> * I don't quite get how equatable is going to work. Do you mind explaining 
>>> that in more detail?
>> 
>> I’m not totally sure what your question is.  Are you asking how 
>> FloatingPoint will conform to Equatable, or how the Equatable protocol will 
>> work?
> 
> Given the many words and passionate articles about how difficult it is to 
> perform floating point comparisons, 
> for example, 
> https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
>  
> ,
>  
> I'm just curious as to what approach you've settled on. The topic has come up 
> on-list quite a few times.

The actual == and != operators should continue to default to exact (IEEE 754) 
equality.  Doing anything else is asking for a lot of trouble when people try 
to convert algorithms from other languages.

Support for equality and comparison with a tolerance would be a great library 
feature, but the difficulty is that it’s impossible to provide a solution 
that’s appropriate for all (or even most) cases.  I have a few sketches of 
things I’d like to do in that direction, but it’s out of scope for Swift 3, 
considering the subtle numerics *and* library/language design issues involved.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Howard Lovatt via swift-evolution
+1 great addition.

Would suggest the naming could be more consistent, in particular:

   1. Anything returning Self could be named xxxed. In the current proposal
   this naming convention is sometimes used, e.g. divided, and sometimes not,
   e.g. subtracting. Suggest all unified with the xxxed convention.
   2. Anything returning Bool could be named isXxx. In some cases this is
   used, e.g. isUnordered, but not others, e.g. totalOrder.


  -- Howard.

On 15 April 2016 at 09:55, Stephen Canon via swift-evolution <
swift-evolution@swift.org> wrote:

> Enhanced floating-point protocols
>
>- Proposal: SE-
>
> 
>- Author(s): Stephen Canon 
>- Status: *Awaiting review*
>- Review manager: TBD
>
>
> 
> Introduction
>
> The current FloatingPoint protocol is quite limited, and provides only a
> small subset of the features expected of an IEEE 754 conforming type. This
> proposal expands the protocol to cover most of the expected basic
> operations, and adds a second protocol, BinaryFloatingPoint, that provides
> a number of useful tools for generic programming with the most commonly
> used types.
>
> 
> Motivation
>
> Beside the high-level motivation provided by the introduction, the
> proposed prototype schema addresses a number of issues and requests that
> we've received from programmers:
>
>- FloatingPoint should conform to Equatable, and Comparable
>- FloatingPoint should conform to FloatLiteralConvertible
>- Deprecate the % operator for floating-point types
>- Provide basic constants (analogues of C's DBL_MAX, etc.)
>- Make Float80 conform to FloatingPoint
>
> It also puts FloatingPoint much more tightly in sync with the work that is
> being done on protocols for Integers, which will make it easier to provide
> a uniform interface for arithmetic scalar types.
>
> Detailed
> design
>
> A new protocol, Arithmetic, is introduced that provides the most basic
> operations (add, subtract, multiply and divide) as well as Equatable and
> IntegerLiteralConvertible, and is conformed to by both integer and
> floating- point types.
>
> There has been some resistance to adding such a protocol, owing to
> differences in behavior between floating point and integer arithmetic.
> While these differences make it difficult to write correct generic code
> that operates on all "arithmetic" types, it is nonetheless convenient to
> provide a single protocol that guarantees the availability of these basic
> operations. It is intended that "number-like" types should provide these
> APIs.
>
> /// Arithmetic protocol declares methods backing binary arithmetic 
> operators,/// such as  `+`, `-` and `*`; and their mutating counterparts.  
> These methods/// operate on arguments of the same type.// Both mutating 
> and non-mutating operations are declared in the protocol, but/// only the 
> mutating ones are required.  Should conforming type omit/// non-mutating 
> implementations, they will be provided by a protocol extension./// 
> Implementation in that case will copy `self`, perform a mutating operation/// 
> on it and return the resulting value.public protocol Arithmetic: Equatable, 
> IntegerLiteralConvertible {
>   /// Initialize to zero
>   init()
>
>   /// The sum of `self` and `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `add` operation.
>   @warn_unused_result
>   func adding(rhs: Self) -> Self
>
>   /// Adds `rhs` to `self`.
>   mutating func add(rhs: Self)
>
>   /// The result of subtracting `rhs` from `self`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `subtract` operation.
>   @warn_unused_result
>   func subtracting(rhs: Self) -> Self
>
>   /// Subtracts `rhs` from `self`.
>   mutating func subtract(rhs: Self)
>
>   /// The product of `self` and `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `multiply` operation.
>   @warn_unused_result
>   func multiplied(by rhs: Self) -> Self
>
>   /// Multiplies `self` by `rhs`.
>   mutating func multiply(by rhs: Self)
>
>   /// The quotient of `self` dividing by `rhs`.
>   //  Arithmetic provides a default implementation of this method in terms
>   //  of the mutating `divide` operation.
>   @warn_unused_result
>   func divided(by rhs: Self) -> Self
>
>   /// Divides `self` by `rhs`.
>   mutating func divide(by rhs: Self)
> }
> /// SignedArithmetic protocol will only be conformed to by signed numbers,/// 
> otherwise it would be po

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Stephen Canon via swift-evolution

> On Apr 14, 2016, at 11:05 PM, Chris Lattner  wrote:
> 
> 
>> On Apr 14, 2016, at 11:01 PM, Chris Lattner via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> On Apr 14, 2016, at 9:49 PM, Stephen Canon > > wrote:
 On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
> Provide basic constants (analogues of C's DBL_MAX, etc.)
 Nice, have you considered adding pi/e and other common constants?  I’d 
 really really like to see use of M_PI go away… :-)
>>> 
>>> That’s a reasonable suggestion.  I’m not sure if FloatingPoint is the right 
>>> protocol to attach them to, but I’m not sure that it’s wrong either.  I’d 
>>> be interested to hear arguments from the community either way.
>> 
>> I’m not sure where the right place is either, I just want them :-)   
>> Seriously though, the notion of pi seems to make sense for both decimal and 
>> binary fp types, it seems base independent.
> 
> Incidentally, if you make pi and e be static members of the type, we should 
> get a pretty fluent style, along the lines of:
> 
>   let x = someDouble * 2 * .pi
> 
> I agree that there is a concern about deciding “which” constants to include.  
> I’ll let you and the numeric elite figure that out :-)

“e” is a great bike-shedding example.  While it would definitely allow a fluent 
style if you know what you’re looking at, I worry a little bit about 
readability of `Float.e` or `.e` in source.  Most programmers are at least 
passingly familiar with pi, but that familiarity doesn’t necessarily extend to 
e.  IDEs and docstrings make this palatable, of course.

I wonder if maybe we shouldn’t expose `.pi` directly, but tuck other constants 
behind something like `.math.e`.  It’s slightly inconsistent, but might be the 
pragmatic solution.  If we did this, we could be a bit more aggressive about 
what constants were included without worrying about being too confusing.  I 
would probably expose most of what’s in math.h initially:

pi, 1/pi, e, log2(e), log10(e), log(2), log(10), sqrt(2), 1/sqrt(2)

The other question is how these play with arbitrary-precision types, if someone 
wants to write one that conforms to Floating Point.  Usually in 
arbitrary-precision libraries, these would be functions (desiredPrecision: Int) 
-> Self, but they could also be implemented as a future that gets evaluated to 
the desired precision when used or something similar.  If we add these to the 
protocols, I wouldn’t want to constrain the design space arbitrarily.  The most 
conservative approach would be to just add them to the concrete types.  We 
could also put them in a FixedWidthFloatingPoint protocol for now if necessary.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread plx via swift-evolution
+1; this is great!

I have nothing but good things to say about the proposal itself.

I have two smaller questions, however; I apologize if they are off-topic.

One is if there’s any ETA or similar for a glimpse at the “complete picture” of 
Swift’s revised numeric protocols; these floating-point protocols look really, 
really good, but this is also (I think) the first glimpse at the new 
`Arithmetic` protocol, and there’s also a new “Integer” protocol coming…and 
it’d be nice to get a sense of the complete vision here.

My other question is potentially subsumed by the above, but I want to raise it 
now: it’d be great if there was some standardized protocol/vocabulary to use 
when converting between various numeric representations that was:

- easy for custom numeric types to *adopt* correctly (e.g. if one were to write 
a fixed-point type, or a rational type, etc.)
- easy for non-experts to *use* correctly for non-expert purposes

…since such conversions from one representation to another are at least IMHO a 
dangerous area; if you know what you’re doing it’s not dangerous, but e.g. even 
if someone is only trying to go from Double -> Int:

- they probably aren’t an expert, doing expert numerical things
- they may not have a solid understanding of floating point (NaN, infinities, 
etc.)
- they thus may not know they may *need* to be careful here
- they may not know *how* to be careful, even if they know they *should* be
- they may not be able to be careful *correctly*, even if they attempt it

…and so it’d again be great if the revised numeric protocols allow as broad a 
range of such conversions as possible to be handled by generic code in the 
standard library. 

It certainly looks like `FloatingPoint` protocol itself provides enough 
information to allow an expert to write generic version of most floating point 
-> integer conversion variants I can think of, but I’m not an expert…but it’d 
be great if e.g. there was some simpler protocol other custom numeric types 
could adopt to take advantage of expert-written generic conversions to other 
numeric types. 

I can provide examples if this is unclear, and if it’s off-topic it can wait 
for another time. 

This `FloatingPoint` revision itself looks really really good! 

> On Apr 14, 2016, at 6:55 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
> Enhanced floating-point protocols
> 


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread Brent Royal-Gordon via swift-evolution
>> Are there potential conforming types which aren't Comparable?
> 
> Not at present, but I expect there to be in the future.  Modular integers and 
> complex numbers come to mind as the most obvious examples.

Ooh, those are great examples. That is definitely the right decision, then.

(One thing I've been vaguely concerned with is dimensional analysis. A strong 
type system opens up the possibility of marking numbers with units, or at least 
dimensions, so that the type system can catch when you try to pass a 
Second> to a call that's expecting a Second>. Doing this 
properly requires more freedom in the multiplication and division operators' 
parameters and return values—but of course, it also requires higher-kinded 
types to construct the right return values, so it's out of reach for Swift 3 
anyway.)

>>> /// NaN `payloads`.  `FloatingPoint` types should either treat inadmissible
>>> /// payloads as zero, or mask them to create an admissible payload.
>>> static func nan(payload payload: RawSignificand, signaling: Bool) -> Self
>> 
>> This seems unusually tolerant of bad inputs. Should this instead be a 
>> precondition, and have an (elidable in unchecked mode) trap if it's violated?
> 
> I don’t think that it’s a particularly useful error to detect,

Maybe it's just my lack of knowledge, but I feel like, if you are calling this 
method, you probably care about getting that payload into the resulting NaN. 
Otherwise you would be using the `nan` property. (There is no `signalingNan` 
property, but there could be.)

What do people use NaN payloads for? Are there a lot of cases where the payload 
is a nice-to-have, but it's okay to destroy or even mangle it?

> and different floating point types may differ greatly in what payloads they 
> support (if any), because they might choose to reserve those encodings for 
> other purposes.

If the data you can actually get into a NaN varies so much from one type to 
another, is this API a useful one to offer on the protocol? Is it something you 
can reliably use on "any floating-point type" without knowing which type it is?

(It also now occurs to me that this might be better off as an initializer: 
`init(nanWithPayload:signaling:)`.)

>> Reading these, I find the use of "least" a little bit misleading—it seems 
>> like they should be negative.
> 
> Magnitudes are strictly positive.  In fairness, that may not be immediately 
> obvious to all readers.

It does make sense now that you've said so! It might be a good doc comment 
note, though.

>>  static var positiveNormals: ClosedRange { get }
>>  static var positiveSubnormals: ClosedRange { get }
>> 
>>  Double.positiveNormals.upperBound   // DBL_MAX
>>  Double.positiveNormals.lowerBound   // DBL_MIN
>>  Double.positiveSubnormals.upperBound// 
>> Self.positiveNormals.lowerBound.nextDown
>>  Double.positiveSubnormals.lowerBound// 0.nextUp
> 
> This seems wildly over-engineered to me personally.  Every language I 
> surveyed provides (a subset of) these quantities as simple scalar values.

Well, I am rather prone to wild over-engineering. :^)

One place where a range like FloatingPoint.positives would be useful is in 
random number generation. Suppose you have:

protocol Randomizer {
…
mutating func choice(from choices: 
ClosedRange) -> T
…
}

Which lets you say:

rng.choice(from: 0...1)

It would then be nice to say something like:

rng.choice(from: Double.positives)
rng.choice(from: Float.finites)
// etc.

Of course, the set of ranges useful for that purpose is probably different from 
these more technical things, so that might not be the best design anyway.

>>> public protocol FloatingPoint: SignedArithmetic, Comparable {
>>> func isLess(than other: Self) -> Bool
>>> func totalOrder(with other: Self) -> Bool
>> 
>> Swift 2's Comparable demands a strict total order. However, the 
>> documentation here seems to imply that totalOrder is *not* what you get from 
>> the < operator. Is something getting reshuffled here?
> 
> The Swift 2 Comparable documentation is probably overly specific.  The 
> requirement should really be something like a strict total order on 
> non-exceptional values.

Okay.

(While I was waiting for your reply, I was thinking about a rework of 
`Comparable` which had a sort-oriented `totalOrder(_:)` as a requirement and 
`isLess(_:)`, `isGreater(_:)`, et. al. which defaulted to using 
`totalOrder(_:)`, but could be overridden for types like FloatingPoint with 
exceptional values. I should just wait for answers sometimes.)

>> Also, since `init(_:)` is lossy and `init(exactly:)` is not, shouldn't their 
>> names technically be switched? Or perhaps `init(_:)` should be exact and 
>> trapping, `init(exactly:)` should be failable, and `init(closest:)` should 
>> always return something or other?
> 
> That would be a large change in the existing behav

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Chris Lattner via swift-evolution

> On Apr 14, 2016, at 11:01 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> On Apr 14, 2016, at 9:49 PM, Stephen Canon  > wrote:
>>> On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
 Provide basic constants (analogues of C's DBL_MAX, etc.)
>>> Nice, have you considered adding pi/e and other common constants?  I’d 
>>> really really like to see use of M_PI go away… :-)
>> 
>> That’s a reasonable suggestion.  I’m not sure if FloatingPoint is the right 
>> protocol to attach them to, but I’m not sure that it’s wrong either.  I’d be 
>> interested to hear arguments from the community either way.
> 
> I’m not sure where the right place is either, I just want them :-)   
> Seriously though, the notion of pi seems to make sense for both decimal and 
> binary fp types, it seems base independent.

Incidentally, if you make pi and e be static members of the type, we should get 
a pretty fluent style, along the lines of:

let x = someDouble * 2 * .pi

I agree that there is a concern about deciding “which” constants to include.  
I’ll let you and the numeric elite figure that out :-)

-Chris

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Chris Lattner via swift-evolution
On Apr 14, 2016, at 9:49 PM, Stephen Canon  wrote:
>> On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>>> Provide basic constants (analogues of C's DBL_MAX, etc.)
>> Nice, have you considered adding pi/e and other common constants?  I’d 
>> really really like to see use of M_PI go away… :-)
> 
> That’s a reasonable suggestion.  I’m not sure if FloatingPoint is the right 
> protocol to attach them to, but I’m not sure that it’s wrong either.  I’d be 
> interested to hear arguments from the community either way.

I’m not sure where the right place is either, I just want them :-)   Seriously 
though, the notion of pi seems to make sense for both decimal and binary fp 
types, it seems base independent.

>> Swift supports instance and type members with the same names, but this is 
>> controversial, leads to confusion, and may go away in the future.  It would 
>> be great to avoid this in your design.
> 
> Interesting.  Both are definitely useful, but Type(1).ulp is sufficiently 
> simple that only having the instance member may be good enough.  Otherwise, 
> ulpOfOne or similar could work.

Either of those work for me.

> 
>> I’m certainly not a floating point guru, but I would have expected 
>> significant to be of type RawSignificand, and thought that the significant 
>> of a nan would return its payload.  Does this approach make sense?
>> 
>> … later: I see that you have this on the binary FP type, so I assume there 
>> is a good reason for this :-)
> 
> Both are useful to have in practice.  I have been attempting to keep the 
> assumptions about representation to a minimum in the top-level FloatingPoint 
> protocol.

Makes sense!

>> I’m used to this being called a “Denormal”, but I suspect that “subnormal” 
>> is the actually right name?  Maybe it would be useful to mention the 
>> “frequently known as denormal” in the comment, like you did with mantissa 
>> earlier.
> 
> Yes, “subnormal” is the preferred IEEE 754 terminology, but I’ll add a note 
> referencing “denormal” as well.

Thanks!

-Chris

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Dave via swift-evolution
In general, I think this is fantastic. In particular, I *really* like the 
notion that `BinaryFloatingPoint` conforms to `FloatingPoint`. I would do a few 
things differently, though:
> On Apr 14, 2016, at 6:55 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
> public protocol FloatingPoint: SignedArithmetic, Comparable {
>   ...
>   /// The greatest finite number.
>   ///
>   /// Compares greater than or equal to all finite numbers, but less than
>   /// infinity.  Corresponds to the C macros `FLT_MAX`, `DBL_MAX`, etc.
>   /// The naming of those macros is slightly misleading, because infinity
>   /// is greater than this value.
>   static var greatestFiniteMagnitude: Self { get }
>   ...
> }

Why put this in FloatingPoint? The concept is valid for any real type (IMHO, 
it’s valid for rectangular Complex/Quaternion/etc types as well... I’m not sure 
if it is for the various polar formats, though). I think a better place for it 
is either in `Arithmetic`, or another protocol to which `Arithmetic` conforms:
protocol HasMinAndMaxFiniteValue {
static var maxFinite: Self {get} // I think “max”/“min" are clear enough 
(especially if the docs are explicit), but I understand the objection
static var minFinite: Self {get} // 0 for unsigned types
}
This would unify the syntax for getting a numeric type’s min or max finite 
value across all the built-in numeric types (this means that `Int.max` would 
become `Int.maxFinite`). Similarly, IMHO infinity shouldn’t be tied to floating 
point types. While it’s true that the *native* integer types don’t support 
infinity, arbitrary precision integer types might.
protocol HasInfinity {
static var infinity: Self {get}
}



> /// Arithmetic protocol declares methods backing binary arithmetic operators,
> /// such as  `+`, `-` and `*`; and their mutating counterparts.  These methods
> /// operate on arguments of the same type.
> ...
> public protocol Arithmetic: Equatable, IntegerLiteralConvertible {
>   init()
>   func adding(rhs: Self) -> Self
>   mutating func add(rhs: Self)
>   func subtracting(rhs: Self) -> Self
>   mutating func subtract(rhs: Self)
>   func multiplied(by rhs: Self) -> Self
>   mutating func multiply(by rhs: Self)
>   func divided(by rhs: Self) -> Self
>   mutating func divide(by rhs: Self)
> }

I’d restructure this a bit:
protocol Arithmetic { //AFAIK *all* numeric types should be able to do these
init()
func adding(rhs: Self) -> Self
mutating func add(rhs: Self)
func subtracting(rhs: Self) -> Self
mutating func subtract(rhs: Self)
}
protocol ScalarArithmetic : Arithmetic { //These can be iffy for non-scalar 
types
func multiplied(by rhs: Self) -> Self
mutating func multiply(by rhs: Self)
func divided(by rhs: Self) -> Self
mutating func divide(by rhs: Self)
}

Multiplication isn't always defined for any two arbitrarily-dimensioned 
matrices (plus, there are so many reasonable matrix “subtypes” that there's no 
guarantee that the return type should always be the same), and I don’t think 
there’s a generally agreed-upon meaning for matrix division at all.

[Slight_Rabbit_Trail] For a while, I was trying to get work around the issue in 
my own code by doing something like (this was before the change to 
“associatedtype”):
public protocol MathLibNumberType {
typealias AddType
typealias AddReturnType
...
func +(_: Self, _: Self.AddType) -> Self.AddReturnType
...
}
But there was some problem when I got to this part:
public protocol ScalarType : MathLibNumberType {
typealias AddType = Self
typealias AddReturnType = Self
...
}
extension Int : ScalarType {}
I can’t remember what the exact problem was anymore. It’s been a while… I think 
maybe even pre-Swift 2.  Hmm… maybe I should try it again...
[/Slight_Rabbit_Trail] 

Anyway, those are my thoughts on the matter.

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Erica Sadun via swift-evolution

> On Apr 14, 2016, at 10:36 PM, Stephen Canon  wrote:
> 
> Hi Erica, thanks for the feedback.
> 
>> On Apr 14, 2016, at 6:29 PM, Erica Sadun > > wrote:
>> 
>> * I do use % for floating point but not as much as I first thought before I 
>> started searching through my code after reading your e-mail. But when I do 
>> use it, it's nice to have a really familiar symbol rather than a big word. 
>> What were the ways that it was used incorrectly? Do you have some examples?
> 
> As it happens, I have a rationale sitting around from an earlier (internal) 
> discussion:
> 

Thanks. That makes plenty of sense although I do still think the name is long 
and hard to discover compared to fmod[1] and %.

>> * I don't quite get how equatable is going to work. Do you mind explaining 
>> that in more detail?
> 
> I’m not totally sure what your question is.  Are you asking how FloatingPoint 
> will conform to Equatable, or how the Equatable protocol will work?

Given the many words and passionate articles about how difficult it is to 
perform floating point comparisons, 
for example, 
https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/,
 
I'm just curious as to what approach you've settled on. The topic has come up 
on-list quite a few times.

-- E

[1] Nearly all of what I *thought* I was doing with % did turn out to be fmod 
(CGFloat a = fmodf(stepAngle * i, 360.0))
 so there's that___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Stephen Canon via swift-evolution
Hi Brent, thanks for the feedback.

> On Apr 14, 2016, at 8:34 PM, Brent Royal-Gordon  
> wrote:
> 
> First of all: I do *not* do crazy things with floating-point numbers, so 
> there's a good chance I'm missing the point with some of this. Consider 
> anything having to do with NaNs, subnormals, or other such strange denizens 
> of the FPU to be prefixed with "I may be totally missing the point, but…”

Noted.

>> public protocol Arithmetic
> 
> Is there a rationale for the name "Arithmetic"? There's probably nothing 
> wrong with it, but I would have guessed you'd use the name "Number”.

Dave A. came up with the name, though I think it’s a good one.  Number isn’t 
bad either.

>> : Equatable, IntegerLiteralConvertible
> 
> Are there potential conforming types which aren't Comparable?

Not at present, but I expect there to be in the future.  Modular integers and 
complex numbers come to mind as the most obvious examples.

>> func adding(rhs: Self) -> Self
>> mutating func add(rhs: Self)
> 
> Is there a reason we're introducing methods and calling them from the 
> operators, rather than listing the operators themselves as requirements?
> 
>>  func negate() -> Self
> 
> Should this be `negated()`? Should there be a mutating `negate()` variant, 
> even if we won't have an operator for it?
> 
> (If a mutating `negate` would be an attractive nuisance, we can use 
> `negative()`/`formNegative()` instead.)

Chris noted this too, and I think you’re both right.

>>  /// NaN `payloads`.  `FloatingPoint` types should either treat inadmissible
>>  /// payloads as zero, or mask them to create an admissible payload.
>>  static func nan(payload payload: RawSignificand, signaling: Bool) -> Self
> 
> This seems unusually tolerant of bad inputs. Should this instead be a 
> precondition, and have an (elidable in unchecked mode) trap if it's violated?

I don’t think that it’s a particularly useful error to detect, and different 
floating point types may differ greatly in what payloads they support (if any), 
because they might choose to reserve those encodings for other purposes.

>> static var greatestFiniteMagnitude: Self { get }
>> static var leastNormalMagnitude: Self { get }
>> static var leastMagnitude: Self { get }
> 
> Reading these, I find the use of "least" a little bit misleading—it seems 
> like they should be negative.

Magnitudes are strictly positive.  In fairness, that may not be immediately 
obvious to all readers.

> I wonder if instead, we can use ClosedIntervals/ClosedRanges to group 
> together related values:
> 
>   static var positiveNormals: ClosedRange { get }
>   static var positiveSubnormals: ClosedRange { get }
> 
>   Double.positiveNormals.upperBound   // DBL_MAX
>   Double.positiveNormals.lowerBound   // DBL_MIN
>   Double.positiveSubnormals.upperBound// 
> Self.positiveNormals.lowerBound.nextDown
>   Double.positiveSubnormals.lowerBound// 0.nextUp
> 
>   // Alternatively, you could have `positives`, running from 0.nextUp to 
> infinity
> 
> Technically, you could probably implement calls like e.g. isNormal in terms 
> of the positiveNormals property, but I'm sure separate calls are much, much 
> faster.
> 
> (It might also be helpful if you could negate signed ClosedIntervals, which 
> would negate and swap the bounds.)

This seems wildly over-engineered to me personally.  Every language I surveyed 
provides (a subset of) these quantities as simple scalar values.

>> public protocol FloatingPoint: SignedArithmetic, Comparable {
>>  func isLess(than other: Self) -> Bool
>>  func totalOrder(with other: Self) -> Bool
> 
> Swift 2's Comparable demands a strict total order. However, the documentation 
> here seems to imply that totalOrder is *not* what you get from the < 
> operator. Is something getting reshuffled here?

The Swift 2 Comparable documentation is probably overly specific.  The 
requirement should really be something like a strict total order on 
non-exceptional values.

>>  init(_ value: Source)
>>  init?(exactly value: Source)
> 
>>  init(_ value: Source)
>>  init?(exactly value: Source)
> 
> It's great to have both of these, but I wonder how they're going to be 
> implemented—if Integer can be either signed or unsigned, I'm not sure how you 
> get the top bit of an unsigned integer out.

These are the bits that are dependent on the new Integer proposal, which should 
be forthcoming soonish.  As you note, they aren’t really implementable without 
it (at least, not easily).  However, I thought that it made the most sense to 
include them with this proposal.

> Also, since `init(_:)` is lossy and `init(exactly:)` is not, shouldn't their 
> names technically be switched? Or perhaps `init(_:)` should be exact and 
> trapping, `init(exactly:)` should be failable, and `init(closest:)` should 
> always return something or other?

That would be a large change in the existing behavior, since we only have the 
(potentially lossy) init(

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Stephen Canon via swift-evolution
Thanks for the feedback, Chris.

> On Apr 14, 2016, at 9:06 PM, Chris Lattner  wrote:
> 
> This proposal looks really really great, let me know when you want to start 
> the review process (or just submit a PR for the -evolution repo) and I’ll 
> happily review manage it for you.
> 
> On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>> Provide basic constants (analogues of C's DBL_MAX, etc.)
> Nice, have you considered adding pi/e and other common constants?  I’d really 
> really like to see use of M_PI go away… :-)

That’s a reasonable suggestion.  I’m not sure if FloatingPoint is the right 
protocol to attach them to, but I’m not sure that it’s wrong either.  I’d be 
interested to hear arguments from the community either way.

>> /// SignedArithmetic protocol will only be conformed to by signed numbers,
>> /// otherwise it would be possible to negate an unsigned value.
>> ///
>> /// The only method of this protocol has the default implementation in an
>> /// extension, that uses a parameterless initializer and subtraction.
>> public protocol SignedArithmetic : Arithmetic {
>>   func negate() -> Self
> Should this be negated / negate?  negate() seems like an in-place mutating 
> version.

Yup, that seems right.

>> /// A floating-point type that provides most of the IEEE 754 basic (clause 5)
> Dumb Q, but is it “IEEE 754” or “IEEE-754”?

It’s commonly styled both ways, but I believe IEEE 754 is the “official" one.

>> /// operations.  The base, precision, and exponent range are not fixed in
>> /// any way by this protocol, but it enforces the basic requirements of
>> /// any IEEE 754 floating-point type.
>> ///
>> /// The BinaryFloatingPoint protocol refines these requirements and provides
>> /// some additional useful operations as well.
>> public protocol FloatingPoint: SignedArithmetic, Comparable {
>> 
>>   static var ulp: Self { get }
>>   var ulp: Self { get }
> Swift supports instance and type members with the same names, but this is 
> controversial, leads to confusion, and may go away in the future.  It would 
> be great to avoid this in your design.

Interesting.  Both are definitely useful, but Type(1).ulp is sufficiently 
simple that only having the instance member may be good enough.  Otherwise, 
ulpOfOne or similar could work.



> I’m certainly not a floating point guru, but I would have expected 
> significant to be of type RawSignificand, and thought that the significant of 
> a nan would return its payload.  Does this approach make sense?
> 
> … later: I see that you have this on the binary FP type, so I assume there is 
> a good reason for this :-)

Both are useful to have in practice.  I have been attempting to keep the 
assumptions about representation to a minimum in the top-level FloatingPoint 
protocol.



>>   /// True if and only if `self` is subnormal.
>>   ///
>>   /// A subnormal number does not use the full precision available to normal
>>   /// numbers of the same format.  Zero is not a subnormal number.
>>   var isSubnormal: Bool { get }
> I’m used to this being called a “Denormal”, but I suspect that “subnormal” is 
> the actually right name?  Maybe it would be useful to mention the “frequently 
> known as denormal” in the comment, like you did with mantissa earlier.

Yes, “subnormal” is the preferred IEEE 754 terminology, but I’ll add a note 
referencing “denormal” as well.

Thanks,
– Steve

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Stephen Canon via swift-evolution
Hi Howard, thanks for the feedback.

> On Apr 14, 2016, at 6:05 PM, Howard Lovatt  wrote:
> 
> +1 great addition.
> 
> Would suggest the naming could be more consistent, in particular:
> Anything returning Self could be named xxxed. In the current proposal this 
> naming convention is sometimes used, e.g. divided, and sometimes not, e.g. 
> subtracting. Suggest all unified with the xxxed convention.
The names in the Arithmetic protocol are Dave A’s creation, but I think they’re 
a reasonable compromise given the constraints placed on us.  While consistency 
would be nice, I think that clarity at use site is more important, under the 
rationale that code is read more often than written.  Also, keep in mind that 
in practice, “everyone” will use the operators for arithmetic.  Dave may have 
more to say on the subject.
> Anything returning Bool could be named isXxx. In some cases this is used, 
> e.g. isUnordered, but not others, e.g. totalOrder.
That’s a reasonable point.  isTotallyOrdered(with: ) is simple, but I’m not 
sure how I would handle totalOrderMagnitude( ) under this scheme.  Thoughts?

Thanks,
– Steve___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Stephen Canon via swift-evolution
Hi Erica, thanks for the feedback.

> On Apr 14, 2016, at 6:29 PM, Erica Sadun  wrote:
> 
> * I do use % for floating point but not as much as I first thought before I 
> started searching through my code after reading your e-mail. But when I do 
> use it, it's nice to have a really familiar symbol rather than a big word. 
> What were the ways that it was used incorrectly? Do you have some examples?

As it happens, I have a rationale sitting around from an earlier (internal) 
discussion:

While C and C++ do not provide the “%” operator for floating-point types, many 
newer languages do (Java, C#, and Python, to name just a few).  Superficially 
this seems reasonable, but there are severe gotchas when % is applied to 
floating-point data, and the results are often extremely surprising to unwary 
users.  C and C++ omitted this operator for good reason.  Even if you think you 
want this operator, it is probably doing the wrong thing in subtle ways that 
will cause trouble for you in the future.

The % operator on integer types satisfies the division algorithm axiom: If b is 
non-zero and q = a/b, r = a%b, then a = q*b + r.  This property does not hold 
for floating-point types, because a/b does not produce an integral value.  If 
it did produce an integral value, it would need to be a bignum type of some 
sort (the integral part of DBL_MAX / DBL_MIN, for example, has over 2000 bits 
or 600 decimal digits).

Even if a bignum type were returned, or if we ignore the loss of the division 
algorithm axiom, % would still be deeply flawed.  Whereas people are generally 
used to modest rounding errors in floating-point arithmetic, because % is not 
continuous small errors are frequently enormously magnified with catastrophic 
results:

(swift) 10.0 % 0.1
// r0 : Double = 0.0995 // What?!

[Explanation: 0.1 cannot be exactly represented in binary floating point; the 
actual value of “0.1” is 
0.155511151231257827021181583404541015625.  Other than that 
rounding, the entire computation is exact.]

Proposed Approach:
Remove the “%” operator for floating-point types.  The operation is still be 
available via the C standard library fmod( ) function (which should be mapped 
to a Swiftier name, but that’s a separate proposal).

Alternative Considered:
Instead of binding “%” to fmod( ), it could be bound to remainder( ), which 
implements the IEEE 754 remainder operation; this is just like fmod( ), except 
instead of returning the remainder under truncating division, it returns the 
remainder of round-to-nearest division, meaning that if a and b are positive, 
remainder(a,b) is in the range [-b/2, b/2] rather than [0, b).  This still has 
a large discontinuity, but the discontinuity is moved away from zero, which 
makes it much less troublesome (that’s why IEEE 754 standardized this 
operation):

(swift) remainder(1, 0.1)
// r1 : Double = -0.55511151231257827 // Looks like normal 
floating-point rounding

The downside to this alternative is that now % behaves totally differently for 
integer and floating-point data, and of course the division algorithm still 
doesn’t hold.

> * I don't quite get how equatable is going to work. Do you mind explaining 
> that in more detail?

I’m not totally sure what your question is.  Are you asking how FloatingPoint 
will conform to Equatable, or how the Equatable protocol will work?

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Chris Lattner via swift-evolution
This proposal looks really really great, let me know when you want to start the 
review process (or just submit a PR for the -evolution repo) and I’ll happily 
review manage it for you.

On Apr 14, 2016, at 4:55 PM, Stephen Canon via swift-evolution 
 wrote:
> Provide basic constants (analogues of C's DBL_MAX, etc.)
Nice, have you considered adding pi/e and other common constants?  I’d really 
really like to see use of M_PI go away… :-)

> 
> /// SignedArithmetic protocol will only be conformed to by signed numbers,
> /// otherwise it would be possible to negate an unsigned value.
> ///
> /// The only method of this protocol has the default implementation in an
> /// extension, that uses a parameterless initializer and subtraction.
> public protocol SignedArithmetic : Arithmetic {
>   func negate() -> Self
Should this be negated / negate?  negate() seems like an in-place mutating 
version.

> /// A floating-point type that provides most of the IEEE 754 basic (clause 5)
Dumb Q, but is it “IEEE 754” or “IEEE-754”?


> /// operations.  The base, precision, and exponent range are not fixed in
> /// any way by this protocol, but it enforces the basic requirements of
> /// any IEEE 754 floating-point type.
> ///
> /// The BinaryFloatingPoint protocol refines these requirements and provides
> /// some additional useful operations as well.
> public protocol FloatingPoint: SignedArithmetic, Comparable {
> 
>   static var ulp: Self { get }
>   var ulp: Self { get }
Swift supports instance and type members with the same names, but this is 
controversial, leads to confusion, and may go away in the future.  It would be 
great to avoid this in your design.


> 
> 
>   //  TODO: strictly speaking a bit and a bool are slightly different
>   //  concepts.  Is another name more appropriate for this property?
>   //  `isNegative` is incorrect because of -0 and NaN.  `isSignMinus` might
>   //  be acceptable, but isn't great.  `signBit` is the IEEE 754 name.
>   var signBit: Bool { get }
I think you have this right, by calling it a bit and typing it as a Bool -using 
a Bool to represent a specific bit from Self seems right. 


>   /// The significand satisfies:
>   ///
>   /// ~~~
>   /// self = (signBit ? -1 : 1) * significand * radix**exponent
** isn’t a defined swift operator, it would be nice to change the comment to 
use something a swift programmer would recognize.


>   /// ~~~
>   ///
>   /// If radix is 2 (the most common case), then for finite non-zero numbers
>   /// `1 <= significand` and `significand < 2`.  For other values of `x`,
>   /// `x.significand` is defined as follows:
>   ///
>   /// - If `x` is zero, then `x.significand` is 0.0.
>   /// - If `x` is infinity, then `x.significand` is 1.0.
>   /// - If `x` is NaN, then `x.significand` is NaN.
...
>   var significand: Self { get }
I’m certainly not a floating point guru, but I would have expected significant 
to be of type RawSignificand, and thought that the significant of a nan would 
return its payload.  Does this approach make sense?

… later: I see that you have this on the binary FP type, so I assume there is a 
good reason for this :-)

>   /// Because of these properties, this initializer implements the IEEE 754
>   /// `scaleB` operation.
>   init(signBit: Bool, exponent: Int, significand: Self)
Stylistic question, but why list the initializers after members?


> 
>   /// Mutating form of square root.
>   mutating func formSquareRoot( )
extra space in the parens?


> 
>   /// Fused multiply-add, accumulating the product of `lhs` and `rhs` to 
> `self`.
>   mutating func addProduct(lhs: Self, _ rhs: Self)
Stylistic, but it is easier to read with the mutating next to the non-mutating 
pairs.

>   /// True if and only if `self` is subnormal.
>   ///
>   /// A subnormal number does not use the full precision available to normal
>   /// numbers of the same format.  Zero is not a subnormal number.
>   var isSubnormal: Bool { get }
I’m used to this being called a “Denormal”, but I suspect that “subnormal” is 
the actually right name?  Maybe it would be useful to mention the “frequently 
known as denormal” in the comment, like you did with mantissa earlier.

> Impact on existing code
> 
> The % operator is no longer available for FloatingPoint types. We don't 
> believe that it was widely used correctly, and the operation is still 
> available via the formTruncatingRemainder method for people who need it.
> 
Also worth mentioning that this operator is not supported in popular languages 
like C either.

-Chris


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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Brent Royal-Gordon via swift-evolution
First of all: I do *not* do crazy things with floating-point numbers, so 
there's a good chance I'm missing the point with some of this. Consider 
anything having to do with NaNs, subnormals, or other such strange denizens of 
the FPU to be prefixed with "I may be totally missing the point, but…"

> public protocol Arithmetic


Is there a rationale for the name "Arithmetic"? There's probably nothing wrong 
with it, but I would have guessed you'd use the name "Number".

> : Equatable, IntegerLiteralConvertible


Are there potential conforming types which aren't Comparable?

> func adding(rhs: Self) -> Self
> mutating func add(rhs: Self)

Is there a reason we're introducing methods and calling them from the 
operators, rather than listing the operators themselves as requirements?

>   func negate() -> Self

Should this be `negated()`? Should there be a mutating `negate()` variant, even 
if we won't have an operator for it?

(If a mutating `negate` would be an attractive nuisance, we can use 
`negative()`/`formNegative()` instead.)

>   /// NaN `payloads`.  `FloatingPoint` types should either treat inadmissible
>   /// payloads as zero, or mask them to create an admissible payload.
>   static func nan(payload payload: RawSignificand, signaling: Bool) -> Self

This seems unusually tolerant of bad inputs. Should this instead be a 
precondition, and have an (elidable in unchecked mode) trap if it's violated?

> static var greatestFiniteMagnitude: Self { get }
> static var leastNormalMagnitude: Self { get }
> static var leastMagnitude: Self { get }

Reading these, I find the use of "least" a little bit misleading—it seems like 
they should be negative. I wonder if instead, we can use 
ClosedIntervals/ClosedRanges to group together related values:

static var positiveNormals: ClosedRange { get }
static var positiveSubnormals: ClosedRange { get }

Double.positiveNormals.upperBound   // DBL_MAX
Double.positiveNormals.lowerBound   // DBL_MIN
Double.positiveSubnormals.upperBound// 
Self.positiveNormals.lowerBound.nextDown
Double.positiveSubnormals.lowerBound// 0.nextUp

// Alternatively, you could have `positives`, running from 0.nextUp to 
infinity

Technically, you could probably implement calls like e.g. isNormal in terms of 
the positiveNormals property, but I'm sure separate calls are much, much faster.

(It might also be helpful if you could negate signed ClosedIntervals, which 
would negate and swap the bounds.)

> public protocol FloatingPoint: SignedArithmetic, Comparable {
>   func isLess(than other: Self) -> Bool
>   func totalOrder(with other: Self) -> Bool

Swift 2's Comparable demands a strict total order. However, the documentation 
here seems to imply that totalOrder is *not* what you get from the < operator. 
Is something getting reshuffled here?

>   init(_ value: Source)
>   init?(exactly value: Source)

>   init(_ value: Source)
>   init?(exactly value: Source)

It's great to have both of these, but I wonder how they're going to be 
implemented—if Integer can be either signed or unsigned, I'm not sure how you 
get the top bit of an unsigned integer out.

Also, since `init(_:)` is lossy and `init(exactly:)` is not, shouldn't their 
names technically be switched? Or perhaps `init(_:)` should be exact and 
trapping, `init(exactly:)` should be failable, and `init(closest:)` should 
always return something or other?

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-14 Thread Erica Sadun via swift-evolution
* I do use % for floating point but not as much as I first thought before I 
started searching through my code after reading your e-mail. But when I do use 
it, it's nice to have a really familiar symbol rather than a big word. What 
were the ways that it was used incorrectly? Do you have some examples?

* I don't quite get how equatable is going to work. Do you mind explaining that 
in more detail?

-- E

> On Apr 14, 2016, at 5:55 PM, Stephen Canon via swift-evolution 
>  wrote:
> Impact on existing code
> 
> The % operator is no longer available for FloatingPoint types. We don't 
> believe that it was widely used correctly, and the operation is still 
> available via the formTruncatingRemainder method for people who need it.
> 

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