ktour.txt 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. 1 + 1 / basic arithmetic can be done with infix notation
  2. 5 * 7
  3. 2 - 4
  4. 3 % 2 / division is done with % since / serves other purposes like the beginning of a comment! :D
  5. 2 ! 37 / This is 37 modulo 2. Note that the modulus is on the left. (explanation to follow .. maybe)
  6. 3 * 4 + 1 / evaluation happens from right to left. There is no precedence between operations.
  7. 3 * (4 + 1)
  8. (3 * 4) + 1 / Use parentheses when you want to control the order of evaluation
  9. 1 2 3 + 3 0 2 / rank polymorphism means these operations work for vectors of equal length
  10. 1 2 + 3 0 2 / you get an error if these vectors are not equal length
  11. 1 + 3 0 2 / by scalar extension however, you can add scalars to vectors.
  12. / it's as if the scalar were repeated until the necessary length
  13. # 9 8 4 5 / length counts the length of a vector
  14. / unlike the previous examples, # takes one argument. single arguments are always taken to the right
  15. 2 4 , 9 0 4 / concat joins two vectors
  16. # 2 4 , 9 0 4
  17. #2 4,9 0 4 / spaces around built-in functions (called verbs in the lingo) are not necessary
  18. / but we'll use them here occasionally for a bit longer
  19. ,1 / enlist puts its argument in a list
  20. / this shows the meaning of "," is overloaded. this happens a bunch in k, but often the meanings are related
  21. # ,1 / this is a list of length 1
  22. # 1 / hmm... scalars have length?? take this on faith for now that this comes in handy
  23. @ 1 / @ returns the type of its argument, this is an "int".
  24. / oh, verbs which take one argument are called "monadic" and ones which take two "dyadic"
  25. @ ,1 / this is a list of ints. Capitals indicate lists. (lists, vectors, same thing)
  26. ,3 7 9 / You can enlist a list
  27. # ,3 7 9 / this is a list of length 1
  28. * 3 7 9 / this takes the "head" of the list. i.e. the first element.
  29. / (not related to multiplication but another case of overloading)
  30. *,3 7 9 / the head of an enlisted list is ... the list. makes sense.
  31. (,1 2 3),(,3 5 0) / the concat of two enlisted lists to form a list of lists
  32. (1 2 3;3 5 0) / (Parens around semi-colon separated items form explicit lists)
  33. #(,1 2 3),(,3 5 0) / .. of length two
  34. (,1 2 3), ,3 5 0 / the parentheses on the right are not necessary because of right-to-left evaluation
  35. (0 1 3;99;6 1) / explicit lists need not be uniform (neither length nor type)
  36. @"string" / strings are lists (capital C) of chars.
  37. @"s" / a single char is also surrounded with double quotes. (this can be a bit confusing at first)
  38. @,"s" / to get a list of a single char, use enlist
  39. ("n";"i";"c";"e") / double quotes are just syntactic sugar to make lists of chars.
  40. "o","k" / Oh yeah! Concat can also concatenate two scalars
  41. "s","tring" / ... or a scalar to a vector. Note that scalar extension does *not* apply here.
  42. ("o";,"k";4 9 2) / An even more mixed array
  43. #'("o";,"k";4 9 2) / verbs can be modified to perform derived functionality
  44. / here ' (called each) modifies length to perform length on each of the elements of its list argument
  45. ,'4 5 6 / each is called an adverb and can be applied to other verbs
  46. / enlist each element of 4 5 6 to get a list of three one-element lists
  47. 3 9 2,'-1 -4 0 / each can be applied to dyadic verbs and pairs up the elements of both args
  48. 0,'3 4 1 / scalar extension applies to such pairing as well
  49. 0,/:3 4 1 / but there is a more explicit way to indicate that the left argument stays the same
  50. / this adverb is called eachright
  51. 1 0,/:3 4 1 / It's useful when scalar extension doesn't apply
  52. 1 0,\:3 4 1 / There is an eachleft as well.
  53. / Are we having fun yet??
  54. / More verbs!
  55. !8 / enumerate numbers from 0 up to (but not including) 8
  56. #!8
  57. 3#!8 / "take" the first three number of this list
  58. 3_!8 / "drop" the first three numbers of this list
  59. -3#!8 / negative numbers to take from the back of the list
  60. -3_!8
  61. 9=3 / just plain equals. true is 1 and false is 0.
  62. 3=3
  63. 4=!6 / oho! scalar extension
  64. 0 1 2=!3 / and rank polymorphism!
  65. 0 1 2~!3 / match. i.e. check that the whole vector is the same
  66. (0;1 2 3)~(9=3;1+!3) / even for mixed vectors
  67. (0;1 2 3)=(9=3;1+!3) / rank polymorphism applies to ragged shapes as well. shapes must match (clearly)
  68. 3>4 / plain old greater than
  69. 3<4
  70. ~3=3 / monadic ~ is not
  71. ~3>4 / less than or equal to is just not greater than.
  72. ~3>3
  73. @7%3 / oh, yeah. floats are not ints
  74. _7%3 / floor strips off everything after the decimal point
  75. @_7%3 / .. and converts to ints
  76. _7 / floor of an int is fine
  77. -_-7%3 / There is no ceiling, but this emoji does the trick
  78. _"Hey, Dan!" / lower case for strings. (similar-ish..)
  79. %25 / monadic % is square root
  80. -35 / this is just an integer
  81. -(4 8 5) / this is the negate verb applied to a list
  82. -4 8 5 / this is just a list of integers
  83. -:4 8 5 / a colon forces this to be treated as a monadic function
  84. / Notice that this monadic function applies to each element of the list unlike length (#)
  85. / (colon has many more tricks up its sleeve...)
  86. |-:4 8 5 / this is that list reversed
  87. -4|8 / maximum of -4 and 8 (clearly no relation to the monadic reverse above)
  88. -4&8 / minimum of -4 and 8
  89. ("abc";!3) / the "matrix" made of the rows "abc" and !3.
  90. / lists of lists of equal length can be thought of a matrices
  91. +("abc";!3) / flip! The transpose of that matrix. Again matrices must have rows of equal length.
  92. ("car";37;1 3 4)[0] / this long and no mention of array indexing??
  93. ("car";37;1 3 4)[0 2] / indices can be lists
  94. ("car";37;1 3 4)[0 0] / lists can have repeats
  95. 1 4 9[2] / no need for explicit list notation
  96. 1 4 9[(0;2 1;(,1;0))] / more generally, indices can be any shape
  97. / the result matches the shape of the indices and picks out the values at the given index
  98. 1 4 9@(0;2 1;(,1;0)) / brackets are just syntactic sugar for the @ verb (called amend)
  99. 1 4 9[1 3] / outdexing results in a null
  100. ^1 4 9[1 3] / ^ tests for null
  101. 99^1 4 9[1 3] / With a value (atom/scalar) to the left fills all nulls with that value
  102. / More adverbs!
  103. +/3 5 9 / slash as an adverb is "left fold" with the accumulator starting as the first element.
  104. / Note here that the verb + is dyadic, but the derived verb +/ is used monadically
  105. 10+/3 5 9 / used dyadically, the left arg becomes the initial value for the accumulator
  106. / slashes used as comments must be preceded with a space
  107. / slashes used as adverbs must *not* be preceded by a space
  108. |/-4 8 5 / this is "max over". I.e. the fold of max over the list -4 8 5
  109. |-4 8 5 / again, this is reverse
  110. |:-4 8 5 / this forces | to be read as its monadic form
  111. +\3 5 9 / the adverb scan is like fold, but produces all of its intermediate results
  112. 10+\3 5 9 / when using an explicit initial accumulator, the inital value is not part of the results
  113. +':9 4 2 / pairs up each element of its list with the prior element and applies the verb. ': is called each-next.
  114. / the first element is left as is
  115. 1+':9 4 2 / but you can supply a seed value to pair it with.
  116. 1-':9 4 2 / Note that the prior element becomes the right arg of the verb
  117. / There are a couple of funky adverbs which modify non-verbs, which we'll call nouns
  118. " "\"Yo yo yo" / Split takes a string and splits the argument it's given by it.
  119. / Actually here it's technically taking the *character* " ", but that works too
  120. "--"\"Yo--yo--yo"
  121. " "/("Hey"; "you") / Join takes an array of strings as its argument
  122. 10\12345 / Encode represents the given number as digits with the given base
  123. 2\13
  124. 10/9 8 7 / Decode calculates the value of a list of digits in the given base
  125. 2/1 0 1 1 0 1
  126. 24 60 60/1 2 3 / The base for each digit need not be the same
  127. / Note that because of how this works, the top base is irrelevant, but needed to match the number of digits
  128. -2 60 60/1 2 3
  129. 10 10\976 / For encode, if you supply a list of bases instead of a scalar,
  130. / you always get as many digits as the length of that list
  131. 2 2 2 2 2\5
  132. 0 2 2 2\134 / If the top base is zero, it just returns whatever is left over after decoding the other digits
  133. 2/0 2 2 2\134
  134. / Back to verbs for a bit...
  135. 8#1 2 / Take can take more items than the list provided in which case it just cycles through
  136. 5#2 / You can even give take a scalar to simply repeat the value
  137. (5#2)\5 / Once again, parentheses are needed here because evaluation is from right-to-left
  138. 6 5#1 2 / You can even use a vector with take to generate lists of lists, one row at a time
  139. / In this case it's often called "reshape" but the idea is the same
  140. 2 5_!10 / Drop with a vector becomes "cut". The vector is split at the given indices and the first part is dropped.
  141. 0 3 7_!10 / To keep the first part, just make 0 the first element of the vector
  142. &0 0 1 0 1 1 / Given a boolean list, where (&) gives the indices of the 1's
  143. &1 0 2 3 0 4 / Actually, this is just a special case of "replicate" which generates a given number of repeats at the given index
  144. / Here there is 1 zero, no ones, two twos, three threes, etc.
  145. ?&1 0 2 3 0 4 / Monadic ? (distinct) only keeps the first occurence of each element in a list
  146. ? 7 8 2 3 7 1 3
  147. 7 8 2 3 7 1 3?1 / Dyadic ? (find) returns the index of the first occurence of the given element in a list
  148. 7 8 2 3 7 1 3?6 / If not found you get back a null
  149. / Now things get a little tricky..
  150. / Some verbs behave differently when given different types of arguments.
  151. / This is kind of true with reshape and cut, but the behaviors weren't too different
  152. / So this next may seem a bit random ...
  153. 15?3 / Dyadic ? with an integer left argument is "roll".
  154. / It generates that many random numbers from 0 to the right argument
  155. 15?"ace" / If given a list as its right argument, it randomly picks elements from that list
  156. -5?5 / Deal is like roll only it doesn't repeat
  157. ?5 / As a monadic function ? returns values from a uniform distribution
  158. / Phew!! There's a lot here. Grab a hot tea and let some of this sink in a bit.
  159. / Feeling refreshed? Let's introduce a few more types...
  160. (1;"a";3%2) / so far, we've seen ints, chars and floats
  161. @'(1;"a";3%2) / with scalar types `i, `c and `f
  162. / Hmm... What is `i?
  163. @`i / A new type! `s represents the symbol type
  164. @`symbol / Symbols are basically scalar strings. In particular are used to represent types.
  165. @"symbol" / Remember vector types are represented with upper case letters. This is a vector of `c elements.
  166. #`symbol
  167. #"symbol"
  168. @`i`c`f / Vectors of symbols can be represented by listing them one after another
  169. / This is sometimes called "stranding". Stranding is only possible for homogenous types
  170. @1 2 3 5 / This is why vectors of integers can simply be listed one after another
  171. @(`i;`c;`f) / Of course explicit array notation is still possible
  172. @@'(1;"a";3%2)
  173. @'(1 2;"ab";3%2 1;`i`c)
  174. 1 0.3 2 / There is some magic here and there. Here the ints are "promoted" to floats
  175. 1 2 3+4 5 6 / Also, it's worth explicitly noting that stranding binds tighter than any of the verbs
  176. (1;2;3+4;5;6) / This is something different.
  177. 1 2,(3+4),5 6 / You could also make this by building it up with the verb concat.
  178. / The parentheses are necessary because of right to left evaluation
  179. @(1;"a";3%2) / Before we get too far away it's also worth noting that @ operates on the whole array
  180. / This is a single type known as a "mixed array" and is represented by `A
  181. @'(1;"a";3%2) / "each" is needed to operate on each element
  182. #'(1 2;"abcd";3%2 1;`i`c`s`A`C) / similar to length
  183. #(1 2;"abcd";3%2 1;`i`c`s`A`C)
  184. / Over time you get used to which functions do this and which ones "permeate".
  185. / i.e. operate on each element naturally like + or *
  186. / Let's introduce one more type: dictionaries
  187. `a`b`c!3 4 5 / Dictionaries act like association lists and created with dyadic ! operating on two lists of equal length
  188. !`a`b`c!3 4 5 / Monadic ! on a dictionary returns the keys of the dictionary
  189. .`a`b`c!3 4 5 / Monadic . on a dictionary returns the values of the dictionary
  190. (`a`b`c!3 4 5)[`b] / Indexing can be used to extract the value associated with a given key
  191. / It's probably best to start introducing some programming basics before moving on
  192. d:`a`b`c!3 4 5 / : is used for assigning to a variable (We told you colon had more tricks!)
  193. d / See? (This tutorial is running in a single session so this variable is still visible.)
  194. d[`b] / That looks nicer. We've extrated the value out of the dictionary d associated with the key `b
  195. / It may worth noting that variables are not symbols and not strings. They use no punctuation.
  196. i123:1 2 3 / You can use numbers in the name but initial character must be a letter
  197. i123[1]
  198. i123@1 / Remember that you can use @ to index into an array
  199. d@`c / Or even for looking up in a dictionary
  200. i123 1 / You can also just list the two next to each other! (This is *not* stranding!)
  201. d`c / You don't even need a space when it's not ambiguous
  202. i123: / Variables don't go away, but you can (re)assign them to "nothing" if you want to free memory
  203. i:1 2 3 / Different variable
  204. i 1 / Here we need a space because i1 would be a(n undefined!) variable name.
  205. d:`a`b`a!3 4 5 / Dictionaries can be weird. You can repeat keys.
  206. d`a / Only the first one is found with lookup
  207. (!d;.d) / But both original lists are still in the keys and values
  208. / BTW, there is no "iter". Keys and values must be extracted separately
  209. +(!d;.d) / Remember "flip"? This gets the list of key/value pairs
  210. (.d)(!d)?`a / This is basically what dictionary lookups do...
  211. (!d)?`a / This extracts the keys and then uses "find" to find the index of the key
  212. (.d)@(!d)?`a / This extracts the values and uses the previously found index to index into the array
  213. (.d)(!d)?`a / But because there's no ambiguity (really!) you don't need the @ here. It's not stranding so it's indexing.
  214. / The parentheses are needed because of right to left evaluation.
  215. / More programming basics ... and a new type! lambdas!
  216. f:{x} / Lambdas are formed with curly braces. This takes a single arg (x) and returns it.
  217. (f[1];f[`a];f[3%2]) / The lambda can be applied to arguments with brackets similar to array indexing
  218. (f@1;f@`a;f@3%2) / Or with @ ..
  219. (f 1;f`a;f 3%2) / Or even just juxtaposition ..
  220. f'(1;`a;3%2) / lambdas take adverbs just like verbs do
  221. {x+y}[2;3] / Brackets are (generally) necessary when supplying more than one arg
  222. f / Also, lambdas don't have to be assigned to a variable the way f was
  223. f:{x+y};f[1;2];f[3;4] / A semicolon can separate multiple statements on a line. Only the output of the last is printed
  224. f:{x+y};f[1;2]; / A trailing semicolon means the last statement was an "empty statement" and so nothing is printed
  225. {a:x+y;2*a}[1;3] / Multiple statements can of course be used inside a lambda as well
  226. / Kind of difficult to demonstrate in this format, but the semicolon can be replaced by a newline
  227. / only if the following line begins with at least one space.
  228. / E.g. {a:x+y
  229. / 2*a}
  230. / But this also means that the closing brace must be on the last line with a statement
  231. / In this example {a:x+y
  232. / 2*a
  233. / }
  234. / The last line is an empty statement and so prints nothing.
  235. {x*y+z}[2;3;4] / Functions can use up to three implicit arguments which have the names x, y and z
  236. f:{x+y}[2] / If fewer args are supplied than required, a "projection" is formed
  237. @'({x};{x+y}[2]) / Projections are actually a different type, but this doesn't come up that often
  238. f'3 4 5 / Projections basically "curry" the supplied argument
  239. {[a;b;c;d]a+b*c-d} / More than three arguments requires explicit argument declaration with brackets
  240. {[x;y]x+y}[2;3] / This can get noisy for simple stuff which is why implicit args exist
  241. {2*y}[1;3] / If you use an implicit y then the function takes (at least) two arguments, three if there is a z.
  242. {2*y}[7] / This is a projection
  243. {2*y}[7]@6 / When called, passes the argument to y
  244. f:+ / BTW, verbs can be assigned to variables too
  245. f[2;3] / But in this form must use bracket indexing instead of infix notation
  246. @f / Verbs have a different type as well
  247. @f:@ / Assignment can also happen inline. This assigns f and then takes its type. (@ is also a verb!)
  248. :[123;451] / Colon is also a (dyadic) verb which returns its second argument.
  249. / .. but is weird because it's hard to parse which of its various forms is meant in the code
  250. :i:1 2 3 / Here it's used monadically(??) to return the value assigned to i
  251. 123:456 / Here it's used dyadically to return the right argument
  252. :i:1 2 3 / This form is often useful when debugging code.
  253. @f:{x}' / Derived lambdas are yet another type
  254. f(1;"a";3%2;`b)
  255. g:+; 5 g/1 2 3 / Derived lambdas actually can be used infix
  256. g:+/; 5 g 1 2 3 / But only with explicit modifiers. This doesn't work.
  257. g:+; 5g/1 2 3 / Actually here the space before the g here is not necessary
  258. / What haven't we covered?...
  259. <"hello world" / grade! grade returns the indices in an order which sorts the input
  260. s@<s:"hello world" / (Remember we can do assignment inline)
  261. s@>s / Actually that was grade up, grade down gives the indices which sort the other direction
  262. / One subtle point is that this is a "stable ordering"
  263. > 3 17 9 17 / i.e. indices which point to the same value remain in the same relative order
  264. < 3 17 9 17 / so grade down is not simply the reverse of grade up
  265. ::("a";98) / :: is the identity function but can be fiddly because of the many uses of :
  266. (::)"same" / Often it's safest to simply put it in parentheses
  267. :: / It has the unique property that when it's the final value on a line it prints nothing
  268. / Similarly, empty values are replaced with the identity
  269. iden:;iden "me" / Here iden is assigned an "empty" value, which simply means the identity function
  270. "happy"; / This amounts to the nitty gritty behind trailing semicolons inhibiting output
  271. ="hello world" / With a list = returns a dictionary
  272. / whose keys are the distinct elements and values are indices where that element occurs
  273. =5 / With a single integer = returns an identity matrix of that size
  274. {~x}_3 0 4 0 0 6 7 / _ becomes "weed out" with a left argument
  275. {~x}@3 0 4 0 0 6 7 / If we apply the function to the *whole* right argument we see which elements are removed
  276. (~:)_3 0 4 0 0 6 7 / We don't actually need a lambda, but a few extra considerations pop up without one
  277. / First we need to surround the verb with parentheses
  278. / to ensure that we're not trying to apply it
  279. / Technically this makes a *noun* out of the *verb* which is why it isn't applied
  280. / Also, we need to make sure that the function is applied monadically, so we use :
  281. (~:)@3 0 4 0 0 6 7 / Can still test to see which items will be removed
  282. / Here we need @ because its left arg is a noun.
  283. / This is all pretty heady. Mostly you just get used to the pattern.
  284. (~#:)@(,"I";"";"am") / Just to emphasize, the filter function is applied to the *whole* right arg
  285. (~#:')@(,"I";"";"am") / For length, which doesn't "permeate" like not, we'll need each
  286. (~#:')_(,"I";"";"am") / to filter out empty strings
  287. (~~#:')#(,"I";"";"am") / With # (replicate) you can specify which items to keep instead of to remove
  288. (3!)@1+!9 / Only replicate behaves differently when the function returns non-Booleans
  289. (3!)#1+!9 / In this case it replicates each value according to the corresponding integer
  290. &(3!)@1+!9 / This is just like where's (&) behavior, except where acts on indices
  291. l@&(3!)@l:1+!9
  292. (3!)_1+!9 / Such replication doesn't make sense with weed out
  293. !4 3 / With a list on the right enumerate becomes "odometer".
  294. / Essentially cyclically count up the bottom row and "tick" each row
  295. / when the row beneath "turns over"
  296. +!4 3 / Alternatively, the transpose lists all possible "samples" of !:'(4;3)
  297. 4 3#+!4 3 / or lists all coordinates of a matrix of shape 4 3
  298. / Coming round the final turn!!
  299. $(123;`happy) / Monadic $ stringifies its argument. Note this is pervasive.
  300. / i.e. that it converts at the element level and not the array level
  301. 4$$(123;`happy) / With an integer left argument limits to that length, padding on the right as necessary
  302. -4$$(123;`happy) / A negative number pads/chops on the left
  303. `s$"happy" / With a symbol on the left converts the right argument to that type when possible
  304. `s$123 / This errors when it's not possible
  305. `s$"@123=" / (Note you can make symbols of arbitrary strings by using quotes.)
  306. `c$104 97 112 112 121
  307. `i$"happy"
  308. 0+"happy" / Characters actually naturally convert to ints when used in an int context. The value is the ASCII code.
  309. `I$"-123" / Use capital `I to convert the entire string to an integer rather than individual characters.
  310. / I/O!
  311. 1 1:"carpark" / with a left arg prints bytes to the left arg. Here 1 is the file descriptor for stdout
  312. `1:"carpark" / An empty symbol is equivalent to stdout
  313. / See help for other options including printing to a file
  314. `0:("happy";"dog") / 0: can take a list of strings as its right argument
  315. 1:1 / Without a left argument 1:reads bytes (buffered). 1 is the file descriptor for stdin. (type something followed by a return)
  316. / Same for 0: for reading lines, but is terminated by EOF. Tricker to demostrate here.
  317. `k@=5 / There are a handful of functions which are under symbols
  318. / `k is the basically the function used to render K objects in the REPL as strings
  319. `k'=5 / It accepts modifiers as well. Here we render each row of this identity matrix.
  320. `0:`k'=5 / It's useful in this tutorial to break out of the constraints of single line outputs.
  321. disp:`0:`k'
  322. disp@!4 3
  323. disp@+!4 3
  324. disp@4 3#+!4 3
  325. ."3+5" / Monadic . with a string right value is "eval and evaluates the string as if it was run through the REPL.
  326. .`k@(1 2;"ab") / `k is designed to be "round-trippable".
  327. / I.e. evaluating the string generated by applying it to an argument should result in the argument.
  328. "HI, MOM"[1 4 5] / We talked about using brackets for indexing.
  329. "HI, MOM"@1 4 5 / Or alternately using the @ verb.
  330. @["HI, MOM";1 4 5] / You can even use bracket indexing with verbs. Including @ itself!
  331. / But @ is more powerful than your average verb...
  332. @["HI, MOM";1 4 5;_:] / With a third arg, replaces the values at that index with the (monadic) function applied to the corresponding value
  333. / Note that this returns the entire array modified at the given indices.
  334. @[!5;1 3 4;-;7 8 2] / With a fourth arg, does the same only using a dyadic function using the final argument as the right arguments
  335. @[!5;1 3 4;:;7 8 2] / A common use is with : as assignment
  336. @[!5;1 1;+;3 7] / Remember repeat indices are fine.
  337. @[!5;(1;,1);+;(3;,7)] / As are odd structures as long as the shapes match.
  338. / The function is applied at the leaves when descending the structure.
  339. disp @[=5;1 2] / Remembering that matrixes are lists of lists, @ simply picks out elements at that top-level list.
  340. disp m:4 3#!*/4 3 / But sometimes you want to dig deeper than the top-level list
  341. .[m;2 1] / Applied like this . becomes "drill", which picks out elements at the given coordinates
  342. disp.[m;2 1;-:] / Drill can also take a third argument
  343. disp.[m;2 1;*;3] / Or a fourth
  344. disp.[m;(3 1;0 2)] / Unlike @, when the second argument is a list, coordinates are generated by taking the Cartesian product
  345. disp 3 1,/:\:0 2
  346. .[m;,3 1] / If this is a singleton list, this is the same as @
  347. @[m;3 1]
  348. / Heavy stuff.. Let's finish off with a few more control structures.
  349. -2 ! 37 / Before that let's sneak in integer division. This is like modulo but with a negative modulus
  350. -2 2 !\: 37 / They're paired so that divmod can be calculated like so.
  351. / On to control structures...
  352. +\1+2*!10 / We've seen fold and scan which roll up values of a list with an accumulator.
  353. {x+y}\1+2*!10 / As a lambda it would look like this. Note that it takes two arguments and that the accumulator is the x argument
  354. {-2!x}\123678 / What if we tried a "scan" with a function which took only one argument? Like (integer) division by 2?
  355. / Instead of scan we get "converges".
  356. / I.e. the output gets fed back into the input and applied over and over until it stabilizes.
  357. -2!7
  358. -2!3
  359. -2!1
  360. -2!0
  361. -2!0
  362. / So the difference between scan and converges is whether the function its being applied to takes two or one argument
  363. {-2!x}/123678 / There's also "converge" which doesn't produce intermediate results. (not as good for demonstration purposes, though.)
  364. {4!x+1}/1 / Actually converge also stops, when the input matches the original input. I.e. it detects complete cycles.
  365. / {4!x+1}/-1 / This on the other hand, never terminates, because while it cycles it never cycles back to the beginning.
  366. 10{4!x+1}\-1 / A left argument to converges isn't a seed. (That wouldn't make sense.) But if it's an integer, it's a repeat count.
  367. / i.e. similar to converges, but instead of detecting when to stop it does exactly that number of iterations.
  368. {~x=3}{4!x+1}\1 / With a function as a left argument, that function is evaluated with each iteration
  369. / and the process continues so long as that value is not zero.
  370. (::){4!x+3}\-1 / The function need not be a lambda. Here we use the identity function.
  371. {~x=3}{4!x+1}/1 / Of course there are versions of each of these which do not produce intermediate results
  372. / There's more we could talk about, but hopefully this is enough to get you started.
  373. / For more personal interaction, try one of the communities: [[https://k.miraheze.org/wiki/Online_Communities]]
  374. / Happy coding!
  375. / FIN