There’s probably a few reasons:
First of all, LazListState is a service object, in a sense: you can call various scrollTo methods at any time. If it were a value object where you got a different instance each time, it would be more awkward to do that. Also it would require recomposing on every single frame during a scroll to update the scroll offset and layout info, which would kill performance.
Additionally, I believe another reason is similar to why we ended up moving to this shape for text fields: there’s complex internal state that need to be changed and read at different times, eg between phases, within the same frame. If you just have a value and a callback, you can’t do that, because the calling code can only give you the updated state between frames.