Steel – An embedded scheme interpreter in Rust

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • WorkOS - The modern identity platform for B2B SaaS
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • SaaSHub - Software Alternatives and Reviews
  • steel

    An embedded scheme interpreter in Rust

  • Basically the differences are in the concepts you'll use to write code. Lisps themselves are very different from each other, but just like the languages you're used to, lisps have standard libraries that can be called, and those building blocks can be used to build applications or whatever else. In this case specifically, Steel provides the facility to call Rust functions within a Steel program: https://github.com/mattwparas/steel.

    So, although I haven't used Steel, it looks like the advantage you'd get from using it is the opportunity to take advantage of features it provides like transducers and contracts, which are feature common to other Lisps as well.

    So, just like choosing any other language, it boils down to a series of tradeoffs.

  • glsp

    The GameLisp scripting language

  • 3. Typed Racket

    I almost used https://gamelisp.rs/ for a project but the nightly feature it needs broke and it's no longer maintained, glad to see something similar arise! You might want to consider adopting their choice of VecDeque as a list replacement, I think it makes a lot more sense than naive linked lists on modern machines.

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
  • im-lists

    Immutable unrolled linked lists

  • To answer each of these:

    1. I do support parameters now, syntax parameters not yet. I would like to! But Racket has a pretty hefty head start on me so it'll take some time.

    2. Right now I have syntax-rules macros, I also have defmacro style macros that get used internally in the kernel during expansion, but haven't yet opened them up for user space yet. Syntax case will be coming soon hopefully.

    3. The odds of me being able to come up with an implementation to match typed racket pound for pound is pretty low. I have toyed with using contracts as types (where possible), with medium/promising success in certain situations. I have a soft spot for racket and have been modeling behavior after it, however it will take time to be able to create a macro system powerful enough to match it. It wouldn't be impossible to create an alternative syntax to just lower to steel after type checking, but I haven't put time into that.

    On the list type - the list in use currently is an unrolled linked list https://github.com/mattwparas/im-lists, which I've found to yield much better performance for iteration than the naive linked lists. When possible, the vm does some in place mutation on the lists as well when consing, which helps performance as well. I also can hot swap for a vlist, but at the moment have stuck with unrolled linked lists.

  • embedded-scripting-languages

    A list of embedded scripting languages

  • Hopefully the linked README provides a general overview (I know I need to write some more documentation!), but Steel is an implementation of the scheme programming language (not entirely compliant yet, but aiming for R5RS and R7RS compliance). It can be used as a standalone language via the interpreter/repl (like Python or Racket), or it can be embedded inside applications, like Lua. There are hundreds (thousands, probably) of embeddable languages, each with their own flavor - see a list compiled here for example https://github.com/dbohdan/embedded-scripting-languages

    Use cases are generally for either configuration, scripting, or plugins - so scripting in games, or adding extensions to your text editor without having to use FFI or RPC + serializing a bunch of data. The advantage it has over using dynamic libraries (in general) is it runs in the same process, and can access the internal data structures directly without a lot of ceremony involved. The downside is typically is not as fast as native code unless a JIT is involved.

    Javascript is an example of an embedded scripting, where the browser is the host application.

  • bacon-rajan-cc

  • Thanks for the recommendation, with some brief poking around it does seem promising! It looks like the algorithm is this? https://github.com/fitzgen/bacon-rajan-cc

    The link to the paper seems dead unfortunately from this blog post https://nim-lang.org/blog/2020/12/08/introducing-orc.html

    I could see how it works as a drop in replacement for Rc

  • samsara

    a reference-counting cycle collection library in rust

  • There are concurrent GC implementations for Rust, e.g. Samsara https://redvice.org/2023/samsara-garbage-collector/ https://github.com/chc4/samsara that avoid blocking, except to a minimal extent in rare cases of contention. That fits pretty well with the pattern of "doing a bit of GC every frame".

  • clojure-toolbox.com

    Source to clojure-toolbox.com

  • InfluxDB

    Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.

    InfluxDB logo
  • component-model

    Repository for design and specification of the Component Model

  • A. Sure, but it isn't sufficiently beneficial for the cost.

    B. WebAssembly is immature for developing a plugin system because of the lack of a sufficient ABI: https://github.com/WebAssembly/component-model

    C. There aren't any other languages that meet the criteria. Lua was a no-go from the start. The maintainers did not like the language, and it necessitated adding more C code to Helix which could complicate building even further. https://github.com/helix-editor/helix/discussions/3806#discu...

  • helix

    A post-modern modal text editor.

  • A. Sure, but it isn't sufficiently beneficial for the cost.

    B. WebAssembly is immature for developing a plugin system because of the lack of a sufficient ABI: https://github.com/WebAssembly/component-model

    C. There aren't any other languages that meet the criteria. Lua was a no-go from the start. The maintainers did not like the language, and it necessitated adding more C code to Helix which could complicate building even further. https://github.com/helix-editor/helix/discussions/3806#discu...

  • coalton

    Coalton is an efficient, statically typed functional programming language that supercharges Common Lisp.

  • Use an editor that auto-inserts parens and that indents the code correctly. Now nothing bad can happen. And the parens are used to edit code structurally.

    re typing: Coalton brings Haskell-like typing on top of CL. https://github.com/coalton-lang/coalton/ Other lisps are typed: typed racket, Carp… and btw, SBCL's compiler brings some welcome type warnings and errors (unlike Python, for instance).

  • im-rs

    Assorted immutable collection datatypes for Rust

  • They're using hash array mapped tries. I don't have my own personal implementation, I have been using https://github.com/bodil/im-rs until I can get around to making my own implementation (not that I really need to, but it would be a fun exercise).

    Functions generate a hash based on a unique id generated for the function, plus the hash of any captured variables, and a hash of the pointer address to the function). That is off the top of my head though so I could be missing some details.

    Hashing maps is tricky! With a sufficiently deep hash map you can run into problems since that invokes an equality check as well - at least how I handle it, is that you just attempt to naively hash the keys and values of the hash map, to create a hash code for that object. If the equality check ends up with a sufficiently large depth, eq returns false so we don't stack overflow.

  • rune

    An embeddable dynamic programming language for Rust. (by rune-rs)

  • A Lisp, a weird dialect of Lisp, is not better than Lua. Why use Rune [0]?!

    [0]: https://rune-rs.github.io/

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts