masak / bel

An interpreter for Bel, Paul Graham's Lisp language
GNU General Public License v3.0
26 stars 1 forks source link

Add a test to capture the fact that 'some' returns a lexical variable and can't be used for modifying the tail of the input list #432

Open masak opened 1 year ago

masak commented 1 year ago
Language::Bel 0.63 -- darwin.
> (set L '(1 2 3 4 5))
(1 2 3 4 5)
> (some (is 3) L)
(3 4 5)
> (set (some (is 3) L) '(10 20 30))
(10 20 30)
> L
(1 2 3 4 5)

Expected that last one to be (1 2 10 20 30).

Seems not only is this one busted, but maybe we also don't have a test for something like this.

masak commented 1 year ago

Not a bug. The final (1 2 3 4 5) is correct.

It would be nice if (set (some ...) ...) worked like that, but it simply doesn't. Recall the definition:

(def some (f xs)
  (if (no xs)      nil
      (f (car xs)) xs
                   (some f (cdr xs))))

Note in particular the xs being returned in the second branch. That's a parameter, so it's a lexical variable. That's the thing that gets modified by set later; it happens (which is why there's no error) but it's not visible.

The fastfunc implementation substantiates this. It's correct.

Seems not only is this one busted, but maybe we also don't have a test for something like this.

It's not busted, it turns out. But I agree with OP that a test for this would be better. Going to rename the issue to reflect this.

The originally-expected behavior for some feels like it could have been useful. I wonder if it can be implemented to do that.