Add typed Kotlin blank string helper

ober

d44ccf467e0568fca80fe3146624b3938648ab1c

diff --git a/docs/typed-kotlin.md b/docs/typed-kotlin.md
index 77cde94..7d8c64f 100644
--- a/docs/typed-kotlin.md
+++ b/docs/typed-kotlin.md
@@ -34,6 +34,7 @@ JVM-sized numeric and array helpers are explicit typed forms:
 - `(string-pad-start text width char)` lowers to Kotlin `String.padStart`.
 - `(string-lowercase text)` lowers to Kotlin `String.lowercase`.
 - `(string-contains? text needle)` lowers to Kotlin `String.contains`.
+- `(string-blank? text)` lowers to Kotlin `String.isBlank`.
 - `(float-array value ...)` produces a Kotlin `FloatArray`; each value must be
   `Float32`.
 - `(float-array-ref array index)` reads a `Float32` from a `FloatArray` at an
diff --git a/lib/jerboa/typed/checker.ss b/lib/jerboa/typed/checker.ss
index 8e59913..e2d9169 100644
--- a/lib/jerboa/typed/checker.ss
+++ b/lib/jerboa/typed/checker.ss
@@ -412,6 +412,9 @@
       (cons 'string-contains?
             (make-typed-call-sig (list 'String 'String) 'Bool '()
               'jvm-string-contains '()))
+      (cons 'string-blank?
+            (make-typed-call-sig (list 'String) 'Bool '()
+              'jvm-string-blank '()))
       ;; crypto primitives — FFI to vetted RustCrypto crates, never reimplemented.
       ;; Each carries kind 'crypto-prim and an info `prim` the emitter dispatches
       ;; on; the Rust block they emit references the crate (sha2/hmac/hkdf) that
diff --git a/lib/jerboa/typed/kotlin/lower.ss b/lib/jerboa/typed/kotlin/lower.ss
index 1b88098..6c9b1fd 100644
--- a/lib/jerboa/typed/kotlin/lower.ss
+++ b/lib/jerboa/typed/kotlin/lower.ss
@@ -230,6 +230,8 @@
          (make-kt-member-call (car args) 'lowercase '())]
         [(jvm-string-contains)
          (make-kt-member-call (car args) 'contains (cdr args))]
+        [(jvm-string-blank)
+         (make-kt-member-call (car args) 'isBlank '())]
         [(jvm-float-array)
          (make-kt-call (kt-name1 'floatArrayOf) args)]
         [(jvm-float-array-ref)
diff --git a/tests/test-typed-kotlin.ss b/tests/test-typed-kotlin.ss
index 02d9e64..cecf84c 100644
--- a/tests/test-typed-kotlin.ss
+++ b/tests/test-typed-kotlin.ss
@@ -257,5 +257,18 @@
 (test-contains "String contains lowers to Kotlin contains" race-kotlin
   "lower.contains(\"andromedan\")")
 
+(define note-form
+  '(typed-library (sample typed notes)
+     (export appendNote)
+     (def (appendNote (existing : String) (note : String)) : String
+       (if (string-blank? existing)
+         note
+         (string-append existing (string-append "; " note))))))
+
+(define note-kotlin (typed-library-form->kotlin-string note-form))
+
+(test-contains "String blank lowers to Kotlin isBlank" note-kotlin
+  "existing.isBlank()")
+
 (printf "typed-kotlin tests: ~a passed, ~a failed~%" pass fail)
 (when (> fail 0) (exit 1))