![]() |
|
![]() |
| C++ metaprogramming was done with cons cells already back in '98. The new syntax provides random access instead, which is completely different from linked lists. |
![]() |
| The corollary to Greenspun’s rule is that any sufficiently complicated Common Lisp program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Prolog. |
![]() |
| Although in a Lisp such as Scheme, you could pass around the negation operator in something like (map - '(1 2 3)), so it would be a valid concern that it might clash. |
![]() |
| The problem with that is that there are spaces between map, -, and '(1 2 3). The only way to get spaces into a name is by using vertical bars:
|
![]() |
| It's almost but not quite arbitrary. It still has to be a valid Rust token stream with matching braces/parens. Since it's whitespace insensitive with respect to tokens and "-" is its own token, "(foo-bar)" and "(foo - bar)" result in the same token stream minus the span information.
You can use proc_macro::Span.line()/column() [1] to track how much whitespace there is between tokens and merge them, but the macro will have to rename them to valid Rust identities ("foo-bar" to "foo_bar") and make sure there's no collisions. [1] https://doc.rust-lang.org/proc_macro/struct.Span.html#method... |
![]() |
| > 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_arr... (and not even hash-tables, these are completely untyped!). |
![]() |
| > 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
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:
Now you can even type-check on lambda expressions, and quasiquotation can sidestep the issue of capturing variables.
https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node44.html |
![]() |
| Steel 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. |
![]() |
| Implementing a lisp in the type system would be fun, that's originally what this project was about until I got distracted with macros. Awesome projects like fortraith (https://github.com/Ashymad/fortraith) already exist, and even far more useful projects like dimensioned (compile time dimensional analysis using type level numbers) are inspiring. These examples, although cool, are probably a worse sign for krick for Rust compared with macro_rules being Turing complete.
|
![]() |
| Except that many crates only provide an async interface. I actually use async for many things, but the whole colored functions thing is really annoying. |
![]() |
| Yes, easy enough but annoying. Going the other direction (async -> sync) is a bit more problematic though. Now you've got to wrap things in spawn_blocking(), which isn't nearly as benign. |
![]() |
| C++ templates, coupled with compile time programming, and eventually static reflection, make it easier than the multiple macro languages from Rust, with the additional dependency on syn crate. |
I've no idea why they don't introduce car/cdr functions and nil for empty parameter packs and allow to store parameter packs instead of the current syntax insanity.