I don’t think the use of Ref to denote that an object should be a scalar is very intuitive, especially for users new to the language. Furthermore, this usage is not mentioned anywhere in the official docs that I can find, not even in the docstring for in. One has to stumble upon it on Discourse or Stack Overflow.
However, I don’t have a concrete suggestion for what the preferred syntax should be…
If performance isn’t an issue, I go for [2,3,4] .∈ [[1,3,5]]. If there’s performance on the table then I use a 1-tuple instead (it requires one extra character ,). I find Ref cumbersome indeed — and the reason why it’s been promoted as an alternative is that there was a proposal to use &x for Ref(x) which could then be shared between ccall and broadcast, but it went nowhere.
Yeah, I suppose [2,3,4] .∈ ([1,3,5],) is not too bad, now that I think about it. I should start using that instead of Ref. I guess I’m biased because I come from R where I can do c(2, 3, 4) %in% c(1, 3, 5) and it “just works” the way I expect.
This was definitely a pain point for me initially, same use-case even. I previously did use the array or the tuple approach, but then I saw the suggestion to use Ref. I actually don’t find it too cumbersome to use although I agree that it isn’t something you are likely to stumble upon on your own.
I think it was once proposed to introduce a dedicated Scalar type, which I believe would be much more intuitive for newcomers to learn about. One problem with Ref is also that it’s mutable and will therefore always allocate, whereas Scalar could just be an immutable struct with a very minimal implementation.
I could get behind that, but calling it Scalar just feels wrong to me. It’s not a scalar; it’s a 1-element container! While it makes sense that you want broadcast to treat the thing it contains as a scalar, that’s not at all what the object itself behaves like.
So, yeah, the word Scalar might make sense to a naive user in the context of broadcast, but it’s wholly confusing everywhere else.