"and", "or", bitwise or shortcircuit, what we get searching docs

I can relate to that.
The and keyword is available in other languages and I very much like it (readability).

In the past I had to ‘try and error’ a few times when performing element-wise AND.
A few of the following lines were (and still are) not entirely intuitive to me.

1<2 & 0<1 #false as discussed above

1<2 && 0<1 #true
(1<2) + (0<1) #2
+((1<2),(0<1)) #2

&&(1<2,0<1) # -> error (which I would not have expected)
#I guess this does not work because && is not a function?

myand(x,y) = x && y
myand(1<2,0<1) #works as expected

#elementwise 
.+(([1,2] .< [2,3]),([0,0] .< [1,1])) # [2,2]
+(([1,2] .< [2,3]),([0,0] .< [1,1])) # [2,2]
myand.(([1,2] .< [2,3]),([0,0] .< [1,1])) # works as expected

([1,2] .< [2,3]) &&. ([0,0] .< [1,1]) #this fails, which may be unexpected to some users too
([1,2] .< [2,3]) .& ([0,0] .< [1,1]) #produces the desired result (as we are working with BitVectors)
1 Like

“Bitwise” means it operates on a per-bit basis. Similar to saying “component-wise” to say something is per-component.

(truncated the leading 0s to Int16 for readability)

julia> bitstring(1000)
"0000001111101000"

julia> bitstring(90)
"0000000001011010"

julia> bitstring(1000 & 90)
"0000000001001000"

julia> 1000 & 90
72

julia> bitstring(1000 | 90)
"0000001111111010"

julia> 1000 | 90
1018

For &, only where both 1000 and 90 have a 1, the result is 1. For |, wherever at least one of them is a 1, the result is 1.

To add another note here: &, |, xor, and bitshift (<</>>, <<</>>>) are the most fundamental computer operations. All other operations (additions, multiplication, etc.) are built in hardware (and software) using circuits (and code) that perform sequences of these operations. These days you can easily get away with never learning this (I personally didn’t for years) but I think it’s nice to know…


Short-circuit has to do with cutting something off in the middle, or otherwise terminating it before the “end”. Short-circuiting comes from electrical circuits, where if two points in the circuit are connect that shouldn’t be, this creates a short-er circuit than was intended (and often also ruins the device).

julia> false && g()
false

julia> g()
ERROR: UndefVarError: g not defined
Stacktrace:
 [1] top-level scope at REPL[65]:1

g() is not defined, but in the first expression, we never even got to g(), so we didn’t run in to the error. Encountering false in a short circuit operation cuts off the evaluation of the expression prematurely. This is why it can be also be used as an if-statement. For example

condition && return _something_

is common.

5 Likes

Yes, && is not a function, it is a control flow construct, normal functions can’t have short-circuiting behavior. That’s also why it doesn’t make sense in broadcasting, because broadcasting can only work with functions. Your myand is no different here and doesn’t short-circuit:

julia> myand(false, (println("Boo!"); true))
Boo!
false
3 Likes

The constructive improvements that seem plausible are adding help entries for ?and and ?or, which can just reference && and ||. Adding cross-references between the logical operators and control flow sections with some explanation of the differences. PRs for either improvements would be welcomed.

15 Likes

Thank you Stefan for the comment. That was what I meant. I would be wiling to help with that, but it is evident that my understanding of the implications of any phrase I might suggest will likely lead to rejection of the PR (clearly I quite often get misunderstood, probably because my limited capacity to express myself in English, like the use of the “normal” word above).

If it was from my point of view I would add a paragraph stating that && means what usually (?), or normally (?), or most frequently (?) one expects (?) to mean and in a conditional evaluation. People searching for bitwise comparisons certainly know what all that is about, it is for the other people that the docs might cause confusion.

@Henrique_Becker made a pull request naming that && is what and is in Python, but I am also hesitant in explaining things by comparison between languages.

2 Likes

If you are curious, my next course (starting next week), will teach the students all the concepts necessary to write this package:

(and it is worth mentioning that since I finished what is there I learnt a lot of things about Julia with the help of people here, and I will be probably rewrite parts of that code).
Leandro

3 Likes

I opened issues for these:

7 Likes

For whatever it’s worth, here’s part of how R’s help explains && (a level of explanation I find helpful as a non-expert programmer):

& and && indicate logical AND and | and || indicate logical OR. The shorter form performs elementwise comparisons in much the same way as arithmetic operators. The longer form evaluates left to right examining only the first element of each vector. Evaluation proceeds only until the result is determined. The longer form is appropriate for programming control-flow and typically preferred in if clauses.

5 Likes

I do agree. Documenting and and or is better, if there is no style guide against documenting keywords/methods that do not exist. I never know, I should close my PR or are you people that close it?

1 Like

I don’t know for sure, but I’d be willing to bet money that any deficits of this sort would be cleared up in a review of the PR, rather than leading to outright rejection. Julia maintainers tend to be remarkable in the amount of effort they are willing to spend on newbies making PRs. Typically, I suspect, they spend substantially more time reviewing / offering suggestions etc than it would take for them to just do it themselves. At least, that was true of the one PR I made

5 Likes

I don’t plan on doing anything here, I just opened the issues, so feel free to make whatever improvements to the docs you’re willing to make.

[Opening an issue only takes a very brief context switch. Doing a Julia PR, even a doc-only one, is a fairly significant context switch, especially since I’m in the middle of trying to get a very annoying PR to Base Julia to pass tests, which were initially failing for a seemingly innumerable number of different tricky and tedious reasons. If I had nothing else in-progress in the Julia repo I might make a doc fix, but right now it’s just too costly: I almost have this PR passing tests on most platforms.]

7 Likes

Oh, I was not suggesting you would do the work. I may do it if I get some free time, but clearly the right way to solve it is the one you proposed in your PRs, not the one in my PR, so it can be closed. I use Github mostly for my own code, so I did not know the protocol (if it was me or you that should close my PR as “will not be done”).

1 Like

Neither was I. I only have the impression that someone with a deeper knowledge on programming languages can do a better job. I am always admired and thankful that you and others have even time to follow these threads. I might try do propose something asap.

1 Like

I think for documentation for constructs like these, not having a deeper knowledge can often be an advantage. Since this will mostly be aimed at newcomers, I think you can probably better relate to the things people are struggling to understand, so please don’t let this stop you from making a PR. Like @kevbonham said, people are usually glad to help with any problems you encounter and review comments can be a great way to learn!

4 Likes

I made a PR there: https://github.com/JuliaLang/julia/issues/37468

And noticed that the Mathematical Operators section was already updated some months ago to include the definition of Boolean operators before the bitwise ones, which is probably enough to avoid misunderstandings. The change is only still not yet the published version of the docs.

4 Likes

I don’t think we should document keywords in other languages in Julia docstrings. Docstrings should not become an X-to-Julia dictionary, simply because there are too many Xs. Again, we have a whole section in the manual for this purpose.

Generally, I am concerned about the tendency of extending the docs whenever people run into an issue that could have been prevented by simply reading the existing documentation.

I know that everyone means well, but such additions will inevitably lead to just bloating the docs for no good reason, leading to a vicious cycle because

  1. things will be even harder to find, and
  2. even fewer people will read through the ever-longer docs.
3 Likes

I agree in general, but I think the intention here is not so much to document other languages’ keywords, but rather to document the mapping of julia operator to the English meaning. That is, the point it’s not too say && means and, but rather that && means “and”.

7 Likes

@Tamas_Papp

  1. Note this was suggested by Stefan, not me. Not sure why you are directing your criticism to me instead of Stefan.
  2. About your first criticism “things will be even harder to find”: no, they will not, ?and and ?or currently return nothing and now they will return something, how will this makes things harder to find?
  3. About your second criticism “even fewer people will read through the ever-longer docs”: I think you are mixing distinct things, method entries are not obligatorily included in the Julia docs/manual body, they need to be explicitly linked there, what I never suggested to be done.
  4. In short, I have found Stefan suggestion better exactly because it does not change the manual in any way.
3 Likes

I don’t know about other people, but IMHO the docs are already well past that threshold. I think the best that can be done is to focus on ways to improve searchability, and if adding a few common natural language terms as search terms for certain things here and there helps that, it seems like a net positive for me.

5 Likes

My remark was against the idea in general and not directed at you, I just happened to reply to your comment because it was convenient. Sorry for the misunderstanding.

Note that all docstrings with relevant keywords turn up in searches, eg apropos. The extra cost may be minor, but there is no free lunch for the signal/noise ratio here.

So ?plus should take you to +, etc? (if not, please explain why).

1 Like