From 940420398237d63eca36fa5aa0a61f2697f67814 Mon Sep 17 00:00:00 2001 From: "breandan.considine" Date: Thu, 27 Dec 2018 23:26:52 -0500 Subject: [PATCH] clean up context doc --- doc/contexts.md | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/doc/contexts.md b/doc/contexts.md index b6b6be44c..ac17d9e52 100644 --- a/doc/contexts.md +++ b/doc/contexts.md @@ -1,50 +1,57 @@ # Context-oriented mathematics ## The problem -A known problem for implementing mathematics in statically-typed languages (and 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 -treat some operations like basic arithmetic operations on Java/Kotlin `Number`. Sometimes there are different ways to do -the same thing like Euclidean and elliptic geometry vector spaces defined 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 -by adding dynamic context-specific behaviors in runtime, but this solution has a lot of drawbacks. +A known problem for implementing mathematics in statically-typed languages (but not only in them) is that different +sets of mathematical operators can be defined on the same mathematical objects. Sometimes there is no single way to +treat some operations, including basic arithmetic operations, on a Java/Kotlin `Number`. Sometimes there are different ways to +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 an existing entity. In dynamic languages those problems are usually solved +by adding dynamic context-specific behaviors at runtime, but this solution has a lot of drawbacks. ## 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: ```kotlin 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 -object: ComplexOperations{ +object ComplexOperations { 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) } ``` -In Java, application of 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: +In Java, applying such external operations could be very cumbersome, but Kotlin has a unique feature which allows +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 -with(ComplexOperations){c1 + c2 - c3} +with(ComplexOperations) { c1 + c2 - c3 } ``` + Kotlin also allows to create functions with receivers: + ```kotlin fun ComplexOperations.doSomethingWithComplex(c1: Complex, c2: Complex, c3: Complex) = 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 -An obvious candidate to get more or less the same functionality is type-class feature. It allows to bind a behavior to -a specific type without modifying the type itself. On a plus side, type-classes do not require explicit context +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 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, -it is impossible to combine them in the single module. Also, unlike type-classes, context could have parameters or even -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. \ No newline at end of file +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 +performance in case of a large amount of structures. \ No newline at end of file