Stdlang: Python Walkthrough

Published

December 6, 2025

Python Walkthrough

Welcome to the walkthrough of std.lang and it’s interaction with the python runtime. Ideally, the reader should have at least some experience with both clojure and python in order to get the most out of the tutorial as the library allows for seamless interop between a clojure runtime and a python one - whether it is on the server side - node, quickjs, osascript - as well as on the browser and other embedded js environments.

Setup

Let us briefly explore the std.lang transpiler.

std.lang can be used in different ways:

  • generate code for different languages
  • run the code in different runtimes of those languages

To specify a way to use it, we use l/script. This will create a runtime for evaluation.

^:kind/println
(l/script :python
  {:require [[xt.lang.base-lib :as k]
             [xt.lang.base-iter :as it]]})
#rt:lang[:python]

It is now possible to transpile lisp forms to code:

(!.py
  (+ 1 2 3))
"1 + 2 + 3"

If more than one environment is required, l/script+ is a way to create an annex that

In For example, let us define the following two annexes, named :code and :live.

Here we define :code as a way to use the transpiler to generate Python code, but not use it in any runtime.

^:kind/println
(l/script+ [:code :python]
  {:require [[xt.lang.base-lib :as k]
             [xt.lang.base-iter :as it]]})
[nil #rt:lang[:python]]

Here we define :live as a way to use the transpiler go generate Python code, and run it in a Node.js runtime.

^:kind/println
(l/script+ [:live :python]
  {:runtime :basic
   :require [[xt.lang.base-lib :as k]
             [xt.lang.base-iter :as it]]})
[nil #rt.basic[:python :no-server]]

Let us now use these two ways for basic arithmetic.

[ ;; No runtime, just generating code:
 (l/! [:code] (+ 1 2))
 ;; Generating, running in Node.js:
 (l/! [:live] (+ 1 2))]
["1 + 2" 3]

Types

Types - Primitives

Null

form code live
nil
None
nil

Boolean

form code live
true
True
true
false
False
false

Strings

form code live
"3"
"3"
"3"
"Hello World"
"Hello World"
"Hello World"

Numbers

form code live
3
3
3
1.5
1.5
1.5
1.54444444444444
1.54444444444444
1.54444444444444

Regex

form code live
#"^[Hh]ello d$"
#"^[Hh]ello d$"
nil

Types - Collection

Lists

form code live
[1 2 3 4]
[1,2,3,4]
[1 2 3 4]
["hello" ["world"]]
["hello",["world"]]
["hello" ["world"]]

Dicts

form code live
{:a 1, :b 2, :c 3}
{"a":1,"b":2,"c":3}
{"a" 1, "b" 2, "c" 3}
{:a {:b {:c 3}}}
{"a":{"b":{"c":3}}}
{"a" {"b" {"c" 3}}}

Tuples

form code live
(quote (1 2 3 4))
(1,2,3,4)
[1 2 3 4]
(quote ("hello" ["world"]))
("hello",["world"])
["hello" ["world"]]

Tuples

form code live
#{1 4 3 2}
{1,4,3,2}
{1, 2, 3, 4}
#{"hello" "world"}
{"hello","world"}
{'world', 'hello'}

Objects - tab

form code live
(tab ["a" 1] ["b" 2] ["c" 3])
{"a":1,"b":2,"c":3}
{"a" 1, "b" 2, "c" 3}

Types - Checks

Operations

Operations - Assignment

Var

form code live
(do (var x 1) x)
x = 1
x
1

Reassign

form code live
(do (var x 1) (:= x 10) x)
x = 1
x = 10
x
10

Operations - Logic

Negation

form code live
(not true)
not True
false
(not false)
not False
true
(not 1)
not 1
false
(not 0)
not 0
true

Or

form code live
(or 0 false)
0 or False
false
(or 1 false)
1 or False
1
(or 0 true)
0 or True
true

And

form code live
(and 0 false)
0 and False
0
(and 1 false)
1 and False
false
(and 0 true)
0 and True
0

Ternary

form code live
(:? true 1 2)
True and 1 or 2
1
(:? (or 0 0) 1 2)
(0 or 0) and 1 or 2
2

Operations - Math

Addition

form code live
(+ 1 2 3)
1 + 2 + 3
6
(+ 1 10)
1 + 10
11

Subtraction

form code live
(- 10)
-10
-10
(- 10 1.1)
10 - 1.1
8.9
(- 4 3 2 1.1)
4 - 3 - 2 - 1.1
-2.1

Multiplication

form code live
(* 10 20)
10 * 20
200
(* 4 3.3 2.2 1.1)
4 * 3.3 * 2.2 * 1.1
31.944000000000003

Division

form code live
(/ 10)
1 / 10
0.1
(/ 10 20)
10 / 20
0.5
(/ 4 3.3 2.2 1.1)
4 / 3.3 / 2.2 / 1.1
0.5008765339343851

Pow

form code live
(pow 10 2)
10 ** 2
100
(pow 0.5 0.2)
0.5 ** 0.2
0.8705505632961241

Mod

form code live
(mod 1123 7)
1123 % 7
3
(mod 1123 7.1)
1123 % 7.1
1.2000000000000561

Operations - Comparison

Equals

form code live
(== 1 1)
1 == 1
true
(== 1 "1")
1 == "1"
false
(== "hello" "hello")
"hello" == "hello"
true

Not Equals

form code live
(not= 1 2)
1 != 2
true
(not= 1 "1")
1 != "1"
true
(not= "hello" "hello")
"hello" != "hello"
false

Less Than

form code live
(< 1 2)
1 < 2
true
(< 1 1)
1 < 1
false

Less Than Equals

form code live
(<= 1 2)
1 <= 2
true
(<= 1 1)
1 <= 1
true

Greater Than

form code live
(> 3 2)
3 > 2
true
(> 3 3)
3 > 3
false

Greater Than Equals

form code live
(>= 3 2)
3 >= 2
true
(>= 3 3)
3 >= 3
true

Operations - Counter

Increment

form code live
(do (var x 1) (:++ x) x)
x = 1
++x
x
1

Increment By

form code live
(do (var x 1) (:+= x 10) x)
x = 1
x += 10
x
11

Decrement

form code live
(do (var x 5) (:-- x) x)
x = 5
--x
x
5

Decrement By

form code live
(do (var x 5) (:-= x 50) x)
x = 5
x -= 50
x
-45

Multiply By

form code live
(do (var x 5) (:*= x 50) x)
x = 5
x *= 50
x
250

Operations - Bitwise

Bitwise Or

form code live
(b:| 7 8)
7 | 8
15
(b:| 7 7)
7 | 7
7
(b:| 7 0)
7 | 0
7

Bitwise And

form code live
(b:& 7 8)
7 & 8
0
(b:& 7 7)
7 & 7
7
(b:& 7 0)
7 & 0
0

Bitwise Xor

form code live
(b:xor 7 8)
7 ^ 8
15
(b:xor 7 7)
7 ^ 7
0
(b:xor 7 0)
7 ^ 0
7

Bitshift Right

form code live
(b:>> 128 3)
128 >> 3
16

Bitshift Left

form code live
(b:<< 128 3)
128 << 3
1024

Operations - Functions

form code live
(fn [x y] (return (+ x y)))
lambda x,y : x + y
. at 0x7fa0d063fac0>
(do (var hello (fn [x y] (return (+ x y)))) (hello 1 2))
def hello(x,y):
  return x + y
hello(1,2)
3

Operations - Blocks

if block

form code live
(do (var arr [1 2 3 4 5]) (var out) (if (< (x:len arr) 10) (:= out true) (:= out false)) out)
arr = [1,2,3,4,5]
out = None
if len(arr) < 10:
  out = True
else:
  out = False
out
true

cond block

form code live
(do (var arr [1 2 3 4 5]) (var out) (cond (< (x:len arr) 5) (:= out "1") (< (x:len arr) 10) (:= out "2") :else (:= out "3")) out)
arr = [1,2,3,4,5]
out = None
if len(arr) < 5:
  out = "1"
elif len(arr) < 10:
  out = "2"
else:
  out = "3"
out
"2"

while block

form code live
(do (var x []) (var i 0) (while (< i 5) (x:arr-push x i) (:++ i)) x)
x = []
i = 0
while i < 5:
  x.append(i)
  ++i
x

for block

form code live
(do (var arr []) (for [(var i 1) (< i 5) (:++ i)] (x:arr-push arr i)) arr)
arr = []
for i = 1, i < 5, ++i:
  arr.append(i)
arr

case block

form code live
(do (var arr 1) (var out) (case arr 1 (do (:= out 1) (break)) 2 (do (:= out 2) (break))) out)
arr = 1
out = None
switch arr:
  case 1:
    out = 1
    break
  case 2:
    out = 2
    break

out

try/catch block

form code live
(do (var out "hello") (try (throw 1) (catch e (:= out "world"))) out)
out = "hello"
try:
  raise 1
except e:
  out = "world"
out

Base Lib

Base Lib - For

for:array

form code live
(do (var out := []) (k/for:array [e [1 2 3 4]] (if (> e 3) (break)) (x:arr-push out e)) out)
out = []
for e in  1, 2, 3, 4:
  if e > 3:
    break
  out.append(e)
out

for:object

form code live
(do (var out := []) (var obj := {:a 1, :b 2}) (k/for:object [[k v] obj] (x:arr-push out [k v])) out)
out = []
obj = {"a":1,"b":2}
for k, v in  obj.items():
  out.append([k,v])
out

for:index

form code live
(do (var out := []) (k/for:index [i [0 10 2]] (x:arr-push out i)) out)
out = []
for i in range(0,10,2):
  out.append(i)
out

for:return

form code live
(do (var out) (var success (fn [cb] (cb nil "OK"))) (k/for:return [[ret err] (success (x:callback))] {:success (:= out ret), :error (:= out err)}) out)
out = None
def success(cb):
  cb(None,"OK")
try:
  ret = success(None)
  out = ret
except Exception as err:
  out = err
out
{:code
 [nil
  {:lang :python,
   :redirect nil,
   :context :lang/python,
   :runtime :default,
   :module scicloj.stdlang.walkthrough-py,
   :module/internal
   {xt.lang.base-lib k,
    xt.lang.base-iter it,
    scicloj.stdlang.walkthrough-py -},
   :module/primary #{}}],
 :live
 [nil
  {:id "soknqk5z4tgx",
   :layout :full,
   :bench
   {:type :bench/basic,
    :lang :python,
    :program nil,
    :port 44065,
    :host "127.0.0.1",
    :process #object [ProcessImpl],
    :thread #object [CompletableFuture],
    :root-dir "/tmp/4738861588542843198"},
   :process
   {:bootstrap #'rt.basic.impl.process-python/default-basic-client,
    :main {},
    :emit
    {:body
     {:transform
      #'rt.basic.impl.process-python/default-body-transform}},
    :json :full,
    :encode :json,
    :timeout 2000},
   :lifecycle
   {:bootstrap #'rt.basic.impl.process-python/default-basic-client,
    :main {},
    :emit
    {:body
     {:transform
      #'rt.basic.impl.process-python/default-body-transform}},
    :json :full,
    :encode :json,
    :timeout 2000},
   :module scicloj.stdlang.walkthrough-py,
   :lang :python,
   :module/internal
   {xt.lang.base-lib k,
    xt.lang.base-iter it,
    scicloj.stdlang.walkthrough-py -},
   :runtime :basic,
   :context :lang/python,
   :module/primary #{},
   :tag :basic}]}

Base Lib - Util

invoke

form code live
(k/invoke k/add 1 2)
1 + 2
3

unpack

form code live
[(k/unpack [1 2 3]) (k/unpack [4 5 6])]
[*[1,2,3],*[4,5,6]]
[1 2 3 4 5 6]

apply

form code live
(k/apply (fn:> [a b] (+ a b)) [1 2])
(lambda a,b : a + b)(*[1,2])
3

eval

form code live
(k/eval "1+2")
eval("1+2")
3
(k/apply k/eval ["1+2"])
(lambda s : eval(s))(*["1+2"])
3

len

form code live
(k/len "1+2")
len(("1+2"))
3
(k/apply k/len ["1+2"])
(lambda arr : len((arr)))(*["1+2"])
3

cat

form code live
(k/cat "1+2" "+3")
"1+2" + "+3"
"1+2+3"

x:del

form code live
(do (var out {:a 1}) (k/x:del (. out ["a"])) out)
out = {"a":1}
del out["a"]
out
{}

x:shell

form code live
(do (var cb {}) (defn call [] (k/x:shell "ls" cb)) (call))
cb = {}
def call():
  res = __import__("os").system("ls")
  f = cb.get("success")
  if f:
    return f(res)
  else:
    return res
call()
0

x:offset

form code live
(k/x:offset)
0
0

x:offset-rev

form code live
(k/x:offset-rev)
-1
-1

x:offset-len

form code live
(k/x:offset-len 10)
9
9

x:offset-rlen

form code live
(k/x:offset-rlen 10)
10
10

nil?

form code live
(k/nil? "hello")
None == "hello"
false
(k/apply k/nil? ["hello"])
(lambda x : None == x)(*["hello"])
false

not-nil?

form code live
(k/not-nil? "hello")
None != "hello"
true
(k/apply k/not-nil? ["hello"])
(lambda x : None != x)(*["hello"])
true

to-string

form code live
(k/to-string 1)
str(1)
"1"
(k/apply k/to-string [1])
(lambda obj : str(obj))(*[1])
"1"

to-number

form code live
(k/to-number "1.1")
float("1.1")
1.1
(k/apply k/to-number ["1.1"])
(lambda obj : float(obj))(*["1.1"])
1.1

is-string?

form code live
(k/is-string? "1.1")
isinstance("1.1",str)
true
(k/apply k/is-string? ["1.1"])
(lambda obj : isinstance(obj,str))(*["1.1"])
true

is-number?

form code live
(k/is-number? 1.1)
isinstance(1.1,(int,float))
true
(k/apply k/is-number? [1.1])
(lambda obj : isinstance(obj,(int,float)))(*[1.1])
true

is-integer?

form code live
(k/is-integer? 1000)
isinstance(1000,(int))
true
(k/apply k/is-integer? [1000])
(lambda obj : isinstance(obj,(int)))(*[1000])
true

is-boolean?

form code live
(k/is-boolean? false)
bool == type(False)
true
(k/apply k/is-boolean? [false])
(lambda obj : bool == type(obj))(*[False])
true

is-function?

form code live
(k/is-function? (fn [] (return 1)))
callable(lambda : 1)
true
(k/apply k/is-function? [(fn [] (return 1))])
(lambda x : callable(x))(*[lambda : 1])
true

is-array?

form code live
(k/is-array? [1 2 3 4 5])
isinstance([1,2,3,4,5],list)
true
(k/apply k/is-array? [[1 2 3 4 5]])
(lambda x : isinstance(x,list))(*[[1,2,3,4,5]])
true

is-object?

form code live
(k/is-object? {:a 1, :b 2})
isinstance({"a":1,"b":2},dict)
true
(k/apply k/is-object? [{:a 1, :b 2}])
(lambda x : isinstance(x,dict))(*[{"a":1,"b":2}])
true

type-native

form code live
(do [(k/type-native {}) (k/type-native [1]) (k/type-native (fn [])) (k/type-native 1) (k/type-native "") (k/type-native true)])
[
  k.type_native({}),
  k.type_native([1]),
  k.type_native(lambda : None),
  k.type_native(1),
  k.type_native(""),
  k.type_native(True)
]
["object" "array" "function" "number" "string" "boolean"]

type-class

form code live
(do [(k/type-class {}) (k/type-class [1]) (k/type-class (fn [])) (k/type-class 1) (k/type-class "") (k/type-class true)])
[
  k.type_class({}),
  k.type_class([1]),
  k.type_class(lambda : None),
  k.type_class(1),
  k.type_class(""),
  k.type_class(True)
]
["object" "array" "function" "number" "string" "boolean"]

print

form code live
(k/print "hello")
print("hello")
nil
(k/apply k/print ["hello"])
print(*["hello"])
nil

random

form code live
(k/random)
__import__("random").random()
0.6657526038917823
(k/apply k/random [])
(lambda : __import__("random").random())(*[])
0.8339897881765754

now-ms

form code live
(k/now-ms)
round(1000 * __import__("time").time())
1765053039875
(k/apply k/now-ms [])
(lambda : round(1000 * __import__("time").time()))(*[])
1765053039967

Base Lib - Global

!:G

Accesses the global object

form code live
!:G
globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': , '__spec__': None, '__annotations__': {}, '__builtins__': , 'return_encode': , 'return_wrap': , 'return_eval': , 'client_basic': , 'OUT_FN': , 'OUT': {...}, 'xt_lang_base_lib____type_native': , 'xt_lang_base_lib____type_class': }

global-set

form code live
(do (k/global-set "HELLO" 1) (. !:G ["HELLO"]))
globals()["HELLO"] = 1
globals()["HELLO"]
1

global-has?

form code live
(do (k/global-set "HELLO" 1) (k/global-has? "HELLO"))
globals()["HELLO"] = 1
not (None == globals().get("HELLO"))
true

global-del

form code live
(do (k/global-del "HELLO") (k/global-has? "HELLO"))
globals()["HELLO"] = None
not (None == globals().get("HELLO"))
false
{:code
 [nil
  {:lang :python,
   :redirect nil,
   :context :lang/python,
   :runtime :default,
   :module scicloj.stdlang.walkthrough-py,
   :module/internal
   {xt.lang.base-lib k,
    xt.lang.base-iter it,
    scicloj.stdlang.walkthrough-py -},
   :module/primary #{}}],
 :live
 [nil
  {:id "t89mx5bhjsj5",
   :layout :full,
   :bench
   {:type :bench/basic,
    :lang :python,
    :program nil,
    :port 40221,
    :host "127.0.0.1",
    :process #object [ProcessImpl],
    :thread #object [CompletableFuture],
    :root-dir "/tmp/1808390413541181461"},
   :process
   {:bootstrap #'rt.basic.impl.process-python/default-basic-client,
    :main {},
    :emit
    {:body
     {:transform
      #'rt.basic.impl.process-python/default-body-transform}},
    :json :full,
    :encode :json,
    :timeout 2000},
   :lifecycle
   {:bootstrap #'rt.basic.impl.process-python/default-basic-client,
    :main {},
    :emit
    {:body
     {:transform
      #'rt.basic.impl.process-python/default-body-transform}},
    :json :full,
    :encode :json,
    :timeout 2000},
   :module scicloj.stdlang.walkthrough-py,
   :lang :python,
   :module/internal
   {xt.lang.base-lib k,
    xt.lang.base-iter it,
    scicloj.stdlang.walkthrough-py -},
   :runtime :basic,
   :context :lang/python,
   :module/primary #{},
   :tag :basic}]}

Base Lib - String

get-char

form code live
(k/get-char "abc" 0)
ord("abc"[0])
97
(k/apply k/get-char ["abc" 0])
(lambda s,i : ord(s[i]))(*["abc",0])
97

gt-string

form code live
[(k/gt-string "a" "b") (k/gt-string "A" "a")]
["b" < "a","a" < "A"]
[false false]

lt-string

form code live
[(k/lt-string "a" "b") (k/lt-string "A" "a")]
["a" < "b","A" < "a"]
[true true]

split

form code live
(k/split "hello/world" "/")
"hello/world".split("/")
["hello" "world"]
(k/apply k/split ["hello/world" "/"])
(lambda s,tok : s.split(tok))(*["hello/world","/"])
["hello" "world"]

join

form code live
(k/join "/" ["hello" "world"])
"/".join(["hello","world"])
"hello/world"
(k/apply k/join ["/" ["hello" "world"]])
(lambda s,arr : s.join(arr))(*["/",["hello","world"]])
"hello/world"

replace

form code live
(k/replace "hello/world" "/" "_")
"hello/world".replace("/","_")
"hello_world"
(k/apply k/replace ["hello/world" "/" "_"])
(lambda s,tok,replacement : s.replace(tok,replacement))(*["hello/world","/","_"])
"hello_world"

index-of

form code live
(k/index-of "hello/world" "/")
"hello/world".find("/") - 0
5
(k/apply k/index-of ["hello/world" "/"])
(lambda s,tok : s.find(tok) - 0)(*["hello/world","/"])
5

substring

form code live
[(k/substring "hello/world" 3) (k/substring "hello/world" 3 8)]
["hello/world"[3:],"hello/world"[3:8]]
["lo/world" "lo/wo"]

to-uppercase

form code live
(k/to-uppercase "hello")
"hello".upper()
"HELLO"
(k/apply k/to-uppercase ["hello"])
(lambda s : s.upper())(*["hello"])
"HELLO"

to-lowercase

form code live
(k/to-lowercase "hello")
"hello".lower()
"hello"
(k/apply k/to-lowercase ["hello"])
(lambda s : s.lower())(*["hello"])
"hello"

starts-with?

form code live
(k/starts-with? "Foo Bar" "Foo")
k.starts_withp("Foo Bar","Foo")
true

ends-with?

form code live
(k/ends-with? "Foo Bar" "Bar")
k.ends_withp("Foo Bar","Bar")
true

capitalize

form code live
(k/capitalize "hello")
k.capitalize("hello")
"Hello"

decapitalize

form code live
(k/decapitalize "HELLO")
k.decapitalize("HELLO")
"hELLO"

pad-left

form code live
(k/pad-left "000" 5 "-")
k.pad_left("000",5,"-")
"--000"

pad-right

form code live
(k/pad-right "000" 5 "-")
k.pad_right("000",5,"-")
"000--"

pad-lines

form code live
(k/pad-lines (k/join "\n" ["hello" "world"]) 2 " ")
k.pad_lines("\n".join(["hello","world"]),2," ")
"  hello\n  world"

split-long

form code live
(k/split-long "1234567890123456789012345678901234567890123456789012345678901234567890" 4)
k.split_long(
  "1234567890123456789012345678901234567890123456789012345678901234567890",
  4
)
["1234" "5678" "9012" "3456" "7890" "1234" "5678" "9012" "3456" "7890" "1234" "5678" "9012" "3456" "7890" "1234" "5678" "90"]

Base Lib - Encode

b64-encode

form code live
(k/b64-encode "hello")
__import__("base64").b64encode(bytes("hello","utf-8")).decode("utf-8")
"aGVsbG8="
(k/apply k/b64-encode ["hello"])
(lambda s : __import__("base64").b64encode(bytes(s,"utf-8")).decode("utf-8"))(*["hello"])
"aGVsbG8="

b64-decode

form code live
(k/b64-decode "aGVsbG8=")
__import__("base64").b64decode("aGVsbG8=").decode("utf-8")
"hello"
(k/apply k/b64-decode ["aGVsbG8="])
(lambda s : __import__("base64").b64decode(s).decode("utf-8"))(*["aGVsbG8="])
"hello"

json-encode

form code live
(k/json-encode [1 2 {:a [{:b 3}]}])
__import__("json").dumps([1,2,{"a":[{"b":3}]}])
"[1, 2, {\"a\": [{\"b\": 3}]}]"
(k/apply k/json-encode [[1 2 {:a [{:b 3}]}]])
(lambda obj : __import__("json").dumps(obj))(*[[1,2,{"a":[{"b":3}]}]])
"[1, 2, {\"a\": [{\"b\": 3}]}]"

json-decode

form code live
(k/json-decode "[1,2,{\"a\":[{\"b\":3}]}]")
__import__("json").loads("[1,2,{\"a\":[{\"b\":3}]}]")
[1 2 {"a" [{"b" 3}]}]
(k/apply k/json-decode ["[1,2,{\"a\":[{\"b\":3}]}]"])
(lambda s : __import__("json").loads(s))(*["[1,2,{\"a\":[{\"b\":3}]}]"])
[1 2 {"a" [{"b" 3}]}]

json-push

form code live
(k/json-push "[1,2,3]" "4")
"[1,2,3]"[0:(len("[1,2,3]") - 1)] + "," + "4" + "]"
"[1,2,3,4]"
(k/apply k/json-push ["[1,2,3]" "4"])
(lambda json,e : json[0:(len(json) - 1)] + "," + e + "]")(*["[1,2,3]","4"])
"[1,2,3,4]"

json-push-first

form code live
(k/json-push-first "[1,2,3]" "0")
"[" + "0" + "," + "[1,2,3]"[1:]
"[0,1,2,3]"
(k/apply k/json-push-first ["[1,2,3]" "0"])
(lambda json,e : "[" + e + "," + json[1:])(*["[1,2,3]","0"])
"[0,1,2,3]"

Base Lib - Symbol

sym-full

form code live
(k/sym-full "hello" "world")
k.sym_full("hello","world")
"hello/world"

sym-name

form code live
(k/sym-name "hello/world")
k.sym_name("hello/world")
"world"

sym-ns

form code live
[(k/sym-ns "hello/world")]
k.sym_ns("hello/world")
"hello"

sym-pair

form code live
(k/sym-pair "hello/world")
k.sym_pair("hello/world")
["hello" "world"]

Base Lib - Math

Base Lib - Math Basic

eq

form code live
[(k/eq 2 2) (k/eq 2 1)]
[2 == 2,2 == 1]
[true false]
(k/apply k/eq [1 1])
(lambda a,b : a == b)(*[1,1])
true

neq

form code live
[(k/neq 2 2) (k/neq 2 1)]
[2 != 2,2 != 1]
[false true]
(k/apply k/neq [1 1])
(lambda a,b : a != b)(*[1,1])
false

add

form code live
(k/add 1 2)
1 + 2
3
(k/apply k/add [1 2])
(lambda a,b : a + b)(*[1,2])
4

sub

form code live
(k/sub 1 2)
1 - 2
-1
(k/apply k/sub [1 2])
(lambda a,b : a - b)(*[1,2])
-1

mul

form code live
(k/mul 10 10)
10 * 10
100
(k/apply k/mul [1 2])
(lambda a,b : a * b)(*[1,2])
2

div

form code live
(k/div 10 2)
10 / 2
5.0
(k/apply k/div [1 2])
(lambda a,b : a / b)(*[1,2])
0.5

gt

form code live
[(k/gt 2 2) (k/gt 2 1)]
[2 > 2,2 > 1]
[false true]
(k/apply k/gt [1 2])
(lambda a,b : a > b)(*[1,2])
false

lt

form code live
[(k/lt 2 2) (k/lt 1 2)]
[2 < 2,1 < 2]
[false true]
(k/apply k/lt [1 2])
(lambda a,b : a < b)(*[1,2])
true

gte

form code live
[(k/gte 2 2) (k/gte 2 1)]
[2 >= 2,2 >= 1]
[true true]
(k/apply k/gte [1 2])
(lambda a,b : a >= b)(*[1,2])
false

lte

form code live
[(k/lte 2 2) (k/lte 1 2)]
[2 <= 2,1 <= 2]
[true true]
(k/apply k/lte [1 2])
(lambda a,b : a <= b)(*[1,2])
true

neg

form code live
[(k/neg 1) (k/neg 0) (k/neg -1)]
[-(1),-(0),-(-1)]
[-1 0 1]
(k/apply k/neg [1])
(lambda x : -(x))(*[1])
-1

inc

form code live
(k/inc 1)
1 + 1
2
(k/apply k/inc [1])
(lambda x : x + 1)(*[1])
2

dec

form code live
(k/dec 1)
1 - 1
0
(k/apply k/dec [1])
(lambda x : x - 1)(*[1])
0

pow

form code live
(k/pow 2 3)
2 ** 3
8
(k/apply k/pow [5 6])
(lambda base,n : base ** n)(*[5,6])
15625

quot

form code live
(k/quot 20 3)
20 // 3
6
(k/apply k/quot [50 6])
(lambda base,n : base // n)(*[50,6])
8

sqrt

form code live
[(k/sqrt 4) (k/sqrt 1)]
[__import__("math").sqrt(4),__import__("math").sqrt(1)]
[2.0 1.0]
(k/apply k/sqrt [16])
(lambda num : __import__("math").sqrt(num))(*[16])
4.0

exp

form code live
(k/exp 3)
__import__("math").exp(3)
20.085536923187668
(k/apply k/exp [6])
(lambda num : __import__("math").exp(num))(*[6])
403.4287934927351

loge

form code live
(k/loge 3)
__import__("math").log(3)
1.0986122886681098
(k/apply k/loge [6])
(lambda num : __import__("math").log(num))(*[6])
1.791759469228055

log10

form code live
(k/log10 3)
__import__("math").log10(3)
0.47712125471966244
(k/apply k/log10 [6])
(lambda num : __import__("math").log10(num))(*[6])
0.7781512503836436

mod

form code live
(k/mod 20 3)
20 % 3
2
(k/apply k/mod [50 6])
(lambda num,denom : num % denom)(*[50,6])
2

mod-pos

form code live
[(mod -11 10) (k/mod-pos -11 10)]
[-11 % 10,k.mod_pos(-11,10)]
[9 9]

mod-offset

form code live
[(k/mod-offset 20 280 360) (k/mod-offset 280 20 360) (k/mod-offset 280 -80 360) (k/mod-offset 20 -60 360) (k/mod-offset 60 30 360)]
[
  k.mod_offset(20,280,360),
  k.mod_offset(280,20,360),
  k.mod_offset(280,-80,360),
  k.mod_offset(20,-60,360),
  k.mod_offset(60,30,360)
]
[-100 100 0 -80 -30]

Base Lib - Math Checks

zero?

form code live
[(k/zero? 1) (k/zero? 0)]
[1 == 0,0 == 0]
[false true]
(k/apply k/zero? [1])
(lambda x : x == 0)(*[1])
false

pos?

form code live
[(k/pos? 1) (k/pos? 0)]
[1 > 0,0 > 0]
[true false]
(k/apply k/pos? [-1])
(lambda x : x > 0)(*[-1])
false

neg?

form code live
[(k/neg? -1) (k/neg? 0)]
[-1 < 0,0 < 0]
[true false]
(k/apply k/neg? [-1])
(lambda x : x < 0)(*[-1])
true

even?

form code live
[(k/even? 2) (k/even? 1)]
[0 == (2 % 2),0 == (1 % 2)]
[true false]
(k/apply k/even? [-1])
(lambda x : 0 == (x % 2))(*[-1])
false

odd?

form code live
[(k/odd? 2) (k/odd? 1)]
[not (0 == (2 % 2)),not (0 == (1 % 2))]
[false true]
(k/apply k/odd? [-1])
(lambda x : not (0 == (x % 2)))(*[-1])
true

Base Lib - Math Util

abs

form code live
[(k/abs -1) (k/abs 1)]
[abs(-1),abs(1)]
[1 1]
(k/apply k/abs [-1])
(lambda num : abs(num))(*[-1])
1

max

form code live
(k/max 1 2 3 2)
max(1,2,3,2)
3
(k/apply k/max [1 2 3 2])
max(*[1,2,3,2])
3

min

form code live
(k/min 1 2 3 2)
min(1,2,3,2)
1
(k/apply k/min [1 2 3 2])
max(*[1,2,3,2])
3

ceil

form code live
[(k/ceil -1.1) (k/ceil 1.1)]
[__import__("math").ceil(-1.1),__import__("math").ceil(1.1)]
[-1 2]
(k/apply k/ceil [-1.1])
(lambda num : __import__("math").ceil(num))(*[-1.1])
-1

floor

form code live
[(k/floor -1.1) (k/floor 1.1)]
[__import__("math").floor(-1.1),__import__("math").floor(1.1)]
[-2 1]
(k/apply k/floor [-1.1])
(lambda num : __import__("math").floor(num))(*[-1.1])
-2

gcd

form code live
(k/gcd 10 6)
k.gcd(10,6)
2

lcm

form code live
(k/lcm 10 6)
k.lcm(10,6)
30.0

mix

form code live
(k/mix 100 20 0.1 nil)
k.mix(100,20,0.1,None)
92.0

sign

form code live
[(k/sign -10) (k/sign 10)]
[k.sign(-10),k.sign(10)]
[-1 1]

round

form code live
[(k/round 0.9) (k/round 1.1) (k/round 1.49) (k/round 1.51)]
[k.round(0.9),k.round(1.1),k.round(1.49),k.round(1.51)]
[1 1 1 2]

clamp

form code live
[(k/clamp 0 5 6) (k/clamp 0 5 -1) (k/clamp 0 5 4)]
[k.clamp(0,5,6),k.clamp(0,5,-1),k.clamp(0,5,4)]
[5 0 4]

Base Lib - Math Bitwise

bit-and

form code live
(k/bit-and 7 4)
7 & 4
4
(k/apply k/bit-and [7 4])
(lambda a,b : a & b)(*[7,4])
4

bit-or

form code live
(k/bit-or 3 4)
3 | 4
7
(k/apply k/bit-or [3 4])
(lambda a,b : a | b)(*[3,4])
7

bit-xor

form code live
(k/bit-xor 3 5)
3 ^ 5
6
(k/apply k/bit-xor [3 5])
(lambda a,b : a ^ b)(*[3,5])
6

bit-lshift

form code live
(k/bit-lshift 7 1)
7 << 1
14
(k/apply k/bit-lshift [7 1])
(lambda x,n : x << n)(*[7,1])
14

bit-rshift

form code live
(k/bit-rshift 7 1)
7 >> 1
3
(k/apply k/bit-rshift [7 1])
(lambda x,n : x >> n)(*[7,1])
3

bit-count

form code live
[(k/bit-count 16) (k/bit-count 10) (k/bit-count 3) (k/bit-count 7)]
[k.bit_count(16),k.bit_count(10),k.bit_count(3),k.bit_count(7)]
[1 2 2 3]

Base Lib - Math Trigonometry

sin

form code live
[(k/sin (/ 3.14159 4)) (k/sin (/ 3.14159 6))]
[
  __import__("math").sin(3.14159 / 4),
  __import__("math").sin(3.14159 / 6)
]
[0.7071063120935576 0.4999996169872557]
(k/apply k/sin [(/ 3.14159 4)])
(lambda num : __import__("math").sin(num))(*[3.14159 / 4])
0.7071063120935576

cos

form code live
[(k/cos (/ 3.14159 4)) (k/cos (/ 3.14159 6))]
[
  __import__("math").cos(3.14159 / 4),
  __import__("math").cos(3.14159 / 6)
]
[0.7071072502792263 0.8660256249168368]
(k/apply k/cos [(/ 3.14159 4)])
(lambda num : __import__("math").cos(num))(*[3.14159 / 4])
0.7071072502792263

tan

form code live
[(k/tan (/ 3.14159 4)) (k/tan (/ 3.14159 6))]
[
  __import__("math").tan(3.14159 / 4),
  __import__("math").tan(3.14159 / 6)
]
[0.9999986732059836 0.5773496795031555]
(k/apply k/tan [(/ 3.14159 4)])
(lambda num : __import__("math").tan(num))(*[3.14159 / 4])
0.9999986732059836

asin

form code live
[(k/asin 0.5) (k/asin 0.8)]
[__import__("math").asin(0.5),__import__("math").asin(0.8)]
[0.5235987755982989 0.9272952180016123]
(k/apply k/asin [0.5])
(lambda num : __import__("math").asin(num))(*[0.5])
0.5235987755982989

acos

form code live
[(k/acos 0.5) (k/acos 0.8)]
[__import__("math").acos(0.5),__import__("math").acos(0.8)]
[1.0471975511965979 0.6435011087932843]
(k/apply k/acos [0.5])
(lambda num : __import__("math").acos(num))(*[0.5])
1.0471975511965979

atan

form code live
[(k/atan 0.5) (k/atan 0.8)]
[__import__("math").atan(0.5),__import__("math").atan(0.8)]
[0.4636476090008061 0.6747409422235527]
(k/apply k/atan [0.5])
(lambda num : __import__("math").atan(num))(*[0.5])
0.4636476090008061

sinh

form code live
[(k/sinh (/ 3.14159 4)) (k/sinh (/ 3.14159 6))]
[
  __import__("math").sinh(3.14159 / 4),
  __import__("math").sinh(3.14159 / 6)
]
[0.8686700827439109 0.5478529696006316]
(k/apply k/sinh [(/ 3.14159 4)])
(lambda num : __import__("math").sinh(num))(*[3.14159 / 4])
0.8686700827439109

cosh

form code live
[(k/cosh (/ 3.14159 4)) (k/cosh (/ 3.14159 6))]
[
  __import__("math").cosh(3.14159 / 4),
  __import__("math").cosh(3.14159 / 6)
]
[1.324608512978198 1.1402380787801425]
(k/apply k/cosh [(/ 3.14159 4)])
(lambda num : __import__("math").cosh(num))(*[3.14159 / 4])
1.324608512978198

tanh

form code live
[(k/tanh (/ 3.14159 4)) (k/tanh (/ 3.14159 6))]
[
  __import__("math").tanh(3.14159 / 4),
  __import__("math").tanh(3.14159 / 6)
]
[0.6557938245397708 0.4804724379900902]
(k/apply k/tanh [(/ 3.14159 4)])
(lambda num : __import__("math").tanh(num))(*[3.14159 / 4])
0.6557938245397708
{:code
 [nil
  {:lang :python,
   :redirect nil,
   :context :lang/python,
   :runtime :default,
   :module scicloj.stdlang.walkthrough-py,
   :module/internal
   {xt.lang.base-lib k,
    xt.lang.base-iter it,
    scicloj.stdlang.walkthrough-py -},
   :module/primary #{}}],
 :live
 [nil
  {:id "1h7tr8qbhrvqa",
   :layout :full,
   :bench
   {:type :bench/basic,
    :lang :python,
    :program nil,
    :port 37671,
    :host "127.0.0.1",
    :process #object [ProcessImpl],
    :thread #object [CompletableFuture],
    :root-dir "/tmp/14694754997762653566"},
   :process
   {:bootstrap #'rt.basic.impl.process-python/default-basic-client,
    :main {},
    :emit
    {:body
     {:transform
      #'rt.basic.impl.process-python/default-body-transform}},
    :json :full,
    :encode :json,
    :timeout 2000},
   :lifecycle
   {:bootstrap #'rt.basic.impl.process-python/default-basic-client,
    :main {},
    :emit
    {:body
     {:transform
      #'rt.basic.impl.process-python/default-body-transform}},
    :json :full,
    :encode :json,
    :timeout 2000},
   :module scicloj.stdlang.walkthrough-py,
   :lang :python,
   :module/internal
   {xt.lang.base-lib k,
    xt.lang.base-iter it,
    scicloj.stdlang.walkthrough-py -},
   :runtime :basic,
   :context :lang/python,
   :module/primary #{},
   :tag :basic}]}

Base Lib - Collection

Base Lib - Sequence

first

form code live
(k/first [1 2 3])
([1,2,3])[0]
1
(k/apply [k/first [[1 2 3]]])
(lambda arr : arr[0])(*[[1,2,3]])
1

second

form code live
(k/second [1 2 3])
([1,2,3])[1]
2
(k/apply [k/second [[1 2 3]]])
(lambda arr : arr[1])(*[[1,2,3]])
2

nth

form code live
(k/nth [1 2 3] 2)
([1,2,3])[2]
3
(k/apply [k/nth [[1 2 3] 2]])
(lambda arr,i : arr[i])(*[[1,2,3],2])
3

last

form code live
(k/last [1 2 3])
([1,2,3])[len([1,2,3]) + -1]
3
(k/apply [k/last [[1 2 3]]])
(lambda arr : arr[len(arr) + -1])(*[[1,2,3]])
3

second-last

form code live
(k/second-last [1 2 3])
([1,2,3])[len([1,2,3]) + -2]
2
(k/apply [k/second-last [[1 2 3]]])
(lambda arr : arr[len(arr) + -2])(*[[1,2,3]])
2

get-idx

form code live
[(k/get-idx [1 2 3] 1) (k/get-idx [1 2 3] 2)]
[([1,2,3])[1],([1,2,3])[2]]
[2 3]
(k/apply k/get-idx [[1 2 3] 1 nil])
(lambda arr,i,d : arr[i] or d)(*[[1,2,3],1,None])
2

set-idx

form code live
(do (var out := [1 2 3 4 5]) (k/set-idx out 2 5) out)
out = [1,2,3,4,5]
out[2] = 5
out
[1 2 5 4 5]

is-empty?

form code live
[(k/is-empty? nil) (k/is-empty? "") (k/is-empty? "123") (k/is-empty? []) (k/is-empty? [1 2 3]) (k/is-empty? {}) (k/is-empty? {:a 1, :b 2})]
[
  k.is_emptyp(None),
  k.is_emptyp(""),
  k.is_emptyp("123"),
  k.is_emptyp([]),
  k.is_emptyp([1,2,3]),
  k.is_emptyp({}),
  k.is_emptyp({"a":1,"b":2})
]
[true true false true false true false]

Base Lib - Keys

has-key?

form code live
[(k/has-key? {:a 1} "a") (k/has-key? {:a 1} "b")]
[{"a":1}.get("a") != None,{"a":1}.get("b") != None]
[true false]
(k/apply k/has-key? [{:a 1} "a"])
(lambda obj,k : obj.get(k) != None)(*[{"a":1},"a"])
true

del-key

form code live
(do (var out := {:a 1, :b 2}) (k/del-key out "a") out)
out = {"a":1,"b":2}
del out["a"]
out
{"b" 2}

get-key

form code live
[(k/get-key {:a 1} "a") (k/get-key {:a 1} "b")]
[{"a":1}.get("a"),{"a":1}.get("b")]
[1 nil]

get-path

form code live

set-key

form code live
(do (var out := {:a 1, :b 2}) (k/set-key out "a" 5) out)
out = {"a":1,"b":2}
out["a"] = 5
out
{"a" 5, "b" 2}

copy-key

form code live
(do (var out := {}) (k/copy-key out {:a 1} "a") out)
out = {}
out["a"] = ({"a":1})["a"]
out
{"a" 1}
(do (var out := {}) (k/copy-key out {:a 1} ["c" "a"]) out)
out = {}
out["c"] = ({"a":1})["a"]
out
{"c" 1}

swap-key

form code live
(do (var out := {:a 1, :b 2}) (k/swap-key out "a" k/inc) out)
out = {"a":1,"b":2}
out["a"] = (out.get("a") + 1)
out
{"a" 2, "b" 2}

Base Lib - Array

x:arr-push

form code live
(do (var out [1 2 3]) (k/x:arr-push out 4) out)
out = [1,2,3]
out.append(4)
out
[1 2 3 4]

x:arr-pop

form code live
(do (var out [1 2 3]) (k/x:arr-pop out) out)
out = [1,2,3]
out.pop()
out
[1 2]

x:arr-push-first

form code live
(do (var out [1 2 3]) (k/x:arr-push-first out 0) out)
out = [1,2,3]
out.insert(0,0)
out
[0 1 2 3]

x:arr-pop-first

form code live
(do (var out [1 2 3]) (k/x:arr-pop-first out) out)
out = [1,2,3]
out.pop(0)
out
[2 3]

x:arr-insert

form code live
(do (var out [1 2 3]) (k/x:arr-insert out (x:offset 2) "a") out)
out = [1,2,3]
out.insert(2,"a")
out
[1 2 "a" 3]

arr-lookup

form code live
(k/arr-lookup ["a" "b" "c"])
k.arr_lookup(["a","b","c"])
{"a" true, "b" true, "c" true}

arr-every

form code live
[(k/arr-every [1 2 3] k/odd?) (k/arr-every [1 3] k/odd?)]
[
  k.arr_every([1,2,3],lambda x : not (0 == (x % 2))),
  k.arr_every([1,3],lambda x : not (0 == (x % 2)))
]
[false true]

arr-some

form code live
[(k/arr-some [1 2 3] k/even?) (k/arr-some [1 3] k/even?)]
[
  k.arr_some([1,2,3],lambda x : 0 == (x % 2)),
  k.arr_some([1,3],lambda x : 0 == (x % 2))
]
[true false]

arr-each

form code live
(do (var out []) (k/arr-each [1 2 3 4 5] (fn [e] (x:arr-push out (+ 1 e)))) out)
out = []
k.arr_each([1,2,3,4,5],lambda e : out.append(1 + e))
out
[2 3 4 5 6]

arr-omit

form code live
(k/arr-omit ["a" "b" "c" "d"] 2)
k.arr_omit(["a","b","c","d"],2)
["a" "b" "d"]

arr-reverse

form code live
(k/arr-reverse [1 2 3 4 5])
k.arr_reverse([1,2,3,4,5])
[5 4 3 2 1]

arr-find

form code live
(k/arr-find [1 2 3 4 5] (fn:> [x] (== x 3)))
k.arr_find([1,2,3,4,5],lambda x : x == 3)
2

arr-zip

form code live
(k/arr-zip ["a" "b" "c"] [1 2 3])
k.arr_zip(["a","b","c"],[1,2,3])
{"a" 1, "b" 2, "c" 3}

arr-map

form code live
(k/arr-map [1 2 3 4 5] k/inc)
k.arr_map([1,2,3,4,5],lambda x : x + 1)
[2 3 4 5 6]

arr-clone

form code live
(k/arr-clone [1 2 3])
k.arr_clone([1,2,3])
[1 2 3]

arr-append

form code live
(do (var out [1 2 3]) (k/arr-append out [4 5]) out)
out = [1,2,3]
k.arr_append(out,[4,5])
out
[1 2 3 4 5]

arr-slice

form code live
(k/arr-slice [1 2 3 4 5] 1 3)
k.arr_slice([1,2,3,4,5],1,3)
[2 3]

arr-rslice

form code live
(k/arr-rslice [1 2 3 4 5] 1 3)
k.arr_rslice([1,2,3,4,5],1,3)
[3 2]

arr-tail

form code live
(k/arr-tail [1 2 3 4 5] 3)
k.arr_tail([1,2,3,4,5],3)
[5 4 3]

arr-mapcat

form code live
(k/arr-mapcat [1 2 3] (fn:> [k] [k k k]))
k.arr_mapcat([1,2,3],lambda k : [k,k,k])
[1 1 1 2 2 2 3 3 3]

arr-partition

form code live
(k/arr-partition [1 2 3 4 5 6 7 8 9 10] 3)
k.arr_partition([1,2,3,4,5,6,7,8,9,10],3)
[[1 2 3] [4 5 6] [7 8 9] [10]]

arr-filter

form code live
(k/arr-filter [1 2 3 4 5] k/odd?)
k.arr_filter([1,2,3,4,5],lambda x : not (0 == (x % 2)))
[1 3 5]

arr-keep

form code live
(k/arr-keep [1 2 3 4 5] (fn:> [x] (:? (k/odd? x) x)))
k.arr_keep([1,2,3,4,5],lambda x : (not (0 == (x % 2))) and x or None)
[1 3 5]

arr-keepf

form code live
(k/arr-keepf [1 2 3 4 5] k/odd? k/identity)
k.arr_keepf([1,2,3,4,5],lambda x : not (0 == (x % 2)),k.identity)
[1 3 5]

arr-juxt

form code live
(k/arr-juxt [["a" 1] ["b" 2] ["c" 3]] k/first k/second)
k.arr_juxt(
  [["a",1],["b",2],["c",3]],
  lambda arr : arr[0],
  lambda arr : arr[1]
)
{"a" 1, "b" 2, "c" 3}

arr-foldl

form code live
(k/arr-foldl [1 2 3 4 5] k/add 0)
k.arr_foldl([1,2,3,4,5],lambda a,b : a + b,0)
15

arr-foldr

form code live
(k/arr-foldr [1 2 3 4 5] k/step-push [])
k.arr_foldr([1,2,3,4,5],k.step_push,[])
[5 4 3 2 1]

arr-pipel

form code live
(k/arr-pipel [(fn:> [x] (* x 10)) (fn:> [x] (+ x 10))] 1)
k.arr_pipel([lambda x : x * 10,lambda x : x + 10],1)
20

arr-piper

form code live
(k/arr-piper [(fn:> [x] (* x 10)) (fn:> [x] (+ x 10))] 1)
k.arr_piper([lambda x : x * 10,lambda x : x + 10],1)
110

arr-group-by

form code live
(k/arr-group-by [["a" 1] ["a" 2] ["b" 3] ["b" 4]] k/first k/second)
k.arr_group_by(
  [["a",1],["a",2],["b",3],["b",4]],
  lambda arr : arr[0],
  lambda arr : arr[1]
)
{"a" [1 2], "b" [3 4]}

arr-range

form code live
[(k/arr-range 10) (k/arr-range [10]) (k/arr-range [2 8]) (k/arr-range [2 9 2])]
[
  k.arr_range(10),
  k.arr_range([10]),
  k.arr_range([2,8]),
  k.arr_range([2,9,2])
]
[[0 1 2 3 4 5 6 7 8 9] [0 1 2 3 4 5 6 7 8 9] [2 3 4 5 6 7] [2 4 6 8]]

arr-intersection

form code live
(k/arr-intersection ["a" "b" "c" "d"] ["c" "d" "e" "f"])
k.arr_intersection(["a","b","c","d"],["c","d","e","f"])
["c" "d"]

arr-difference

form code live
(k/arr-difference ["a" "b" "c" "d"] ["c" "d" "e" "f"])
k.arr_difference(["a","b","c","d"],["c","d","e","f"])
["e" "f"]

arr-union

form code live
(k/arr-union ["a" "b" "c" "d"] ["c" "d" "e" "f"])
k.arr_union(["a","b","c","d"],["c","d","e","f"])
["a" "b" "c" "d" "e" "f"]

arr-sort

form code live
[(k/arr-sort [3 4 1 2] k/identity (fn:> [a b] (< a b))) (k/arr-sort [3 4 1 2] k/identity (fn:> [a b] (< b a))) (k/arr-sort [["c" 3] ["d" 4] ["a" 1] ["b" 2]] k/first (fn:> [a b] (x:arr-str-comp a b))) (k/arr-sort [["c" 3] ["d" 4] ["a" 1] ["b" 2]] k/second (fn:> [a b] (< a b)))]
[
  k.arr_sort([3,4,1,2],k.identity,lambda a,b : a < b),
  k.arr_sort([3,4,1,2],k.identity,lambda a,b : b < a),
  k.arr_sort(
  [["c",3],["d",4],["a",1],["b",2]],
  lambda arr : arr[0],
  lambda a,b : a < b
),
  k.arr_sort(
  [["c",3],["d",4],["a",1],["b",2]],
  lambda arr : arr[1],
  lambda a,b : a < b
)
]
[[1 2 3 4] [4 3 2 1] [["a" 1] ["b" 2] ["c" 3] ["d" 4]] [["a" 1] ["b" 2] ["c" 3] ["d" 4]]]

arr-sorted-merge

form code live
[(k/arr-sorted-merge [1 2 3] [4 5 6] k/lt) (k/arr-sorted-merge [1 2 4] [3 5 6] k/lt) (k/arr-sorted-merge (k/arr-reverse [1 2 4]) (k/arr-reverse [3 5 6]) k/gt)]
[
  k.arr_sorted_merge([1,2,3],[4,5,6],lambda a,b : a < b),
  k.arr_sorted_merge([1,2,4],[3,5,6],lambda a,b : a < b),
  k.arr_sorted_merge(
  k.arr_reverse([1,2,4]),
  k.arr_reverse([3,5,6]),
  lambda a,b : a > b
)
]
[[1 2 3 4 5 6] [1 2 3 4 5 6] [6 5 4 3 2 1]]

arr-shuffle

form code live
(k/arr-shuffle [1 2 3 4 5])
k.arr_shuffle([1,2,3,4,5])
[2 3 1 5 4]

arr-pushl

form code live
[(k/arr-pushl [1 2 3 4] 5 100) (k/arr-pushl [1 2 3 4] 5 4)]
[k.arr_pushl([1,2,3,4],5,100),k.arr_pushl([1,2,3,4],5,4)]
[[1 2 3 4 5] [2 3 4 5]]

arr-pushr

form code live
[(k/arr-pushr [1 2 3 4] 5 100) (k/arr-pushr [1 2 3 4] 5 4)]
[k.arr_pushr([1,2,3,4],5,100),k.arr_pushr([1,2,3,4],5,4)]
[[5 1 2 3 4] [5 1 2 3]]

arr-join

form code live
(k/arr-join ["1" "2" "3" "4"] " ")
k.arr_join(["1","2","3","4"]," ")
"1 2 3 4"

arr-interpose

form code live
(k/arr-interpose ["1" "2" "3" "4"] "XX")
k.arr_interpose(["1","2","3","4"],"XX")
["1" "XX" "2" "XX" "3" "XX" "4"]

arr-repeat

form code live
[(k/arr-repeat "1" 4)]
[k.arr_repeat("1",4)]
[["1" "1" "1" "1"]]

arr-random

form code live
(k/arr-random [1 2 3 4])
k.arr_random([1,2,3,4])
4

arr-normalise

form code live
(k/arr-normalise [1 2 3 4])
k.arr_normalise([1,2,3,4])
[0.1 0.2 0.3 0.4]

arr-sample

form code live
(k/arr-sample ["left" "right" "up" "down"] [0.1 0.2 0.3 0.4])
k.arr_sample(["left","right","up","down"],[0.1,0.2,0.3,0.4])
"up"

arrayify

form code live
[(k/arrayify 1) (k/arrayify [1])]
[k.arrayify(1),k.arrayify([1])]
[[1] [1]]

Base Lib - Object

obj-empty?

form code live
[(k/obj-empty? {}) (k/obj-empty? {:a 1})]
[k.obj_emptyp({}),k.obj_emptyp({"a":1})]
[true false]

obj-not-empty?

form code live
[(k/obj-not-empty? {}) (k/obj-not-empty? {:a 1})]
[k.obj_not_emptyp({}),k.obj_not_emptyp({"a":1})]
[false true]

obj-first-key

form code live
(k/obj-first-key {:a 1})
k.obj_first_key({"a":1})
"a"

obj-first-val

form code live
(k/obj-first-val {:a 1})
k.obj_first_val({"a":1})
1

obj-keys

form code live
(k/obj-keys {:a 1, :b 2})
k.obj_keys({"a":1,"b":2})
["a" "b"]

obj-vals

form code live
(k/obj-vals {:a 1, :b 2})
k.obj_vals({"a":1,"b":2})
[1 2]

obj-pairs

form code live
(k/obj-pairs {:a 1, :b 2, :c 2})
k.obj_pairs({"a":1,"b":2,"c":2})
[["a" 1] ["b" 2] ["c" 2]]

obj-clone

form code live
(k/obj-clone {:a 1, :b 2, :c 3})
k.obj_clone({"a":1,"b":2,"c":3})
{"a" 1, "b" 2, "c" 3}

obj-assign

form code live
(do (var out := {:a 1}) (k/obj-assign out {:b 2, :c 3}) out)
out = {"a":1}
k.obj_assign(out,{"b":2,"c":3})
out
{"a" 1, "b" 2, "c" 3}

obj-assign-nested

form code live
[(k/obj-assign-nested {:a 1} {:b 2}) (k/obj-assign-nested {:a {:b {:c 1}}} {:a {:b {:d 1}}})]
[
  k.obj_assign_nested({"a":1},{"b":2}),
  k.obj_assign_nested({"a":{"b":{"c":1}}},{"a":{"b":{"d":1}}})
]
[{"a" 1, "b" 2} {"a" {"b" {"d" 1, "c" 1}}}]

obj-assign-with

form code live
(k/obj-assign-with {:a {:b true}} {:a {:c true}} k/obj-assign)
k.obj_assign_with({"a":{"b":True}},{"a":{"c":True}},k.obj_assign)
{"a" {"b" true, "c" true}}

obj-from-pairs

form code live
(k/obj-from-pairs [["a" 1] ["b" 2] ["c" 3]])
k.obj_from_pairs([["a",1],["b",2],["c",3]])
{"a" 1, "b" 2, "c" 3}

obj-del

form code live
(k/obj-del {:a 1, :b 2, :c 3} ["a" "b"])
k.obj_del({"a":1,"b":2,"c":3},["a","b"])
{"c" 3}

obj-del-all

form code live
(k/obj-del-all {:a 1, :b 2, :c 3})
k.obj_del_all({"a":1,"b":2,"c":3})
{}

obj-pick

form code live
(k/obj-pick {:a 1, :b 2, :c 3} ["a" "b"])
k.obj_pick({"a":1,"b":2,"c":3},["a","b"])
{"a" 1, "b" 2}

obj-omit

form code live
(k/obj-omit {:a 1, :b 2, :c 3} ["a" "b"])
k.obj_omit({"a":1,"b":2,"c":3},["a","b"])
{"c" 3}

obj-transpose

form code live
(k/obj-transpose {:a "x", :b "y", :c "z"})
k.obj_transpose({"a":"x","b":"y","c":"z"})
{"z" "c", "x" "a", "y" "b"}

obj-nest

form code live
(k/obj-nest ["a" "b"] 1)
k.obj_nest(["a","b"],1)
{"a" {"b" 1}}

obj-map

form code live
(k/obj-map {:a 1, :b 2, :c 3} k/inc)
k.obj_map({"a":1,"b":2,"c":3},lambda x : x + 1)
{"a" 2, "b" 3, "c" 4}

obj-filter

form code live
(k/obj-filter {:a 1, :b 2, :c 3} k/odd?)
k.obj_filter({"a":1,"b":2,"c":3},lambda x : not (0 == (x % 2)))
{"a" 1, "c" 3}

obj-keep

form code live
(k/obj-keep {:a 1, :b 2, :c 3} (fn:> [x] (:? (k/odd? x) x)))
k.obj_keep(
  {"a":1,"b":2,"c":3},
  lambda x : (not (0 == (x % 2))) and x or None
)
{"a" 1, "c" 3}

obj-keepf

form code live
(k/obj-keepf {:a 1, :b 2, :c 3} k/odd? k/identity)
k.obj_keepf({"a":1,"b":2,"c":3},lambda x : not (0 == (x % 2)),k.identity)
{"a" 1, "c" 3}

obj-intersection

form code live
(k/obj-intersection {:a true, :b true} {:c true, :b true})
k.obj_intersection({"a":True,"b":True},{"c":True,"b":True})
["b"]

obj-difference

form code live
[(k/obj-difference {:a true, :b true} {:c true, :b true}) (k/obj-difference {:c true, :b true} {:a true, :b true})]
[
  k.obj_difference({"a":True,"b":True},{"c":True,"b":True}),
  k.obj_difference({"c":True,"b":True},{"a":True,"b":True})
]
[["c"] ["a"]]

obj-keys-nested

form code live
(k/obj-keys-nested {:a {:b {:c 1, :d 2}, :e {:f 4, :g 5}}} [])
k.obj_keys_nested({"a":{"b":{"c":1,"d":2},"e":{"f":4,"g":5}}},[])
[[["a" "b" "c"] 1] [["a" "b" "d"] 2] [["a" "e" "f"] 4] [["a" "e" "g"] 5]]

to-flat

form code live
[(k/to-flat {:a 1, :b 2, :c 3}) (k/to-flat (k/obj-pairs {:a 1, :b 2, :c 3}))]
[
  k.to_flat({"a":1,"b":2,"c":3}),
  k.to_flat(k.obj_pairs({"a":1,"b":2,"c":3}))
]
[["a" 1 "b" 2 "c" 3] ["a" 1 "b" 2 "c" 3]]

from-flat

form code live
(k/from-flat ["a" 1 "b" 2 "c" 3] k/step-set-key {})
k.from_flat(["a",1,"b",2,"c",3],k.step_set_key,{})
{"a" 1, "b" 2, "c" 3}

get-in

form code live
(k/get-in {:a {:b {:c 1}}} ["a" "b"])
k.get_in({"a":{"b":{"c":1}}},["a","b"])
{"c" 1}

set-in

form code live
(do (var out {:a {:b {:c 1}}}) (k/set-in out ["a" "b"] 2) out)
out = {"a":{"b":{"c":1}}}
k.set_in(out,["a","b"],2)
out
{"a" {"b" 2}}

eq-nested

form code live
[(k/eq-nested {:a {:b {:c 1}}} {:a {:b {:c 1}}}) (k/eq-nested {:a {:b {:c 1}}} {:a {:b {:c 2}}}) (k/eq-nested 1 1) (k/eq-nested 1 2) (k/eq-nested [1] [1]) (k/eq-nested [1] [2]) (k/eq-nested {:a [{:b {:c 1}}]} {:a [{:b {:c 1}}]}) (k/eq-nested {:a [{:b {:c 1}}]} {:a [{:b {:c 2}}]})]
[
  k.eq_nested({"a":{"b":{"c":1}}},{"a":{"b":{"c":1}}}),
  k.eq_nested({"a":{"b":{"c":1}}},{"a":{"b":{"c":2}}}),
  k.eq_nested(1,1),
  k.eq_nested(1,2),
  k.eq_nested([1],[1]),
  k.eq_nested([1],[2]),
  k.eq_nested({"a":[{"b":{"c":1}}]},{"a":[{"b":{"c":1}}]}),
  k.eq_nested({"a":[{"b":{"c":1}}]},{"a":[{"b":{"c":2}}]})
]
[true false true false true false true false]

obj-diff

form code live
(k/obj-diff {:a 1, :b 2} {:a 1, :c 2})
k.obj_diff({"a":1,"b":2},{"a":1,"c":2})
{"c" 2}

obj-diff-nested

form code live
[(k/obj-diff-nested {:a 1, :b 2} {:a 1, :c 2}) (k/obj-diff-nested {:a 1, :b {:c 3}} {:a 1, :b {:d 3}}) (k/obj-diff-nested {:a 1, :b {:c {:d 3}}} {:a 1, :b {:c {:e 3}}})]
[
  k.obj_diff_nested({"a":1,"b":2},{"a":1,"c":2}),
  k.obj_diff_nested({"a":1,"b":{"c":3}},{"a":1,"b":{"d":3}}),
  k.obj_diff_nested({"a":1,"b":{"c":{"d":3}}},{"a":1,"b":{"c":{"e":3}}})
]
[{"c" 2} {"b" {"d" 3}} {"b" {"c" {"e" 3}}}]

objify

decodes object if string

form code live
(k/objify "{}")
k.objify("{}")
{}

clone-nested

form code live
(k/clone-nested {:a [1 2 3 {:b [4 5 6]}]})
k.clone_nested({"a":[1,2,3,{"b":[4,5,6]}]})
{"a" [1 2 3 {"b" [4 5 6]}]}

walk

form code live
(k/walk [1 {:a {:b 3}}] (fn [x] (return (:? (k/is-number? x) (+ x 1) x))) k/identity)
k.walk(
  [1,{"a":{"b":3}}],
  lambda x : isinstance(x,(int,float)) and (x + 1) or x,
  k.identity
)
[2 {"a" {"b" 4}}]

get-data

form code live
(k/get-data {:a 1, :b "hello", :c {:d [1 2 (fn:>)], :e "hello", :f {:g (fn:>), :h 2}}})
k.get_data({
  "a":1,
  "b":"hello",
  "c":{
    "d":[1,2,lambda : None],
    "e":"hello",
    "f":{"g":lambda : None,"h":2}
  }
})
{"a" 1, "b" "hello", "c" {"d" [1 2 ""], "f" {"g" "", "h" 2}, "e" "hello"}}

get-spec

form code live
(k/get-spec {:a 1, :b "hello", :c {:d [1 2 (fn:>)], :e "hello", :f {:g (fn:>), :h 2}}})
k.get_spec({
  "a":1,
  "b":"hello",
  "c":{
    "d":[1,2,lambda : None],
    "e":"hello",
    "f":{"g":lambda : None,"h":2}
  }
})
{"a" "number", "b" "string", "c" {"d" ["number" "number" "function"], "f" {"g" "function", "h" "number"}, "e" "string"}}

Iter Lib

for:iter

form code live
(do (var out []) (for:iter [e [1 2 3 4]] (x:arr-push out (* 2 e))) out)
out = []
for e in  1, 2, 3, 4:
  out.append(2 * e)
out
[2 4 6 8]

iter-from-obj

form code live
(it/arr< (it/iter-from-obj {:a 1, :b 2}))
it.arr_lt(iter({"a":1,"b":2}.items()))
[["a" 1] ["b" 2]]

iter-from-arr

form code live
(it/arr< (it/iter-from-arr [1 2 3 4 5]))
it.arr_lt(iter([1,2,3,4,5]))
[1 2 3 4 5]

iter-from

form code live
(it/arr< (it/iter-from [1 2 3 4 5]))
it.arr_lt(iter([1,2,3,4,5]))
[1 2 3 4 5]

iter

form code live
(it/iter [1 2 3 4 5])
it.iter([1,2,3,4,5])

iter?

form code live
(it/iter? (it/iter []))
it.iterp(it.iter([]))
true

iter-next

form code live
(it/iter-next (it/iter [1 2 3]))
next(it.iter([1,2,3]))
1

iter-has?

form code live
[(it/iter-has? 123) (it/iter-has? [1 2 3])]
[hasattr(123,"__iter__"),hasattr([1,2,3],"__iter__")]
[false true]

iter-native?

form code live
[(it/iter-native? (it/iter [1 2 3])) (it/iter-native? 1)]
[hasattr(it.iter([1,2,3]),"__next__"),hasattr(1,"__next__")]
[true false]

iter-eq

form code live
(do (var eq-fn (fn:> [a b] (== a b))) [(it/iter-eq (it/iter [1 2 4 4]) (it/iter [1 2 4 4]) eq-fn) (it/iter-eq (it/iter [1 2 4 4]) (it/iter [1 2 3 4]) eq-fn) (it/iter-eq (it/iter [1 2 4]) (it/iter [1 2 4 4]) eq-fn) (it/iter-eq (it/iter [1 2 4 4]) (it/iter [1 2 4]) eq-fn)])
def eq_fn(a,b):
  return a == b
[
  it.iter_eq(it.iter([1,2,4,4]),it.iter([1,2,4,4]),eq_fn),
  it.iter_eq(it.iter([1,2,4,4]),it.iter([1,2,3,4]),eq_fn),
  it.iter_eq(it.iter([1,2,4]),it.iter([1,2,4,4]),eq_fn),
  it.iter_eq(it.iter([1,2,4,4]),it.iter([1,2,4]),eq_fn)
]
[true false false false]

iter-null

form code live
(it/arr< (it/iter-null))
it.arr_lt(it.iter_null())
[]

collect

form code live
(it/collect [1 2 3 4] k/step-push [])
it.collect([1,2,3,4],k.step_push,[])
[1 2 3 4]

nil<

form code live
(it/nil< (it/iter [1 2 3 4]))
it.nil_lt(it.iter([1,2,3,4]))
nil

arr<

form code live
(it/arr< (it/iter [1 2 3 4]))
it.arr_lt(it.iter([1,2,3,4]))
[1 2 3 4]

obj<

form code live
(it/obj< (it/iter [["a" 2] ["b" 4]]))
it.obj_lt(it.iter([["a",2],["b",4]]))
{"a" 2, "b" 4}

take

form code live
(it/arr< (it/take 4 (it/iter [1 2 3 4 5 6 7])))
it.arr_lt(it.take(4,it.iter([1,2,3,4,5,6,7])))
[1 2 3 4]

constantly

form code live
(it/arr< (it/take 4 (it/constantly 1)))
it.arr_lt(it.take(4,it.constantly(1)))
[1 1 1 1]

iterate

form code live
(it/arr< (it/take 4 (it/iterate k/inc 11)))
it.arr_lt(it.take(4,it.iterate(lambda x : x + 1,11)))
[11 12 13 14]

repeatedly

form code live
(it/arr< (it/take 5 (it/repeatedly (fn [] (return 5)))))
it.arr_lt(it.take(5,it.repeatedly(lambda : 5)))
[5 5 5 5 5]

cycle

form code live
(it/arr< (it/take 5 (it/cycle [1 2 3])))
it.arr_lt(it.take(5,it.cycle([1,2,3])))
[1 2 3 1 2]

range

form code live
(it/arr< (it/range [-10 -3]))
it.arr_lt(it.range([-10,-3]))
[-10 -9 -8 -7 -6 -5 -4]

drop

form code live
(it/arr< (it/drop 3 (it/range 10)))
it.arr_lt(it.drop(3,it.range(10)))
[3 4 5 6 7 8 9]

peek

form code live
(do (var out := []) (it/nil< (it/peek (fn [e] (k/step-push out e)) [1 2 3 4 5])) out)
out = []
it.nil_lt(it.peek(lambda e : k.step_push(out,e),[1,2,3,4,5]))
out
[1 2 3 4 5]

map

form code live
(it/arr< (it/map k/inc [1 2 3]))
it.arr_lt(it.map(lambda x : x + 1,[1,2,3]))
[2 3 4]

mapcat

form code live
[(it/arr< (it/mapcat (fn:> [x] [x x]) [1 2 3])) (it/arr< (it/mapcat (fn:> [x] x) [[1 2 3] [4 5 6]])) (it/arr< (it/mapcat (fn:> [x] (it/range x)) (it/range 4))) (it/arr< (it/mapcat (fn:> [x] x) [(it/range 3) (it/range 3)]))]
[
  it.arr_lt(it.mapcat(lambda x : [x,x],[1,2,3])),
  it.arr_lt(it.mapcat(lambda x : x,[[1,2,3],[4,5,6]])),
  it.arr_lt(it.mapcat(lambda x : it.range(x),it.range(4))),
  it.arr_lt(it.mapcat(lambda x : x,[it.range(3),it.range(3)]))
]
[[1 1 2 2 3 3] [1 2 3 4 5 6] [0 0 1 0 1 2] [0 1 2 0 1 2]]

concat

form code live
(it/arr< (it/concat [(it/range 3) (it/range [4 6])]))
it.arr_lt(it.concat([it.range(3),it.range([4,6])]))
[0 1 2 4 5]

filter

form code live
(it/arr< (it/filter k/odd? [1 2 3 4]))
it.arr_lt(it.filter(lambda x : not (0 == (x % 2)),[1,2,3,4]))
[1 3]

keep

form code live
(it/arr< (it/keep (fn:> [x] (:? (k/odd? x) {:a x})) [1 2 3 4]))
it.arr_lt(it.keep(
  lambda x : (not (0 == (x % 2))) and {"a":x} or None,
  [1,2,3,4]
))
[{"a" 1} {"a" 3}]

partition

form code live
(it/arr< (it/partition 3 (it/range 10)))
it.arr_lt(it.partition(3,it.range(10)))
[[0 1 2] [4 5 6] [8 9]]

take-nth

form code live
[(it/arr< (it/take-nth 2 (it/range 10))) (it/arr< (it/take-nth 3 (it/range 10))) (it/arr< (it/take-nth 4 (it/drop 1 (it/range 10))))]
[
  it.arr_lt(it.take_nth(2,it.range(10))),
  it.arr_lt(it.take_nth(3,it.range(10))),
  it.arr_lt(it.take_nth(4,it.drop(1,it.range(10))))
]
[[0 2 4 6 8] [0 3 6 9] [1 5 9]]
source: src/scicloj/stdlang/walkthrough_py.clj