Adding Exclusive OR to ASH

What should we do about XOR in ASH?

  • Don't bother adding XOR

    Votes: 3 25.0%
  • XOR is ^ and expt is ** or a function.

    Votes: 7 58.3%
  • XOR is ^^ and expt remains ^

    Votes: 1 8.3%
  • None of the above

    Votes: 1 8.3%

  • Total voters
    12
  • Poll closed .

Veracity

Developer
Staff member
Ash now has arithmetic AND, OR, and NOT. Those actually suffice; you can use them to generate the other 14 truth tables. For example, a NAND b = NOT ( a AND b). And a XOR b is (a AND NOT b) OR (b AND NOT a)

Unfortunately, XOR is a common enough operation that many computer languages offer it as an operator, along with the three I added to ASH. The "usual" operator used for it is "^".

Unfortunately, ASH already uses that operator - for exponentiation. Just like Algol 60 - an obsolete language. Other languages, obsolete or not (Fortran and Python) use **. Still others (C, Java, etc.) do not offer an operator for exponentiation. Instead, they offer functions.

I'm considering adding XOR to ASH. I see three options:

1) Don't bother. If the purported XOR operator is "^", you can get it yourself like this:

a ^ b --> (a & ~b) | (b & ~a)
a ^= b --> a = (a & ~b) | (b & ~a)

Advantages: developer sloth
Disadvantages: script writer pain

2) Change ASH such that ^ is XOR (like most modern languages) and exponentiation is ** or a function.

Advantages: Modernity
Disadvantages: not backwards compatible. Existing scripts - including zlib - would need to change. Earlier versions of said scripts could not run with current versions of KoLmafia and vice versa

3) Add XOR as ^^ and ^^=

Advantages: backwards compatibility
Disadvantages: non-standard - unique, even - operator to confuse experienced programmers in other modern languages.

Vote and comment, please. Thanks.
 
In case 1, a ^ b ^ c would become ridiculously painful to type, if that were ever necessary. I personally haven't worked much with bitwise operators, so that's about all I can say. Although I do like the idea of ASH conforming to modern standards in this regard -- sure, ^ for exponentiation is probably what non-programmers are used to, considering its use in calculators, but an exp() function would make a lot more sense (it'd also be a lot easier to implement).
 
I'm a don't bother, but of the yes choices I prefer 2). We just need to announce it will be happening and be prepared for the inevitable deluge of people who feel entitled to have their scripts work unchanged. But I'm OK with that.
 
I've cast my vote for: XOR is ^ and expt is ** or a function

I'm all in favor of making ash cooler and more capable. It is good for it to grow as a real language whose functions are easily recognized by real programmers, not just hobbyists in a niche.

The biggest problem is zlib. However, I'm pretty sure that when zarqon casts his vote here he'll express that he's reasonably happy to change his use of exponents. To make that upgrade easier on him you might want to implement ** or the exponent function before you change ^ to XOR, so that the two coexist for a few days.
 
Despite my own desires, if bitwise is being added, the goal should be completeness. And since ^ is the standard for XOR, I would say option 2. As far as backwards compatibility, I admire the developers intent to keep previous 3rd party works compatible, but like KoL itself, KoLmafia is never going to be finished in the traditional sense of programming. Thus, script writers should be ready, willing, and able to adapt to any changes that come along. We must evolve or we will die.

As far as changing scripts, it's easy enough to a Find in Files for the ^. Notepad++, in fact, can use a regex to find and replace in all files by finding \^ and replacing with \*\*
 
Yeah... working to standards is good. I'd suggest a delay where ** and ^ are both exponent, and after a week or two, it goes to just **.

And Fluxxdog, that will break scripts with regexp matching currently. Which is where most of the ^ bits are.
 
As far as changing scripts, it's easy enough to a Find in Files for the ^. Notepad++, in fact, can use a regex to find and replace in all files by finding \^ and replacing with \*\*

Bad idea, since ^ might be used in a string (e.g. part of a regexp pattern that's used as an argument to create_matcher(). ([^\[])\^ replaced with \1** might be a slightly better method, since that avoids replacing ^ as used in regexes. (this is also mentioned by Theraze)
 
As usual, my preference is lacking as a poll option. :p For reference, I vote "whatever makes the KoLmafia devs happiest." I do however agree with the idea of allowing the new power() or exp() or ** or whatever to exist alongside the current ^ for a while as the transition is made, if it is made.

Also, regarding the find & replace, it isn't something that will happen often, so a verify-each find & replace should be no huge issue. Or, construct a more complicated regex. ;)
 
Also, I was wondering if (a & ~b) | (b & ~a) (what Veracity mentioned as the alternative for XOR) would be functionally equivalent to (a | b) & ~(a & b), if the latter's even proper syntax. It really doesn't make a difference; it just makes more sense (to me) to think "(a OR b) and not (a AND b)" rather than "(a and not b) or (b and not a)" -- it seems more like the definition of XOR as I learned it.

(This isn't really relevant to the discussion at hand.)
 
I suppose if the choice must be made I'd opt for ^ to be XOR (though I do hate the immediate destruction of backward compatibility... is there an ASH "checkver()" so scripters can get around this?)

Though for powers, I'd prefer exp() over **. Or perhaps both. Or... pow().. doesn't exp() generally take 1 argument and assume a base of e?
 
<slaps forehead> Wasn't even thinking of regexes using them. Was thinking more of math operators. I'll shush now ^^
 
is there an ASH "checkver()" so scripters can get around this?

It's awesome that the KoLmafia wiki has a search function 'cause I didn't remember the name of the function either: get_revision(). Though it will only help with backwards compatibility if the writers of old scripts were prescient.
 
Last edited:
Because get_revision() can only work if the script loads correctly, it's most useful in comparing to a "required version" as part of an update script (such as check_version() from zlib). But I've been making use of that since before zlib! (Had to get in on the "I've been using zlib since..." train. :p)
 
Though it will only help with backwards compatibility if the writers of old scripts were prescient.

I was thinking less in terms of Old Script on New Mafia and more New Script on Old Mafia... but as whoever below you pointed out (can't see now, I'm thinking StDoodle) whatever the new function is would cause the script to fail on load anyway.
 
Wouldn't another possibility be to actually implement XOR as just that. a XOR b?

I guess I just like ^ too much as a exponential operator and have never used bitwise operators to want to loose ^ in favour of a slightly more annoying pow() or exp().
 
Though for powers, I'd prefer exp() over **. Or perhaps both. Or... pow().. doesn't exp() generally take 1 argument and assume a base of e?

Yeah, it's usually pow(). My bad. Realized the whole thing about exp() some time after I typed that up, but by then, several folks had already started using that term.
 
Basically, what Bale said. I would be happy to edit ZLib, etc. if it allows the developers to make ASH a more featured language. ZLib also required editing when max() and min() were added to ASH, and this was a change I was all too happy to make.

As far as my preference, I like ^ for XOR, but I also like ^ for exp. This puts me in a state of irreconcilable cognitive dissonance, so basically I will be happy to go along with whatever the majority decides. I do feel, however, that exponents are more likely to used than XOR, so if one of the two must be substandard, I vote in favor of making XOR the oddball.

Perhaps x||? hehehe
 
I wouldn't say it's a consensus, but I think it's clear: I'm going to move exponentiation to ** and will add ^ as XOR a few days later.

I'll do the former today, giving time for the major scripts to get updated and a daily build to come out to support it.
I'll probably do the latter when I get home from my little work trip to Boston, next Monday. And I'll spin a new release then.
 
It's probably best to also make this change to the modifier_eval() function if possible, for consistency. Presently modifier_eval() still assesses ^ as exponentiation, and doesn't understand **.
 
Back
Top