Коротка відповідь: ні, зараз немає інструментів для перевірки типу вашого коду Julia. Однак в принципі це можливо, і деяка робота в цьому напрямку робилася в минулому, але зараз це не дуже вдало.
Більш довга відповідь полягає в тому, що "анотації типу" - це червона оселедець, те, що ви насправді хочете, це перевірка типу, тому більш широка частина вашого питання насправді є правильним питанням. Я можу трохи поговорити про те, чому анотації типу червоної оселедця, деякі інші речі, які не є правильним рішенням, і як виглядатиме правильний вид рішення.
Потрібні анотації типу, ймовірно, не виконують те, що ви хочете: ви можете просто розмістити ::Any
будь-яке поле, аргумент або вираз, і він мав би анотацію типу, але не таку, яка розповість вам або компілятору нічого корисного щодо фактичного типу цієї речі. Це додає багато візуального шуму, фактично не додаючи ніякої інформації.
Що з вимогою вимагати анотацій конкретного типу? Це виключає просто надягання ::Any
на все (що Юлія неявно все одно робить). Однак існує безліч ідеально використаних абстрактних типів, які могли б зробити незаконними. Наприклад, визначення identity
функції є
identity(x) = x
Яку конкретну анотацію типу ви б поставили x
під цю вимогу? Визначення застосовується до будь-якого x
, незалежно від типу, такого типу точки функції. Єдина правильна примітка - цеx::Any
. Це не аномалія: існує безліч визначень функцій, які потребують абстрактних типів, щоб бути правильними, тому примушувати їх використовувати конкретні типи було б досить обмежуючим з точки зору того, який код Юлії можна написати.
Існує поняття "стабільність типу", про яке часто говорять у Джулії. Термін, схоже, зародився у спільноті Джулія, але його підхопили інші динамічні мовні спільноти, наприклад Р. Визначити це трохи непросто, але це приблизно означає, що якщо ви знаєте конкретні типи аргументів методу, ви також знаєте тип його повернення. Навіть якщо метод стійкий до типу, цього недостатньо, щоб гарантувати, що він буде перевіряти тип, оскільки стабільність типу не говорить про будь-які правила для вирішення того, чи перевіряє щось тип чи ні. Але це виходить у правильному напрямку: ви хочете мати можливість перевірити, чи є визначення кожного методу стабільним.
Ви багатьом не хочете вимагати стабільності типу, навіть якщо могли. Починаючи з Julia 1.0, стало звичним використовувати невеликі спілки. Це почалося з перероблення протоколу ітерації, який зараз використовується nothing
для вказівки, що ітерація робиться проти повернення а є прийнятною, але не що-небудь більш непередбачуване, ніж це.(value, state)
кортежу, коли для ітерації є більше значень. Ці find*
функції в стандартній бібліотеці також використовувати значення, що повертається , nothing
щоб вказати , що значення не було знайдено. Це технічні нестабільності, але вони навмисні, і компілятор досить добре міркує про них, оптимізуючи навколо нестабільності. Тож принаймні малі спілки, мабуть, повинні бути дозволені в коді. Більше того, немає чіткого місця, де можна провести лінію. Хоча, можливо, можна сказати, що такий тип поверненняUnion{Nothing, T}
Однак ви, мабуть, дійсно хочете, а не вимагати анотацій типу чи стабільності типу, - це мати інструмент, який перевірить, чи ваш код не може викидати помилки методу, або, можливо, ширше, що він не викличе будь-якої несподіваної помилки. Компілятор часто може точно визначити, який метод буде викликатися на кожному сайті виклику, або принаймні звузити його до пари методів. Ось так він створює швидкий код - повна динамічна відправка дуже повільна (наприклад, набагато повільніше, ніж vtables у C ++). Якщо ви написали невірний код, з іншого боку, компілятор може допустити безумовну помилку: компілятор знає, що ви зробили помилку, але не повідомляє вас до часу виконання, оскільки це мовна семантика. Можна вимагати, щоб компілятор міг визначати, які методи можуть бути викликані на кожному сайті виклику: це гарантувало б швидкість коду та відсутність помилок методу. Ось що повинен зробити хороший інструмент перевірки типу для Юлії. Існує чудова основа для подібних речей, оскільки компілятор вже робить велику частину цієї роботи в рамках процесу генерації коду.
hasmethod(f, (Any,) )
повернеться,false
якщо не було визначено загального. Вам все одно знадобиться відповідати кількості аргументів (тобтоhasmethod(f, (Any,Any) )
для функції двох аргументів).