Is there a programming language which allows the redefinition of numbers?

277 Views Asked by At

My first stab at this problem was in C

#define 2 5
assert(2+2 == 10);

Unfortunately

error: macro name must be an identifier

I also tried Scheme

(define 2 5)

but

can't define a non-symbol: (define 2 5)

I was wondering if there are any programming languages where this is possible.

2

There are 2 best solutions below

2
On

I sincerely hope not.

But that said, I do know of a way in Java: you can use reflection to adjust the values of the cached boxed Integers: a JVM must cache all values in the range -128 to +127, and there does exist a mechanism to adjust the numeric values in that cache!

See https://codegolf.stackexchange.com/questions/28786/write-a-program-that-makes-2-2-5/28818#28818 for more details. Here's the code in full:

import java.lang.reflect.Field;
public class Main {
    public static void main(String[] args) throws Exception {
        Class cache = Integer.class.getDeclaredClasses()[0];
        Field c = cache.getDeclaredField("cache");
        c.setAccessible(true);
        Integer[] array = (Integer[]) c.get(cache);
        array[132] = array[133];

        System.out.printf("%d", 2 + 2);
    }
}

The output is 5, essentially achieved by redefining the number 4.

0
On

I remembered hearing a story about this long ago, and today I decided to follow-up on it. That follow-up lead me to this question which unfortunately isn't exactly answered. This isn't exactly an answer, either, but ... here ya go.

I believe this can be done with early Fortran compilers.

From that post (which is a copy of an original post to comp.lang.python which I haven't been able to track-down):

>     subroutine munge (i)
>     i = 3
>     return
>and then in your main program did:
>     j = 7
>     call munge (7)
>     write (6, 11) j
> 11    format ('j = ', i6)
>it would print 3!

The reason seems to be due to a combination of:

The compiler interns the constant value (7) and then calls the munge function with a pointer to the interned "constant" 7. The munge function changes the value of the passed-by-reference integer value and so now the interned constant value is 3.

So, this won't universally change the value of 7 to 3 across the whole program, but anywhere that interned "constant" value is used will now be using 3 as its numeric value.

This can be extraordinarily surprising (and rightly so, IMO) to younger programmers who have only dealt with languages whose arguments are almost always passed by value (unless otherwise specified). C, C++, C#, Erlang, Java, javascript, Perl, Python, Ruby, etc. all use pass-by-value. For those languages, pass-by-reference semantics are achieved either using encapsulation (e.g. passing a mutable complex type such as an object) or explicitly passing a pointer to a value instead of the value (e.g. using the & operator in C and similar languages).