spy16 / slurp

Slurp is a highly customisable LISP toolkit for Go applications. 💻

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bug: vector is empty after evaluation

spy16 opened this issue · comments

Looks like the vector result after eval is empty. This happens in the REPL when I run go run examples/simple/main.go and enter [ 1 2 3]. Also trying to execute [a b c] (where the vars are not bound) doesn't cause an error. (Seems to be happening both before and after #10)

@lthibault Any clues? I have not tried to go through the code on the vectors yet.

This was a strange one to debug. All the tests passed, and the problem wasn't in the vector code ... it was in the readVector macro! I was trying to be clever (sorry ... 😞) by doing this:

func readVector(rd *Reader, _ rune) (core.Any, error) {
	const vecEnd = ']'

	v := builtin.EmptyVector.Transient()
	return v.Persistent(), rd.Container(vecEnd, "Vector", func(val core.Any) error {
		v.Cons(val)
		return nil
	})
}

... which of course results in the call to Persistent() being made before the call to rd.Container(...) 😬 .

I'm pleasantly surprised that it failed in such an obvious way, though. I would have expected this to nevertheless produce correct-looking results due to the persistent vector being mutated by subsequent calls to its transient. This would have been really nasty in terms of concurrency bugs, but somehow it doesn't seem to happen here! I think what's happening is that Persistent() ends up copying the vector's struct, so the cnt field no longer gets updated by the transient. So although the nodes are mutated (!!!😱!!!), empty transients are a special case where it will at least appear that they have not changed ... until you try comparing/hashing the resulting vector.

At any rate, please see #12. I'm off to check if I've done the same stupid thing in Wetware...! Thanks for catching this!