5 ms·
I wish there was a well-supported Lisp in Rust, not just the macros. I wonder how much memory safety you would retain or lose being based in Rust. Is it even po
by gleenn 2y ago
I wish there was a well-supported Lisp in Rust, not just the macros. I wonder how much memory safety you would retain or lose being based in Rust. Is it even possible to leverage the borrow checker any any sane way?
- alilleybrinker 2y agoSteel seems alright: https://github.com/mattwparas/steel https://github.com/mattwparas/steel There are other Lisps too (https://github.com/alilleybrinker/langs-in-rust https://github.com/alilleybrinker/langs-in-rust) though I think they’re less actively maintained.
- robinsonrc 2y agoSteel has worked well for me as far as I’ve used it. It’s easy to get going and the partnership with Helix will surely give it a popularity boost over the next year or so.
- dokyun 2y agoSome Lisp compilers like SBCL are already capable of more extensive compile-time type-checking, but its information that the programmer is up to supply, and tends to be the part of the optimization stage rather than normal, incremental development. Lisp is usually defined by its dynamic nature, and run-time type checking is a big part of this. Making the programmer have to worry about how objects are managed before the fact would conflict with the freedom and expressibility one would expect from such a system. It also makes the compilers themselves simpler in comparison: Normal code without any extra declarations is safe by default, some systems might ignore such declarations for always being 'safe' (say if you're on a bytecode VM like CLISP or a Lisp machine that does hardware type-checking). SBCL compiles code quite quickly--so I've heard others tend to be even faster; the Rust compiler on the other hand is more likely to introduce a young programmer to the concept of thrashing. I really see them as two mutually incompatible worlds although they may not seem to be at first glance. One thing to remember is that Lisp is essentially the flagship "The Right Thing" language, while C is the "Worse is Better" language. Rust is neither, it is something entirely different which I think is overdue for a name, perhaps something that reflects the losing characteristics of both philosophies. (This isn't to discredit the OP article: it's still a cool hack!)
- wild_egg 2y ago> perhaps something that reflects the losing characteristics of both philosophies. Oof. With how much love Rust gets here, I didn't expect to see it being called out like that. How about "The Worse Thing"?
- BoingBoomTschak 2y ago> Some Lisp compilers like SBCL are already capable of more extensive compile-time type-checking, but its information that the programmer is up to supply Which is nice and all, but very much gimped by the glaring holes in CL's typing tooling: you can't create actual types, only derived types (deftype) and struct/class types. The two consequences of that is that you can't type cons-based lists/trees (arguably THE Lisp data structure) because deftype can't be recursive and you can't create parametric types, it's an internal thing only used for https://www.lispworks.com/documentation/HyperSpec/Body/t_array.htm https://www.lispworks.com/documentation/HyperSpec/Body/t_arr... (and not even hash-tables, these are completely untyped!).
- dokyun 2y ago> you can't type cons-based lists/trees (arguably THE Lisp data structure) because deftype can't be recursive and you can't create parametric types (deftype list-of (type) `(cons ,type (or null (list-of ,type)))) (typep '(1 2 3 4) '(list-of integer)) => T Most of the standard types from which derived types can be made are parametric types, which specialize on their arguments in different ways. They work the same way as macros. One upon a time I wrote a type specifier that allows you to specialize on a lambda expression, using the ordinary 'satisfies' type that only lets you provide named functions: (deftype satisfiesp (function) (let (predicate) (cond ((symbolp function) (setq predicate function)) ((functionp function) (setq predicate (gensym)) (setf (symbol-function predicate) function)) ((and (consp function) (eq (car function) 'lambda)) (setq predicate (gensym)) (compile predicate function)) (t (error "~S is neither a lambda expression, function or symbol." function))) `(satisfies ,predicate))) Now you can even type-check on lambda expressions, and quasiquotation can sidestep the issue of capturing variables. (defvar foo 'bar) (typep 'bar `(satisfiesp (lambda (x) (eq x ',foo)))) => T https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node44.html https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node44.html