Skip to content

Commit

Permalink
Merge pull request apple#97 from stephentyrone/prefix-modules
Browse files Browse the repository at this point in the history
Enable name lookup for modules by suffixing `Module` when needed to break ambiguity.

In particular, the following module renames are applied:

- Real -> RealModule
- Complex -> ComplexModule

This is a source-breaking change, if you currently directly import these modules. (sorry!)
The fix is to either import Numerics instead, or to use the new, suffixed, names. The good news is that fixing this should require only a straightforward search-and-replace for anyone affected.
  • Loading branch information
stephentyrone authored Feb 21, 2020
2 parents 119377c + 014ce56 commit 5dfc460
Show file tree
Hide file tree
Showing 23 changed files with 55 additions and 36 deletions.
16 changes: 8 additions & 8 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@ import PackageDescription
let package = Package(
name: "swift-numerics",
products: [
.library(name: "Complex", targets: ["Complex"]),
.library(name: "ComplexModule", targets: ["ComplexModule"]),
.library(name: "Numerics", targets: ["Numerics"]),
.library(name: "Real", targets: ["Real"]),
.library(name: "RealModule", targets: ["RealModule"]),
],
dependencies: [
],
targets: [
.target(name: "Complex", dependencies: ["Real"]),
.target(name: "Numerics", dependencies: ["Complex", "Real"]),
.target(name: "NumericsShims", dependencies: []),
.target(name: "Real", dependencies: ["NumericsShims"]),
.target(name: "ComplexModule", dependencies: ["RealModule"]),
.target(name: "Numerics", dependencies: ["ComplexModule", "RealModule"]),
.target(name: "_NumericsShims", dependencies: []),
.target(name: "RealModule", dependencies: ["_NumericsShims"]),

.testTarget(name: "ComplexTests", dependencies: ["Complex", "NumericsShims"]),
.testTarget(name: "RealTests", dependencies: ["Real"]),
.testTarget(name: "ComplexTests", dependencies: ["ComplexModule", "_NumericsShims"]),
.testTarget(name: "RealTests", dependencies: ["RealModule"]),
]
)
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ These modules fall broadly into two categories:

There is some overlap between these two categories, and API that begins in the first category may migrate to the second as it matures and new uses are discovered.

Swift Numerics modules are fine-grained; if you need support for Complex numbers, you can import the Complex module without pulling in everything else in the library as well:
Swift Numerics modules are fine-grained; if you need support for Complex numbers, you can import ComplexModule<sup><a name="back1">[1](#foot1)</a></sup> without pulling in everything else in the library as well:
```swift
import Complex
import ComplexModule

let z = Complex<Double>.i
```
Expand Down Expand Up @@ -51,13 +51,32 @@ To fix a bug, or make smaller improvements:
Questions about how to use Swift Numerics modules, or issues that are not clearly bugs can be discussed in the ["Swift Numerics" section of the Swift forums.](https://forums.swift.org/c/related-projects/swift-numerics)

## Modules
1. [Real](Sources/Real/README.md)
2. [Complex](Sources/Complex/README.md)
1. [RealModule](Sources/RealModule/README.md)
2. [ComplexModule](Sources/ComplexModule/README.md)

## Future expansion
1. [Approximate Equality](https://github.com/apple/swift-numerics/issues/3)
2. [Large Fixed-Width Integers](https://github.com/apple/swift-numerics/issues/4)
3. [Arbitrary-Precision Integers](https://github.com/apple/swift-numerics/issues/5)
4. [Shaped Arrays](https://github.com/apple/swift-numerics/issues/6)
5. [Decimal Floating-point](https://github.com/apple/swift-numerics/issues/7)
6. [Float16](https://github.com/apple/swift-numerics/issues/8)

## Notes
<sup><a name="foot1">[1](#back1)</a></sup> Swift is currently unable to use the fully-qualified name for types when a type and module have the same name (discussion here: https://forums.swift.org/t/pitch-fully-qualified-name-syntax/28482).
This would prevent users of Swift Numerics who don't need generic types from doing things like:
```swift
import Complex
// I know I only ever want Complex<Double>, so I shouldn't need the generic parameter.
typealias Complex = Complex.Complex<Double> // doesn't work, because name lookup fails.
```
For this reason, modules that would have this ambiguity are suffixed with `Module` within Swift Numerics:
```swift
import ComplexModule
// I know I only ever want Complex<Double>, so I shouldn't need the generic parameter.
typealias Complex = ComplexModule.Complex<Double>
// But I can still refer to the generic type by qualifying the name if I need it occasionally:
let a = ComplexModule.Complex<Float>
```
The `Real` module does not contain a `Real` type, but does contain a `Real` protocol, and users may want to define their own `Real` type (and possibly re-export the `Real` module), so the suffix is also applied there.
New modules have to evaluate this decision carefully, but can err on the side of adding the suffix.
It's expected that most users will simply `import Numerics`, so this isn't an issue for them.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import Real
import RealModule

// MARK: - Additive structure
extension Complex: AdditiveArithmetic {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import Real
import RealModule

/// A complex number represented by real and imaginary parts.
///
Expand Down
4 changes: 2 additions & 2 deletions Sources/Complex/README.md → Sources/ComplexModule/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

This module provides a `Complex` number type generic over an underlying `RealType`:
```swift
1> import Complex
1> import ComplexModule
2> let z = Complex(1,1) // z = 1 + i
```
This module provides approximate feature parity and memory layout compatibility with C, Fortran, and C++ complex types (although the importer cannot map the types for you, buffers may be reinterpreted to shim API defined in other languages).

The usual arithmetic operators are provided for Complex numbers, as well as conversion to and from polar coordinates and many useful properties, plus conformances to the obvious usual protocols: `Equatable`, `Hashable`, `Codable` (if the underlying `RealType` is), and `AlgebraicField` (hence also `AdditiveArithmetic` and `SignedNumeric`).

### Dependencies:
- The `Real` module.
- `RealModule`.

## Design notes

Expand Down
4 changes: 2 additions & 2 deletions Sources/Numerics/Numerics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
//===----------------------------------------------------------------------===//

// A module that re-exports the complete Swift Numerics public API.
@_exported import Real
@_exported import Complex
@_exported import RealModule
@_exported import ComplexModule
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import NumericsShims
import _NumericsShims

extension Double: Real {
@_transparent
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import NumericsShims
import _NumericsShims

extension Float: Real {
@_transparent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//
//===----------------------------------------------------------------------===//

import NumericsShims
import _NumericsShims

// Restrict extension to platforms for which Float80 exists.
#if (arch(i386) || arch(x86_64)) && !os(Windows) && !os(Android)
Expand Down
8 changes: 4 additions & 4 deletions Sources/Real/README.md → Sources/RealModule/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Real
# Real Module

[SE-0246] proposed an API for "basic math functions" that would make operations like sine and logarithm available in generic contexts.
It was accepted, but because of limitations in the compiler, the API could not be added to the standard library in a source-stable manner.
The `Real` module provides that API as a separate module so that you can use it right away to get access to the improved API for these operations in your projects.
`RealModule` provides that API as a separate module so that you can use it right away to get access to the improved API for these operations in your projects.

## Protocols and Methods

Expand Down Expand Up @@ -34,7 +34,7 @@ The primary use of this protocol is for writing code that is generic over real a

## Using Real

First, either import `Real` directly or import the `Numerics` umbrella module.
First, either import `RealModule` directly or import the `Numerics` umbrella module.

Suppose we were experimenting with some basic machine learning, and needed a generic [sigmoid function][Sigmoid] activation function:

Expand Down Expand Up @@ -69,7 +69,7 @@ When new basic floating-point types are added to Swift, like `Float16` or `Float
Not having this protocol is a significant missing feature for numerical computing in Swift, and I'm really looking forward to seeing what people do with it.

### Dependencies:
- The C standard math library (`libm`) via the `NumericShims` target.
- The C standard math library (`libm`) via the `_NumericsShims` target.

[ErrorFunction]: https://en.wikipedia.org/wiki/Error_function
[GammaFunction]: https://en.wikipedia.org/wiki/Gamma_function
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
// If any shims are added that are not pure header inlines, whatever runtime
// support they require can be added to this file.

#include "NumericsShims.h"
#include "_NumericsShims.h"
4 changes: 2 additions & 2 deletions Tests/ComplexTests/ArithmeticBenchmarkTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
//===----------------------------------------------------------------------===//

import XCTest
import Complex
import ComplexModule

// For CComplex and shims
import NumericsShims
import _NumericsShims

extension Complex where RealType == Double {
@_transparent
Expand Down
4 changes: 2 additions & 2 deletions Tests/ComplexTests/ArithmeticTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
//===----------------------------------------------------------------------===//

import XCTest
import Complex
import Real
import ComplexModule
import RealModule

// TODO: improve this to be a general-purpose complex comparison with tolerance
func relativeError<T>(_ a: Complex<T>, _ b: Complex<T>) -> T {
Expand Down
4 changes: 2 additions & 2 deletions Tests/ComplexTests/PropertyTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
//===----------------------------------------------------------------------===//

import XCTest
import Complex
import Real
import ComplexModule
import RealModule

final class PropertyTests: XCTestCase {

Expand Down
2 changes: 1 addition & 1 deletion Tests/RealTests/IntegerExponentTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//===----------------------------------------------------------------------===//

import XCTest
import Real
import RealModule

internal extension Real where Self: BinaryFloatingPoint {
static func testIntegerExponentCommon() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/RealTests/RealTestSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//===----------------------------------------------------------------------===//

import XCTest
import Real
import RealModule

#if (arch(i386) || arch(x86_64)) && !os(Windows) && !os(Android)
typealias TestLiteralType = Float80
Expand Down
2 changes: 1 addition & 1 deletion Tests/RealTests/RealTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//===----------------------------------------------------------------------===//

import XCTest
import Real
import RealModule

internal extension ElementaryFunctions where Self: BinaryFloatingPoint {
static func elementaryFunctionChecks() {
Expand Down

0 comments on commit 5dfc460

Please sign in to comment.