-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathk9.info
4889 lines (3650 loc) · 119 KB
/
k9.info
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
This is k9.info, produced by texi2any version 6.8 from k.manual.texi.
April 15, 2023
Copyright (C) 2020 John Estrada
File: k9.info, Node: Top, Next: Introduction, Up: (dir)
k9: Manual
**********
This manual is for Shakti (k9) build 2023.03.09.
The Shakti programming language is the work of Arthur Whitney and the team at Shakti. The language comes from a lineage of similar languages going back to APL. It's also known as k9 given the
similarities to k, k2, ..., k6, k7 and the fact that Arthur also wrote those. k9 is still under development so expect a bit of syntax change and likely even more improvements.
Learning k9 means code like '{x@(!#x)+\!#y}' is clear and actually prefered to something much longer and verbose. You'll have to go a bit down the rabbit hole before it starts to come together but once
it does you'll probably be happy you gave it a chance and end up learning a few things. You'll understand how fast k9 can be in processing and analyzing data and how terse code is less likely to
contain errors. Unfortunately you will be less likely to be content using more bloated and slow frameworks.
Alas this manual is not as elegant as the k9 language in that the text version of this document is almost as big as the binary of the language.
The built-in reference screen ('\') containing all the k9 commands.
select *note count:: *note first:: last min max sum avg var dev .. by ..
in n_(rand) n@(multiply) n?(divide) n@n?(bar)
Verb monad Ad*note verb: Verb. Type
+ + ' *note each:: *note char:: " ab"
- - / *note over: cover. sym ``ab
* * \ *note scan: cscan. *note bool:: 011b
% *note div:: *note int:: 2 3 4
! *note mod:: *note where:: *note System:: float 2 3e4
& & *note flip:: *note \l: load. load -fixed 2.0 3.4
| | *note reverse:: *note \t: timing. time -locus -74::40.7
< < *note asc:: *note \v: variables. vars *note z.d:: *note date:: 2001.02.03
> > *note desc:: \w work *note z.t:: *note time:: 12:34:56.789
= = freq *note z.T:: *note datetime::
~ ~ ~
, , ,
# *note take:: *note count:: I/O Class
_ *note drop:: *note first:: 0' line *note expr: Expression. :2+a
^ *note cut:: *note sort:: 1' char/stdout *note func: User Functions. f[a] 2+a
@ @ *note type:: 2' data/stderr
? *note find:: unique *3' set *note list: List. (2;3.4)
$ *note parse:: *note str:: *4' get *note dict: Dictionary. {a:2 3}
. *note dict:: *note value:: *5' *note ffi:: *note table: Tables. [a:2 3]
* Menu:
* Introduction:: An introduction to shakti/k9, a novel computer language for data analysis
* Verb:: Elementary functions
* Adverb:: Function modifiers
* Noun:: Basic data types
* List:: Uniform and non-uniform lists
* Dictionary:: Dictionaries and functions for dictionaries
* User Functions:: User-defined functions
* Expression:: Expression Evaluation
* Named Functions:: Named functions
* Knit Functions:: Function to modify lists and dictionaries
* I/O:: Input and output
* FF:: Foreign functions
* Tables:: Tables to store data
* kSQL:: kSQL to query tables
* System:: System functions and measurements
* Control Flow:: If/Do/While Statements
* Temporal Functions:: Functions for date and time
* Errors:: Error messages
* Examples:: A Short Finance Example + Practice Decomposing Other People's Code
* Benchmark:: Learn how fast this language is
* Conclusion:: Conclusion
File: k9.info, Node: Introduction, Next: Verb, Prev: Top, Up: Top
1 Introduction
**************
The k9 programming language is designed primarily for the analysis of data. It may surprise new users with two rather different paradigms, (1) fast data analysis and (2) concise syntax. After you
become familiar with the language, these features will both seem normal and intuitive. Also, going back to slow and verbose programming will be surprisingly difficult.
1.1 Going fast
==============
Imagine you have a small, on-disk, 100 million row database containing a time-series with two float values at each time. Additionally this data could be split in three different tables covering
different measurements. Here's how fast k9 can read in the data from disk and compute a statistic, average difference over each table, which uses each and every row.
This section requires 2: a feature only in the enterprise version of Shakti. If that is not available then use the section below with 1:
bash-3.2$ ./k
2021.xx.xx 17GB 4core (c) shakti
\t q:2:`q;{select s:avg a-b from x}'q[!q]
884
That's 884 ms to read the data in from disk and compute over all the 100 million values. The data read is the biggest bit. If the data were already in memory then the computation would be faster:
\t {select s:avg a-b from x}'q[!q]
217
217 ms, not bad for 100 million calculations.
The code to generate the on-disk database is presented below. Speed of course will depend on your hardware so times will vary.
nf:d+*|d:(|-d),d:683 954 997 1000;
T:^`t ?[;_8.64e7]@
B:100++\1e-2*-3+nf bin/:?[;*|nf]@
S:?[;1e-2*2,2,8#1]@
L:{select t,b,a:b+s from +`t`b`s!(T;B;S)@'x}
q:`eurusd`usdjpy`usdchf!L'_60e6 20e6 20e6
`q 2:q
This section requires 1: a feature in all versions of Shakti.
bash-3.2$ ./k
2021.xx.xx 17GB 4core (c) shakti
\t select s:avg a-b from q:`csv?1:"q.csv"
832
That's 832 ms to read the data in from disk and compute over all the 10 million values. The data read and csv conversion process are the biggest bits.
Here is the code to generate the q.csv on-disk file. Note in this example only 10 million lines are generated versus the 100 million lines in the previous example using 2:
nf:d+*|d:(|-d),d:683 954 997 1000;
T:^`t ?[;_8.64e7]@
B:100++\1e-2*-3+nf bin/:?[;*|nf]@
S:?[;1e-2*2,2,8#1]@
L:{select t,b,a:b+s from +`t`b`s!(T;B;S)x́}
q:L[_10e6]
"q.csv"1:`csv@q
"q.csv"
1.2 Going concise
=================
The k9 language is more closely related to mathematics syntax than most programming lanauges. It requires the developer to learn to "speak" k9 but once that happens most find an ability to speak
quicker and more accurately in k9 than in other languages. At this point an example might help.
In mathematics, "3+2" is read as "3 plus 2" as you learn at an early age that "+" is the "plus" sign. For trival operations like arithmetic most programming languages use symbols also. When moving
beyond arithmetic, most programming lanauges switch to words while k9 remains with symbols. As an example, to determine the distinct values of a list most programming languages might use a syntax like
'distinct()' while k9 uses '?'. This requires the developer to learn how to say a number of symbols but once that happens it results in much shorter code that is quicker to write, easier to inspect,
and easier to maintain.
This should not be surprising. In arithmetic, which do you find easier to understand?
/ math with text
Three plus two times open parenthesis six plus fourteen close parenthesis
/ math with symbols
3+2*(6+14)
In code, if you're new to k9 then it's unlikley you can understand the second example.
/ code with text
x = (0,12,3,11,3);y=5;
distinct_x = list(set(x));
sorted(i for i in distinct_x if i >= y)
/ code with symbols
x:0 12 3 11 3;y:5;
z@&y<z:?x
When you first learned arithmetic you likely didn't have a choice. Now you have a choice whether or not you want to learn k9. If you give it a try, then you'll likely get it quickly and move onto the
power phase fast enough that you'll be happy you gave it a chance.
1.3 Get k9.
===========
<https://shakti.com>
k9 is available in two versions, standard (under download) and enterprise. The enterprise version has additional features indicated on the k9 help page and also indicated in this tutorial.
Once downloaded you will need to change the file mode with the following commmand
chmod +x k
On the mac if you then attempt to run this file you likely won't succeed due to MacOS security. You'll need to go to "System Preferences..." and then "Security and Privacy" and select to allow this
binary to run. (You'll have to have tried and failed to have it appear here automatically.)
On linux (and macos if you have installed npm) one can download k from the command line via
npm i @kparc/k -g
1.4 Help / Info Card
====================
Typing '\' in a terminal window gives you a concise overview of the language. This document aims to provide details to beginning user where the help screen is a bit too terse. Some commands are not
available in the basic version and thus marked with an asterisk, eg. *4: https get.
select count first last min max sum avg var dev .. by ..
in n_(rand) n@(multiply) n?(divide) n@n?(bar)
Verb monad Adverb Type
+ + ' each char " ab"
- - / over sym ``ab
* * \ scan bool 011b
% div int 2 3 4
! mod where System float 2 3e4
& & flip \l load -fixed 2.0 3.4
| | reverse \t time -locus -74::40.7
< < asc \v vars z.d date 2001.02.03
> > desc \w work z.t time 12:34:56.789
= = freq z.T datetime
~ ~ ~
, , ,
# take count I/O Class
_ drop first 0' line expr :2+a
^ cut sort 1' char/stdout func f[a] 2+a
@ @ type 2' data/stderr
? find unique *3' set list (2;3.4)
$ parse str *4' get dict {a:2 3}
. dict value *5' ffi table [a:2 3]
1.5 rlwrap
==========
Although you only need the 'k' binary to run k9 most will also install rlwrap, if not already installed, in order to get command history in a terminal window. rlwrap is "Readline wrapper: adds readline
support to tools that lack it" and allows one to arrow up to go through the command buffer history.
In order to start k9 you should either run 'k' or 'rlwrap k' to get started. Here I will show both options but one should run as desired. In this document lines with input are shown with a leading
space and output will be without. In the examples below the user starts a terminal window in the directory with the 'k' binary file. Then the users enters 'rlwrap ./k <RET>'. k9 starts and displays
the date of the build, (c), and shakti and then listens to user input. In this example I have entered the command to exit k9, '\\'. Then I start k9 again without rlwrap and again exit the session.
rlwrap ./k
Sep 13 2020 16GB (c) shakti
\\
./k
Sep 13 2020 16GB (c) shakti
\\
1.6 REPL
========
k9 runs as a read, evaluation, print loop (REPL). This means that one either programs in an interactive programming environment (eg. a shell/terminal window) or by running a script. There is no reason
to compile code into an executable.
1.7 Simple example
==================
Here I will start up k9, perform some trivial calculations, and then close the session. After this example it will be assumed the user will have a k9 session running and working in repl mode. Comments
('/') will be added to the end of lines as needed. One can review *note plus::, *note where::, *note floor:: and *note timing:: as needed.
1+2 / add 1 and 2
3
!5 / generate a list of 5 integers from 0 to 4
0 1 2 3 4
1+!5 / add one to each element of the list
1 2 3 4 5
!_100e6; / generate a list of 100 million integers (suppress output with ;)
1+!_100e6; / do 100 million sums
\t 1+!_100e6 / time the operations in milliseconds
82
Now let's exit the session.
\\
bash-3.2$
1.8 Document formatting for code examples
=========================================
This document uses a number of examples to familiarize the reader with k9. The syntax is to have input with a leading space and output without a leading space. This follows the terminal syntax where
the REPL input has space but prints output without.
3+2 / this is input
5 / this is output
1.9 k9 idiosyncracies
=====================
One will need to understand some basic rules of k9 in order to progress. These may seem strange at first but the faster you learn them, the faster you'll move forward. Also, some of them, like
overloading based on number of arguments, add a lot of expressability to the language.
1.9.1 Colon (':') is used to set a variable to a value
------------------------------------------------------
'a:3' is used to set the variable, a, to the value, 3. 'a=3' is an equality test to determine if a is equal to 3.
1.9.2 Percent ('%') is used to divide numbers
---------------------------------------------
Yeah, 2 divided by 5 is written as '2%5', not '2/5'. This choice is because '%' is similar to ÷, and the \ and / symbols are used elsewhere.
1.9.3 Evaluation is done right to left
--------------------------------------
2+5*3 is 17 and 2*5+3 is 16. 2+5*3 is first evaluated on the right most portion, 5*3, and once that is computed then it proceeds with 2+15. 2*5+3 goes to 2*8 which becomes 16.
1.9.4 There is no arithmetic order
----------------------------------
+ has equal precedence as *. The order of evaluation is done right to left unless parenthesis are used. (2+5)*3 = 21 as the 2+5 in parenthesis is done before being multiplied by 3.
1.9.5 Operators are overloaded depending on the number of arguments.
--------------------------------------------------------------------
*(13;6;9) / single argument: * returns the first element
13
2*(13;6;9) / two arguments: * is multiplication
26 12 18
1.9.6 Lists and functions are very similar.
-------------------------------------------
k9 syntax encourages you to treat lists and functions in a similar function. They should both be thought of a mapping from a value to another value or from a domain to a range. Lists and functions do
not have the same type.
l:3 4 7 12
f:{3+x*x}
l@2
7
f@2
7
@l
`I
@f
`.
1.9.7 k9 notions of Noun, Verb, and Adverb
------------------------------------------
k9 uses an analogy with grammar to describe language syntax. The k9 grammar consists of nouns (data), verbs (functions) and adverbs (function modifiers).
* The boy ate an appple. (Noun verb noun)
* The girl ate each olive. (Noun verb adverb noun)
In k9 as the Help/Info card shows data are nouns, functions/lists are verbs and modifiers are adverbs.
* 3 > 2 (Noun verb noun)
* 3 >' (1 12;1 4 5) (Noun verb adverb noun)
File: k9.info, Node: Verb, Next: Adverb, Prev: Introduction, Up: Top
2 Verbs
*******
This chapter covers verbs which are the core primitives of k9. Given how different it is to call functions in k9 than in most other languages, you may have to read this chapter a few times. Once you
can "speak" k9 you'll read '|x' better than 'reverse(x)'.
Most functions are overloaded and change depending on the number of arguments. This can confuse new users. Eg. '(1 4)++(2 3;5 6;7 8)' contains the plus symbol once as flip and then for addition.
(Remember evaluation is right to left!)
Verb monad
+ +
- -
* *
% *note div::
! *note mod:: *note where::
& & *note flip::
| | *note reverse::
< < *note asc::
> > *note desc::
= = *note freq::
~ ~ ~
, , ,
# *note take:: *note count::
_ *note drop:: *note first::
^ *note cut:: *note sort::
@ @ *note type::
? *note find:: *note unique::
$ *note parse:: *note str::
. *note dict:: *note value::
2.1 plus => x+y
===============
Add x and y. Arguments can be elements or lists but if both x and y are lists then they must be of equal length.
3+7
10
a:3;
a+8
11
3+4 5 6 7
7 8 9 10
3 4 5+4 5 6
7 9 11
3 4+1 2 3 / lengths don't match
!length
10:00+1 / add a minute
10:01
10:00:00+1 / add a second
10:00:01
10:00:00.000+1 / add a millisecond
10:00:00.001
2.2 negate => -x.
=================
-3
-3
--3
3
x:4;
-x
-4
d:`a`b!((1 2 3);(4 5 6))
-d
a|-1 -2 -3
b|-4 -5 -6
2.3 minus => x-y.
=================
Subtract y from x.
5-2
3
x:4;y:1;
x-y
3
2.4 first => _x
===============
Return the first value of x.
_1 2 3
1
_((1 2);(3 4);(5 6))
1 2
__((1 2);(3 4);(5 6))
1
_`a`b.((1 2 3);(4 5 6))
1 2 3
_|1 2 3
3
2.5 times => x*y
================
Mutliply x and y.
3*4
12
3*4 5 6
12 15 18
1 2 3*4 5 6
4 10 18
2.6 sqrt => %x
==============
Return the square root of x.
%25
5.000e+00
%14.4
3.794e+00
2.7 div => x'%'y
================
Divide x by y.
12%5
2.400e+00
6%2
3.000e+00
2.8 mod => x!y
==============
The remainder after y divided by x using integer division. x and y must be integers.
12!27
3
5!22
2
2.9 where => !x
===============
Given a list of boolean values return the non-zero indices.
!00110011b
2 3 6 7
"banana"="a"
010101
!"banana"="a"
1 3 5
x@!30<x:12.7 0.1 35.6 -12.1 101.101
3.560e+01 1.011e+02
2.10 flip => &x
===============
Flip, or transpose, x where x is list of 2 or more dimensions.
x:(1 2;3 4;5 6);x
(1 2;3 4;5 6)
&x
(1 3 5;2 4 6)
`a`b.&x
{a:1 3 5;b:2 4 6}
&`a`b.&x
[a:1 3 5;b:2 4 6]
Given a list of boolean values return a list of indices where the value is zero (index 0) and non-zero (index 1).
&00110011b
(0 1 4 5;2 3 6 7)
"banana"="a"
010101
&"banana"="a"
(0 2 4;1 3 5)
x@&30<x:12.7 0.1 35.6 -12.1 101.101
(1.270e+01 0.100e+00 -1.210e+01;3.560e+01 1.011e+02)
Given a list of non-binary values, return the ascending sorted indices.
& 4 1 2 -3 4 1
(,3;1 5;,2;0 4)
&`a`b`a`d
(0 2;,1;,3)
&"blue red greeen"
(4 8;,0;,7;3 6 11 12 13;,9;,1;,14;5 10;,2)
& 2023.01.01 2023.01.02 2023.01.01
(0 2;,1)
2.11 and => x&y
===============
The smaller of x and y. One can use the over adverb to determine the min value in a list.
3&2
2
1 2 3&4 5 6
1 2 3
0 1 0 0 1 0&1 1 1 0 0 0
0 1 0 0 0 0
`a&`b
`a
&/ 3 2 10 -200 47
-200
2.12 reverse => |x
==================
Reverse the list x.
|0 3 1 2
2 1 3 0
|"banana"
"ananab"
|((1 2 3);4;(5 6))
(5 6;4;1 2 3)
To get the last element, one can take the first element of the reverse list (*|`a`b`c).
2.13 or => x|y
==============
The greater of x and y. Max of a list can be determine by use of the adverb over.
3|2
3
1 2 3|4 5 6
4 5 6
1 0 1 1 0 1|0 0 0 1 1 1
1 0 1 1 1 1
|/12 2 3 10 / use over to determine the max of a list
12
2.14 asc(desc) => < (>) x
=========================
Sort a list or dictionary in ascending (<) or descending (>) order. Applied to a list, these will return the indices to be used to achieve the sort.
<5 7 0 12
2 0 1 3
x@<x:5 7 0 12
0 5 7 12
d:`a`b`c!3 2 1;d
a|3
b|2
c|1
<d / a dictionary is sorted by value
c|1
b|2
a|3
2.15 less (more) => x < (>) y
=============================
Return true (1b) if x is less (more) than y else false (0b).
3<2
0b
2<3
1b
1 2 3<4 5 6
1 1 1
((1 2 3);4;(5 6))<((101 0 5);12;(10 0)) / size needs to match
1 0 1
1
1 0
"a"<"b"
1b
2.16 freq=> =x
==============
Freq takes a list of uniform type, x, and returns a dictionary of the distinct values (key) and their number of occurences (value).
="banana"
abn.3 1 2
=0 1 0 2 10 7 0 1 12
0 1 2 7 10 12.3 2 1 1 1 1
2.17 equal => x=y
=================
Return true (1b) if x is equal to y else false (0b).
2=2
1
2=3
0
2=2.
1
"banana"="abnaoo" / check strings of equal length by character
0 0 1 1 0 0
"banana"="apple" / unequal length strings error
!length
2.18 not => ~x
==============
Boolean invert of x
~1
0
~1 0 1
0 1 0
~37 0 12
0 1 0
2.19 match => x~y
=================
Return true (1) if x matches y else false (0). A match happens if the two arguments evaluate to the same expression.
2~2
1
2~3
0
2~2.
0
"banana"~"apple"
0
`a`b~`a`b / different than = which is element-wise comparison
1
`a`b=`a`b
1 1
f:{x+y}
f~{x+y}
1
2.20 enlist => ,x
=================
Create a list from x
,3
,3
,1 2 3
1 2 3
3=,3
,1
3~,3
0
2.21 cat => x,y
===============
Concatenate x and y.
3,7
3 7
"hello"," ","there"
"hello there"
C:("ab";"c";("def";"ghi"));C
ab
c
("def";"ghi")
,/C / join the list once
a
b
c
def
ghi
,//:C / converge over join until single list
"abcdefghi"
2.22 sort => ^x
===============
Sort list, dictionary, or table x into ascending order. Dictionaries are sorted using the keys and tables by the first column field. One can sort tables by arbitrary columns by first reordering the
columns in the table using *note take:: or by extracting the sort column by index or expression.
^0 3 2 1
0 1 2 3
^`b`a!((0 1 2);(7 6 5)) / sort dictionary by key
[a:7 6 5;b:0 1 2]
^[[]z:`c`a`b;y:3 2 1] / sort table by 1st col
z y
- -
a 2
b 1
c 3
^`y`z#[[]z:`c`a`b;y:3 2 1] / sort table by new 1st col
y z
- -
1 b
2 a
3 c
2.23 [f]cut => x^y
==================
Cut list y by size, indices, or function x. Also, cut table y into key x and value.
action x
*note rows: cut1. positive int
*note columns: cut2. negative int
*note indices: cut3. list
*note function: cut4. function
*note table: cut5. column
Positve integer x, cut y into x rows
3^101+!18 / 3 rows
101 102 103 104 105 106
107 108 109 110 111 112
113 114 115 116 117 118
Negative integer, cut y into x elements per row
-3^101+!18 / 3 columns
101 102 103
104 105 106
107 108 109
110 111 112
113 114 115
116 117 118
Positive integer array x, cut at each element in x
2 3 7 ^!17 / left list indicates start number of each row.
,2
3 4 5 6
7 8 9 10 11 12 13 14 15 16
8 9 10 11 12^.1*!20
,0.8
,0.9
,1.
,1.1
1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
Function returning boolean array, cut at each index where f is non-zero.
{(x*x)within .5 1.5}^.1*!20
0.8
0.9
1.
1.1
1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9
Table returning utable (aka keyed table).
t:[[]a:`x`y`z;b:1 20 1];t / an unkeyed table
a b
- --
x 1
y 20
z 1
kt:`a^t;kt / set `a as the key
a|b
-|--
x| 1
y|20
z| 1
2.24 count => #x
================
Count the number of elements in list, dictionary, or table x.
#0 1 2 12
4
#((0 1 2);3;(4 5))
3
#`a`b!((1 2 3);(4 5 6)) / count the number of keys
2
#5 / single element is 1
1
2.25 [f]take => x#y
===================
[f]take has a number of different actions depending on x. These include head (take from front of list), tail (take from back of list), common (take common elements), filter (take where function is
non-zero), and select (take columns from table).
action x y
*note head: take1. positive int list
*note tail: take1. negative int list
*note common: take2. list list / dictionary
*note filter: take3. function list
*note select: take4. name(s) table
Postive (negative) x returns the first (last) x elements of y. If abs[x]>count[y] then repeatedly pull from y.
3#0 1 2 3 4 5 / take first 3 elements of a list
0 1 2
10 # 17 12 25 / take repeat: take from list and repeat as needed
17 12 25 17 12 25 17 12 25 17
-3#0 1 2 3 4 5 / take last elements of a list
3 4 5
If x and y are lists, then take returns any values common in both x and y. If x is a list and y is a dictionary, then take returns those values in y where the keys are in x.
(1 2 3 7 8 9)#(2 8 20) / common
2 8
(2 4 6 2 6 5 4) # (4 6 7 8 2 4 4 4) / substring of right argument
4 6 2 4 4 4
(4 6 7 8 2 4 4 4) # (2 4 6 2 6 5 4)
2 4 6 2 6 4
`b`d#`a`b`c`d!1 4 2 3
b|4
d|3
If x is a function, then select the values where the function is non-zero.
(0.5<)#10?1. / select values greater than 0.5
0.840732 0.5330717 0.7539563 0.643315 0.6993048f
If x is a name or list of names, then take the name column or columns from the table.
t:[[]x:`a`b`c;y:3 1 2;z:"tab"];t
x y z
- - -
a 3 t
b 1 a
c 2 b
`y#t
y
-
3
1
2
`z`y#t
z y
- -
t 3
a 1
b 2
`x`z`y#t
x z y
- - -
a t 3
b a 1
c b 2
2.26 floor => _x
================
Return the integer floor of float x.
_3.7
3
2.27 [f]drop => x_y
===================
[f]drop has a number of different actions depending on x. This include de-head (drop from front of list), de-tail (drop from back of list), uncommon (drop common elements), and filter (drop where
function is zero).
action x y
*note dehead: drop1. positive int list
*note detail: drop1. negative int list
*note uncommon: drop2. list list / dictionary
*note filter: drop3. function list
Postive (negative) x drops the first (last) x elements of y.
3_0 1 2 3 4 5 / drop first three
3 4 5
-2_0 1 2 3 4 5 / drop last two
0 1 2 3
If x and y are lists, then drop returns any values from y not found in x. If x is a list and y is a dictionary, then drop returns those values in y where the keys are not in x.
(1 2 3 7 8 9)_(2 8 20) / uncommon
,20
`b`d_`a`b`c`d!1 4 2 3
a|1
c|2
If x is a function, then select values where the function is zero.
(0.5<)_10?1. / values less than or equal to 0.5
0.02049699 0.1269226
2.28 str => $x
==============
Cast x to string.
$`abc
"abc"
$4.7
"4.7"
2.29 parse => x$y
=================
Parse string y into type x.
`i$"23"
23