17

In Algol 68, I can declare the priority (precedence) of an operator-symbol:

    prio @ = 5;

(Higher number means higher precedence).

I can apparently redefine the priorities of built-in operators:

    begin
    prio + = 7, x = 6;
    print(2+3x4)
    end

This should result in printing the value 20, rather than the 14 that a standard parse would give.

Did actual implementations actually behave that way? With a quick scan, I see nothing in either the Informal Introduction to ALGOL 68 nor the ALGOL 68-R Users Guide to say it wouldn't. Still, I find that mutability to be a strange feature.

(I should try it and see but I don't have an ALGOL 68 system at my fingertips right now).

dave
  • 35,301
  • 3
  • 80
  • 160
  • Somewhat unrelated: In Haskell you can also declare operator precedence, so I had to quickly try to re-define existing ones, but it looks like you cannot do that without also declaring them, so that would need some tricks to make it actually work... not that anybody would actually want to do that. – dirkt Apr 07 '22 at 05:48
  • Why don't you try with an ALGOL 68 system before posting an question? – the busybee Apr 07 '22 at 05:48
  • Yes: I believe you can. Algol-68 Genie is here http://sw.ccs.bcs.org/CCs/g3/index.html and David Holdsworthy's restoration of Algol68R at http://sw.ccs.bcs.org/CCs/g3/index.html. I'll check out later and consult my copy of Lindsey and Van der Meulen – Brian Tompsett - 汤莱恩 Apr 07 '22 at 07:34
  • I have GEORGE 3 and ALGOL-68R on a computer somewhere in the basement, but have to dig it out. – dave Apr 07 '22 at 11:55
  • 2
    @thebusybee - well, I thought the question might also be of interest to the RC community. – dave Apr 07 '22 at 11:56
  • @BrianTompsett-汤莱恩 - "Holdsworth" – dave Apr 07 '22 at 11:59
  • It's implied by 0.2.2.c in the report: "Finally, in ALGOL 68, a priority-declaration and an operation-declaration permit the introduction of new operators, the definition of their operation and the extension of the class of operands of, and the revision of the meaning of, already established operators." – texdr.aft Apr 07 '22 at 17:28
  • By "the revision ... established operators" I understand I can add an overload of (say) '+' between operands of some new mode. But it wasn't necessarily clear that you could change the priority of an existing operator symbol (and the priority cannot depend on the operand modes). The Informal Introduction adds no such caveat, and of course Lindsey and van der Meulen were careful writers, but nevertheless I wasn't sure I believed it. – dave Apr 07 '22 at 22:01

2 Answers2

21

Yes you can, and it is also scoped (as you would expect with an orthogonal language like Algol 68). On Algol 68 Genie you get the following result:

C:\Users\Brian>a68g SODave.a68
        +20        +14

C:\Users\Brian>type SODave.a68 BEGIN BEGIN PRIO + = 7, * = 6; print(2+34) END; print(2+34) END

C:\Users\Brian>

  • 1
    Wow, that sounds as annoying as the True, False = False, True annoyance in earlier versions of Python :-) – paxdiablo Apr 07 '22 at 12:04
  • 5
    @paxdiablo One of my coworkers once redefined NIL on a Lisp Machine; it crashed almost immediately. And I hope we all remember that Fortran's pass-by-reference allowed reassigning numeric literals. – Barmar Apr 07 '22 at 14:27
  • 1
    Ooh are we doing this? I like #define while if. – Adam Barnes Apr 07 '22 at 16:43
  • 1
    One of the more esoteric features that no other commonly used language adopted. – cup Apr 07 '22 at 17:14
  • 1
    Do you know more information? Is the effect of these prio statements lexically scoped to the containing block? Can it be done module-wide (entire scope of a file)? – Kaz Apr 07 '22 at 17:46
  • 1
    @AdamBarnes: My favorite was #define EVER ;;. It allowed you to do this for(EVER) { ... } – Flydog57 Apr 07 '22 at 19:20
  • 2
    @kaz Scoping does apply as shown in my edited example. – Brian Tompsett - 汤莱恩 Apr 07 '22 at 21:18
  • 1
    Concur about the scoping rules. For "file-wide", that's the same as "program-wide" in Algol 68 as per the Report (implementations may have mechanisms for separate compilation), so putting the prio declarations after the opening begin would affect everything except the standard-prelude and library-prelude. – dave Apr 07 '22 at 22:08
  • @cup: "Commonly used" is definitely subjective, but FWIW, Standard ML lets you do this, too; the expression let infix 9 + in 2 + 3 * 4 end evaluates to 20, just like in the OP's example. (The infix 9 + declaration boosts the precedence of + to the max within the scope of the let ... in ... end expression.) – ruakh Apr 08 '22 at 02:54
  • @ruakh Until your posting, I've never heard or read of ML or Standard ML, even though it came out in 1973. – cup Apr 08 '22 at 08:33
  • A more interesting question is what drove them to do this in the first place. Was there some field where precedence was different from normal? There are several languages that don't have precedence (beyond left to right), but that's a different issue. – Will Hartung Apr 09 '22 at 03:29
  • @cup: Fair enough. It's not uncommon in academic CS settings; an ACM library search for "Standard ML" gets 1,342 hits, which is small but not minuscule. (Fortran gets 17,374; ALGOL, 6,031.) – ruakh Apr 09 '22 at 17:43
4

This is just an answer to @Will Hartung's query about why priority changes were added. Say there is a list with two routines

ref List ListAdd(ref List ll, int item)
ref List ListRemove(ref List ll, int item)

We can code as

ListAdd(lll, item1);
ListRemove(lll, item2);

Instead of doing that, we can define two operators

op + = (ref List ll, int ii) ref List 
op - = (ref List ll, int ii) ref List

So we can do

lll := lll + 3;
lll := lll - 4;

What if we wanted to combine the operations?

lll := lll + 3 - 4;

Since + and - are the same priority, the order is indeterminate. It could be

lll := (lll + 3) - 4

or

lll := lll + (3 - 4);

If I remember correctly, the default priority of + and - is 6. There are obscure things that you remember even though you haven't used them for 40+ years. If we want the first case, we could change the priority of + to be 7 so that the + always happens first.

Alternatively, if you do no wish to redefine priorities, do it as two separate statements or just use parenthesis.

cup
  • 2,525
  • 1
  • 9
  • 21
  • In ALGOL 68 was there a defined (by the language) associativity for operators at the same priority? – davidbak Apr 10 '22 at 22:50
  • 1
    The associated priorities are defined in pg 130, sect 10.2.3.0 of the Revised Report on the Alogrithmic Language Algol 68, http://www.softwarepreservation.org/projects/ALGOL/report/Algol68_revised_report-AB-600dpi.pdf . The associativity is not defined. I remember being caught by that when I went from the Algol68-R (from RSRE, now Qinetiq) compiler to the Algol68-S (from Cambridge Uni) compiler. – cup Apr 12 '22 at 07:10
  • Thanks, I didn't realize ALGOL 68 allowed you to define operators on data structures. – Will Hartung Apr 14 '22 at 21:16