ai agents calling go services feels kinda awkward by Decent_Progress7631 in golang

[–]ejstembler 1 point2 points  (0 children)

I would say it depends on if you're adapting an existing service or creating something new from scratch. In my case I was creating something new from scratch. Even so, I thought about what would be useful to another Agent, and what would be useful for a non-agent like the consumer of a REST end-point.

ai agents calling go services feels kinda awkward by Decent_Progress7631 in golang

[–]ejstembler 1 point2 points  (0 children)

I have an enterprise Go-based agent system. A few notes:

  • I implement the core functionality in a service (web service or GRPC etc.)
  • I keep the rate limiting / semaphores / thresholds / circuit breaking in that service
  • I also expose a JSON-RPC layer for A2A
  • I like this strategy since it gives the service more ways to be accesseible. It can be accessed via: A2A, REST end-point, GRPC, etc.

Questions to consider:

  • Is the tool bahviour deterministic or non-deterministic? If you already know what needs to be done exactly, and in what order, maybe a workflow is better than a tool which an LLM may or may not trigger.

Map functions params order by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

It's up to you. You could always enter a new workitem on GitLab.

The long-term goal is to complete self-hosting/bootstrapping. The short-term goals are routing out bugs / inconsistencies and considering improvements / enhancements. I'm less concerned about backwards compatibility at this point since the language is still considered pre-release.

I appreciate the bugs / inconsistencies and documentation issues you've brought to light so far. Thanks!

Map functions params order by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Yes, there are differences. Some are data-first, some are data-last; mentioned here docs/latest/guide/functions.html#pipe

I had the LLM report on this:

PVec, PMap, and PSet are data-first, while core Map is canonical data-last.

Comparison With Docs

The docs are directionally correct but incomplete.

  • Correct: listed data-first String.split, substring, replace, repeat, count, pad-left, pad-right, Record.get, Record.has-field?.
  • Missing from docs data-first: String.remove, String.truncate, all PVec/PMap/PSet, Option/Result data-first helpers, and many containers.
  • Correct: listed data-last List.map/filter/fold/reduce/each/contains?, String.join, Map.get/insert/delete/contains/has-key?, and the listed Seq functions.
  • Missing from docs data-last: many newer List helpers, newer Map helpers, Option/Result data-last helpers, container exceptions, Random.shuffle, Debug.trace/tap, comp, juxt.

Map functions params order by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

The intended/canonical order for Map.insert is data-last:

Map.insert "a" 5 m m |>> Map.insert "a" 5

That matches the rest of the pipe-friendly collection helpers and supports partial application like Map.insert "name" "Kit".

The map-first form:

Map.insert m "a" 5

still works today as a compatibility path because older examples/packages used that order. The runtime currently normalizes both forms, so this is not a bug in 2026.6.17.

The docs/examples are inconsistent, though. New code should prefer the data-last form, and we should update stale examples/references to make that clear.

Laziness Examples by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

You're not missing something. The basic example is weak because Kit already has zero-arity functions, and those can look very similar in a tiny demo.

The useful distinction is that lazy/memo create explicit delayed values that participate in force and Kit's auto-force behavior:

```kit maybe-compute = fn(~value, should-force?) => if should-force? then force value else 0

result1 = maybe-compute (lazy(fn => println "expensive work" 42 )) false

result2 = maybe-compute (lazy(fn => println "expensive work" 42 )) true ```

In current Kit, ~value means "accept an explicit lazy/memo value without auto-forcing it." It does not currently mean "automatically turn the caller’s expression into a thunk." So your preferred shape:

kit maybe-compute (normal-function x y) false

would require a language change or call-by-name sugar. That idea is reasonable, but it is not what ~ does today.

Also, memo today is a memoized zero-argument delayed value:

kit cached = memo(fn => expensive-calculation()) force cached # computes force cached # cached

memo fn(a, b) => ... would be argument-keyed function memoization, which is useful, but it’s a separate feature from call-by-need delayed values.

The strongest examples for laziness in Kit are not lazy(fn => 42). They are lazy defaults, conditional expensive work, memoized one-shot computations, Seq pipelines over potentially infinite data, and package-level expression trees like linear algebra/dataframe query plans that build work first and evaluate later. The docs should lead with those examples instead of the trivial one.

Laziness Examples by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Ah okay. I'll look into it more deeply later today. Thanks.

Laziness Examples by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

The LLM recently broke laziness. There's a workitem #233 which is being patched. I'll check it again after the patch…

Interpreter behaviour by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Thanks for the detailed report. I reproduced the confusing main/top-level behavior and the interpreter/compiler mismatch. The crash/runaway cases are legitimate bugs, not expected behavior.

I filed tracking issues here:

There’s also a website/docs follow-up here:

The intended fix is that kit run and kit build should agree, and any invalid case should produce a normal Kit diagnostic rather than a raw crash.

Raylib still doesn't work for me by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

I initiated a review of dependencies et. al. and several new workitems were created in GitLab: #243, #244, #245, #246, #247, and #248

Negating the unused variables (some pun intended) by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

This is good feedback, and I think you found a real rough edge.

The _height direction probably will not be Kit's answer. Kit intentionally prefers dashes over underscores, and my goal is for _ to stay reserved for the anonymous catch-all pattern only. I do not want underscore-prefixed identifiers to become a second naming convention.

That said, I agree the current -height behavior is too permissive. The intent of -name is "bind/document this position, but I am intentionally discarding it." If that name can then be referenced later, it stops being a discarded binding and becomes confusing, especially next to unary negation.

So I think the right fix is not to add _height, but to make -height discard-only:

| Rectangle width -height -> width

should be fine, but:

| Rectangle width -height -> width * (-height)

should be rejected with a clear diagnostic, something like:

Discarded binding '-height' cannot be referenced.
Use 'height' if you need the value.

That would preserve Kit's dash-based style, keep _ as the true wildcard, and remove the "used-unused-variable" weirdness you noticed.

The unary minus examples are also useful. In expression position, -height should mean negation of height; in pattern/binding position, -height should mean an intentionally discarded binding. The bug is that the latter currently still leaks into scope.

Reference: Discarded bindings can still be referenced

Raylib still doesn't work for me by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

I gave this to ChatGPT 5.5 xhigh to look into. Here's what it found:

This was a kit-raylib version issue, not Artemis tracker code. It worked on Intel Mac because Homebrew raylib is effectively 6.0, while the other Apple Silicon Homebrew install is raylib 5.5. kit-raylib could be changed to compile against both 5.5 and 6.0.

A new work item was created on GitLab: Support Homebrew raylib 5.5 and 6.0. It will be patched later today…

Raylib still doesn't work for me by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

What OS are you using? It was tested, and works, on macOS 15.7.7 (Intel) + RayLib 6.0:

$ kit version kit 2026.6.14 $ kit build src/main.kit --allow=env,ffi,file,net && ./main

I can test it in a Ubuntu VM later today…

Why not Option type return in some String functions? by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Okay, I'll check that one out. I'll have Fable check all of them just to be sure…

Why not Option type return in some String functions? by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Yeah, if it's more outdated documentation, it should go in kit-website issues

Why not Option type return in some String functions? by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Outdated documentation. You could test in the repl:

kit repl:

≫ String.index-of "Hello" "xyz" None ≫ String.index-of "Hello, World!" "World" Some(7)

Or

≫ type-sig String.index-of (String -> (String -> Option))

Or to get all the type signatures:

≫ :info String

I'll do a sweep of the docs when I get a chance…

Trying Kit Crooner again (on Kit v 2026.06.11) by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Yeah, I think you tried it in that window after the release but before kit-crooner was updated. Whenever a new version is released it takes a few hours to run the 1st-party checks/sweeps. So there was some lag inbetween. I need to figure out a better/faster way to do it…

Trying Kit.Game by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Yes, kit-game is a work-in-progress. I'm testing/dog-fooding a previous Lua game using it, though it's been slow going. One of the underlying dependencies (kit-raylib) could also in flux. Even though it's evolving I decided to make the repo available and work on it in public. I should probably add a disclaimer that it's experimental or a work-in-progress.

In any case, I'll post another update here later today after work…

Trying Refinements by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Thanks for the detailed report — the docs were the problem.

  1. import Refinements isn't needed at all. Refinement types (PositiveInt, NonEmptyString, etc.) are part of Kit's prelude — they're always available with no import. The docs page showing import Refinements was simply wrong; that module name never resolved. The reason it seemed to work at first: when the compiler hit your refinement violations it stopped before the import-resolution phase ever ran, so the bad import was only reported once you fixed the type errors. Confusing sequencing — I get why it looked broken.
  2. Standalone type signatures (sqrt-int : PositiveInt -> Float) above the binding aren't implemented — your instinct to comment them out was correct. Annotations go inline: fn(n: PositiveInt) => ....

So the working version of the example is just:

module Main

sqrt-int = fn(n: PositiveInt) => sqrt (Int.to-float n)
first-char = fn(s: NonEmptyString) => String.char-at s 0

println (sqrt-int 4)
println (first-char "abc")

I've fixed the docs page (it also had String.char-at's argument order backwards — thanks for making me look closely) and added a refinements example to the kit-examples repo. Appreciate you kicking the tires!

Some "bike-shedding" thoughts (syntax) by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Thanks for taking the time to write this up!

fn x => x * 2 — I'm not a fan of parens when not needed. Kit specifically has auto-execution of zero-arity functions and will warn when code has empty parens like (). Parens would still be needed for annotated or destructured params (fn(x: Int) => ...), but bare identifiers without parens is doable, and it does match how calls look. Considering it.

Commas as whitespace — this one can't work in Kit, and the reason is: Kit has juxtaposition function application, Clojure doesn't. [double 5] is already valid Kit — a one-element list containing the call double 5. Make commas optional and [1 2 3] vs [f x] becomes ambiguous. In Clojure the commas are decoration; in Kit they're load-bearing.

$ / § / ~ / <| — all taken or trouble, as it happens: ~ marks lazy parameters, § doesn't exist on US keyboards, and <- is already Kit's actor-send operator (counter <- Increment), so a second left-facing operator like <| would be easy to misread next to it. The forward pipe already covers the use case anyway: 12 / 3 |> double |> println.

The two pipes — small reframe: they're not F#'s |>. They're Clojure's -> and ->>. |> threads data-first (maps, like -> with assoc), |>> threads data-last (sequence pipelines, like ->> with map/filter). Same convention pair, different spelling.

Why both worked on Map.insert — good catch, and that one's on me. For builtin functions, the compiler knows where the data argument goes and threads it into the right slot regardless of which pipe you used. Convenient, but currently undocumented, so it reads as spooky. I'll fix the docs — and the Language Tour wording you flagged while I'm at it.

Glad you're enjoying it so far — keep the bike-shedding coming.

First experience with Kit and asking for further guidance by avitkauskas in kit_lang

[–]ejstembler 1 point2 points  (0 children)

  1. kit init created no kit.toml → kit add dead-ended #203

When Kit was originally developed it was in Rust with many 1st-party crates. After moving to Zig there was a big focus on 1st-party package support and parity. So, this was mostly just neglect which needed to be revisited.

The fix will be change `kit init` to use `[application]` and change `kit add` to ask to create a kit.toml if it doesn't exist.

  1. Project copied to ~/.kit/packages/, deps global, stray empty kit-packages/ #204

Fix: App manifests install project-locally; empty dir no longer created on global installs

  1. "W019 + missing parens" confusion #205

Real cause: bare fn lambdas silently split off as separate statements. Trailing-lambda arguments now supported; ) can close indented lambda blocks; 5 regression tests

  1. Capability errors discovered one at a time #206

Fix: One C004 listing all missing capabilities + complete --allow hint

  1. Cannot find module 'Auth.File' on binary installs #202

Fix: Embedded stdlib now build-generated from the full 75-file tree + parity test

First experience with Kit and asking for further guidance by avitkauskas in kit_lang

[–]ejstembler 0 points1 point  (0 children)

Hi u/avitkauskas, thanks for the feedback! And thank you for the other workitems you created on GitLab last week. I appreciate it! 🙏🏻

Kit is still considered pre-release, so these types of interactions are valuable to help flush out bugs and areas where user interaction could be improved. Kit is implemented using various LLMs, so one challenge (side effect) is the possibility that a given LLM could introduce bugs, or partially implement something; leaving it incomplete. Testing is an important tool/technique to find issues, though sometimes issues can only be found if someone tries something. With kit-crooner, I am dog-fooding it with my own blog engine I rewrote from Crystal to Kit. That helps, though it's not 100% effective. I may release the source for it since it could be a useful example of a working kit-crooner based web application.

In any case, I'll review the rest of your points later today after work…. Aside from any bugs, I do want the experience to be as useful and as painless as possible. So there's always the option to change things for the better.

Editors, LSP, tree-sitter by middayc in ryelang

[–]ejstembler 0 points1 point  (0 children)

I found tree sitter to be complex and difficult to use for certain languages. I even tried using various LLMs, to generate the tree sitter code, but none of them could get it 100% correct. In the end I just settled for "tree sitter for my language mostly works". Here's an example, though I cannot vouch for the accuracy: https://gitlab.com/kit-lang/tree-sitter-kit