Подтвердить что ты не робот

Что препятствует тому, чтобы статически типизированный язык имел что-то вроде Ruby method_missing?

У меня нет большого опыта работы со статически типизированными языками (в настоящее время изучаю Scala и любя его!), но я заметил, что они никогда не имеют ничего похожего на Ruby method_missing или ColdFusion onMissingMethod. Есть ли какое-то присущее ограничение в статически типизированных языках, которые мешают или затрудняют это?

4b9b3361

Ответ 1

Конечно, может быть добавлен механизм их обработки, но он не согласуется с тем, что статическая типизация: определение времени компиляции в вашей программе не содержит ошибок типа.

Добавление

Scala 2.9 введен экспериментальный вариант, позволяющий эту динамическую обработку доступа к типам таким образом, чтобы в противном случае была бы невозможна проверка статического типа. Он был усовершенствован и не был экспериментальным в 2.10, хотя он по-прежнему контролируется флагом функции по умолчанию. Вы можете прочитать об этом в документе SIP 17. См. SIP 18 для объяснения Scala 2.10 "модуляции" и флагов функций.

Ответ 2

Scala версия 2.9 вводит эту функциональность с помощью признака Dynamic (scaladoc). Классы, которые расширяют Dynamic, получают магический метод applyDynamic(methodName, args), который аналогичен Ruby method_missing. Начиная с Scala 2.9, параметр -Xexperimental должен быть включен для использования Dynamic.

Ответ 3

В статически типизированных языках функции-члены вызываются напрямую. Если компилятор не может определить, какую функцию-член вызывать, программа не будет компилироваться. Вызов метода в этом смысле статичен.

В динамически типизированных языках функции-члены не вызываются напрямую. Скорее, вызывающий код отправляет сообщение объекту, а затем среда выполнения языка определяет, что делать с этим сообщением. Например, среда выполнения сканирует объект для метода с тем же именем и затем сканирует объект для метода с именем method_missing. Вызов метода в этом смысле является динамическим.

С# 4 сочетает статическую типизацию с динамической типизацией. Переменная может иметь тип времени компиляции dynamic. Любые вызовы методов для этой переменной будут обрабатываться так же, как и в динамически типизированных языках. Любые вызовы методов для переменных со статическими типами будут обрабатываться как в статически типизированных языках.

# static invocation, bound at compile time by the compiler
var s = 6;
s.ToString();

# dynamic invocation, handled at runtime by the CLR
dynamic d = 6;
d.ToString();

Ответ 4

Просто для дальнейшего сообщения Рэндалла это возможно, но причина, по которой он идет против статической парадигмы, заключается в том, что она выходит за рамки "динамической отправки". Динамическая отправка с радостью позволяет вам отправить функцию, динамически связанную с известной статической частью кода. то есть компилятор устанавливает отправку, которая детерминированно выполняется во время выполнения, с ее точки зрения.

Что делает вызов method_missing, по сути делает "catch all", где вы решаете, что делать на основе имени метода, используя оператор switch или что-то эквивалентное (что, я уверен, вы знаете). Таким образом, компилятор понятия не имеет, что произойдет здесь. Скажем, компилятор сделал что-то вроде:

if (function is known at compile time)
{
  provide static call or dynamic call to "some" derivation
}
else
{
  bind the function call to obj.method_missing(...) and pass in the "details"
}

Затем вы должны указать method_missing следующим образом:

def method_missing(intendedFunctionName, arguments)
{
  if (intendedFunctionName is "X")
  {
    X may not need arguments, so just do something
  }
  else if (intendedFunctionName is "Y")
  {
    Y expects 5 arguments of varying types
    Throw exception if there isn't the right number or types
  }
  ... etc ...
}

Попросив компилятор отправить вам произвольные (т.е. неизвестные во время компиляции) аргументы произвольных типов с intendedFunctionName, которые вы, возможно, не учитываете... ну, это не очень безопасно, и Scala - это статически безопасный язык.

Да, это выполнимо, но не в духе статического языка. Если вам действительно нужен такой тип гибкости, программирование полиглота, вероятно, ваш друг.

Примечание. Objective-C не является строго статически типизированным. Существует механизм выполнения, на котором выполняется код, и система динамического набора не позволяет удалять или вставлять код как C/С++.

Ответ 5

Objective-C имеет "method_missing" (в частности, forwardInvocation и methodSignatureForSelector) и, возможно, статически типизирован. Это работает потому, что будет обрабатывать ошибки статического типа как предупреждения, а не ошибки во время компиляции, поскольку отправка метода происходит во время выполнения в гораздо большей степени, чем что-то вроде виртуальных методов на С++ (и именно поэтому вы можете иметь "method_missing" ).