Add Gradle Wrapper and clean up docs a bit #28

Merged
breandan merged 4 commits from dev into dev 2018-12-28 07:51:48 +03:00
Showing only changes of commit 9404203982 - Show all commits

View File

@ -1,50 +1,57 @@
# Context-oriented mathematics # Context-oriented mathematics
## The problem ## The problem
A known problem for implementing mathematics in statically-typed languages (and not only in them) is that different A known problem for implementing mathematics in statically-typed languages (but not only in them) is that different
sets of mathematical operation could be defined on the same mathematical objects. Sometimes there is not single way to sets of mathematical operators can be defined on the same mathematical objects. Sometimes there is no single way to
treat some operations like basic arithmetic operations on Java/Kotlin `Number`. Sometimes there are different ways to do treat some operations, including basic arithmetic operations, on a Java/Kotlin `Number`. Sometimes there are different ways to
the same thing like Euclidean and elliptic geometry vector spaces defined over real vectors. Another problem arises when define the same structure, such as Euclidean and elliptic geometry vector spaces over real vectors. Another problem arises when
one wants to add some kind of behavior to existing entity. In dynamic languages those problems are usually solved one wants to add some kind of behavior to an existing entity. In dynamic languages those problems are usually solved
by adding dynamic context-specific behaviors in runtime, but this solution has a lot of drawbacks. by adding dynamic context-specific behaviors at runtime, but this solution has a lot of drawbacks.
## Context-oriented approach ## Context-oriented approach
One of possible solutions to those problems is to completely separate object numerical representations from behaviors.
In terms of kotlin it means to have separate class to represent some entity without any operations, One possible solution to these problems is to completely separate numerical representations from behaviors.
One solution in Kotlin, is to define a separate class which represents some entity without any operations,
for example a complex number: for example a complex number:
```kotlin ```kotlin
data class Complex(val re: Double, val im: Double) data class Complex(val re: Double, val im: Double)
``` ```
And a separate class or singleton, representing operation on those complex numbers:
And then define a separate class or singleton, representing an operation on those complex numbers:
```kotlin ```kotlin
object: ComplexOperations{ object ComplexOperations {
operator fun Complex.plus(other: Complex) = Complex(re + other.re, im + other.im) operator fun Complex.plus(other: Complex) = Complex(re + other.re, im + other.im)
operator fun Complex.minus(other: Complex) = Complex(re - other.re, im - other.im) operator fun Complex.minus(other: Complex) = Complex(re - other.re, im - other.im)
} }
``` ```
In Java, application of such external operations could be very cumbersome, but Kotlin has a unique feature which allows In Java, applying such external operations could be very cumbersome, but Kotlin has a unique feature which allows
to treat this situation: blocks with receivers. So in kotlin, operation on complex number could beimplemented as: to treat this situation: [extensions with receivers](https://kotlinlang.org/docs/reference/extensions.html#extension-functions).
So in Kotlin, an operation on complex number could be implemented as:
```kotlin ```kotlin
with(ComplexOperations) { c1 + c2 - c3 } with(ComplexOperations) { c1 + c2 - c3 }
``` ```
Kotlin also allows to create functions with receivers: Kotlin also allows to create functions with receivers:
```kotlin ```kotlin
fun ComplexOperations.doSomethingWithComplex(c1: Complex, c2: Complex, c3: Complex) = c1 + c2 - c3 fun ComplexOperations.doSomethingWithComplex(c1: Complex, c2: Complex, c3: Complex) = c1 + c2 - c3
ComplexOperations.doComethingWithComplex(c1,c2,c3) ComplexOperations.doComethingWithComplex(c1,c2,c3)
``` ```
In fact, whole parts of program could run in a mathematical context or even multiple nested contexts. In fact, whole parts of a program may be run within a mathematical context or even multiple nested contexts.
In `kmath` contexts are responsible not only for operations, but also for raw object creation and advanced features. In KMath, contexts are responsible not only for operations, but also for raw object creation and advanced features.
## Other possibilities ## Other possibilities
An obvious candidate to get more or less the same functionality is type-class feature. It allows to bind a behavior to An obvious candidate to get more or less the same functionality is the type-class, which allows one to bind a behavior to
a specific type without modifying the type itself. On a plus side, type-classes do not require explicit context a specific type without modifying the type itself. On the plus side, type-classes do not require explicit context
declaration, so the code looks cleaner. On the minus side, if there are different sets of behaviors for the same types, declaration, so the code looks cleaner. On the minus side, if there are different sets of behaviors for the same types,
it is impossible to combine them in the single module. Also, unlike type-classes, context could have parameters or even it is impossible to combine them into one module. Also, unlike type-classes, context can have parameters or even
state. For example in `kmath`, sizes and strides for `NDElement` or `Matrix` could be moved to context to optimize state. For example in KMath, sizes and strides for `NDElement` or `Matrix` could be moved to context to optimize
performance in case of large amount of structures. performance in case of a large amount of structures.