I think you’re seeing that type instability because foo is global, and f closes over that global variable, so between two calls of f the complier doesn’t know that foo hasn’t changed into some other type.
you may want to pass foo as an argument to f, or create foo inside a function and return the closure f.
It was only for the example. In practice I wanted to use the broadcasting f() = getfield.(foo.bars, :x).
While trying to find the source of instability it boiled down to the non-broadcasted call.
I have to look again because I do see type instability in my code but there it is not global scope.
If the variable that f is closing over has some sufficiently-complicated stuff going on with it, it’s possible that the compiler can’t prove that it’ll never change type so it’s doing the dynamic dispatch you’re seeing.
You could try putting a let foo=foo block around your f closure definition to see if that helps.
Actually, I simply used [bar.x for bar in foo.bars] instead of the broadcast. It’s old code that I’m optimizing so I think didn’t know this notation back then.