Есть ли язык программирования, который позволяет переопределять числа?
Мой первый удар по этой проблеме был в C
#define 2 5
assert(2+2 == 10);
к несчастью
error: macro name must be an identifier
Я тоже пробовал схему
(define 2 5)
но
can't define a non-symbol: (define 2 5)
Мне было интересно, если есть какие-либо языки программирования, где это возможно.
2 ответа
Я искренне надеюсь, что нет.
Но, тем не менее, я знаю способ в Java: вы можете использовать отражение, чтобы скорректировать значения в кэше в штучной упаковке Integer
s: JVM должна кэшировать все значения в диапазоне от -128 до +127, и существует механизм для корректировки числовых значений в этом кэше!
См. https://codegolf.stackexchange.com/questions/28786/write-a-program-that-makes-2-2-5/28818 для получения дополнительной информации. Вот код в полном объеме:
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);
}
}
Выходное значение 5, по существу, достигается путем переопределения числа 4.
Я вспомнил, что слышал историю об этом давным-давно, и сегодня я решил продолжить ее. Это последующее действие привело меня к этому вопросу, на который, к сожалению, нет точного ответа. Это тоже не совсем ответ, но... вот.
Я считаю, что это можно сделать с помощью ранних компиляторов Fortran .
Из этого поста (который является копией оригинального поста вcomp.lang.python
который я не смог отследить):
> 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!
Причина, по-видимому, связана с комбинацией:
- Постоянное стажирование
- Семантика передачи по ссылке в Фортране
Компилятор интернирует значение константы (), а затем вызывает функцию с указателем на интернированную «константу» 7.munge
функция изменяет значение переданного по ссылке целочисленного значения, и поэтому теперь значение интернированной константы равно 3.
Таким образом, это не изменит универсально значение7
к3
во всей программе, но везде, где используется это интернированное «константное» значение, теперь будет использоваться 3 в качестве его числового значения.
Это может быть необычайно удивительным (и правильно, IMO) для молодых программистов, которые имели дело только с языками, аргументы которых почти всегда передаются по значению (если не указано иное). C, C++, C#, Erlang, Java, javascript, Perl, Python, Ruby и т. д. — все используют передачу по значению. Для этих языков семантика передачи по ссылке достигается либо с помощью инкапсуляции (например, с передачей изменяемого сложного типа, такого как объект), либо с явной передачей указателя на значение вместо значения (например, с помощью&
оператор в C и подобных языках).