Protocol-Oriented Number System in Pure Swift
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
PONS.xcworkspace
Sources
Tests
graph
macOS.playground
scripts
.gitignore
.travis.yml
LICENSE
Makefile
Package.swift
README.md

README.md

Swift 4.1 MIT LiCENSE build status

swift-pons

Protocol-Oriented Number System in Pure Swift

Synopsis

var bi = BigInt(1) << 1024 - 1          // BigInt
var bq = BigInt(1).over(BigInt(2))      // BigRat
bq = BigRat.sqrt(bq)                    // and Its math functions
var bf = BigFloat(bq)                   // and BigFloat
BigFloat.acos(bf)                       // and Its math functions, too
var cd  = Complex.sqrt(-1.0)            // and Complex<Double>
let pi128 = BigFloat.PI(precision:128)
var cbf = Complex.exp(pi128.i)          // and Complex<BigFloat>
// and more!

Description

Back in the day of Swift 2, PONS was created to demonstrate

func fib<T:SomeType>(_ n:T)->T {
    return n < 2 ? n: (2...Int(n)).reduce((T(0), T(1))){
        (p, _) in (p.1, p.0 + p.1)
    }.1
}

let F11  = fib(11 as Int8)
let F13  = fib(13 as UInt8)
let F23  = fib(23 as Int16)
let F24  = fib(24 as UInt16)
let F46  = fib(46 as Int32)
let F47  = fib(47 as UInt32)
let F92  = fib(92 as Int64)
let F93  = fib(93 as UInt64)
let F666 = fib(666 as BigInt)

is possible. With SE-0104 which is implemented in Swift 4, you can do that out-of-the-box. Just replace SomeType with BinaryInteger and it just works. Ironically that broke the previous version but I am glad Swift has evolved the way it should be. What I was not so happy was that PONS was more than a prototype of protocol-oriented numeric types. It offered

  • Arbitrary-precision Integer (BigInt)
  • Arbitrary-precision Rational (BigRat)
  • Arbitrary-precision Floating Point (BigFloat)
  • Generic Complex.

and so forth. So I decided to restore them but this time with Swift Standard Library and Swift Package Manager. See the graph below.

As you see most types are Swift built-ins and the new PONS acts as an add-on. Now see the graph below.

This is what PONS was. Virtually all necessary protocols and types were custom-made.

PONS was also too monolithic, which was ironical because the best part of the protocol-oriented programming was modularization, or distribution of labor. Thanks to Swift Package Manager PONS is modular. BigInt, for instance, is fetched from attaswift/BigInt. PONS is now an aggregator module that currently binds the following:

  • BigInt: arbitrary-precision integer
  • BigNum: arbitrary-precision floating-point (BigRat and BigFloat
  • Int2X: Double-width integers that is recursively built as typealias Int128 = Int2X<UInt64>
  • Interval: Interval arithmetic. Interval<FloatingPioint> is also <FloatingPoint> so interval arithmetic is easier than ever.
  • Complex: Complex numbers. Any FloatingPoint can be its .real and .imag. To avoid misuse, complex integers are named GaussianInt.

Usage

build

$ git clone https://github.com/dankogai/swift-complex.git
$ cd swift-complex # the following assumes your $PWD is here
$ swift build

REPL

Simply

$ scripts/run-repl.sh

or

$ swift build && swift -I.build/debug -L.build/debug -lComplex

and in your repl,

Welcome to Apple Swift version 4.1 (swiftlang-902.0.48 clang-902.0.39.1). Type :help for assistance.
  1> import PONS

Xcode

Xcode project is deliberately excluded from the repository because it should be generated via swift package generate-xcodeproj . For convenience, you can

$ scripts/prep-xcode

And the Workspace opens up for you with Playground on top. The playground is written as a manual.

From Your SwiftPM-Managed Projects

Add the following to the dependencies section:

.package(
  url: "https://github.com/dankogai/swift-pons.git", .branch("master")
)

and the following to the .target argument:

.target(
  name: "YourSwiftyPackage",
  dependencies: ["PONS"])

Now all you have to do is:

import Complex

in your code. Enjoy!

Prerequisite

Swift 4.1 or better, OS X or Linux to build.