Live data from Hacker News

Lisp implemented in Rust macros

github.com

71–80 of 85 posts

Re: Lisp implemented in Rust macros

#71

But C++ is not a sane language because templates are Turing-complete, right?

C++ is not a sane language for anyone with a passing familiarity. At least Rusts macros aren't literal text substitutions, a move towards the light.

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.

Re: Lisp implemented in Rust macros

#72

But C++ is not a sane language because templates are Turing-complete, right?

C++ templates are a hell to develop with, at least macro_expand is a thing in Rust. It's the fact Rust's tooling is so well done.

There are C++ template debugging tools in IDEs.

Re: Lisp implemented in Rust macros

#73
post #62
post #48

Earlier quoted context omitted.

The only real change since 1.0 was async. If you want to live without async that is completely up to you. It is an entirely optional part of the language. If you want a language guided by the principle of simplicity Rust was never that and you have plenty of options elsewhere.

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.

One trick to get out of this is to wrap any function with an asynchronous interface with pollster::block_on which turns the call back into exactly how it would have run if it had been synchronous (which leads to no color leaking).

Re: Lisp implemented in Rust macros

#75
post #64

Greenspun's tenth rule strikes again! https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule

A great example of the rule is that C++ rediscovers car/cdr at a glacial pace in the template language. In C++26 one can finally get the car of a typename parameter pack with Args...[0]. 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.

Store where?

C++ templates are a lambda calculus, there's no notion of memory cells or state.

Re: Lisp implemented in Rust macros

#76
post #62

Earlier quoted context omitted.

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.

One trick to get out of this is to wrap any function with an asynchronous interface with pollster::block_on which turns the call back into exactly how it would have run if it had been synchronous (which leads to no color leaking).

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.

Re: Lisp implemented in Rust macros

#78
post #64

Earlier quoted context omitted.

A great example of the rule is that C++ rediscovers car/cdr at a glacial pace in the template language. In C++26 one can finally get the car of a typename parameter pack with Args...[0]. 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.

Store where? C++ templates are a lambda calculus, there's no notion of memory cells or state.

In a struct! Pseudo code for extracting the types from subclasses and calling a multimethod on them:

  template 
  struct Foo : Visitor {
    Result res;
    UntypedList lst; // This does not exist!
    Tail... tail;    // This is not possible!
    Foo(UntypedList l; Head hd, Tail... tl) : lst(l), tail(tl) {
      hd->accept(*this);
    }
    void visit(float *f) {
      res = Foo(append(lst, f), tail)::res; }
    }
  };
 
  // Base case that calls the multimethod omitted.
There are two issues here: You can't store the parameter pack in Foo() which is later required by the continuation in visit(). And you would have to use tuples and tuple_cat() instead of UntypedList.

Why can the compiler not infer the types in such an UntypedList? Why is there no car/cdr for tuples?

Re: Lisp implemented in Rust macros

#79
post #14

Earlier quoted context omitted.

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, 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 t…

> 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…

> 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

Re: Lisp implemented in Rust macros

#80
post #26

Earlier quoted context omitted.

No, I think it's pretty fair. One could argue about these, but except for "slow" these are more quality qualifiers, rather than quantity. So you either agree it's "bug-ridden" or not (i.e. the number and seriousness of bugs in it is negligible by whatever standards). And I think even "slow" can be discussed in the same manner, the actual speed is quantitative, of course, but in the end one either argues that this spe…

A man of culture would never refer to an epigram as a definition.

Which culture? What about women? What a strange comment.
Post reply on HN