Interop
Koskari and Python share one process. Calls cross the boundary in both directions.
Koskari calls Python
Python
from math import sqrt
import os.path as osp
sqrt(9)
osp.join("a", "b")
"abc".upper()
Koskari
import-from math sqrt
import [os.path as: osp]
(sqrt 9)
(osp.join "a" "b")
("abc".upper)
Do I convert anything?
No. Every value is already a Python object. Arguments go in as they are, results come back as they are, and a Python function sees nothing unusual about being called from Koskari.
Are attribute names translated?
No. Python names are used verbatim: (asyncio.get_running_loop), with
the underscore. Koskari’s own names keep their dashes unless a Python
caller has to reach them by identifier, in which case spell them with
underscores.
Python calls Koskari
Python
import koskari # installs the .ki import hook
import mypkg.tools # loads mypkg/tools.ki
mypkg.tools.CONSTANT
Koskari
;; mypkg/tools.ki
var CONSTANT 42
@demand
def shout [word]:
(+ (word.upper) "!")
Why @demand?
A plain def produces an ambiently async function. Called from
Koskari it returns a value; called from Python it returns a coroutine.
@demand above the def wraps the function so a Python caller with
no event loop gets the value. Any function Python will call directly wants it;
functions called only from Koskari do not.
Python
from mypkg.tools import shout
shout("hi") # 'HI!'
Koskari
(shout "hi") ; "HI!" either way
Callbacks
Python
sorted(rows, key=lambda r: r["k"])
rows.sort(key=lambda r: r["k"])
Koskari
(sorted rows key: (lambda [r] r["k"]))
(rows.sort key: (demand (lambda [r] r["k"])))
Why does one need demand and not the other?
sorted is a Koskari builtin that wraps the key for you. rows.sort
is Python’s method and calls the key directly, so it gets coroutines
unless the lambda is wrapped. itemgetter and attrgetter are the
usual answer: (rows.sort key: (itemgetter "k")) builds a plain Python
callable with no lambda at all. The same applies to min, max, and
any Python function that calls what you hand it.
Async
Do I write await?
Rarely. A call that returns an awaitable is awaited at the call. The
explicit await is for a defer, a Task, or a Future you chose to
hold. See Demand, async, and defer.
What does not cross
Can I paste Python into a .ki file?
No. The syntax is Koskari’s. Everything Python’s import system can reach is usable; Python source is not.
Run it
At the REPL:
>>> (import-from math pi)
>>> (* pi 2)
6.283185307179586
To host Koskari inside a Python application, load files into a namespace you control, or run the REPL from Python, see Hosting Koskari from Python.