Форум программистов, компьютерный форум, киберфорум
Священные войны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/40: Рейтинг темы: голосов - 40, средняя оценка - 4.63
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9

Динамически типизированные языки : один вред, никакой пользы

31.01.2016, 01:13. Показов 9422. Ответов 177
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Я имею ввиду языки, в которых только или почти только используются динамически типизированные данных. Не будем сейчас рассматривать рефлексию, в языках .NET или java – там используются динамические типы, но используется сама рефлексия относительно редко.

Где ещё, якобы нужна динамическая типизация?

Для доступа к БД? Не нужна, если сама БД не написана на динамическом языке и/или не специально спроектирована для взаимодействия с динамическим языком. Если посмотреть API конкретных СУДБ (например, oracle, postgreSQL, Firebird/Interbase, SQLite) или ODBC API, то выяснится, что динамическая типизация не нужна.

Для JSON ? Нет, не нужна. Библиотеки для работы с JSON реализованы, наверное, для всех распространённых, статически типизированных языков.

Метапрограммирование? Смотря какое. Если под ним подразумевать выполнение строки кода введённого пользователем, то может оказаться и нужна. Только это для скриптов. При чём для скриптов без предкомпиляции (хотя бы в байт код). Сейчас 21 век, и код, даже на скрипте, должен вначале хотя бы парситься с проверкой типов весь, что бы не выгребать баги лопатой после жалоб пользователей (тулзы типа JSHint, это эрзацы. Декларации типов должна быть встроены в язык и несоответствия обнаруживаться компилятором.). А если под метапрограммированием понимать перекладывание на компилятор генерацию рутинных, повторяющихся кусков кода, то такое метапрограммирование (как и программирование вообще), предпочтительно типобезопасное и в динамической типизации не нуждается.

Сторонники динамических языков часто возражают примерно так «мне нужно, что бы переменная xyz принимала то значение строки, то значение вот с эдакой структурой». Заметим, на практике, если уж мы будем работать с содержимым xyz, то кол-во вариантов конечно, и ограничено логикой программы (да, для выполнения, например, копирования xyz в другую область памяти, нам ничего кроме ссылки и размера не нужно, но не для работы с конкретным её содержимым). А раз так, то xyz может быть алгебраического типа. В pascal можно заменить на запись с вариантами, в С на union и пр.

Распространённость динамически типизированных языков я связываю со временем, когда web-сервера были практически только у провайдеров, а они разрешали абонентам использовать на своих страницах почти только perl и php. В те времена ни о какой предкомпиляции и JIT слыхом не слыхивали. Как и о песочницах. Интерпретаторы этих скриптов делали на коленке и каждый помаленьку. По этому они, впрочем как и js, по дизайну напоминают письмо из простоквашино. Потом скрипты «возмужали» и «заматерели», обзавелись кое где JIT-ом, но примитивность динамической типизации осталась.

Не даром сейчас полным ходом идёт разработка и внедрение языков со статической типизацией компилируемых в js (TypeScript, Elm), а php держится за счёт инерции мышления (как фортран или кобол), не более.

Да, есть ещё вполне динамический, и более свежий Ruby. Ну, дык, его автор сам до того прогал на perlе, стало быть привык к динамической типизации, да и рассчитывал на любителей перловки.

Собственно, я что хочу сказать. В конкретном, динамически типизированном скрипте могут быть очень интересные и полезные фенечки за что его могут любить прогеры с ограниченным знанием языков. Только фенечки фенечками, а динамическая типизация бяка. Почему бяка? Ну, легко нагуглить, и навикипедить. Использовать же в компилируемом языке динамическую типизацию – вообще маразм. Исключение – языки выполняемые на виртуальной Erlang машине со встроенной динамической типизацией. Автор (или кто то из разрабов) утверждал что иначе механизм динамической замены кода не получался. Со скрипом, поверим на слово. Тем более, что там стараются контролировать типы на уровне библиотеки.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.01.2016, 01:13
Ответы с готовыми решениями:

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

Meta Keywords - капля пользы?
Поглядел куча сайтов, keywords'ы народ до сих пор прописывает. Актуально ли?

Нужен пример рекурсивной функции для понимания ее назначения и практической пользы
Не могу понять пользу рекурсии, может ли кто привести код в пример.

177
 Аватар для Voivoid
710 / 283 / 16
Регистрация: 31.03.2013
Сообщений: 1,340
27.02.2016, 21:42
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от hoggy Посмотреть сообщение
"забиванием гвоздей микроскопом" ?
Забивание гвоздей микроскопом это неправильное использование инструмента.

Цитата Сообщение от hoggy Посмотреть сообщение
когда в статике в принципе не возможно реализовать некоторые элементы динамики
Ровно наоборот, динамическая типизация в общем случае просто подможноство статической типизации.

Ты кстати уже несколько раз повторяешь свой пример со строкой, но похоже кроме тебя никто не понимает, что ты им хочешь показать.
0
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,782
27.02.2016, 23:49
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Почему именно в статике нельзя сделать безопасно?
Потому что, если тебе понадобится изменить тип, всё сломается.

Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
И на практике подтверждено, я давал выше ссылку.
Ты сам-то читал, что там написано? Ходил дальше вики, в документацию? Мало того, что это не то, так ещё и кастомная фича Nginx'а, а не общий механизм рантайма Си.

Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Что за ограничения?
Например JVM как бы умеет обновлять код в рантайме (это используется, например, Eclipse'ом при дебаге), но только реализации методов нестатических методов.

Вообще, вот, почитай: http://www.cse.iitk.ac.in/user... otcode.pdf
Там как раз о попытке реализовать горячую замену кода в Cloud Haskell'е и с какими проблемами (в т.ч. и типизиации) авторы столкнулись .

Добавлено через 1 минуту
Цитата Сообщение от Voivoid Посмотреть сообщение
динамическая типизация в общем случае просто подможноство статической типизации.
Ты всё перепутал. Кроме того, это не множества, чтобы быть подмножествами друг друга.

Добавлено через 2 минуты
KolodeznyDiver, ну и вот ещё: http://erlang.org/pipermail/er... 39261.html

Добавлено через 22 минуты
Тут тоже есть, что почитать:

Through the years, there were some attempts to build type systems on top of Erlang. One such attempt happened back in 1997, conducted by Simon Marlow, one of the lead developers of the Glasgow Haskell Compiler, and Philip Wadler, who worked on Haskell's design and has contributed to the theory behind monads (Read the paper on said type system). Joe Armstrong later commented on the paper:

One day Phil phoned me up and announced that a) Erlang needed a type system, b) he had written a small prototype of a type system and c) he had a one year’s sabbatical and was going to write a type system for Erlang and “were we interested?” Answer —“Yes.”

Phil Wadler and Simon Marlow worked on a type system for over a year and the results were published in [20]. The results of the project were somewhat disappointing. To start with, only a subset of the language was type-checkable, the major omission being the lack of process types and of type checking inter-process messages.
Processes and messages both being one of the core features of Erlang, it may explain why the system was never added to the language. Other attempts at typing Erlang failed.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
28.02.2016, 12:20
Цитата Сообщение от Voivoid Посмотреть сообщение
Забивание гвоздей микроскопом это неправильное использование инструмента.
а ну то есть, мне предложили привести пример задачи, когда статика налажает.

я его привожу, и вуаля:
вы мне инкрементируете неверное использование инструмента.

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

Цитата Сообщение от Voivoid Посмотреть сообщение
Ровно наоборот, динамическая типизация в общем случае просто подможноство статической типизации.
динамика реализуется через статику.
но из этого никак не вытекает,
что динамическая типизация подмножество статической.

это два принципиально разных подхода.

в динамике доступно то,
что в принципе не доступно в статике,
например.

Цитата Сообщение от Voivoid Посмотреть сообщение
Ты кстати уже несколько раз повторяешь свой пример со строкой, но похоже кроме тебя никто не понимает, что ты им хочешь показать.
сама по себе проблема не зависит от языка.
но иллюстрировал я её на примере с++

поэтому я и не рассчитывал, что понять смогут все присутствующие
однако, рассчитывал, что его сможете понять вы и Ctor.


ок, давайте ещё раз.

задача - спроектировать и реализовать универсальный аргумент.
это - контейнер, способный принимать,
и хранить ссылки на объекты любых типов.

ближайшие аналоги: void*, boost::any

пример использования:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void foo(arg a)
{
    // если аргумент может быть извлечен как тип данных int
    // тогда извлекаем и печатаем
    if( a.can_as<int>() )
        print("int: ", a.as<int>() ); 
 
    // если аргумент может быть извлечен как тип данных string
    // тогда извлекаем и печатаем
    if( a.can_as<string>() )
        print("string: ", a.as<string>() ); 
}
 
...
 
int main()
{
    foo(10); //<--- arg запоминает какой тип данных ему скормили
     // в дальнейшем, при извлечении будет выполнена
     // рантайм проверка корректности типов и их квалификаторов
 
    string s = "hello";
    foo(s); 
}
что первое бросается в глаза?

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

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

и второе:

могу ли я сделать так:

C++
1
2
3
4
5
int v = 10;
 
arg a = v;   //<--- записал int
 
double d = a; //<--- извлек как double
вообще то тип double умеет из int без потерь данных.
и в статике такая операция была бы правомерна.

но как это сделать в динамике?

другой пример этой же проблемы:
в статике подобная операция правомерна:

C++
1
2
3
4
5
inf foo(auto& a)
{
    string s = a;
    print("string: ", a.as<string>() ); 
}
string может быть построен из массива буковок.

следовательно, мы вправе ожидать аналогичного поведение от динамики:

C++
1
2
arg a = "hello";   //<--- записал массив буковок
string d = a; //<--- извлек как строку
мы легко можем проверить в рантайме точное соответствие типов,
запоминая некий идентификатор типа при создании arg
и сверяясь с ним при извлечении.

именно так и работают boost::any и компания.


но мы не сможем реализовать полноценную поддержку правил
для различного приведения типов.

объясняю почему:

метод извлечения имеет вид:

C++
1
2
3
4
5
6
7
8
//сильно упрощенная версия
template<class T> T operator()const  
{
    if (  get_rtti_<T>() == get_my_rtti()  )
        return  extract<T>();
    else
        raise_error("invalid type");
}
при извлечении сверяем идентификатор типа по которому происходит извлечение,
с идентификатором типа, который был запомнен при создании контейнера.

если все гладко - отлично.
извлекаем данные.

она работает при точном соответствии типов, и не работает,
если требуется приведение типов

проблема в том, что эта схема - единственная,
которая работает в статике.


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// контейнер хранит массив буковок
// а извлекать хотим как строку
// тобишь T ==  string
template<class T> T operator()const  
{
    // нужно не просто выполнять сверку 
    // типов извлечения и хранимого
    // нужно выполнять проверку:
    // может ли T построится на основе 
    // хранимого типа.
 
    // для этого, зная rtti ресурса
    // нужно задавать классу T вопрос:
    // если ли у тебя конструктор,
    //способный построится на основе типа данных
    // которому соответствует указанный rtti ?
 
    if (  get_rtti_<T>() == get_my_rtti()  )
        return  extract<T>();
    else
        raise_error("invalid type");
}
теперь предположим гипотетически,
что наш статический язык - не какой то там жалкий с++,
а очень даже оснащен статической рефлексией,
и мы все таки смогли решить проблему валидации типов.

будем считать, что как то мы это порешали.
просто поехали дальше:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// контейнер хранит массив буковок
// а извлекать хотим как строку
// тобишь T ==  string
template<class T> T operator()const  
{
    // контейнер хранит массив букв
    // а извлекаем как строку
    // благодаря волшебству
    // мы сумели выяснить,
    // что операция правомерна
    if (  cat_extract_as_<T>()  )
    {
       // однако есть проблема:
       // мы не можем тупо привести массив к строке
       // мы должны построить строку на основе массива
 
       U& data = extract_by_rtti(); // <--- получаем нативный тип данных
         // соответствующий информации о хранимом типе
        // в данном случае data - массив буковок
 
     // а вот теперь, выполнив предварительно извлечение  
     // мы уже можем вернуть наружу запрошенный тип
     return T(data);
 
 
    }
    else
        raise_error("invalid type");
}
проблема в строке:

C++
1
2
3
       U& data = extract_by_rtti(); // <--- получаем нативный тип данных
         // соответствующий информации о хранимом типе
        // в данном случае data - массив буковок
в статике это реализовать невозможно.
дело не в ограничении языков.

это - проблема здравого смысла.

невозможно заранее (в статике) поиметь то,
что известно станет только в рантайме,
и от случая к случаю может быть разным.

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

механизмы наподобие boost::any могут действовать только с дикими ограничениями.

и в любом случае теряются бонусы статической типизации:
эффективность и проверки времени компиляции.

вместо этого имеем:
отсутствие оптимизаций,
проверки времени выполнения,
ограничение возможностей.

резюмируя:
учитывая, что мы все равно не можем поиметь выигрыша,
сражаясь с ограничениями статики,
и максимум, что у нас получится - велосипед динамики,
то не проще ли сразу же взять годный динамический язык,
и не заморачиваться?
0
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9
28.02.2016, 13:39  [ТС]
Цитата Сообщение от korvin_ Посмотреть сообщение
Потому что, если тебе понадобится изменить тип, всё сломается.
В принципе, можно кидаться сообщениями "а ля Erlang". Что содержат сообщения Erlang: ограниченный набор примитивных типов скомбинированных в кортежи и списки. В статике это деревья и списки из ADT, где варианты в ADT - это заранее известный, тот самый набор примитивных
типов. Всё это без проблем сериализуется. Но не обеспечивает автоматически совместимость модулей разных версий, в том числе для дин.языков, в том числе для Erlang. В общем случае, требуется знать какие версии протокола обмена (на уровне приложения) поддерживают другие модули. Например, в приведённом по Вашей ссылке первом примере из pankaj2014hotcode.pdf модуль, взаимодействующий с обновляемым, должен знать, поддерживает ли тот уже новую команду или "выкручиваться" самому. Вообще, документ интересный, но описываемые там проблемы, это не проблемы статики, а общие проблемы DSU (совместимость версий модулей, перенос состояния процесса в новую версию, корректность функционирования во время обновления и т.п.), большая часть которых стоит и в Erlang. К тому же, в Erlang часть проблем решается на уровне rts, а авторы ставят задачу решения на уровне библиотеки, что, естественно, сложнее. Впрочем, Cloud Haskell развивается, с 2014-го для него появились фишки и на уровне компилятора-rts (StaticPointers).
Цитата Сообщение от korvin_ Посмотреть сообщение
Ты сам-то читал, что там написано?
Я nginx-ы настраивал. Потому и вспомнилось. И, да, это пример реализации горячей замены в конкретной программе, "а не общий механизм рантайма Си". Такой мне не известен, да и сейчас не интересен.
Цитата Сообщение от korvin_ Посмотреть сообщение
Это я и имел ввиду в конце СП. Но с 2008-го много воды утекло. Тот же Cloud Haskell делает успехи в этом направлении. Не будем забывать что Erlang разрабатывали динамщики (прологеры) и если у них "The results of the project were somewhat disappointing." и "Other attempts at typing Erlang failed." то это ничего не доказывает.
(Про себя скажу что я системы с DSU не делал, а вот просто распределённые с обновлением отдельных модулей делал и делаю. И там одна только проблема совместимости версий доставляет. И никак не соотносится со статикой - см. выше про версии протоколов. Приходится хранить в модулях версии протоколов других модулей и поддерживать их актуальность.)
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 01:24
Цитата Сообщение от ct0r Посмотреть сообщение
Только поначалу, пока кол-во кода не достигло критической массы.
Я склоняюсь к мнению, что на качество продукта больше влияет культура программирования и командной работы, чем вид типизации в языке. На популярной динамике написано много достаточно больших проектов. Я не видел никаких исследований о порогах и критических массах кода касательно динамической типизации. Зато достоверно знаю что, big ball of mud возможен при любых языках и видах типизации

Добавлено через 18 минут
Цитата Сообщение от ct0r Посмотреть сообщение
Для чтения явное указание типов всяко лучше.
На мой взгляд, не всегда. Тут дело в мере. Часто бывает, что явные аннотации типов просто как шум и хорошо выраженный код читается лучше без них.
Цитата Сообщение от ct0r Посмотреть сообщение
Короче, очень-очень спорный аргумент, особенно в свете существования аннотации типов (ее же не просто так ввели?)
Совершенно верно, аннотации типов существуют. Но тут важный момент - они не являются обязательными. Обычно, хорошим тоном, является аннотирование типов к публичным функциям модуля. А в статике вы просто обязаны аннотировать все типы в любом (пусть даже самом понятном и простом) коде.

Добавлено через 4 минуты
Цитата Сообщение от ct0r Посмотреть сообщение
А еще при написании контроль типов может заменить некоторое кол-во юнит-тестов.
Это вряд-ли. Никто тесты на проверку типов не пишет (если, конечно, это не тесты языка программирования проверяющие работу с типами).

Добавлено через 9 минут
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
По своему опыту (и, да, мои проги в космос не летают, но баг убытки тоже немалые может принести) знаю что СТ необходима в комплексе мер по отказоустойчивости.
Возможно. Но софта в требованиях к которому нужна супер отказоустойчивость дай бог один процент. Большинству нужен софт который может делать что-то клёвое и, возможно, сложное, что не умеет делать другой софт И желательно побыстрее. И в большинстве случаев, чёрт с ним, что есть баги в каких-нибудь пограничных случаях. Ведь писать что-то классное всегда интереснее, чем искать баги и наяривать на отказоустойчивость (и производительность ) Для того, чтобы увеличить производительность труда, нужны языки максимально гибкие. Статически типизированные языки таковыми не являются по определению.
0
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9
29.02.2016, 09:47  [ТС]
Цитата Сообщение от nullxdth Посмотреть сообщение
А в статике вы просто обязаны аннотировать все типы в любом (пусть даже самом понятном и простом) коде.
Вывод типов. Если вообще не указывать типы, то код сложнее простого учебного примера перестаёт через некоторое время быть понятным и автору. Либо же понадобится комментировать
JavaScript
1
function damage(pts /* HealthPoints */)
, либо же давать длинное имя аргументу получая громоздкие выражения
JavaScript
1
function damage(HealthPoints)
. Оба хуже
F#
1
let damage (pts : HealthPoints )
, плюс, в статике тип ещё и накладывает ограничения, типа запрета перемножения двух HealthPoints или сложения HealthPoints с HitPoints.
Цитата Сообщение от nullxdth Посмотреть сообщение
Никто тесты на проверку типов не пишет
в большинстве динамических языков есть функции или конструкции для проверки типов. В библиотеках они активно используются. При этом тесты на проверки типов не делают? Ну, видимо, некоторые не делают.
Цитата Сообщение от nullxdth Посмотреть сообщение
Большинству нужен софт который может делать что-то клёвое и, возможно, сложное, что не умеет делать другой софт И желательно побыстрее. И в большинстве случаев, чёрт с ним, что есть баги в каких-нибудь пограничных случаях.
Попробуйте такое сказать на собеседовании.
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 12:47
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Вывод типов.
Да, но ты же понимаешь, что автовывод в приличном виде есть только в функциональной и редкоиспользуемой статике (Haskell, OCaml). А в других его нет (Java, Go, C) или же есть в весьма ограниченном виде (C++, C#).
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Если вообще не указывать типы, то код сложнее простого учебного примера перестаёт через некоторое время быть понятным и автору.
Когда такой момент наступает и действительно сложно понять с какими данными работаем, то имеет смысла аннотировать тип.
Например, в Python это делается в docstring-ах в определённом формате, который, например, хорошо понимает PyCharm https://www.jetbrains.com/pych... charm.html.
Обрати внимание, это делают тогда, когда действительно нужно, а не параноидально на каждый чих.
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 13:09
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Либо же понадобится комментировать
В грамотных динамических языках, таких, например, как Common Lisp - не понадобится тем более.
Обрати внимание, в первом случае SBCL в compile time определил что тип строчного литерала "foo" не является целым числом.
Во втором и третьем случае, мы получили run time ошибки типов - входной аргумента не является чётным числом и выходной аргумент не является нечётным числом соответственно.
Тут примечательно то, что проверка на чётность/нечётность определена в декларации типа, а не явным образом в теле функции. Не подскажешь, как в Haskell описать подобный тип?
Миниатюры
Динамически типизированные языки : один вред, никакой пользы   Динамически типизированные языки : один вред, никакой пользы   Динамически типизированные языки : один вред, никакой пользы  

0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 13:24
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
в большинстве динамических языков есть функции или конструкции для проверки типов
Есть. Но пользоваться ими следует в крайнем случае. Повсеместное использование этой функциональности - дурной тон.

Добавлено через 10 минут
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Попробуйте такое сказать на собеседовании.
Почему бы и нет? Я всегда жду подобных высказываний на собеседованиях. В большинстве случаев нужны не сверхбезопасные решения, а смелые и инновационные.
0
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9
29.02.2016, 13:50  [ТС]
Цитата Сообщение от nullxdth Посмотреть сообщение
автовывод в приличном виде есть только в функциональной и редкоиспользуемой статике
В старых языках нет, да и то вводят помаленьку. В rust,F# есть. OCaml,F# не функциональные, а мультипарадигменные, а некоторые полагают что и не редкоиспользуемые. Автовывод - не признак функциональности. Просто, и то и другое сейчас активно внедряется. Сравнивая динамика vs статика стоит ориентироваться на современные, лучшие решения, а не вспоминать что в С ничего нет.
Цитата Сообщение от nullxdth Посмотреть сообщение
в Python это делается в docstring-ах
Костыли. Громоздкие при том.
Цитата Сообщение от nullxdth Посмотреть сообщение
который, например, хорошо понимает PyCharm
Т.е. IDE получит неполную информацию. И нет гарантии что корректную. Эти комментарии, поди, никакими тестами на соответствие действительности не проверяются.

Не по теме:

Реклама скобок поскипана.

Цитата Сообщение от nullxdth Посмотреть сообщение
в compile time определил что тип строчного литерала "foo" не является целым числом.
- это, конечно, Великое Чудо. Уникальная Возможность. Киллер Фича.
Цитата Сообщение от nullxdth Посмотреть сообщение
мы получили run time ошибки типов
а мы, в статике, получили ct ошибки типов. Мы, правда, не смотрели рекламные картинки, но и так понятно, что к теме это не относится.

0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 14:54
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
В старых языках нет, да и то вводят помаленьку.
В том то и дело, что "помаленьку". Потому что по нормальному не ввести.
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Автовывод - не признак функциональности.
Более менее нормальный автовывод самый что ни на есть признак. Фактически, вывод по Хиндли-Милнеру (и его модификаций) работает только в достаточно простых случаях и с ограниченными системами типов (которые присущи исключительно функциональным языкам).
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
OCaml,F# не функциональные, а мультипарадигменные
OCaml и F# функциональные языки с некоторыми возможностями императивного программирования. Впрочем, для любого практичного ФЯ императивная функциональность обязательна.

Добавлено через 4 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
- это, конечно, Великое Чудо. Уникальная Возможность. Киллер Фича.
Конечно это уникальная функциональность. Я не припомню ни одного языка с грамотной гибридной системой типов. Система типов Common Lisp не столь убога и ограничена исключительно compile time-ом, как, например система в Haskell.
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
а мы, в статике, получили ct ошибки типов.
Да? Ну тогда тебе не составит труда показать, как выглядит описание чётных целых чисел в Haskell? Ну и заодно слегка рассказать, как Haskell чекает такие типы в compile time?

Добавлено через 2 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Мы, правда, не смотрели рекламные картинки, но и так понятно, что к теме это не относится.
Как это не относится? Относится на все 100%. Речь идёт о динамических и статических системах. Я продемонстрировал некоторую функциональность гибридной системы, которая может и так и сяк, но преимущественно является динамической.

Добавлено через 7 минут
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Костыли. Громоздкие при том.
Вот и я говорю, что Python говно. CL нужно использовать.
0
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9
29.02.2016, 16:02  [ТС]
Цитата Сообщение от nullxdth Посмотреть сообщение
В том то и дело, что "помаленьку". Потому что по нормальному не ввести.
И фик с ними. Да здравствует прогресс!
Цитата Сообщение от nullxdth Посмотреть сообщение
Фактически, вывод по Хиндли-Милнеру (и его модификаций) работает только в достаточно простых случаях и с ограниченными системами типов
Видимо прочитали в вики "Такой алгоритм не всегда помогает определить тип выражения". В подавляющем большинстве случаев он выводит и позволяет сократить код. Не выводит, там где и человек не догадается. К тому же, указывать типы лучше даже чаще чем компилятору надо. И понятнее, и проще найти проблему когда компилятор ругается на типы.

Не по теме:

Цитата Сообщение от nullxdth Посмотреть сообщение
OCaml и F# функциональные языки с некоторыми возможностями императивного программирования.
"стакан наполовину пуст или наполовину полон". Александр Вершилов, если не путаю (У меня сложилось впечатление что у него iq где то под 200.), как то рычал на F# : "имперрррративщина".
Цитата Сообщение от nullxdth Посмотреть сообщение
Впрочем, для любого практичного ФЯ императивная функциональность обязательна.
Не знаю что такое "императивная функциональность", но согласен. В отличии от функциональщиков с высоким iq я считаю что ФП надо применять по максимому где возможно, но где невозможно, не стоит пропихивать круглое в треугольное.


Цитата Сообщение от nullxdth Посмотреть сообщение
Я не припомню ни одного языка с грамотной гибридной системой типов.
Не знаю в точности что это такое и нужно ли. Динамические типы же есть в .NET.

Не по теме:

Цитата Сообщение от nullxdth Посмотреть сообщение
Ну тогда тебе не составит труда показать, как выглядит описание чётных целых чисел в Haskell? Ну и заодно слегка рассказать, как Haskell чекает такие типы в compile time?
Будто в Вашем примере в compile time. Описываем свою реализацию Num, примерно как тут, только проще, параметры на уровне типа задавать не надо.
Цитата Сообщение от nullxdth Посмотреть сообщение
Как это не относится?
Так. У Вас там не тип переменной/значения описывается, который бы по всей программе контролировался, а ограничения для одной конкретной функции. Чётность проверяется в rt. Зачем такая громоздкость, когда проще в начале тела функции проверить и кинуть иксцепшн. Скобочники - чего с вас взять.

0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 16:25
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
И фик с ними. Да здравствует прогресс!
Ну то есть мы приходим к тому, что автовыводилки не работаю в общем случае. И только в некоторых случаях можно дать эту работу компилятору. Но с другой стороны, со стороны динамической типизации, типы можно не указывать вообще и это работает в общем случае. Модель такая. Это удобно, хоть и не лишено недостатков.
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Будто в Вашем примере в compile time.
Нет, конечно, в run time. В compile time эти проверки не решаются в принципе. Только разве что на константах/литералах, но SBCL этого не делает, видимо потому что предикат может быть произвольной сложности и может содержать side effect-ы.
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Описываем свою реализацию Num, примерно как тут, только проще, параметры на уровне типа задавать не надо.
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Зачем такая громоздкость, когда проще в начале тела функции проверить и кинуть иксцепшн. Скобочники - чего с вас взять.
Громоздкость? О да, отлично, проверку корректности типа мы херачим в код который работает с переменными этого типа? Красота, нечего сказать. Почему тогда вообще нужны какие-то декларации типов. Давайте static assert-ами в функциях всё проверять, не правда-ли проще?
0
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9
29.02.2016, 16:53  [ТС]
Цитата Сообщение от nullxdth Посмотреть сообщение
Ну то есть мы приходим к тому, что автовыводилки не работаю в общем случае.
Они позволяют эффективно сократить код. Что и требуется.
Цитата Сообщение от nullxdth Посмотреть сообщение
Но с другой стороны, со стороны динамической типизации, типы можно не указывать вообще
... и иметь проблемы динамики (сказочка про белого бычка).
Цитата Сообщение от nullxdth Посмотреть сообщение
В compile time эти проверки не решаются в принципе.
Решаются с 1980 г. (Ада).
Цитата Сообщение от nullxdth Посмотреть сообщение
О да, отлично, проверку корректности типа мы херачим в код который работает с переменными этого типа?
В Вашем примере есть проверка не типа, а значения аргумента. Если добавите другую функцию, то будете описывать проверки для неё отдельно. В статическом языке можно указать что аргумент имеет тип MyEvenInt, и использовать это имя в 100500 функциях.
Для проверке в rt достаточно определить приведение в MyEvenInt из целого с проверкой на чётность. Для проверки в сt константы в Haskell понадобится написать слайд (макрос). Кажется, это же можно получить макросом rust. Полноценная проверка преобразования константных выражений в ct, "до куда можно" есть, насколько знаю, только в Ada.
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 17:28
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Так. У Вас там не тип переменной/значения описывается, который бы по всей программе контролировался, а ограничения для одной конкретной функции.
Да нет же. У меня определён тип функции. Если хочется, можно типы, например так:
Lisp
1
2
3
4
5
6
7
8
9
10
(deftype even-number ()
  '(and fixnum (satisfies evenp)))
 
(deftype odd-number ()
  '(and fixnum (satisfies oddp)))
 
(deftype even->odd ()
  '(function (even-number) odd-number))
 
(declaim (ftype even->odd foo bar baz xyz))
Добавлено через 4 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Решаются с 1980 г. (Ада).
Да неужели? И как же Ada в compile-time проверит чётность числа прилетевшего в run-time?

Добавлено через 8 минут
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
В Вашем примере есть проверка не типа, а значения аргумента. Если добавите другую функцию, то будете описывать проверки для неё отдельно. В статическом языке можно указать что аргумент имеет тип MyEvenInt, и использовать это имя в 100500 функциях.
Всё тоже самое и в Common Lisp. Совершенно не обязательно описывать тип ad-hoc образом. Пример привёл выше.

Добавлено через 1 минуту
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Для проверке в rt достаточно определить приведение в MyEvenInt из целого с проверкой на чётность.
Как это будет выглядеть? И где будет осуществляется приведение? Лучше кодом.

Добавлено через 3 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Полноценная проверка преобразования константных выражений в ct, "до куда можно" есть, насколько знаю, только в Ada.
Хм. Ну это надо посмотреть, что там делает Ada. Как выглядят код этих преобразований... Может кто знает Ada, покажет всю мощь

Добавлено через 15 минут
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Для проверки в сt константы в Haskell понадобится написать слайд (макрос)
Интересно, как это будет выглядеть в конечном коде. Будет специальный литерал, синтаксически записанный особым образом?
0
Модератор
 Аватар для Curry
5165 / 3527 / 536
Регистрация: 01.06.2013
Сообщений: 7,676
Записей в блоге: 9
29.02.2016, 21:29  [ТС]
Цитата Сообщение от nullxdth Посмотреть сообщение
У меня определён тип функции
но не тип аргумента. Для функций с разными сигнатурами понадобится дублировать описания. Ни чем не лучше чем, даже на голых сях.
Кликните здесь для просмотра всего текста
C
1
2
3
4
5
6
7
8
#define EVEN_CHK(a) {if(a & 1){printf("%s == %d, is not even. In file %s, line %d\n",#a,a,__FILE__, __LINE__);exit(1);}}
 
long f(int a, long b)
{
    EVEN_CHK(a);
    EVEN_CHK(b);
    return a+b;
}
Сразу видно что требуется. И в моём варианте весь код. А у Вас за ширмой ещё определения всяких макросов. Другое дело, если бы ограничение накладывалось на тип, но я следую Вашему примеру - ограничение на конкретные аргументы конкретных функций.
Цитата Сообщение от nullxdth Посмотреть сообщение
И как же Ada в compile-time проверит чётность числа прилетевшего в run-time?
Не болтайте ерундой. Проверка константных выражений в ct, не константных в rt (хотя ... см. ниже).
Цитата Сообщение от nullxdth Посмотреть сообщение
Как это будет выглядеть? И где будет осуществляется приведение?
Где надо, там и будет. Если повторять Ваш код, то в начале тела функции. А если нужен тип, значения которого должны быть только чётными, то там где его значения будут создаваться. Но тогда для него нужно определять свои арифм. операции. У Вас ничего похожего.
Цитата Сообщение от nullxdth Посмотреть сообщение
это надо посмотреть, что там делает Ada
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
WITH Ada.Text_IO; USE Ada.Text_IO;
 
PROCEDURE Main IS
   TYPE MyRange  IS range 1 .. 10;
   a : MyRange;
BEGIN
   a:=7;
   a:=a+8;
   Put_Line(MyRange'Image(a));
END Main;
8:8 warning: "Constraint_Error" will be raised at run time
8:8 warning: value not in range of type "MyRange" defined at line 4
Преобразование выражений чисто из констант известных во время компиляции проверяется тем более. До кучи : контроль размерностей (допустим) физических величин. В F# тоже есть (хотя, кажется, попримитивнее).
Цитата Сообщение от nullxdth Посмотреть сообщение
Интересно, как это будет выглядеть в конечном коде.
Haskell
1
$(mkEven 28)
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 22:34
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
но не тип аргумента. Для функций с разными сигнатурами понадобится дублировать описания.
Ещё раз посмотри внимательнее на код Динамически типизированные языки : один вред, никакой пользы.
Где и что мне придётся дублировать, чем такое описание принципиально отличается от сигнатур функций в каком-нибудь ML?

Добавлено через 2 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Сразу видно что требуется. И в моём варианте весь код.
Это шутка что-ли? Ты серьёзно полагаешь, чем какая-то часть проверки типа описана в функции, а часть вынесена в декларации - это клёво?

Добавлено через 1 минуту
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Не болтайте ерундой. Проверка константных выражений в ct, не константных в rt (хотя ... см. ниже).
Ну извини, я просто спросил. Ты же говорил, что хачкиль всё прочекает в ct. И небо и Аллаха. Не знаю уж, кто тут из нас ерунду говорит.

Добавлено через 2 минуты
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Где надо, там и будет. Если повторять Ваш код, то в начале тела функции.
Какой мой код? У меня никаких чеков типов в теле функции нет.
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
 Аватар для volvo
33467 / 21566 / 8249
Регистрация: 22.10.2011
Сообщений: 37,021
Записей в блоге: 12
29.02.2016, 22:36
Цитата Сообщение от nullxdth Посмотреть сообщение
как же Ada в compile-time проверит чётность числа прилетевшего в run-time?
В CT - никак, в RT - запросто:
Code
1
2
   subtype Even is Integer
     with Dynamic_Predicate => Even mod 2 = 0;
, и любая попытка поработать с нечетным значением через тип Even окончится raised Dynamic_Predicate failed
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 22:37
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Но тогда для него нужно определять свои арифм. операции. У Вас ничего похожего.
А зачем это нужно? Если попытаться модифицировать переменную любым значением отличным от целого чётного числа, то будет сигнализирована ошибка типа.
0
 Аватар для nullxdth
2305 / 1064 / 77
Регистрация: 12.03.2013
Сообщений: 4,987
29.02.2016, 22:41
Цитата Сообщение от KolodeznyDiver Посмотреть сообщение
Преобразование выражений чисто из констант известных во время компиляции проверяется тем более.
Ranges - это боян. Они зашиты в Аду. Вообщем-то CL без труда с этим справляется (см. screenshot).
Миниатюры
Динамически типизированные языки : один вред, никакой пользы  
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.02.2016, 22:41

Как динамически выделять память на один элемент массива?
Вот программа: int main() { int n,a,b; Item *mas; cout &lt;&lt; &quot;Enter amount of coordinates&quot; &lt;&lt; endl; cin &gt;&gt;...

Один обработчик события для нескольких динамически созданных объектов
Я программно создаю несколько картинок и их кол-во всегда разное. Создаю картинки циклом: for I := 1 to count_book do ...

Интерпретируемые языки VS Компилируемые языки
Я лично не смог вспомнить чем хоть один из них, лучше другого :) Хотя возможно скоростью

В коде динамически наполняется массив и его элементы выводятся на сцену, но выводится только один элемент
В коде представленном ниже...при клике на кнопку (в роли кнопки прямоугольник) Должен наполнятся массив одинаковыми элементами в данном...

никакой тип
как реализовать процедуру вроде этой procedure config(name,text:string;t,l,w,h:integer); begin name.top:=t; name.left:=l; ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
140
Ответ Создать тему
Новые блоги и статьи
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
Мысли в слух
kumehtar 17.08.2026
Забавно, насколько сейчас стала доступна информация. Например о магии, духовном развитии, медитациях, и других подобных направлениях, ранее зачастую тайных, передаваемых от учителя к ученику. Хотя. . .
Перемещение строк из ТЧ в другой документ с учетом текущего пробега
Maks 17.08.2026
Реализация из решения ниже выполнена на примере нетипового документа "Автозапчасти", с ТЧ "Шины". За основу взят алгоритм отсюда: https:/ / www. cyberforum. ru/ blogs/ 359708/ 10838. html Задача: . . .
Саморегулирующийся социальный контракт для сервера cross-section.
Hrethgir 14.08.2026
С кодом конечно таких глубоких размышлений пока не было, впрочем я уже привык к алгоритмизации. Суть предмета записи: снова в диалоге с нейросетью (я взял пока себе ник для учётки админа - Rector). . . .
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru