Ask HN: What programming languages distinguish between “old” and “new” values?

https://news.ycombinator.com/item?id=32030553
by aappleby • 4 years ago
1 8 4 years ago

Suppose I have this trivial C++ program:

  #include <stdio.h>

  int a = 0;
  int b = 0;

  void update_state() {
    a = b + 1;
    b = a + 1;
  }

  int main() {
    for (int i = 0; i < 3; i++) {
      update_state();
      printf("%d %d\n", a, b);  
    }
    return 0;
  }
This will print
  1 2
  3 4
  5 6
which shouldn't be too surprising. What it does _not_ print is:
  1 1
  2 2
  3 3
because "b = a + 1" is reading the "new" value of A, not the "old" value as you might expect if you were a new programmer just skimming through the source. If we wanted that behavior we could write
  void update() {
    int a_old = a;
    int b_old = b;
    a = b_old + 1;
    b = a_old + 1;
  }
or
  void update() {
    int a_new = b + 1;
    int b_new = a + 1;
    a = a_new;
    b = b_new;
  }
but in both cases we have to introduce new temporary variables to hold a copy of either the "old" or "new" state so we don't clobber one of them. If we could annotate our variable names with "oldness" and "newness" we could write something like this:
  void update() {
    a_new = b_old + 1;
    b_new = a_old + 1;
  }
But that won't work in plain C because "_old" and "_new" aren't meaningful suffixes. More importantly, we can't realistically implement any way of explicitly distinguishing between old and new values in C++ at all - classes and templates don't quite give us enough flexibility to do so.

In this trivial example it's easy to see why the different update() methods produce different results, but in large systems it's surprisingly easy to introduce subtle bugs by changing the order of function calls : ClassA expects to read some "new" state from ClassB, code gets refactored, ClassA now inadvertently reads "old" state from ClassB, everything appears to work fine until one day a timing issue causes ClassA and ClassB to get out of sync and everything blows up.

After looking around at existing programming languages (and some CS papers from Google Scholar), it doesn't appear that any major programming languages support this sort of annotation. The closest you can get is the "<=" operator in Verilog, which means something like "assign the RHS to the LHS, but don't do it yet - do it after the current simulation step is done running".

I feel like this is probably a thoroughly covered topic already, but my research skills are failing to turn up anything relevant. Is there some computer sciencey term I'm unaware of to describe languages that allow for these sorts of old/new distinctions?

Related Stories

Loading related stories...

Source preview

news.ycombinator.com