But linear types? A value can be used only once? Cool. We call that "linearity"? Um, what? What's linear about that?
But linear types? A value can be used only once? Cool. We call that "linearity"? Um, what? What's linear about that?
1. The linear tensor product A ⊗ B gets interpreted as the tensor product of vector spaces.
2. The linear function space A ⊸ B gets interpreted as the vector space of linear functions between A and B.
3. The Cartesian product A × B gets interpreted as the direct product of vector spaces (i.e., the categorical product).
4. The sum type A + B gets interpreted as the direct sum of vector spaces (i.e., the categorical coproduct).
5. The exponential !A gets interpreted by the Fock space construction.
This explains why the choice of name is sensible, but I don't actually know if that was the reason why Jean-Yves Girard named it so. If memory serves, he invented linear logic after thinking about Berry's notion of stable functions, but I don't know for sure when the vector space model was invented. (It's not in his 1987 paper, but it can't have appeared very long after that.)
There are two ways this resemblance manifests.
First off, the basic elements of a coherent space are called cliques which are analogous to vectors in a vector space. The functions constituting the coherent space A => B preserve directed unions of cliques but the linear functions of A -o B preserve arbitrary unions of cliques which is strongly analogous to preserving arbitrary linear combinations of vectors.
Second off is that you can build a symmetric monoidal category out of coherent spaces and vector spaces are the archetypal symmetric monoidal category. There are models of fragments of Linear Logic where the linear functions are literally polynomials of degree 1, but in its full generality it doesn't quite match exactly with linear algebra.
Nonetheless the metaphor goes deep and you can even capture notions of differentiability in extensions to the logic.
For a technical exposition you can read this paper by a guy who's applying this sort of stuff to machine learning: https://arxiv.org/abs/1407.2650 I apologize if this is all too obscure to justify the name. Linear Logic's applications to programming were sort of secondary to its proof theoretic novelty at its inception.
[0]: this requires you to discard the intuition that a linear function looks like a line when plotted.
To be more precise, linear functions correspond to lines/planes/etc passing through the origin since f(0)=0
Math.pow(x,y) cannot be made into a linear function?
As explained in the other answer, it's possible to implement the power function which is "type-linear" on each argument, but that function will not otherwise be linear (ie, the mathematical meaning of linear) on its arguments.
In Rust for instance, affine types are used to restrict usage of values linearly, which means that a value passed as argument will be by default moved from caller to callee: The value will not be available anymore to the caller. This has some consequences for instance for binary operators on values which require special care when moved (structures, arrays): with the restriction explained above, a value cannot be passed more than once to a function, and thus doing something like 'mult(x,x)' (where x is eg. a matrix) will not work because x appears twice, but may only be moved once. The solution offered by the language, called "borrowing" is to use references for the arguments: a borrowed value is no longer being moved; instead, it remains in the scope of the caller, and the callee only receives a reference. References may be created and duplicated, allowing multiple uses of the same piece of data.
Elaborating on this, with a function signature like the following:
fn mult(x : Vec<f32>, y : Vec<f32>) -> Vec<f32> {
// matrix product implementation
}
arguments x and y cannot point to the same value, because a value cannot be moved twice.
A call like mult(a,a)
will generate an error.Conversely, with the following signature:
fn mult(x : &Vec<f32>, y : &Vec<f32>) -> Vec<f32> {
// ...
}
the call: mult(&a,&a)
will typecheck, because values are passed by reference.Now, nothing prevents one to implement the function square, based on the second version of mult:
fn square(x : Vec<f32>) -> Vec<f32> {
return mult(&x,&x)
}
which is type-linear on its parameter x, but computationally is not linear.Clearly your original question was spot on.
https://math.stackexchange.com/questions/2339147/why-is-it-c...
Apparently there is some connection to vector spaces in the structure of linear logic which linear types are based on.