#+tanco-format: 0.2
This file catalogs all K primitives and their proposed English names for implish. Each primitive shows examples from the K language (oK manual) for reference.
> plus[3; 4 5 6] 7 8 9 > plus["ab"; 5] 102 103
Dyadic + is addition. Fully atomic.
> flip [1 2; 3 4] [[1, 3] [2, 4]] > flip [5; 3 4] [[5, 3] [5, 4]]
Monadic +: is transpose/flip. Takes the transpose of matrices.
Atoms are spread to match the dimension of other columns.
> minus[23 9; 5 10] 18 -1
Dyadic - is subtraction. Fully atomic.
> negate 4 -10 8 -4 10 -8 > negate "b" -98
Monadic -: flips the sign of numbers. Right atomic.
> times[5 0 -3; 2 2 1] 10 0 -3
Dyadic * is multiplication. Fully atomic.
> first 5 19 8 5
Monadic *: extracts the first element of a list.
> first :[`a 23; `b 34] 23
NOTE: K dictionaries use [a:val; b:val] syntax. Implish may use different dictionary syntax.
This extracts the first value from a dictionary.
> divide[2 20 9; 0.5 10 2] 4 2 4.5
Dyadic % is division. Fully atomic.
> sqrt 25 7 100 5 2.6457513110645907 10
Monadic %: is square root. Right atomic.
> mod[3; 34 2 8] 1 2 2
Dyadic ! with positive left arg is modulo. Right atomic.
> div[-3; 5 6 27] 1 2 9
Dyadic ! with negative left arg divides y by x and truncates. Right atomic.
> map[`a `b; 3 4] :[`a 3; `b 4] > map[4 5; 6 7] [4 5 ! 6 7]
Dyadic ! can make a dictionary from x keys and y value(s).
NOTE: May not translate directly to implish dictionary syntax.
> int 5 0 1 2 3 4 > int -3 -3 -2 -1
Monadic !: generates a range from 0 up to but excluding N.
If N is negative, count up and exclude zero.
(NOTE: Already implemented as ! in implish)
> int 2 3 [0 0 0 1 1 1, 0 1 2 0 1 2]
Monadic !: on a list generates ranged permutations (odometer/cartesian product).
> keys :[`a 3; `b 4] `a `b
Monadic !: on a dictionary returns list of keys.
NOTE: Depends on implish dictionary implementation.
> less[2 3 5; 1 0 6] 0 0 1
Dyadic < tests less-than. Fully atomic. Returns boolean (0 or 1).
> asc 5 8 2 7 2 0 3 1
Monadic <: is “grade up” or ascending sort indices.
Generates a permutation vector which would sort argument into ascending order.
> asc :[`a 2; `b 5; `c 1] `c `a `b
Monadic <: on dictionaries sorts keys by their values.
> more[2 3 5; 1 0 6] 1 1 0
Dyadic > tests greater-than. Fully atomic. Returns boolean (0 or 1).
> desc 5 8 2 7 1 3 0 2
Monadic >: is “grade down” or descending sort indices.
Generates a permutation vector which would sort argument into descending order.
> desc :[`a 2; `b 5; `c 1] `b `a `c
Monadic >: on dictionaries sorts keys by their values (descending).
> equal[3 4 6; 6] 0 0 1
Dyadic === tests equality. Fully atomic. Returns boolean (0 or 1).
> group `c `a `b `b `a `c `a :[`c 0 5; `a 1 4 6; `b 2 3]
Monadic : generates a dictionary from items to the indices where they were found.
NOTE: Depends on implish dictionary implementation.
> identity-matrix 3 [1 0 0, 0 1 0, 0 0 1]
Monadic : on a number generates an NxN identity matrix.
> min[3 5 7; 0 6 9] 0 5 7
Dyadic & is minimum. Fully atomic. For booleans, effectively logical AND.
> where 2 3 1 0 0 1 1 1 2 > where 1 0 0 1 0 1 0 3 5
Monadic &: makes N copies of sequential indices.
For boolean lists, gathers indices of nonzero elements.
> where map[`a `b `c; 1 0 2] `a `c `c
Monadic &: indexes dictionary keys by where of values.
> max[3 5 7; 0 6 9] 3 6 9
Dyadic | is maximum. Fully atomic. For booleans, effectively logical OR.
> reverse "ABDEF" "FEDBA"
Monadic |: reverses a list.
> reverse :[`a 3; `b 4] :[`b 4; `a 3]
Monadic |: reverses both keys and values in a dictionary.
> match[(`a; 2 3 4); (`a; 2 3)] 0 > match[(`a; 2 3 4); (`a; 2 3 4)] 1
Dyadic ~ tests if x and y are recursively identical.
Returns 1 if they match exactly, 0 otherwise.
> not [0 1; 3 7 -1] [1 0, 0 0 0]
Monadic ~: is logical not. Nonzero numbers become 0, zero becomes 1. Right atomic.
> not :[`a [2, 0]; `b 1] :[`a [0, 1]; `b 0]
Monadic ~: applies to the values of dictionaries.
> concat[1; 2 3] 1 2 3 > concat[2; 3] 2 3 > concat[1; nil] 1
Dyadic , joins together lists or atoms to produce a list.
> concat[:[`a 1; `b 3]; :[`b 5; `c 7]] :[`a 1; `b 5; `c 7]
Concatenating dictionaries favors values of y (right argument).
> enlist 1 2 3 [1 2 3]
Monadic ,: places item in a 1-length list (enlistment).
> count 4 7 10 3 > count "c" 1
Monadic #: counts elements. Atoms have count 1.
> count :[`a 3; `b 17] 2
Monadic #: counts key-value pairs in dictionaries.
> take[2; "ABC"] "AB" > take[6; "ABC"] "ABCABC" > take[-2; "ABC"] "BC"
Dyadic # truncates or repeats y to produce a list of length x.
Negative x takes from the end of y.
> take["fb"; map["fab"; 3 5 9]] map["fb"; 3 9]
Dyadic # selects elements from dictionary keyed in x.
NOTE: Not yet implemented. The take function currently only handles integer counts.
Need to extend take to handle string/list of keys as left argument when right is dictionary.
> reshape[3 2; 1 2 3] [1 2, 3 1, 2 3] > reshape[3 2 2; 1 2 3] [[1 2, 3 1] [2 3, 1 2] [3 1, 2 3]]
Dyadic # with list left argument creates arbitrary dimensioned result.
Produces strands (INTs/NUMs/SYMs) at the innermost level for vector inputs.
> reshape[0N 3; int 6] [0 1 2, 3 4 5] > reshape[2 0N; int 8] [0 1 2 3, 4 5 6 7]
If leading or trailing element of a length-2 rank vector is 0N,
reshape treats that dimension as maximal. Produces strands at the innermost level.
> filter[{mod[2; x]}; int 8]
1 3 5 7
> filter[{min / x}; (1 0 1 1; 1 1; 0 1 0; 1 2 1)]
(1 1; 1 2 1)
> filter[{match[x; reverse x]}; ("racecar"; "nope"; "bob")]
("racecar"; "bob")
Dyadic # with monadic function m filters list by applying m to each element.
Equivalent to at[l; where each[m; l]].
NOTE: Not yet implemented. Requires adverbs (each, /) and higher-order function support.
> filter[{mod[2; x]}; map["abcdef"; 2 3 4 5 6 7]]
map["bdf"; 3 5 7]
Dictionaries are filtered by their values and result in dictionaries. NOTE: Not yet implemented. Depends on filter being implemented first.
> drop[3; "ABCDE"] "DE" > drop[-3; "ABCDE"] "AB"
Dyadic _ removes x elements from the start of y.
Negative x drops from the end.
> drop[`b `e; map[`a `b `c; 3 5 9]] map[`a `c; 3 9]
Dyadic _ filters out keys from a dictionary.
NOTE: Not yet implemented. The drop function currently only handles integer counts.
Need to extend drop to handle list of keys as left argument when right is dictionary.
> cut[0 4; "feedface"] ["feed" "face"] > cut[1 2 4; "feedface"] ["e" "ed" "face"]
Dyadic _ with list of indices splits y at those indices.
Indices must be ascending.
> filter-out[{mod[2; x]}; int 8]
0 2 4 6
> filter-out[{min / x}; (1 0 1 1; 1 1; 0 1 0; 1 2 1)]
(1 0 1 1; 0 1 0)
> filter-out[{match[x; reverse x]}; ("racecar"; "nope"; "bob")]
("nope")
Dyadic _ with monadic function m filters out elements where m returns truthy.
Equivalent to at[l; where not each[m; l]].
NOTE: Not yet implemented. Requires adverbs and higher-order function support.
> filter-out[{mod[2; x]}; map["abcdef"; 2 3 4 5 6 7]]
map["ace"; 2 4 6]
Dictionaries are filtered-out by their values. NOTE: Not yet implemented. Depends on filter-out being implemented first.
> floor 2.3 7.6 9 -2.3 2 7 9 -3
Monadic _: is floor function. Right atomic.
> lowercase "ABCdef!" "abcdef!"
Monadic _: converts characters to lowercase. Right atomic.
> null? [5; `; 0N] 0 1 1
Monadic ^: tests if item is null. Right atomic.
Returns 1 for null values (` or 0N), 0 otherwise.
> except[1 3 2 5 1 2 3; 1 3 5] 2 2
Dyadic ^ removes all instances of each item in y from x.
> fill["c"; [5; `; 0N]] [5 "c" "c"]
Dyadic ^ replaces all nulls in y with x.
> distinct [[`a `b]; 3; [`a `b]; 7; 3] [[`a `b] 3, 7]
Monadic ?: produces a list of unique elements.
> random-floats 6 0.197 0.8382 0.1811 0.9084 0.6113 0.1958
Monadic ?: on a number produces x random floats from 0 up to but excluding 1.
(Note: actual values will vary)
NOTE: Not yet implemented. Need to add random-floats function.
> find["XYZ"; "XYXZB"] 0 1 0 2 0N
Dyadic ? determines the index of y in x. Returns 0N if not found. Right atomic.
For strings, treats them as character arrays.
> find[map[`a `b `c `d; 23 14 9 5]; 9 14] `c `b
Dyadic ? on dictionaries looks up the key associated with the value y. Right atomic.
> random[5; 10] 0 3 3 7 7 > random[5; 10] 3 5 2 7 9
Dyadic ? with numbers produces x random integers from 0 up to but excluding y.
(Note: actual values will vary)
NOTE: Not yet implemented. Need to add random number generation.
> random-pick[8; "ABC"] "ACBBCBCB"
Dyadic ? picks x random elements from list y.
(Note: actual values will vary)
NOTE: Not yet implemented. Depends on random being implemented first.
> random-chars[10; "A"] "GHIJKLMNOP" > random-chars[10; "0"] "0123456789"
Dyadic ? with character picks random elements from the 26 characters including and up from that char.
(Note: actual values will vary)
NOTE: Not yet implemented. Depends on random being implemented first.
> random-distinct[-5; 10] 3 7 1 9 2 > random-distinct[-8; "ABC"] "CABCABCA"
For n ? n or n ? l, if x is negative, pick abs(x) distinct items.
(Note: actual values will vary)
NOTE: Not yet implemented. Depends on random being implemented first.
> type `a -11 > type "d" -10 > type nil 0
Monadic @: returns a magic number indicating the type of the noun.
General lists are 0, listy things are positive, non-listy things are negative.
> at[3 7 8; 0 1 1] 3 7 7 > at[negate; 5] -5
Dyadic @ indexes a list or applies single argument to a function.
Invalid indices produce 0N.
NOTE: Function application works for built-in functions but not yet for implish functions (would need evaluator context).
> at[map[`a `b; 4 7]; `a] 4
Dyadic @ indexes a dictionary. Invalid keys produce nil (which doesn’t print in REPL; K would produce 0N).
> string 120 4 ["120" "4"] > string `beef "beef"
Monadic $: converts atoms into strings. Right atomic.
> pad[5; "beef"] "beef " > pad[-7; "beef"] " beef"
Dyadic $ adjusts strings to x characters long.
Under length: right-pad with spaces. Over length: strip from end.
Negative x pads/strips from left.
NOTE: Current implementation only handles single strings, not lists of strings with different padding lengths.
> cast[`i; "Hello."] 72 101 108 108 111 46 > cast[`c; 72 101 108 108 111 46] "Hello." > cast[`f `i `b; 31] [31, 31, 1]
Dyadic $ converts values to different types based on a symbol. Fully atomic.
Conversion symbols: `c (char), `i (int), `f (float), `b (bool), ` (str to sym).
> value "1 + 2" 3
Monadic .: evaluates implish expressions from strings.
> value map[`a `b; 11 22] 11 22
Monadic .: gives the values of a dictionary.
> value {plus[x; y]}
[in: {match[x; y]; not null find[y; x]}]
Monadic .: gives the bound environment of a function as a dictionary (oK-specific).
NOTE: Not yet implemented. This is oK-specific functionality that may not apply to implish.
> dot-apply[[2 3; 4 5]; 1 0]
4
> dot-apply[{concat[x; times[2; y]]}; 3 5]
3 10
Dyadic . indexes at depth or applies a list of arguments to a function.
NOTE: Not yet implemented. Need to add dot-apply for deep indexing and function application.
> f: bind[{a +:: x}; map[`a; 100]]
{[x] a::. `a plus x}
> at[f; 5]
105
> at[f; 20]
125
> value f
map[`a; 125]
Dyadic . treats the dictionary as new global scope for function (oK-specific).
NOTE: Not yet implemented. This is oK-specific functionality for binding closures.
> each[{times[2; x]}; 5 7 2]
10 14 4
Monadic ' applies the monad to each element, producing a new list.
If x is an atom, this is equivalent to at[m; a].
> each2[{concat[x; times[2; y]]}; 2 7 9; 1 3 4]
[2 2, 7 6, 9 8]
> each2[concat; 5; 1 3 4]
[5 1, 5 3, 5 4]
Dyadic ' pairs up values from x and y and applies them to the dyad.
If x or y is an atom, spread it to the elements of the other sequence.
> eachprior[equal; 3 3 4 4 5] 0 1 0 1 0 > eachprior[minus; 1 3 5 2 9] 1 2 2 -3 7 > eachprior[concat; 2 3 4] ((2); (3 2); (4 3))
Dyadic ': applies dyad to each element (left) and preceding element (right).
First element paired with 0N, or special initial values for plus, times, minus, min (0, 1, 0, first element).
Comma concat provided with only 1 parameter for first element.
> eachprior[concat; 99; 2 3 4] (2 99; 3 2; 4 3)
Dyadic ': with atom left specifies explicit initial value for eachprior.
> stencil[{over[join; string x]}; 3; 11 22 33 44]
("112233"; "223344")
Monadic ': with number applies monad to overlapping windows of specified size.
Convenience for “each window”.
> eachright[concat; 2 3; 4 5 6] (2 3 4; 2 3 5; 2 3 6)
Dyadic /: applies dyad to entire left argument and each right argument.
> eachleft[concat; 2 3; 4 5 6] (2 4 5 6; 3 4 5 6)
Dyadic \: applies dyad to each left argument and entire right argument.
> over[plus; 4 5 2] 11
Dyadic / is fold/reduce. Applies dyad left-to-right, carrying result forward.
Special initial values for empty lists: plus → 0, times → 1, max → -∞, min → +∞.
> over[plus; 4; 5 2] 11
Dyadic / with initial value x applies fold starting from x.
> fixedpoint[{divide[floor x; 2]}; 32]
0
Monadic / repeatedly applies monad until value stops changing or repeats initial value.
> for[enlist; 5; 7] (((((7)))))
Monadic / with number applies monad x times.
> while[{less[x; 100]}; {times[x; 2]}; 1]
128
Monadic / with two monads applies right monad while left monad returns true.
> scan[plus; 4 5 6] 4 9 15
Dyadic \ is scan. Like over/fold, but accumulates intermediate results.
> scan[times; 2; 3 2 9] 6 12 108
Dyadic \ with initial value x starts scan from x.
Note: initial value not included in results.
> scan-fixedpoint[{divide[floor x; 2]}; 32]
32 16 8 4 2 1 0
> scan-fixedpoint[{mod[3; plus[1; x]]}; 2]
2 0 1
Monadic \ repeatedly applies monad until stops changing, accumulating results.
> scan-for[enlist; 5; 7] (7; (7); ((7)); (((7))); ((((7)))); (((((7))))))
Monadic \ with number applies monad x times, accumulating results.
> scan-while[{less[x; 100]}; {times[x; 2]}; 1]
1 2 4 8 16 32 64 128
Monadic \ with two monads applies while condition true, accumulating results.
> bin[0 2 4 6 8 10; 5] 2 > bin[0 2 4 6 8 10; -10 0 4 5 6 20] -1 0 2 2 3 5
Dyadic ' with list left argument performs binary search for y in x.
x must already be sorted. Right atomic.
> join["|"; ["a"; "bc"; "def"]] "a|bc|def"
Dyadic / with character/string joins strings with separator.
NOTE: Use square brackets for lists in implish.
> encode[2 2 2; 1 0 1] 5 > encode[10 10 10; 3 4 5] 345
Dyadic / combines digits y in base x into single value.
> split[","; "cat,dog,banana"] ["cat" "dog" "banana"]
Dyadic \ breaks string y at instances of character x.
> decode[2 2 2; 5] 1 0 1 > decode[10 10 10; 345] 3 4 5
Dyadic \ splits number y into base x representation.
> window[3; int 5] [0 1 2, 1 2 3, 2 3 4] > window[2; int 5] [0 1, 1 2, 2 3, 3 4]
Dyadic ': creates sliding window of length x from y.
If x < 0: equivalent to window[3; concat[0; concat[y; 0]]].
If x = 0: equivalent to reshape[plus[1; count y]; nil].
> splice[1 2 3; 1 1; 4] 1 4 2 3 > splice["test"; 1 3; "u"] "tut" > splice["hello world"; 0 5; "goodbye"] "goodbye world"
Ternadic ? replaces elements in interval [start end] with value.
NOTE: May require special parsing in implish.
> splice[2 7 9; 1 2; times[2]] 2 14 9 > splice["a look back"; 2 6; reverse] "a kool back"
If third arg is monadic function, applies to interval instead of replacing.
NOTE: K uses {times[2; x]} lambda syntax, implish uses partial application times[2].
> try[plus; [1; 2]] [0, 3] > try[plus; [`a; 2]] [1 "expected number or vector, got: SYM"]
Calls function with args, catches errors.
Returns [0; result] on success, [1; error-message] on failure.
NOTE: K uses {plus[1; x]} lambda syntax with single arg (1). Implish uses plus with arg list [1; 2].
> cond[1; "A"; 0; "B"; "C"] "A" > cond[0; "A"; 0; "B"; "C"] "C"
The symbol $ with 3+ arguments is cond (like Lisp cond).
Considers arguments in pairs: if first is truthy, return second. Else continue.
If no conditions match, return final value.
NOTE: Already described in ok-manual but under special section, not verbs.
Truthy: anything except 0, 0x00, or nil.
> sin 0 0.5 3.141 0 0.479425538604203 0.0005926535550994539
Monadic sin calculates sine. Atomic.
> cos 0 0.5 3.141 1 0.8775825618903728 -0.9999998243808664
Monadic cos calculates cosine. Atomic.
> exp 1 5 12 2.718281828459045 148.4131591025766 162754.79141900392
Monadic exp calculates exponential (e^x). Atomic.
> log 2.7183 5 10 1.0000066849139877 1.6094379124341003 2.302585092994046
Monadic log calculates natural logarithm. Atomic.
> prm "AB" ["AB" "BA"] > prm 3 [0 1 2, 0 2 1, 1 0 2, 1 2 0, 2 0 1, 2 1 0]
Monadic prm generates all permutations of items in list.
If x is a number, treats as int x.
> in[1 3 7; 1 2 3 4 5] 1 1 0
Dyadic in tests membership. Is x a member of y? Left-atomic.
Once the English-named primitives are implemented, add these symbol aliases:
+alias forplus+:alias forflip-alias forminus-:alias fornegate*alias fortimes*:alias forfirst%=alias for =divide%:alias forsqrt!alias formod/div/map(ambivalent based on left arg sign)!:alias forint/odometer/keys(ambivalent based on arg type)
<alias forless<:alias forasc>alias formore>:alias fordesc- === alias for
equal - ==:= alias for
group/identity-matrix(ambivalent based on arg type)
&alias formin&:alias forwhere|alias formax|:alias forreverse~alias formatch~:alias fornot
,alias forconcat,:alias forenlist#alias fortake/reshape/filter(ambivalent based on arg types)#:alias forcount_alias fordrop/cut/filter-out(ambivalent based on arg types)_:alias forfloor/lowercase(ambivalent based on arg type)
^alias forexcept/fill(ambivalent based on left arg)^:alias fornull?alias forfind/random/random-pick(ambivalent)?:alias fordistinct/random-floats(ambivalent)
@alias forat@:alias fortype$alias forpad/cast(ambivalent)$:alias forstring.alias fordot-apply/bind(ambivalent).:alias forvalue
'(each, each-dyad, bin)':(eachprior, stencil, window)/(over, fixedpoint, for, while, join, encode)\(scan variants, split, decode)/:(eachright)\:(eachleft)