A Modest Proposal (for !, &, | and ~)

Here is my combination of a lot of other people’s ideas and a few of my own into what I believe is a rather consistent proposal, that would meet everybody’s needs and desires (at least, so far as not go much against other people’s).

First off, I think that the one real invariant I’ve seen for the use of ! in computer languages, is that the result is a boolean (or whatever the accepted values for true/false are, i.e. t and (), or 1 and 0, or true and false, etc.). I guess that’s why making ! to also be a bitwise operator seems so wrong to me.
The current definition makes ! not very useful, it’s only defined for Bool, Function, and Missing.
(The third one concerns me a bit, does it make sense that !missing is missing? Is that supposed to be for 3VL?)

So, my proposal:
& becomes and and , and it could be freed up for something else (I have an idea for that!), and could even still be used for a Boolean only non-short circuiting AND, which then makes .& make sense on arrays of booleans.
| becomes or and , and could then be used for piping, maybe.
$ has already become xor and (note the nice visual consistency between the Unicode or and xor :wink: )
~ (unary) becomes not and ¬, freeing up both unary and binary ~.

! could be used in a nice generic fashion with a lot of types:
! on an Integer would work as in other languages, and return true for 0, false for non-zero (i.e. the same as iszero, but much shorter), and of course would still work as always on Bool. It could also be used to like in Lisp, for isempty. !s on an AbstractString would then be the same as isempty(s) or (s == "") (that would have saved a lot of typing in my Strs.jl package!!!)
I think that having it as a generic operator that means iszero, isempty, isnull etc. would make sense, be very useful, and people would catch on to the meaning very quickly (just as they have with the use of && and || in Julia for short conditions, like isempty(foo) && break

Lastly, & would be free, and after I read Stefan’s comment (on GitHub?) that they hadn’t thought of any other use for it, I then remembered a very common use for it, in what was one of the most popular languages in the world - and it does match the semantic meaning of “and”, if I say I have foo and bar, well then, maybe that makes foobar! So then "foo" & "bar" means string concatenation, just as all those Basic versions out there.

(Waiting now for the tomatoes :tomato::tomato::tomato: to be thrown! :nerd_face::joy:)

1 Like

:tomato:

At least tell why I get the tomato! :smiley:

haha, all I read was throw tomatoes, so I threw one :stuck_out_tongue_winking_eye:.

Overall I’m a bit indifferent to the proposal: on the one hand, and/or have already been shot down a number of times, so it makes me cringe a little to see it come up again. On the other hand, going full-bore consistency w/ the bit operators is enticing (plus being able to use those operators for other things).

What was shot down was using infix and and or to replace && and ||, as short-circuiting boolean operators, which I was also rather against, having become accustomed to Julia code using && and || to make nice succint conditional statements, and the way the && and || stand out visually when reading code.
There was another idea of using and, or, and not, https://github.com/JuliaLang/julia/pull/25180, from @sacha, that I wouldn’t mind if just three lines are added :-), for the Unicode operator aliases.

:tomato:

Oh come on now! :wink: I don’t mind the tomatoes (makes me think it’s time to go make me a salad for dinner!), but please, what do you not like about this proposal (which is really just #25180 + the idea for the Unicode operators from https://github.com/JuliaLang/julia/pull/25435#issuecomment-357080669, and a couple additional thoughts of mine (really separable) about the meaning of ! as a generic operator and a possible use for & after it is freed up.

As long as I get the magic infix/prefix parser rules (not x parses as not(x), x xor y as xor(x,y), x and y as and(x,y), x or y as or(x,y)), I’m happy.

This allows to keep most source-files ascii only, which is always a plus whenever you use non julia aware tools (e.g. grep, meld, …).

In order to make life easier for bit-fiddlers, the obvious use for & is of course infix reinterpret or convert, e.g. T & x= reinterpret(T,x) (this is a joke; convert makes more sense, but I’d really like a version that never emits runtime checks or throws inexact errors if T and typeof(x) are known at compile-time).

I don’t know how difficult that would be, I haven’t looked at how alphabetic infix operators (like in) are parsed in the Scheme code yet, but that seems nice to me also.

There does seem to be a convention, at least with some integer types, to define % (or rem) with a type, to convert to that type without giving inexact errors. I use that all the time in my bit twiddling (it’s very efficient, for getting the low byte for example, foobar%UInt8)

:tomato: :tomato: :tomato: :tomato:

for

  1. opening yet another topic on this while the bit-twiddler one, which was also started by you, is still active,

  2. restarting surface syntax discussions which have been discussed ad nauseam,

  3. suggesting that the proposal

while it is very clear from recent and past discussions that many people have an issue with one element or another,

  1. making ! a catch-all for isempty, Boolean not, iszero, and isnull.
2 Likes

That was about not conflating logical not ! with bitwise compliment ~.

This is about a proposal for a solution to:

  1. the vexing problem of the inconsistencies between the various logical and bitwise operations (i.e. &, |, and ~ don’t have the function names that you might expect (and, or, not) seeing that is also xor)
  2. keeping logical not ! separate from bitwise compliment
  3. Freeing up the precious ASCII operators &, |, and ~ for other purposes.
  4. Keeping things from being too confusing (and therefor prone to bugs, especially in the case of operators having meanings that are close, but not quite the same, as what they expect) for people coming to Julia from the most used languages, which for the most part consistently use C-like expressions.
  5. Keeping very common operations for people doing lots of bit twiddling operations readable and compact, which is not the case with proposals to change &, |, ~ to bitand, bitor, and bitnot to free up those characters.

No, this has a totally new proposal, that has never been discussed before, because & was not available.
Stefan said just recently that there was no other meaning for &, but as I pointed out, millions of Basic programmers would see that logically as concatenation (i.e. in English, if I put the directory and the file name together, I get the path, so dir & filename meets the generic, semantic definition of “and”)
There was quite a bit of support for ++ (a la Haskell), but it looking like the C pre- or post-increment operator was one strike against it, along with people just not wanting to change things in their code.

I didn’t mean that people wouldn’t have an issue with one element or another, I meant that, in the spirit of compromise, it would meet their needs. A number of the objections seem to be more along the lines of “I prefer this, and I don’t want anybody else to use that” (i.e. ! vs. == 0)
I’ve already detailed those needs above.

OK, you don’t like that part, but as I said, the parts about using & for concatenation once it is freed up, and to have ! follow the invariant used in other languages (with the lone exception of Rust, AFAICT), that it always returns a boolean value, no matter the type of its operand (the same as all the relational operators), can actually be two follow on separate proposals, which I should have made clearer, and they can be debated separately.
If this proposal were accepted, then people could use & and ! how they wanted in their own code anyway, as @jeff.bezanson showed.

1 Like