More Quirl Functions

All functions on this page are predefined in addition to Quirl's core functions. Unlike core functions, they have been programmed with Quirl itself. You can view their definitions by clicking on the source toggles. The source code is automatically processed as system prompt at the start of a Quirl chat.

ArithmeticComparativeComplexConditionalGenerativeHigher-orderInteger-relatedList-relatedLogicalPolynomialSet-relatedSize-relatedStatisticalTrigonometricTuple-relatedMiscellaneous

Arithmetic

cfrac(Field ...Field) → Field

Returns the value of a continued fraction whose leading term and partial denominators are given as arguments while the partial numerators are all one. For example, cfrac(3 4 5 6) computes 3 + 1/(4 + 1/(5 + 1/(6))).

cfrac(3, 4, 5, 6); # 421/130

Source

cfrac(Field) = $a;
cfrac(...Field Field Field) = cfrac($a add($b inv($c)));

div(Field Field) → Field

Divides the first argument by the second and returns the result. The second argument may not be zero.

div(221, -13); # -17

Source

div(Field Field) = mul($a inv($b));

Trying to divide by zero causes an exception via the inv core function.

gcd(Rat ...Rat) → Rat

Returns the greatest common divisor of all given arguments, which may not all be zero.

gcd(49, -28, 91); # 7

Source

This implementation uses that rationals are represented as fractions that get reduced to their lowest terms internally.

gcd(Rat):not@ord($a 0) = $a;
gcd(Rat Rat):not@ord($a 0) = div($a den@div($b $a));
gcd(0 ...Rat):not@same(0 $b) = gcd($b);
gcd(Rat ...Rat):not@ord(0 $a) = gcd(neg($a) $b);
gcd(Rat Rat Rat ...Rat):not@ord($a 0) = gcd(gcd($a $b) $c $d);

pow(Field Int) → Field

Returns the first argument to the power of the second. The function does not define 0⁰ at the moment.

pow(2, 40); # 1099511627776

Source

The implementation uses square and multiply, also known as binary exponentiation.

pow(Sing 1) = $a;
pow(Sing Int):ord(2 $b):odd($b) = mul(pow(mul($a $a) mul(add($b -1) 1/2)) $a);
pow(Sing Int):ord(2 $b):even($b) = pow(mul($a $a) mul($b 1/2));
pow(Field 0):not@zero($a) = mul($a inv($a));
pow(Field Int):ord($b -1) = inv(pow($a neg($b)));

prod(Sing ...Sing) → Sing

Returns the product of all arguments. The empty product is not defined here as it differs depending on the context, e.g. 1 for numbers and T for truth values.

prod(-101, -11, 11, 101); # 1234321

Source

prod(Sing) = $a;
prod(Sing Sing ...Sing) = prod(mul($a $b) $c);

sub(Group Group) → Group

Implements subtraction, so returns the first argument minus the second argument. The result is also known as difference of the arguments.

sub(15, 16); # -1

Source

sub(Group Group) = add($a neg($b));

sum(Soup ...Soup) → Soup

Returns the sum of all arguments. This is also known as repeated addition. The empty sum is not defined here, as it differs depending on the context, e.g. 0 for numbers, "" for text, {} for sets, Impossible for types.

sum(-101, -11, 11, 101); # 0

Source

sum(Soup) = $a;
sum(Soup Soup ...Soup) = sum(add($a $b) $c);

Comparative

alike(Operand ...Operand) → Bool

Returns whether the arguments are approximately equal. That is whether they are the same after conversion to a common type.

alike(!3, \9, 138/46); # T
alike("three", "3");   # F

Source

alike(Operand ...Operand) = mono({$a $b});

dec(Ordered ...Ordered) → Bool

Returns whether the arguments are strictly decreasing. This is also known as greater than as a binary relation.

dec(-3, 0, 18, 271);      # F
dec("a", "b", "b", "c");  # F
dec(5/16, 5/16, 5/16);    # F
dec(345°, 90°, 1/4t, 5°); # F
dec("Z", "Y", "X");       # T

Source

dec(Ordered+Beyond) = T;
dec(Ordered Ordered ...?):ord($a $b) = F;
dec(Ordered Ordered ...?):not@ord($a $b) = dec($b $c);

dec(-& +& ...?) = F;
dec(+& -& ...?) = dec($b $c);
dec(-& Int+Rat ...?) = F;
dec(+& Int+Rat ...?) = dec($b $c);
dec(Int+Rat -& ...?) = dec($b $c);
dec(Int+Rat +& ...?) = F;

deq(Ordered ...Ordered) → Bool

Returns whether the arguments are weakly decreasing. This is also known as greater than or equal to as a binary relation.

deq(-3, 0, 18, 271);      # F
deq("a", "b", "b", "c");  # F
deq(5/16, 5/16, 5/16);    # T
deq(345°, 90°, 1/4t, 5°); # T
deq("Z", "Y", "X");       # T

Source

deq(Ordered+Beyond) = T;
deq(Ordered Ordered ...?):ord($b $a) = deq($b $c);
deq(Ordered Ordered ...?):not@ord($b $a) = F;

deq(-& +& ...?) = F;
deq(+& -& ...?) = deq($b $c);
deq(-& Int+Rat ...?) = F;
deq(+& Int+Rat ...?) = deq($b $c);
deq(Int+Rat -& ...?) = deq($b $c);
deq(Int+Rat +& ...?) = F;

eq(Ordered ...Ordered) → Bool

Returns whether the arguments are equal. For ordered types, the result is the same as for the same function. The difference here is a narrower domain. In particular, eq(& &) is not defined whereas same(& &) would be true. The narrower domain can help catch flaws in the code.

eq(-3, 0, 18, 271);      # F
eq("a", "b", "b", "c");  # F
eq(5/16, 5/16, 5/16);    # T
eq(345°, 90°, 1/4t, 5°); # F
eq("Z", "Y", "X");       # F

Source

eq(Ordered ...Ordered) = mono({$a $b});

inc(Ordered ...Ordered) → Bool

Returns whether the arguments are strictly increasing. This is also known as less than as a binary relation.

inc(-3, 0, 18, 271);      # T
inc("a", "b", "b", "c");  # F
inc(5/16, 5/16, 5/16);    # F
inc(345°, 90°, 1/4t, 5°); # F
inc("Z", "Y", "X");       # F

Source

inc(Ordered+Beyond) = T;
inc(Ordered Ordered ...?):ord($b $a) = F;
inc(Ordered Ordered ...?):not@ord($b $a) = inc($b $c);

inc(-& +& ...?) = inc($b $c);
inc(+& -& ...?) = F;
inc(-& Int+Rat ...?) = inc($b $c);
inc(+& Int+Rat ...?) = F;
inc(Int+Rat -& ...?) = F;
inc(Int+Rat +& ...?) = inc($b $c);

inq(Ordered ...Ordered) → Bool

Returns whether the arguments are weakly increasing. This is also known as less than or equal to as a binary relation.

inq(-3, 0, 18, 271);      # T
inq("a", "b", "b", "c");  # T
inq(5/16, 5/16, 5/16);    # T
inq(345°, 90°, 1/4t, 5°); # F
inq("Z", "Y", "X");       # F

Source

inq(Ordered+Beyond) = T;
inq(Ordered Ordered ...?):ord($a $b) = inq($b $c);
inq(Ordered Ordered ...?):not@ord($a $b) = F;

inq(-& +& ...?) = inq($b $c);
inq(+& -& ...?) = F;
inq(-& Int+Rat ...?) = inq($b $c);
inq(+& Int+Rat ...?) = F;
inq(Int+Rat -& ...?) = F;
inq(Int+Rat +& ...?) = inq($b $c);

same(? ...?) → Bool

Returns whether all arguments look the same. The function is similar to the alike function above; the difference here is that arguments are not converted to a common type. This results in same(1 !1) to be false whereas alike(1 !1) would be true, since conversion to a common type would make it equivalent to alike(!1 !1).

same(!3, \9, 138/46);   # F
same(5/16, 5/16, 5/16); # T
same(90°, 1/4t, -270°); # T

Source

same(? ...?) = mono({$a $b});

unlike(...Operand) → Bool

Returns whether all arguments are distinct after conversion to a common type.

unlike(-3, 0, 18, 271);      # T
unlike("a", "b", "b", "c");  # F
unlike(5/16, 5/16, 5/16);    # F
unlike(345°, 90°, 1/4t, 5°); # F
unlike("Z", "Y", "X");       # T

Source

unlike(...Operand) = ord(count($a) size({$a}));

zero(Group) → Bool

Returns whether the argument is the algebraic group's additive identity element, for example 0 for numbers.

zero(!0);   # T
zero(0i);   # T
zero(0t);   # T
zero(12%3); # T

Source

The implementation is based on the fact that add($a neg($a)) is the identity element in a group.

zero(Group) = mono({$a add($a $a)});

Complex

abs(Complex) → Complex

Returns the absolute value, i.e. the Euclidean distance from the origin in the complex plane.

abs(4-3i); # 5

Source

abs(Complex) = sqrt(mul($a con($a)));

im(Complex) → Complex

Returns the imaginary part of a complex number.

im(4-3i); # -3

Source

im(Complex) = mul(-1/2i add($a con(neg($a))));

re(Complex) → Complex

Returns the real part of a complex number.

re(4-3i); # 4

Source

re(Complex) = mul(1/2 add($a con($a)));

roots(Rootable*Complex Int) → List

Returns all the b-th roots of a complex number given as first argument. b is given as second argument and must be a positive integer.

roots(16, 8); # \2, 1+i, \2i, -1+i, -\2, -1-i, -\2i, 1-i

Source

roots(Rootable*Complex Int):ord(1 $b):zero($a) = $a;
roots(Rootable*Complex Int):ord(1 $b):not@zero($a)
= order(arg map(rot(root($a $b) ?) lin(0t scale(1/2t div(2 $b)) $b)));

rot(Complex Angle) → Complex

Rotates a complex number in the complex plane around the origin.

rot(4-3i, 90°); # 3+4i

Source

rot(Complex Angle) = mul($a add(cos($b) mul(sin($b) i)));

sgn(Complex) → Complex

Returns 0 if the argument is zero. Otherwise returns the number on the unit circle in the complex plane that is closest to the argument. This coincides with the usual sign function for real arguments.

sgn(22/7); # 1
sgn(4-3i); # 4/5-3/5i

Source

sgn(Complex):zero($a) = $a;
sgn(Complex):not@zero($a) = div($a abs($a));

sqrt(Complex) → Complex

Returns the principal square root of a real number. The principal square root of a positive number is positive as well. The principal square root of a negative number is on the positive imaginary axis.

sqrt(22/7); # 1/7\154

Source

sqrt(Complex):zero($a) = $a;
sqrt(Complex):not@zero($a):zero@arg($a) = switch(zero@arg@root($a 2) root($a 2) neg@root($a 2));
sqrt(Complex):not@zero($a):alike(arg($a) 1/2t) = mul(sqrt@neg($a) i);

Conditional

The following conditional functions are functions indeed, not control structures as in various programming languages. They do not control whether or which arguments get evaluated. All arguments get evaluated even before they are passed to the function. The boolean first argument just decides which arguments are returned.

if(Bool ...?) → List

Returns all other arguments, if the first argument is true. Otherwise returns an empty list.

if(T, "okay", "k.o."); # "okay", "k.o."
if(F, "okay", "k.o."); #

Source

if(T ...?) = $b;
if(F ...?) = ;

switch(Bool ? ?) → ?

Returns either the second or the third argument depending on whether the first argument is true or false respectively. So it is an if-then-else construct. But be aware that it is a function, not a control structure.

switch(T, "okay", "k.o."); # "okay"
switch(F, "okay", "k.o."); # "k.o."

Source

switch(T ? ?) = $b;
switch(F ? ?) = $c;

Generative

geo(Field Field Int) → List

Returns a geometric progression whose initial terms are given by the first two arguments. Neither may be zero. The third argument determines how many terms are returned. It may not be negative.

geo(1, 2/3, 5); # 1, 2/3, 4/9, 8/27, 16/81

Source

geo(Field Field 0):not@zero($a):not@zero($b) =;
geo(Field Field Int):not@zero($a):not@zero($b):ord(1 $c) = $a geo($b mul($b mul($b inv($a))) add($c -1));

lin(Group Group Int) → List

Returns a linear progression, also called arithmetic progression, whose initial terms are given by the first two arguments. The third argument determines how many terms are returned. It may not be negative.

lin(1, 2/3, 5); # 1, 2/3, 1/3, 0, -1/3

Source

lin(Group Group 0) =;
lin(Group Group Int):ord(1 $c) = $a lin($b add($b add($b neg($a))) add($c -1));

pascal(Int) → List

The given argument determines which row of Pascal's triangle the function returns. The rows are counted form the triangle's top starting at zero. The argument must therefore be non-negative.

pascal(4); # 1, 4, 6, 4, 1

Source

pascal(0) = 1;
pascal(1) = 1 1;
pascal(Int):ord(2 $a) = 1 link(add pascal(add($a -1))) 1;

range(Int Int) → List

Returns all integers including and between the given arguments. The returned list is ascending, if the first argument is smaller than the second argument, and descending, if the first argument is greater than the second argument.

range(8, 12); # 8, 9, 10, 11, 12

Source

range(Int Int):inc($a $b) = $a range(add($a 1) $b);
range(Int Int):eq($a $b)  = $a;
range(Int Int):dec($a $b) = $a range(add($a -1) $b);

rep(...? Int) → List

Repeats all but the last argument b times where b is given by the last argument.

rep("ha", 5); # "ha", "ha", "ha", "ha", "ha"

Source

rep(...? 0) =;
rep(...? Int):ord(1 $b):even($b) = rep($a $a div($b 2));
rep(...? Int):ord(1 $b):odd($b) = $a rep($a add($b -1));

Higher-order

Higher-order functions are functions which expect a function – or another callable – as one of their arguments. Most higher-order functions implement common recursive programming patterns and make them available with a simpler function call. Here is a sketch of the effects of a selection of higher-order functions:

   comb(a b c d e) ⇔ if(a(1) b), if(a(2) c), if(a(3) d), if(a(4) e)
   feed(a b c d e) ⇔ a(b(c(d(e))))
   find(a b c d e) ⇔ if(a(b) b), if(a(c) c), if(a(d) d), if(a(e) e)
   fold(a b c d e) ⇔ a(a(a(b c) d) e)
   fuse(a b c d e) ⇔ a(a(b c), a(d e))
   link(a b c d e) ⇔ a(b c), a(c d), a(d e)
    map(a b c d e) ⇔ a(b), a(c), a(d), a(e)
   pair(a b c d e) ⇔ a(b c), a(d e)
   scan(a b c d e) ⇔ b, a(b c), a(a(b c) d), a(a(a(b c) d) e)
zip(a [b c] [d e]) ⇔ a(b d), a(c e)

The zip function is defined below with tuple-related functions.

comb(Callable ...?) → List

Returns those arguments matched by the variadic parameter ...? for whose index, starting at 1, the given callable evaluates to true. For example, comb(odd "a" "b" "c" "d") would return "a", "c" because "a" and "c" are the 1st and 3rd arguments matched by ...? and 1 and 3 are odd numbers.

comb(even, "a", "b", "c", "d"); # "b", "d"

Source

List items don't actually have an index that can be queried, so an Int counter is added to the parameter lists in the second and third mappings below. Additionally, & is prepended to differentiate these cases from the first mapping with the callable at the start. The Int counter itself would not work to tell the cases apart, neither as last nor as first parameter, because Int is convertible to Pol which is callable.

comb(Callable ...?) = comb(& $a $b 1);
comb(& Callable Int) =;
comb(& Callable ? ...? Int) = if($b($e) $c) comb(& $b $d add($e 1));

feed(...Callable ?) → List

Feeds the last supplied argument into the callable before it, the result into another callable before it etc. and returns the last result. This is much like Quirl's function composition – but the callables here can be dynamically generated unlike function compositions.

feed(text, neg, inv, 7/8); # "-8/7"

Source

feed(?) = $a;
feed(...Callable Callable ?) = feed($a $b($c));

find(Callable ...?) → List

Returns all arguments matched by ...? for which the callable given as first argument returns true. Such a function is also known as filter.

find(even, 0, -512, 5, 6); # 0, -512, 6

Source

find(Callable) =;
find(Callable ? ...?) = if($a($b) $b) find($a $c);

fold(Callable ? ...?) → ?

Uses the first callable argument to reduce the other arguments to a single value. This is done by applying the callable to the following two arguments, then applying it recursively to the result and the next argument repeatedly.

fold(add, 1, 2, 3, 4, 5); # 15 i.e. add(add(add(add(1, 2), 3), 4), 5)

Source

fold(Callable ?) = $b;
fold(Callable ? ? ...?) = fold($a $a($b $c) $d);

fuse(Callable ? ...?) → ?

Uses a callable supplied as first argument to reduce the other arguments to a single value. It does this by grouping the other arguments in pairs and applying the callable to each of them. Then it groups the results in pairs and applies the callable again until a single value is left. For example, fuse(add 1 2 5 4) adds 1 and 2 to get 3 as well as 5 and 4 to get 9, then adds 3 and 9 to return 12.

The results of the functions fold and fuse are the same, if they are given the same arguments and the callable satisfies the associative law on the given arguments. However, performance can vary. For instance, using fold to merge ordered, initially single-element tuples corresponds to the insertionsort strategy whereas using fuse corresponds to the quicker mergesort strategy.

fuse(add, 1, 2, 3, 4, 5); # 15

Source

fuse(Callable ?) = $b;
fuse(Callable ? ? ...?) = fuse($a pair($a $b $c $d));

Source

link(Callable ? ?) = $a($b $c);
link(Callable ? ? ? ...?) = $a($b $c) link($a $c $d $e);

map(Callable ...?) → List

Applies the callable first argument to each of the other arguments and returns the results.

map(x^2, 1, 2, 3, 4, 5); # 1, 4, 9, 16, 25

Source

map(Callable) =;
map(Callable ? ...?) = $a($b) map($a $c);

order(Callable ...?) → List

Orders all but the first argument by the values the callable first argument produces when applied to each of them. The callable function must accept a single argument and return a value with the Ordered trait. For instance, order(arg ...?) sorts complex numbers by their argument. The following example orders rationals by their absolute value.

order(abs, 22/7, -5, 0, 4); # 0, 22/7, 4, -5

Source

order(Callable ...?) = sort(ord@map($a ? ?) $b);

pair(Callable ...?) → List

Groups all arguments except the first into pairs and applies the callable first parameter to each pair. The callable must accept two arguments. If ...? matches an odd number of arguments, the last one is preserved without a callable being applied to it.

pair(tuple, 1, 2, 3, 4, 5); # [1, 2], [3, 4], 5

Source

pair(Callable) =;
pair(Callable ?) = $b;
pair(Callable ? ? ...?) = $a($b $c) pair($a $d);

scan(Callable ? ...?) → List

Scan makes the same computation as fold, but also returns the results of all intermediate computations, starting with the unaltered second argument. Scan is also known as inclusive prefix sum.

scan(add, 1, 2, 3, 4, 5); # 1, 3, 6, 10, 15

Source

scan(Callable ?) = $b;
scan(Callable ? ? ...?) = $b scan($a $a($b $c) $d);

sort(Callable ...?) → List

Use the comparison function provided as first argument to sort all the other arguments and return the result. The comparison function must accept two arguments and return whether they are already sorted correctly.

sort(ord, "Huey", "Louie", "Dewey"); # "Dewey", "Huey", "Louie"

Source

This uses a quicksort approach currently. We may use another algorithm with better worst-case performance in the future.

sort(Callable) =;
sort(Callable ? ...?) = sort($a find($a(? $b) $c)) $b sort($a find(not@$a(? $b) $c));

Logical

all(...Bool) → Bool

Returns whether all arguments are true. This generalizes the logical operation conjunction, also know as logical and, to arbitrarily many arguments.

all(T, F, T, T); # F

Source

all() = T;
all(F ...Bool) = F;
all(T ...Bool) = all($b);

any(...Bool) → Bool

Returns whether at least one argument is true. This generalizes the logical operation inclusive disjunction, also known as logical or, to arbitrarily many arguments.

any(T, F, T, T); # T

Source

any() = F;
any(T ...Bool) = T;
any(F ...Bool) = any($b);

not(Bool) → Bool

Returns the logically converse value, also known as boolean negation or logical not.

not(F); # T

Source

not(F) = T;
not(T) = F;

Polynomial

coeff(Pol Int) → Rat

Returns the coefficient of the b-th power of x from a given polynomial; b is the second argument passed to the function.

coeff(1/3x^3-1/2x^2-x, 2); # -1/2

Source

coeff(0 Int) = 0;
coeff(Pol Int):mono($a):same(deg($a) $b) = $a(1);
coeff(Pol Int):mono($a):not@same(deg($a) $b) = 0;
coeff(Pol Int):poly($a) = sum@map(coeff(? $b) split($a));

cont(Pol) → Rat

Returns the content of a nonzero polynomial, that is the greatest common divisor of its coefficients.

cont(1/3x^3-1/2x^2-x); # 1/6

Source

cont(Pol):not@zero($a) = gcd@map(lead split($a));

ddx(Pol) → Pol

Returns the first derivative of the given polynomial. That is, it implements differentiation.

ddx(x^2-x-1); # 2x-1

Source

ddx(0) = 0;
ddx(Pol):same(0 deg($a)) = 0;
ddx(Pol):mono($a):same(1 deg($a)) = $a(1);
ddx(Pol):mono($a):ord(2 deg($a)) = scale(pow(x add(deg($a) -1)) mul($a(1) deg($a)));
ddx(Pol):poly($a) = sum(map(ddx split($a)));

integral(Pol) → Pol

Returns an antiderivative, also known as indefinite integral, without constant term. Any rational number can be added to the result to find another antiderivative.

integral(x^2-x-1); # 1/3x^3-1/2x^2-x

Source

integral(0) = 0;
integral(Pol):mono($a) = mul($a scale(x inv@add(1 deg($a))));
integral(Pol):poly($a) = sum(map(integral split($a)));

integral(Pol Scalable*Sing Scalable*Sing) → Scalable*Sing

Returns the definite integral of the polynomial function given as first argument with respect to the variable x on the interval from the second to the third argument.

integral(x^2-x-1, 0, 2); # -4/3

Source

integral(Pol Scalable*Sing Scalable*Sing) = sub(integral($a)($c) integral($a)($b));

lead(Pol) → Rat

Returns the leading coefficient of any given nonzero polynomial.

lead(1/3x^3-1/2x^2-x); # 1/3

Source

lead(Pol):not@zero($a) = coeff($a deg($a));

poldiv(Pol Pol) → Pol

Returns the quotient of polynomial division of the first argument by the second argument. Use the function rem to get the corresponding remainder.

poldiv(x^4+4x^3+6x^2+4x+1, x^2-4x+4); # x^2+8x+34

Source

poldiv(Pol Pol):not@zero($b):inc(deg($a) deg($b)) = 0;
poldiv(Pol Pol):not@zero($b): eq(deg($a) deg($b)) = div(lead($a) lead($b));
poldiv(Pol Pol):not@zero($b):dec(deg($a) deg($b)) = add(
	prod(lead($a) inv@lead($b) pow(x sub(deg($a) deg($b))))
	poldiv(sub($a prod(lead($a) inv@lead($b) pow(x sub(deg($a) deg($b))) $b)) $b)
);

pp(Pol) → Pol

Returns the primitive part of a nonzero polynomial, that is a polynomial with integer coefficients whose greatest common divisor is 1. The primitive part has the same zeros as the original polynomial.

pp(1/3x^3-1/2x^2-x); # 2x^3-3x^2-6x

Source

pp(Pol):not@zero($a) = scale($a inv@cont($a));

rem(Pol Pol) → Pol

Returns the remainder of polynomial division of the first argument by the second argument. Use the function poldiv to compute the corresponding quotient.

rem(x^4+4x^3+6x^2+4x+1, x^2-4x+4); # 108x-135

Source

rem(Pol Pol):not@zero($b):inc(deg($a) deg($b)) = $a;
rem(Pol Pol):not@zero($b): eq(deg($a) deg($b)) = sub($a prod(lead($a) inv@lead($b) $b));
rem(Pol Pol):not@zero($b):dec(deg($a) deg($b)) = rem(sub($a prod(lead($a) inv@lead($b) pow(x sub(deg($a) deg($b))) $b)) $b);

Statistical

avg(Scalable*Soup ...Scalable*Soup) → Scalable*Soup

Returns the arithmetic mean, commonly known as average, of all arguments.

avg(1, 4, 5, 6, 2, 3); # 7/2

Source

avg(Scalable*Soup ...Scalable*Soup) = scale(sum($a $b) inv@count($a $b));

max(Ordered ...Ordered) → Ordered

Returns the maximum, i.e. the biggest argument.

max(1, 4, 5, 6, 2, 3); # 6

Source

max(Ordered) = $a;
max(Ordered Ordered) = switch(ord($a $b) $b $a);
max(Ordered Ordered Ordered ...Ordered) = max(max($a $b) $c $d);

median(Ordered Ordered) → Ordered

Returns the lower median of all arguments.

median(1, 4, 5, 6, 2, 3); # 3

Source

median(Ordered ...Ordered) = pick(mid@sort(ord $a $b) 1);

min(Ordered ...Ordered) → Ordered

Returns the minimum, i.e. the smallest argument.

min(1, 4, 5, 6, 2, 3); # 1

Source

min(Ordered) = $a;
min(Ordered Ordered) = switch(ord($a $b) $a $b);
min(Ordered Ordered Ordered ...Ordered) = min(min($a $b) $c $d);

Trigonometric

cos(Angle+Float)

Returns the cosine of the given angle or of the given number.

cos(30°); # 1/2\3

Source

cos(Angle) = sin@add($a 1/4t);
cos(Float) = mul(add(exp@mul($a !i) exp@mul($a !-i)) !0.5);

cot(Angle)

Returns the cotangent of the given angle or of the given number.

cot(30°); # \3

Source

cot(Angle+Float):not@zero@sin($a) = inv(tan($a));

crd(Angle)

Returns the chord of the given angle. This is a historically significant trigonometric function. Not so much today.

crd(30°); # -1/2\2+1/2\6

Source

crd(Angle) = mul(2 sin@scale($a 1/2));

sin(Float)

Returns the sine of the given number. Note that sin is also a core function for angular arguments, so you can compute the sine of an angle just as well.

sin(0.5235987755982989); # !0.5

Source

sin(Float) = mul(sub(exp@mul($a !-i) exp@mul($a !i)) !0.5i);

tan(Angle+Float)

Returns the tangent of the given angle or of the given number.

tan(30°); # 1/3\3

Source

tan( 1/16t) = -1+\2;
tan( 3/16t) =  1+\2;
tan( 5/16t) = -1-\2;
tan( 7/16t) =  1-\2;
tan( 9/16t) = -1+\2;
tan(11/16t) =  1+\2;
tan(13/16t) = -1-\2;
tan(15/16t) =  1-\2;
tan(Angle+Float)
: not@zero@cos($a)
: not@in($a {1/16t, 3/16t, 5/16t, 7/16t, 9/16t, 11/16t, 13/16t, 15/16t})
= div(sin($a) cos($a));

Miscellaneous

float(Float+Circ) → Float+Circ

Converts numbers and angles to floating-point approximations. This loses precision, but the representation of a floating-point number can often provide a better feeling for the magnitude of a number. It may also reveal a familiar sequence of decimal digits.

float(2549491779/811528438); # !3.141592653589793

Source

float(Float+Circ) = $a;

The conversion of an argument happens implicitly to meet the function's parameter type. The function itself does nothing except for returning its input as output.


Get minified source code!