В конечном итоге мы говорим здесь о времени компиляции и времени выполнения.
Ошибки времени компиляции, если вы об этом думаете, в конечном итоге сводятся к тому, что компилятор может определить, какие проблемы у вас есть в вашей программе еще до ее запуска. Это явно не компилятор "произвольного языка", но я вернусь к этому в ближайшее время. Однако компилятор во всей своей бесконечной мудрости не перечисляет все проблемы, которые могут быть определены компилятором. Частично это зависит от того, насколько хорошо написан компилятор, но основная причина этого заключается в том, что во время выполнения определяется множество вещей .
Ошибки во время выполнения, как вы хорошо знаете, я уверен, что и я, это любой тип ошибок, возникающих во время выполнения самой программы. Это включает деление на ноль, исключения нулевого указателя, проблемы с оборудованием и многие другие факторы.
Природа ошибок во время выполнения означает, что вы не можете предвидеть эти ошибки во время компиляции. Если бы вы могли, они почти наверняка были бы проверены во время компиляции. Если бы вы могли гарантировать, что число равно нулю во время компиляции, то вы могли бы сделать определенные логические выводы, например, деление любого числа на это число приведет к арифметической ошибке, вызванной делением на ноль.
Таким образом, очень реальным образом, враг программного обеспечения правильного функционирования программы выполняет проверки во время выполнения, а не проверки времени компиляции. Примером этого может быть динамическое приведение к другому типу. Если это разрешено, вы, программист, по существу переопределяете способность компилятора знать, безопасно ли это делать. Некоторые языки программирования решили, что это приемлемо, в то время как другие по крайней мере предупредят вас во время компиляции.
Другим хорошим примером может быть то, что пустые значения могут быть частью языка, поскольку исключения пустых указателей могут произойти, если вы разрешите пустые значения. Некоторые языки полностью устранили эту проблему, запретив переменным, которые не были явно объявлены, содержать пустые значения для объявления без немедленного присвоения значения (например, Kotlin). Хотя вы не можете устранить ошибку времени выполнения исключения нулевого указателя, вы можете предотвратить ее возникновение, удалив динамическую природу языка. В Kotlin вы, конечно, можете принудительно устанавливать нулевые значения, но само собой разумеется, что это метафорический «покупатель, остерегайтесь», поскольку вы должны явно заявить об этом.
Не могли бы вы концептуально иметь компилятор, который мог бы проверять ошибки на каждом языке? Да, но, скорее всего, это будет неуклюжий и крайне нестабильный компилятор, в котором вы должны обязательно указать язык, скомпилированный заранее. Он также не мог знать много вещей о вашей программе, так же как компиляторы для определенных языков не знали о ней некоторые вещи, такие как проблема остановки, как вы упоминали. Как выясняется, довольно много информации, которую было бы интересно узнать о программе, невозможно найти. Это было доказано, поэтому вряд ли изменится в ближайшее время.
Возвращаясь к вашей основной точке. Методы не являются автоматически потокобезопасными. Для этого есть практическая причина, которая заключается в том, что безопасные для потоков методы также медленнее, даже когда потоки не используются. Rust решает, что они могут устранить проблемы во время выполнения, сделав методы потокобезопасными по умолчанию, и это их выбор. Это приходит по цене, хотя.
Может быть возможно математически доказать правильность программы, но это будет с оговоркой, что у вас будут буквально нулевые функции времени выполнения в языке. Вы сможете читать этот язык и знать, что он делает, без каких-либо сюрпризов. Язык, вероятно, выглядел бы очень математически по своей природе, и это, вероятно, не случайно. Второе предостережение заключается в том, что по- прежнему возникают ошибки времени выполнения , которые могут не иметь ничего общего с самой программой. Таким образом, программа может быть доказана правильной, принимая ряд предположений о том компьютере, которая запускается на точности и не изменяется, что, конечно , всегда это произойдет в любом случае и часто.