[HN Gopher] Koto Programming Language
___________________________________________________________________
Koto Programming Language
Author : virtualritz
Score : 131 points
Date : 2025-03-29 12:14 UTC (10 hours ago)
(HTM) web link (koto.dev)
(TXT) w3m dump (koto.dev)
| martin-t wrote:
| The amount of scripting languages _for Rust_ is a symptom of how
| Rust fails to satisfy the need to write code with less strict
| requirements.
|
| It makes perfect sense to use Rust as the main language for your
| application but have areas which are either in the prototype
| stage, need to be written quicker or which simply don't need the
| performance. But Rust does not offer a way to enter such a less
| strict context and such proposals keep getting shot down by the
| community, even when they are made from core members of the Rust
| team.
|
| Contrast that with C# which has a dynamic keyword, allows
| enabling a checked context (not just in code where you can't miss
| it but also from csproj), has reflection, etc.
|
| I really want Rust to succeed but sometimes the attitude borders
| on zealotry.
| Sytten wrote:
| What are you rambling about, this is a sanboxed scripting
| language to allow your users to define customization at
| runtime. This has nothing to do with rust, it could be written
| in C or C++. You would not run random user provided C# in your
| application at runtime.
|
| It is like saying browser should be coded in C# because C++
| can't be use instead of JavaScript...
| 01HNNWZ0MV43FF wrote:
| Since it's written in Rust, that's the easiest place to use
| the embedding API. https://koto.dev/docs/0.15/api/ I imagine
| one _could_ use it from C, but it wouldn't be as ergonomic as
| Lua's C API. And Lua in turn isn't a perfect match for
| embedding in Rust
| benwilber0 wrote:
| Or like saying that C++ was somehow deficient just because
| NodeJS had to be created in order to script v8.
| martin-t wrote:
| It literally says "for Rust applications" on its front page.
|
| Your tone is insulting and has no place in technical
| discussions.
| VWWHFSfQ wrote:
| Describing rust programmers as "zealots" also has no place
| in a technical discussion.
| Onavo wrote:
| We need LuaJIT in Rust.
| benwilber0 wrote:
| This is already available as an optional Lua target in mlua
| [0]. I recently built a programmable server for Server-Sent
| Events scriptable with Lua [1]. I chose Lua 5.4, but it's
| trivial to switch it to LuaJIT, or really any other Lua
| derivative including Roblox Luau. It's just a matter of
| enabling the mlua feature you want.
|
| [0] https://github.com/mlua-rs/mlua
|
| [1] https://tinysse.com/
| Philpax wrote:
| While I would like a Rust-like language that has those things,
| complaining that Rust, a compiled native language with no
| runtime whose closest competitor is C++, does not is a little
| strange to me.
|
| Yes, it is very multi-paradigm and can be used in many domains,
| but it's not trying to be C# and it can't be C#. I would love
| to see Rust# as a language, but Rust itself cannot be that
| language.
| martin-t wrote:
| Should new languages artificially restrict themselves based
| on the restrictions of their main competitor even if it's
| possible to serve a wider range of usecases?
|
| Dynamic can be implemented in a compile-to-native lang.
| Contexts with different rules as well. Reflection support
| would likely have overhead which would need a granular opt in
| mechanism but is very likely possible.
|
| Similarly many features rust is missing like compile time
| reflection, field in traits, ...
| Philpax wrote:
| > Should new languages artificially restrict themselves
| based on the restrictions of their main competitor even if
| it's possible to serve a wider range of usecases?
|
| Nope - and indeed, we're seeing Rust used in a more diverse
| set of applications than C++ (e.g. there are several Rust
| web frontend frameworks, it's a popular WASM language in
| general, etc)
|
| However, Rust is targeting the same kind of general
| constraints as C++ for development and deployment, which
| means it can't add anything that would depend on a runtime
| or impose an undue burden on users. (Of course, C++ cheats
| in this regard - RTTI and exceptions - but Rust matches
| that, and doesn't go beyond.)
|
| > Dynamic can be implemented in a compile-to-native lang.
|
| Requires runtime functionality, and it's not really clear
| what the resulting semantics would be, anyway: aside from
| the usual type-safety concerns, how do you deal with
| lifetimes and other compile-time constraints?
|
| > Contexts with different rules as well.
|
| What kind of different rules? The problem is that any
| deviation from the rules needs to be reconciled at some
| point, and that reconciliation has to be watertight: you
| can't weaken the guarantees somewhere that interacts with
| safe Rust code, because the weakness you've introduced can
| spread. This is already a pretty significant issue with
| unsafe Rust.
|
| Similarly, moving to a higher level of abstraction has
| similar issues: how do you reconcile the interactions of
| GC'd objects with the rest of Rust, which expects
| deterministic destruction and somewhat-predictable object
| lifetimes?
|
| > Reflection support would likely have overhead which would
| need a granular opt in mechanism but is very likely
| possible.
|
| If you're already committing to a granular opt-in
| mechanism, you might as well use a library, which offers
| you more options:
| https://docs.rs/bevy_reflect/latest/bevy_reflect/
|
| > Similarly many features rust is missing like compile time
| reflection, field in traits, ...
|
| I'll give you compile-time reflection; that _would_ have
| been quite nice to have, but the Rust Foundation alienated
| the primary person with a plan (https://thephd.dev/i-am-no-
| longer-speaking-at-rustconf-2023), so who knows when we'll
| see the next proposal? I agree that it's a shame, but
| there's usually ways to work around it (proc macros can be
| used to patch over a lot of Rust's relative deficiencies)
|
| Field-in-traits has been discussed before, but is
| complicated due to the borrow checker:
| https://internals.rust-lang.org/t/fields-in-traits/6933/1
|
| In general, the borrow checker is the primary impediment to
| copying features from other languages; it's just generally
| non-trivial to fit them into the Rust paradigm without
| significant R&D. That's why I think a higher-level Rust
| would have to be a separate language, not an extension of
| Rust proper: resolving the collision of semantics between
| abstraction levels is just too difficult in the general
| case.
| jakkos wrote:
| Would you be able to share examples of these "shot down
| proposals"?
|
| I personally haven't found Rust that difficult to prototype in,
| when I need to I just liberally use clone/Arc/RefCell.
|
| I see the main benefit of these scripting languages as being
| able to write/run code at runtime, e.g. live coding music or
| mods for video games.
| perrygeo wrote:
| > I personally haven't found Rust that difficult to prototype
| in
|
| Rust is actually a pretty nice language for prototyping IMO.
| I agree with your take - Rust has many escape hatches you can
| use to develop quickly. Then when it comes time to clean up,
| it's obvious where the deficiencies are (look for all the
| clones and unwraps, etc)
|
| > I see the main benefit of these scripting languages as
| being able to write/run code at runtime
|
| Thank you. Some commenters seem to think a scripting language
| somehow reveals some deficiency in the core language.
| Reality: not all code is available at compile time. Many
| applications need some way to inject code without
| recompiling.
| martin-t wrote:
| Niko Matsakis made a proposal on his blog for opt-in contexts
| with relaxed rules (such as implicit conversions) and it was
| hated, at least on reddit. I doubt he would delete it but i
| can't find it now.
| HKH2 wrote:
| Maybe I'm a zealot, but I use Rust-script with cmd_lib. Rust-
| script lets you define the libraries at the top of the file
| (instead of in a Cargo file) and cmd_lib gives you macros to
| call commands directly almost like in Bash. Then you can
| iterate over the output way faster than in Bash. It recompiles
| after any changes, and subsequent runs just call the compiled
| executable. The downside is that the cache does grow, but it's
| not that noticeable.
| jakkos wrote:
| I really like the idea of rust-script but last time I looked
| there didn't seem to be a good way to get rust-analyzer to
| work when writing a script. Maybe I'm a little too reliant on
| LSPs but I find writing Rust painful without it, has the
| situation improved at all since?
| hypeatei wrote:
| > Contrast that with C# which has a dynamic keyword
|
| `dynamic` has a very narrow use-case and generally shouldn't be
| used at all (even when prototyping)
|
| I believe it was introduced to make working with poorly
| designed external libraries easier (e.g. Windows/Office libs)
| BiteCode_dev wrote:
| I think it's just a convenient and popular language to
| experiment with.
|
| For production systems, people just use Python + Rust when
| needing a balance between dynamism and strictness. The tooling
| to mix them is very mature and the communities are overlapping.
|
| With uv becoming the defacto packaging solution for python, I
| expect the border to blur even more in the future.
| mostafah wrote:
| Very cool. I really like the idea of implementing higher level
| features as extensions on top of a smaller core. I wish real
| scripting languages like this were more common and in use. Lua
| comes to mind when thinking about a generic scripting language,
| but even that is not that widespread.
| nine_k wrote:
| I think "implementing higher level features as extensions on
| top of a smaller core" is a hallmark of the Lisp family. Check
| out Fennel [0] or Janet [1] for two different approaches. On
| top of everything, Fennel is 100% Lua-compatible.
|
| [0]: https://fennel-lang.org/
|
| [1]: https://janet-lang.org/
| mostafah wrote:
| I agree. Emacs and its Emacs Lisp are one of the best
| examples of this design. Thank you for the links.
| nine_k wrote:
| As an avid Emacs user, can't but agree :)
| fstarship wrote:
| It seems every scripting language does duck/dynamic typing (as
| far as I can tell this applies to Koto).
|
| I don't understand why... inferred typing is nearly as easy to
| use while being more robust.
|
| For me the biggest gap in programming languages is a rust like
| language with a garbage collector, instead of a borrow checker.
|
| Rust has a lot of features that should be strongly considered for
| the next generation of programming languages such as
|
| result/sum types
|
| Inferred typing
|
| Not object oriented or overly prescriptive with functional
| programming.
|
| I think the closest language to filling that gap is occaml (I am
| not familiar with it).
|
| I have coworker's that are more skilled in domain logic that can
| write basic self contained programs, but stuff like traits, OOP
| functional programming is a bridge too far.
|
| I feel like a language that fills that gap could be useful,
| context is a manufacturing ERP system.
| dustbunny wrote:
| Check out Wren.
|
| https://wren.io/
|
| Written by Bob Nystrom, author of Crafting Interpretors.
| fstarship wrote:
| Thanks for your suggestion.
|
| At first glance it appears to be object oriented, which is
| against preference but not a deal breaker.
|
| However error case looks to be try catch which is a deal
| breaker.
| pansa2 wrote:
| > _However error case looks to be try catch which is a deal
| breaker_
|
| Wren uses coroutines ("fibers") for error handling, which
| is unusual. But yes, ultimately it does seem to be
| equivalent to try-catch.
| pansa2 wrote:
| Wren is dynamically-typed, though
| sramsay wrote:
| Last release was four years ago.
| oDot wrote:
| You're describing Gleam
|
| https://gleam.run
| fstarship wrote:
| Thanks looks great so far.
|
| Also has pattern matching which I should also have mentioned
| in my top level post.
| macintux wrote:
| After learning Erlang, it was painful to go back to any
| language which didn't offer pattern matching. Such a great
| language feature.
| oDot wrote:
| I use it in production[0] and it's a delight so far. When
| Porffor[1] is ready you could compile to WASM through JS
| for self-contained binaries!
|
| [0]: https://blog.nestful.app/p/why-i-rewrote-nestful-in-
| gleam
|
| [1]: https://porffor.dev/
| IshKebab wrote:
| Can you easily embed it though? Looks like it depends on
| Erlang which means the answer is likely no.
| oDot wrote:
| It also compiles to Javascript, which runs in a lot of
| places (to say the least). For WebAssembly, see my other
| comment about Porffor
| IshKebab wrote:
| Javascript isn't the nicest thing to embed either tbh. It
| looks like a nice language but it's clearly not in the
| same space as Lua or Rhai.
| letmeinhere wrote:
| For one thing, inferred types may feel easy to use when
| implemented (well) but they are not easy to implement.
| rapind wrote:
| I'd keep an eye on Roc https://www.roc-lang.org/
|
| Also, Elixir is working on gradual types, which is something I
| would keep an eye on. https://hexdocs.pm/elixir/main/gradual-
| set-theoretic-types.h...
|
| https://www.youtube.com/watch?v=giYbq4HmfGA&t=1s
| no_wizard wrote:
| I want Clojure on Rust, or a similar LISP.
|
| Such a great programming paradigm that sadly has few breakout
| successes
| whytevuhuni wrote:
| I'm having a hard time picturing that. What would it look
| like?
| cultofmetatron wrote:
| roc as a language looks really interesting but its by elm
| devs and I don't have much confidence in their ability to
| handle the transition to being a widely used language with
| all the cultural shifts that requires.
| Hasnep wrote:
| It's created by Richard Feldman who was big in the Elm
| community, but I think most contributors to the Roc
| compiler have only used Elm a bit or have never used it.
| ossopite wrote:
| I think you really are describing ocaml, which is a great
| language, although its ecosystem isn't the best. It probably
| inspired most of the features you mentioned in rust. It also
| supports OOP (hence the O) but it's easy to avoid.
|
| That said, I wouldn't compare it to scripting languages. The
| lack of implicit conversions / traits / ad-hoc polymorphism
| means it's not that convenient for scripting.
| nerdponx wrote:
| Nim was great along these lines when I tried it. But that was
| before the v2.0 which apparently was accompanied by drama and
| a fork.
| rattray wrote:
| What happened?
| threatofrain wrote:
| Implicit conversion is not _obviously_ that convenient for
| scripting. The JS community has largely moved to anti-
| recommend implicit conversion, such as by basically striking
| `==` from their vocabulary.
| raphinou wrote:
| Fsharp, which originally was ocaml on dotnet, can also be run
| as scripts. It is a really practical way to start a project.
| I blogged about it here: https://asfaload.com/blog/fsharp-
| fsx-starting-point/
| soulbadguy wrote:
| Fsharp is such a nice languange. Such a shame that I never
| seem to get the light it deserves. Between the alternative
| light syntax, type providers and first class "scripting"
| mode supported it really was a great middle point between
| fully scripting language and fast prototyping and full blow
| projects
| jeltz wrote:
| Ruby does very little implicit type conversion and is great
| for scripting. I think implicit type conversion is not
| required or even a good thing for scripting languages.
| xigoi wrote:
| What makes OCaml inconvenient for scripting is how difficult
| it is to run code that uses some external libraries. You
| basically need to create a whole project structure with
| several config files, which creates a lot of friction
| compared to `import numpy as np`.
| rTX5CMRXIfFG wrote:
| I'm not sure what you're getting at here but none of the
| features you mentioned are groundbreaking anymore? At least in
| Swift:
|
| result/sum types = enums whose cases have associated values
|
| inferred typing = Swift "type inference"
|
| Not object oriented or overly prescriptive with functional
| programming. = Uh, yes
|
| Those features map to Kotlin too
| sanderjd wrote:
| Yeah I think Kotlin is quite close to the OP's description.
| But it is perhaps more focused on object orientation than
| they would like, and also only runs on the JVM.
|
| But if I were to create a self-contained (that is, non-JVM)
| "Rust-like but with GC", I think it would look a lot like
| Kotlin.
| karmakaze wrote:
| I haven't tried it but Kotlin/Native targets platforms like
| iOS, macOS, Linux, Windows, etc. There's also Kotlin/JS for
| JavaScript, and a WASM target with limitations.
| lolinder wrote:
| It's been a few years since I tried Kotlin/Native but
| even then it was pretty good.
| sanderjd wrote:
| Neat. I didn't know that.
| valenterry wrote:
| Rather Scala but leaving out a few parts. Kotlin is very
| very OOP focussed and comes with a lot of baggage from
| Java.
|
| Rust-like but with GC is already Scala. The reason is that
| Scala (unlike Kotlin) focusses on immutability, which makes
| it more similar to Rust. It's actually even easier to use
| (no borrow checker) but at the cost of performance.
|
| After Rust, I would see F# as the next closest language,
| quite far before Kotlin.
| sanderjd wrote:
| > _Rust-like but with GC is already Scala._
|
| Maybe like _a third_ of Scala. But yeah, Scala has a lot
| of good parts, it 's also just a huge surface area. I
| agree that you could pluck a subset out of Scala and make
| it this "Rust-like but with GC" language.
|
| But it's nigh-impossible to actually make that "only use
| this subset" idea work in practice, because it just ends
| up being a bikeshed.
|
| But you're right that the same can be said of the OO
| focus of Kotlin.
| fstarship wrote:
| I am aware of 3 "rust inspired scripting" languages that have
| dynamic types.
|
| Rhai Rune Dyon
|
| Mun is not dynamic, however it does not have string support
| afaik.
|
| Kotlin and Swift may be better candidates than these
| scripting languages for my imagined usecase.
|
| Come to think of it, maybe I don't have a point other then
| there is so many scripting language's inspired by rust that
| is dropping a major convenience feature, that I am surprised
| is negotiable (inferred typing ).
| zozbot234 wrote:
| Rust itself has dynamic types via the Any trait and &dyn
| Any variables. They are not the default of course, but
| they're available should you really want them. IIRC C#
| works similarly, only its feature is called Dynamic
| instead, or something like that.
| skitter wrote:
| They're rather different: In Rust types only exist at
| compile time; dyn Any is a normal trait object, so you
| can only call the trait's methods. With C#'s dynamic, you
| can call arbitrary methods and access any fields with
| type checking of those accesses being delayed until
| runtime, which works because types exist at runtime too.
|
| Rust's dyn Any corresponds better to C#'s Object; dynamic
| exists to interface with dynamic languages and is rarely
| used.
| madeofpalk wrote:
| I don't think you're disagreeing with parent. I also think
| these features are not groundbreaking and should be
| considered table stakes for any new/sane language.
| chris_pie wrote:
| I'd say F# is closer to filling that gap than OCaml. It's a bit
| less insistent on being functional and has a more familiar
| syntax. I find it more practical in general.
| pjerem wrote:
| I somehow discovered F# by accident and it's really an hidden
| gem.
|
| Its ahead of its time in basically every aspect, it's 100%
| compatible transparently with the whole C# ecosystem, it's
| mature yet still evolving.
|
| The type system is something I never saw before : creating
| types is so ergonomic and fast that you can create custom
| type for basically any value of your program without
| boilerplate if you want.
|
| It's really a refreshing language that anyone should try.
|
| What I really love with it is that it's hard to write (when
| you are learning it) but incredibly clear to read.
| chris_pie wrote:
| Also the Units of Measure are a great feature. I think
| they're a zero-cost abstraction that Rust users love to
| mention.
| ossopite wrote:
| I'm curious what you have in mind when it comes to ways in
| which OCaml is insistent on being functional while F# isn't.
| After all, OCaml has mutable data structures, mutable record
| fields, for loops and so on. Is it just that more libraries
| assume immutability and use functional abstractions?
| chris_pie wrote:
| To be fair, my knowledge of F# is a bit basic, but I meant
| stuff like classes (including abstract ones), interfaces,
| and the ingrained interop with C#.
| haxiomic wrote:
| Haxe is the best fit for me, think of typescript with
| functional patterns and inferred typing. Written in ocaml and
| inspired by the language
| camdenreslink wrote:
| You could probably write F# in the style that you describe (it
| is a descendant of OCaml).
| pansa2 wrote:
| > _It seems every scripting language does duck /dynamic typing
| (as far as I can tell this applies to Koto)._
|
| It looks like Koto supports type hints - not sure if these are
| checked at compile-time, run-time, or both.
|
| > _I don't understand why... inferred typing is nearly as easy
| to use while being more robust._
|
| Is it (nearly as easy to use)? Every static type system seems
| to have special cases and exceptions which are avoided by
| dynamic typing. I'd love to find one that's actually simple.
|
| Also, it's definitely not nearly as easy to _implement_ - which
| is important for a language being designed and built by a small
| team and targeting a lightweight runtime.
| pansa2 wrote:
| > _not sure if these are checked at compile-time, run-time,
| or both_
|
| It looks like Koto only checks types at run-time. That means
| its type annotations are essentially shorthand for something
| like Python's `if not isinstance(...): raise TypeError`.
| irh wrote:
| Yes that's right, they're checked at runtime (with the
| option to disable the checks if the performance cost is a
| concern) and failed checks simply throw exceptions.
|
| The hints aren't used for other purposes at compile time
| yet, but they could enable some warnings.
| tuveson wrote:
| > Also, it's definitely not nearly as easy to implement
|
| I think this is the real reason why there are so many dynamic
| language implementations. If you want to implement a dynamic
| language, you just slap a type tag on your runtime objects
| and boom, your "type system" is done.
|
| Dynamic languages get a lot of expressiveness "for free",
| whereas having a really expressive static type system
| requires a lot of work. It's not that hard to get a type
| system on the level of C, but if the language is interpreted,
| it's still going to be pretty slow.
|
| I do think there can be benefits to having typing in a
| scripting language (and not a bolted-on type system like
| typescript or mypy). It's much easier to work with an FFI if
| the type system of the scripting language maps closely to the
| implementation language. It also does make it much easier to
| optimize the language down the line, if that becomes a
| priority. Making a fully dynamic language efficient is very,
| very difficult.
| IshKebab wrote:
| I totally agree. I think it's simply because most of these
| projects are pretty much one-man efforts and implementing
| static typing is a _lot_ more effort than dynamic typing.
| notnullorvoid wrote:
| > For me the biggest gap in programming languages is a rust
| like language with a garbage collector, instead of a borrow
| checker.
|
| I agree, though I often think Rust is probably good enough. You
| can use RC or grab a GC crate. It's not as ergonomic as just
| assuming all values are GCed, but I think it gives the
| flexibility and fast iteration of working in a GCed language.
| teleforce wrote:
| Rust is not as good as D in this domain in which D is
| designed for this, since it's GC by default, please see my
| other comments.
| valenterry wrote:
| You are looking for Scala or F#, depending on your choice of
| ecosystem.
|
| Both come with very powerful features, but you don't need to
| use them and you can use libraries accordingly. Especially
| Scala can be made to feel very similar to python
| zozbot234 wrote:
| Rust will probably gain support for "pluggable" and optional
| garbage collectors as part of its upcoming local allocators
| API. This will ultimately give devs the best of both choices -
| use tracing GC where it's actually needed (because you're
| working with totally general graph-like data and that's the
| only feasible memory management strategy) and manual memory
| management (supplemented by RAII and reference counting)
| elsewhere - for other parts of the program that don't have to
| manage general "spaghetti" graphs. Unfortunately the way GC's
| trace objects and collect garbage varies wildly among
| implementations, so there's no easy way to standardize a
| "generic" interface to pluggable garbage collection, that all
| custom crates might be expected to tap into by default. But
| other uses should be quite feasible.
| SkiFire13 wrote:
| > Rust will probably gain support for "pluggable" and
| optional garbage collectors as part of its upcoming local
| allocators API.
|
| Source? AFAIK there's no confirmed upcoming allocators APIs,
| and even if there was they would just allow reusing the
| builtin `Box`/`Vec`/etc etc with custom allocators. This is
| not much different than what you could do with a custom type,
| so I find it hard to believe it would allow garbage
| collectors that are not possible right now.
| simon_void wrote:
| check out Borgo https://github.com/borgo-lang/borgo It is Go
| with algebraic datatypes!
| beagle3 wrote:
| You are describing Nim.
| mirekrusin wrote:
| MoonBit lang is probably closer. Beautiful language.
| teleforce wrote:
| >For me the biggest gap in programming languages is a rust like
| language with a garbage collector, instead of a borrow checker.
|
| I cannot agree more that's the much needed sweet
| spot/Goldilock/etc. Personally I have been advocating this
| approach for some times. Apparently the language is already
| widely available and currently has stable and wide compiler
| support including the venerable GNU compiler suite (GDC). It
| also one of the fastest, if not the fastest programming in
| existence for both compilation and execution [1].
|
| It has been beating Fortran in its number crunching territory,
| no small feat given the Fortran pedigree with many languages
| still depending on Fortran based infrastructure for their
| number crunching capabilities including Matlab, Julia, Rust,
| Go, C, C++, etc [2].
|
| It also has a nice bulti-in REPL system due to its very fast
| compilation and execution [3].
|
| For an excellent overview of D programming language please
| check this presentation at ACCU conference [4].
|
| [1] D website:
|
| https://dlang.org/
|
| [2] Numeric age for D: Mir GLAS is faster than OpenBLAS and
| Eigen:
|
| http://blog.mir.dlang.io/glas/benchmark/openblas/2016/09/23/...
|
| [3] Why I use the D programming language for scripting (2021):
|
| https://news.ycombinator.com/item?id=36928485
|
| [4] How DLang Improves my Modern C++ and Vice Versa - Mike Shah
| - ACCU 2024:
|
| https://youtu.be/CnKsOak0DHU
| nine_k wrote:
| The point of many scripting languages is quick tinkering,
| mucking with stuff in a REPL, on top of a complex contraption
| of already-live objects. This works well with duck typing. It
| does not work with nice static type inference, because once you
| change something high upstream, it potentially invalidates
| everything downstream, your entire current session you've spent
| an hour building.
|
| "Everything should be built top-down, except for the first
| time" (See #15 in https://www.cs.yale.edu/homes/perlis-
| alan/quotes.html)
| sparkie wrote:
| > I don't understand why...
|
| Because dynamic typing has its own advantages, which are worthy
| of experimentation even if you perceive absence of static
| typing as a weakness.
|
| Gradual typing can offer us the benefits of both worlds.
|
| > inferred typing is nearly as easy to use while being more
| robust.
|
| Implementing type inference can be fairly trivial if your types
| are all disjoint. Hindley-Milner type inference is well studied
| and there's plenty of literature.
|
| But as soon as you introduce subtyping, the traditional methods
| are not sufficient. It's only in the past decade that good
| solutions have been discovered, notably Dolan & Mycroft's
| MLsub[1], based on Dolan's Algebriac Subtyping thesis[2], and
| Parreaux & Chau's MLstruct[3], which uses a boolean algebra
| approach[4]. Type inference with subtyping is not a solved
| problem - these developments are big steps forward, but there
| are still open problems under research.
|
| Subtyping doesn't imply object-oriented. Structural typing (ie
| "static duck typing") is a form of subtyping.
|
| [1]:https://github.com/stedolan/mlsub
|
| [2]:https://www.cs.tufts.edu/~nr/cs257/archive/stephen-
| dolan/the...
|
| [3]:https://github.com/hkust-taco/mlstruct
|
| [4]:https://dl.acm.org/doi/pdf/10.1145/3563304
| zozbot234 wrote:
| > Gradual typing can offer us the benefits of both worlds.
|
| Gradual typing has much the same overhead as other kinds of
| dynamic typing. It's broadly appropriate as part of the
| interface between separately-developed software components,
| and not very much otherwise.
| sparkie wrote:
| Gradual typing is static typing augmented with a known
| static type `dynamic`, and some rules by which conversions
| to/from `dynamic` are statically checked, called
| consistency.
|
| A program in a gradually typed language which does not use
| `dynamic` is fully statically checked and has no overheads.
| The overheads only appear when `dynamic` is used.
|
| This is why it offers the best of both worlds. We get
| static typing everywhere where we're not using dynamic, and
| when we do use dynamic, we can basically use it however we
| want and have the benefits of dynamic typing, because from
| the static perspective, dynamic ~ dynamic, regardless of
| what the runtime type is.
|
| The important innovation is that consistency (~) is not
| transitive - so it doesn't allow us to implicitly convert
| one type to another - only conversions to/from dynamic are
| implicit, and other conversions must be done explicitly.
|
| Obviously, this provides an "escape hatch" from static
| typing where we do use it - we can get around some static
| type check by casting to/from dynamic explicitly, but this
| works out well in practice.
|
| C# is an example of a gradually typed language since v4
| which introduced `dynamic`.
|
| Haskell is close , in that it has the type `Data.Dynamic`,
| but it doesn't support implicit conversions to/from it,
| which would be possible if it had a consistency rule. We
| have to do the conversions explicitly.
|
| https://jsiek.github.io/home/WhatIsGradualTyping.html
| amedvednikov wrote:
| > For me the biggest gap in programming languages is a rust
| like language with a garbage collector, instead of a borrow
| checker.
|
| https://vlang.io
|
| GC, sum types, result/option types, interfaces, no OOP, fast
| compilation.
| egl2020 wrote:
| > I don't understand why.
|
| Favors minimal text entry. You keep the type information in
| your head and enter fewer tokens. Historically you also reduced
| the work and improved responsiveness for the interpreter, which
| might have been running on an 8- or 16-bit computer at 5 MHz.
| brookritz wrote:
| Jabdah
| sagacity wrote:
| Strange voice coming from the space!
| tzury wrote:
| Interesting.
|
| At the time we did it with Lua.
|
| We extended Nginx and Envoy-proxy with a Rust library (and a
| server), and added a Lua interface, so users can further tweak
| the config and the flow.
|
| https://github.com/zuriby/curiefense/tree/main/curiefense/cu...
| benwilber0 wrote:
| I've used OpenResty extensively which is basically just nginx +
| luajit with a lot of additional APIs and features. The nginx-
| lua-module is available separately from the OpenResty
| distribution of nginx, so you can just install and run it as a
| dynamic nginx module.
| chaosprint wrote:
| Should compare with Rhai (https://rhai.rs/)
|
| I found rhai's syntax very straightforward, and I could almost
| accomplish my needs just by looking at some basic examples.
|
| I use Rhai in wasm, and it can handle real-time audio blocks,
| which is really impressive:
|
| https://glicol.org/tour#meta2
| nine_k wrote:
| Rhai looks somehow more OO, and is somehow conceptually bigger,
| with function overloading, operator overloading, currying, etc.
| Koto looks more like FP an stream processing, with pervasive
| anonymous functions, very simple data structures, and an
| emphasis on iterators.
|
| Rhai also offers some safety guarantees: no panics, no stack
| overflows, etc. Rhai seemingly requires slightly less ceremony
| when interfacing with Rust: direct use of many things, as
| opposed to implementing a trait to interact with Koto.
|
| (Disclaimer: I spent 5 minutes skimming the docs of each.)
| esafak wrote:
| Would this compile fast enough to be used in shell scripts?
| #/usr/bin/env koto
| irh wrote:
| Yes! I'm using it for adding commands to Helix.
|
| e.g.
| https://github.com/irh/dotfiles/blob/main/scripts/.scripts/t...
| mentalgear wrote:
| > Syntax: [...] minimizing visual distractions, while also
| managing to avoid inexpressive terseness.
|
| Nice! Now, if it only had type support.
| pansa2 wrote:
| It says Coffeescript and Moonscript influenced Koto's syntax,
| which is a little worrying. IMO those languages are a little
| _too_ flexible and sail too close to ambiguity - very small
| changes to code can sometimes radically change its meaning.
|
| Edit: Sure enough, "whitespace is important in Koto, and
| because of optional parentheses, `f(1, 2)` is not the same as
| `f (1, 2)`. The former is parsed as a call to f with two
| arguments, whereas the latter is a call to f with a tuple as
| the single argument."
| nine_k wrote:
| Oh, the usual Coffeescript footguns :(
|
| One of the problems of terse syntaxes is that one typo away
| from a syntactically valid program lies another syntactically
| valid program with entirely different semantics.
|
| I prefer a syntax that has enough "gaps" between syntactic
| constructs, so that a single typo usually leads to an obvious
| syntax error. In this regard, Python or Java or TS are
| comfortable, Haskell or Lisp or C are okay, and Coffescript
| or Scala or C++ are terrible.
| Mawr wrote:
| Oh it has optional parentheses? Into the trash it goes.
|
| I'm guessing because "it's cleaner/simpler", but that's a
| shallow understanding of those words. Just because there are
| two characters fewer on the screen doesn't make the code
| simpler. Simple _semantics_ are what you should aim for and
| inconsistencies like these throw a wrench into that.
|
| For example, strings in JSON vs YAML. Isn't it "simpler" to
| not have to quote every string? So long as your string isn't
| "no" that may be true. So now instead of a simple mental
| model of "every string must be quoted" it's "strings don't
| need quotes except for these specific exceptions that cause
| issues: <list>". So much simpler... _sigh_.
| irh wrote:
| What I've had in mind with Koto is that when I need
| strictness and precision I'll generally be using Rust, and
| Koto is more intended for another aspect of programming where
| I want things to be much more fluid and easy-going.
|
| My thinking is that the potential footgun here is outweighed
| by the win of paren-free calls for quick scripting / rapid
| iteration, but it certainly counts towards the language
| strangeness budget [1] so I figured it was worth pointing out
| in the guide.
|
| [1] https://steveklabnik.com/writing/the-language-
| strangeness-bu...
| iTokio wrote:
| It has optional types
| seivan wrote:
| The documentation and integration with Rust for this amazing,
| well done! Like other commenters, I also wish it had better
| static typing and looked more like Elixir with anonymous sum
| types and template literal types.
| amadoury wrote:
| Koto means big brother in Fulani (a West African language).
| replwoacause wrote:
| Elegant syntax!
| fithisux wrote:
| Koto? Like the Italo-Disco band?
| nine_k wrote:
| Or like the Japanese musical instrument?
| https://en.wikipedia.org/wiki/Koto_(instrument)
| irh wrote:
| Yes it's named after the instrument, although I'm happy to
| hear about the Italo disco connection =)
| account-5 wrote:
| If I was going to chose a scripting language for rust I'd pick
| nushell's syntax. Nushell is an amazing shell and it's syntax is
| one of the reasons why.
| irh wrote:
| Koto creator here, nice surprise to see this on HN so I'm a bit
| late to the discussion. Happy to answer any questions!
| riidom wrote:
| Would you say Koto (or some direct competitors, for that
| matter), is viable to learn when I otherwise don't intend to
| learn Rust at all? But let's say, want to keep the option open
| to participate in Rust-based projects which support Koto et
| al.?
| irh wrote:
| Yes I would certainly hope so, you shouldn't need to know any
| Rust if you want to learn Koto. The guide assumes that the
| reader has some general experience with programming, but not
| from using any specific language.
|
| https://koto.dev/docs/next/language/
___________________________________________________________________
(page generated 2025-03-29 23:01 UTC)