Idiomatic Koskari

Koskari has a direct, named form for each common operation. Code ported mechanically from Python reaches the same operations by assembling primitives, which is correct and reads as a translation. Each pair below is behaviour-equivalent, and the second spelling is the idiom.

The rule: prefer the direct form over the same result built from primitives.

Slicing

item-slice slices a sequence. Building a slice object and handing it to item is the assembled version.

(item seq (slice 1 None))    ; assembled
(item-slice seq 1)           ; idiom

(item seq (slice None n))    ; assembled
(item-slice seq stop: n)     ; idiom, naming the bound

Attribute assignment

A dotted target on set! is an attribute location, so set-attr is not needed.

(set-attr obj value 7)   ; assembled
(set! obj.value 7)       ; idiom

The dotted form reads as (set! (attr obj value) 7).

Destructuring

When a form returns a sequence, bind its parts with var over a pattern rather than indexing each position.

; assembled
var fn (item pair 0)
var args (item pair 1)

; idiom
var [fn args] pair

The pattern takes a *: rest, which replaces a head plus a slice:

; assembled
var name (item argv 0)
var rest (item argv (slice 1 None))

; idiom
var [name *: rest] argv

These two differ in the type of the tail. Slicing a list yields a list, while the *: collector always yields a tuple, so rest is #["b" "c"] from the slice and #("b" "c") from the collector. Use the collector when the tail is iterated or unpacked, and the slice when the caller needs a list.

Testing for None

None? is the predicate for the None singleton.

(is x None)       ; assembled
(None? x)         ; idiom

(is-not x None)   ; assembled
(not (None? x))   ; idiom

For a one-armed guard, keep the predicate positive and let the control form carry the polarity. unless and when exist so the test is not negated.

; assembled
if (is-not x None):
  handle x

; idiom
unless (None? x):
  handle x

when (None? x): is the guard for the other case. if is for a two-armed choice, with the arms swapped when that keeps None? positive.

None? tests identity against None, not truthiness; see None? and nil?.