brundonsmith / rust_lisp

A Rust-embeddable Lisp, with support for interop with native Rust functions
234 stars 20 forks source link

Add comparable type codes to Value #26

Closed Qix- closed 1 year ago

Qix- commented 1 year ago

This allows a Value to decay to a Type via Value::ty() (named such since otherwise it'd have to be Value::r#type()). It's useful for a variety of typechecking casees.

This will conflict with #25 a bit, so either this PR or the other one will need to be updated when the opposite lands.

brundonsmith commented 1 year ago

Do you have a use-case and/or a precedent in an established lisp (common lisp, scheme, clojure, etc) for this feature?

I could imagine it maybe being useful, but I try to keep this library minimalist and not go too far into hypotheticals. It does seem like most of the cases where you'd use this would be nearly as well-served by matching over the main Value enum, so I just wanted to make sure the feature is justified

Qix- commented 1 year ago

Yes, all of my PRs here stem from me trying to use this library. :)

I had a bunch of configuration keys I wanted to set from lisp and needed to make sure thay the values for each key matched a certain type. Needed to store a hash map of the string=>type mapping but no type enum existed without comparing strings (via .type_name()).

brundonsmith commented 1 year ago

Ah, so you've got like a schema in Rust from property name "foo" to type String and you wanted to represent those as a hashmap, and set the actual values from lisp and then validate them against the hashmap?

You should be able to accomplish roughly the same thing like this:

properties.iter()
  .all(|property|
    match property.name {
      "foo" => matches!(property.value, Value::Int(_)),
    }
  )

In TypeScript I would definitely go the other way- lay out the data as a global const and then just check against it. But I've found Rust tends to lend itself more to the above kind of approach, where things are done with code instead of constant data

Apologies if I come off as a stickler with these requests 🙂 I would be very excited to have more people using it, I just also want to make sure it sticks to its goals of being simple and clean and focused, so I want to treat any additions with a critical eye

But with that said, I intend to keep working through each of these issues with you and make sure it's possible to serve your use-case, in one way or another

Qix- commented 1 year ago

Yes that's of course possible, but not very ergonomic in the case that the hash map needs to be managed at runtime. Match statements cannot be extended ad hoc.

As an aside, while the debate is of course a little frustrating at times, it's exactly why I appreciate the Rust community, so by all means please keep doing so. I think we end up with a better result in the end than if we hadn't! :)

Qix- commented 1 year ago

Actually. I thought about this some more. A hash map that has a fn(&Value)->bool value type isn't a problem. Then matches! can be used appropriately. Wouldn't that work? (not close to a Rust tool chain at the moment to be able to test, just thinking out loud...)

Qix- commented 1 year ago

Yeah this is workable. https://godbolt.org/z/Eaxehf818 I'll do that instead :)