Здравствуйте, dotneter, Вы писали:
D>Ок, я сдался. Толи вы не хотите ничего понимать, то ли я плохо объясняю, но вроде тут насколько все очевидно ...
Вот мне тоже кажется что у тебя в результате получается неуклюжая, неудобная эмуляция динамики на статическом языке,
притом с потерей почти всех преимуществ статики.
Re[12]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, dotneter, Вы писали:
D>>Ок, я сдался. Толи вы не хотите ничего понимать, то ли я плохо объясняю, но вроде тут насколько все очевидно ...
FR>Вот мне тоже кажется что у тебя в результате получается неуклюжая, неудобная эмуляция динамики на статическом языке, FR>притом с потерей почти всех преимуществ статики.
Давайте попробуем с вами.
У меня нет никакой эмуляции, это все теже ат (алгебраические типы), только матчинг по конструктору заменен матчингом по типу.
data Either a b
= Left a
| Right b
case x of
Left _ -> ...
Right _ -> ...
data X = int|string
case x of
_ :: int ->
_ :: string ->
Тоесть все что вы говорите автоматом относится и к ат.
Ат это неуклюжая эмуляция динамики с потерей всех приемуществ статики. Вы это имеете в виду?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[13]: [Динамик не нужен] Анонимные алгебраические типы.
D>Тоесть все что вы говорите автоматом относится и к ат. D>Ат это неуклюжая эмуляция динамики с потерей всех приемуществ статики. Вы это имеете в виду?
То есть никакого вывода возвращаемого значения, его тип заранее жестко задан?
Тогда не вижу вообще темы для обсуждения у тебя просто получается сахар к обычным АТД в виде неявных конструкторов.
Я не думаю что это сильно что-то упростит, это и так не сложно:
type ret = Int of int | String of string
let foo x = if x = 0 then Int x else String "bar"let test = function
| Int x -> printf "%d\n" x
| String s -> printf "%s\n" s
Re[14]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, dotneter, Вы писали:
D>>Тоесть все что вы говорите автоматом относится и к ат. D>>Ат это неуклюжая эмуляция динамики с потерей всех приемуществ статики. Вы это имеете в виду?
FR>То есть никакого вывода возвращаемого значения, его тип заранее жестко задан?
Что мешает ему быть выведеным? Выкидываем имя X, и возвращаемся к первому примеру.
let foo x = if x == 0 then 0 else "bar" end
foo :: int -> int | string
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[15]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, dotneter, Вы писали:
FR>>То есть никакого вывода возвращаемого значения, его тип заранее жестко задан? D>Что мешает ему быть выведеным? Выкидываем имя X, и возвращаемся к первому примеру. D>let foo x = if x == 0 then 0 else "bar" end D>foo :: int -> int | string
let foo x =
if x = 0 then `MyInt 0 else `MyStr "bar"
let print = function
| `MyInt x -> printf "`MyInt = %d\n" x
| `MyStr1 x -> printf "`MyStr = %s\n" x
print foo 1
Правильно я понимаю что это скомпилируется, и упадет в рантайме?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[17]: [Динамик не нужен] Анонимные алгебраические типы.
D>Правильно я понимаю что это скомпилируется, и упадет в рантайме?
Нет будет ошибка компиляции, тип же выводится в print и соответственно он будет требовать `MyInt | `MyStr1 что не включает в
себя возвращаемый foo тип `MyInt | `MyStr. Вот если в print добавить | _ -> printf "unknown\n" то тогда все скомпилируется и
не будет падать, но опечатку `MyStr1 вместо `MyStr компилятор уже нам не найдет.
Re[13]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Честно говоря, не вижу причин, по которым количество и типы аргументов обязательно должны быть всегда известны статически.
Например?
ВВ>Но даже это и неважно. Если ты строку формата не можешь явно скормить компилятору в виде константы, то он просто не сможет типизировать функцию. Другого пути нет.
Это просто не правда. Функцию можно типизировать по ее параметрам.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[14]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну через заглушку работает, но чем это от варианта отличается ВВ>А rectypes вообще достаточно стремная штука. К сожалению, она не просто включает рекурсивные типы, а еще и дает по голове тайп-чекеру так, что он начинает пропускать ошибочный код.
Ну это косяк ОКамла. И не говорит ничего плохого о рекурсивных типах как таковых.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, dotneter, Вы писали:
D>>Правильно я понимаю что это скомпилируется, и упадет в рантайме?
FR>Нет будет ошибка компиляции, тип же выводится в print и соответственно он будет требовать `MyInt | `MyStr1 что не включает в FR>себя возвращаемый foo тип `MyInt | `MyStr. Вот если в print добавить | _ -> printf "unknown\n" то тогда все скомпилируется и FR>не будет падать, но опечатку `MyStr1 вместо `MyStr компилятор уже нам не найдет.
Ну так, не делать _ -> и не будет никакой динамики. Если и в моем случае так писать, то тогда тоже непонятно что там на входе, я бы заставлял при использовании _ -> явно описывать тип функции, тогда и проблем никаких.
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Talk is cheap. Show me the code.
Re[14]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, WolfHound, Вы писали:
ВВ>>Но даже это и неважно. Если ты строку формата не можешь явно скормить компилятору в виде константы, то он просто не сможет типизировать функцию. Другого пути нет. WH>Это просто не правда. Функцию можно типизировать по ее параметрам.
Ну так тип единственного параметра printf и вычисляется в компайл-тайме на основе *значения* строки формата.
Re[15]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, WolfHound, Вы писали:
ВВ>>Ну через заглушку работает, но чем это от варианта отличается ВВ>>А rectypes вообще достаточно стремная штука. К сожалению, она не просто включает рекурсивные типы, а еще и дает по голове тайп-чекеру так, что он начинает пропускать ошибочный код. WH>Ну это косяк ОКамла. И не говорит ничего плохого о рекурсивных типах как таковых.
Речь тут в общем-то не о рекурсивных типах вообще, а конкретно о циклических типах. И в теории они должны быть решаемы. Но на практике оказывается, что в существующие системы типов чистые рекурсивные типы не очень вписываются. В том же Хаскеле, например, изорекурсивный тип выразить можно, а с эквирекурсивный, а соответственно, и циклический, АФАИК нет.
Re[15]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Ну так тип единственного параметра printf и вычисляется в компайл-тайме на основе *значения* строки формата.
Один? Правда? А что тогда в строку форматирования то подставляется?
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, WolfHound, Вы писали:
ВВ>>Ну так тип единственного параметра printf и вычисляется в компайл-тайме на основе *значения* строки формата. WH>Один? Правда? А что тогда в строку форматирования то подставляется?
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Параметр действительно один. Я тебе скажу больше — в OCaml, F#, Haskell да и в Ela в принципе невозможно написать функцию, которая принимает больше одного параметра.
Типа языки только ими и ограничиваются
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[18]: [Динамик не нужен] Анонимные алгебраические типы.
Здравствуйте, WolfHound, Вы писали:
ВВ>>Параметр действительно один. Я тебе скажу больше — в OCaml, F#, Haskell да и в Ela в принципе невозможно написать функцию, которая принимает больше одного параметра. WH>Типа языки только ими и ограничиваются
Вроде бы речь была, процитирую, про "ML-ный printf"
ЗЫ. А вообще вместо того, чтобы в очередной раз спорить на увлекательнейшую тему динамика вс. статика лучше взять какие-нибудь задачки отсюда да посмотреть как они решаются на статике и динамике. Заодно могли бы расширить страницу Немерле примерами кода, коих там сейчас вообще нет.
Re[5]: Анонимные алгебраические типы. Более сложный случай.
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, maxkar, Вы писали:
M>>Да, неплохо. Только вот мне не нравится, что это шаблон. Я хочу именно функцию. Чтобы ее можно было куда-нибудь еще передавать, например.
FR>Этот шаблон порождает полноценную функцию полностью совпадающую по типу с ее функцией аргументом, с ней можно делать все что можно делать с любой другой функцией. Тут чуть разъясню, шаблоны D в отличии от шаблонов C++ могут порождать любые типы, а не только структуры/классы или функции.
Я не про то. Я сам exceptionProtect хочу иметь как first-class object. То, что его результат является функцией — понятно. Например, можно было бы exceptionProtect в Array.map передать или куда-нибудь еще. Другой "шаблон" построить в рантайме и т.п. И вот как раз полноценной работы с типами мне хватило бы. Причем передачи AST мне ни в один шаблон не нужно. Туда передаются значения разной природы. Это могут быть объекты, это могут быть функции и на выходе как-то строится тип результата. Т.е. "более типизированная" "динамика". В принципе, возможность работы таких "шаблонов" в рантайме упирается в необходимость хорошего RTTI, возможность порождать описания типов в рантайме и "динамический" способ вызова функции.
Re[5]: Анонимные алгебраические типы. Более сложный случай.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, maxkar, Вы писали:
M>>Потому что изначально метод предназначался для защиты функции, строящейся по конфигу во время исполнения, а не во время написания кода. Что-то вроде WH>Ну строится. WH>Ну по конфигу. WH>Дальше то что? WH>Почему у функции тип не известен?
Известен только в рантайме этот тип. Потому что берется из конфига. При этом тип может быть не "точный" (требуемый реализациями), а "приводимый" к требуемому. Например, возможно следующее:
const f : Function = function(a : int, b : int = 3) : int {
return a + b;
}
f(3);
f(5, 6);
Второй аргумент к функции может появиться в процессе эволюции. Весь код, который работал ранее с функцией от одного аргумента, будет с ней работать даже без перекомпиляции. А вот новая функциональность будет использовать и второй аргумент.
M>>Оно строит новый объект, имеющий те же поля (с теми же значениями) но функции обернуты и защищены. Полезно на инфраструктурном уровне, например, в dependency injection framework. Ну или любой другой внешней конфигурации модулей и межмодульного взаимодействия. WH>Давай конкретный пример.
Вот что-то в подобном роде используется в реальном коде. Обработчики 'about-dialog', 'format-drive-dialog' и т.п. могут находиться в различных подгружаемых модулях, описываются в конфиге. На самом деле чуть еще сложнее, но это не важно. Сервисы передаются в диалоги, так как эти же сервисы предоставляют интерфейс к графической подсистеме, менеджер окон, те же вызовы сервисов и т.п. При желании можно "модифицировать" сервис и передавать уже его в различные диалоги. Все подобные обработчики вообще не имеют никакого глобального состояния и привязок, им достаточно входных аргументов этого вызова.
Словить интеграционную ошибку в рантайме и поправить вызов для меня проще (и быстрее), чем писать и поддерживать типизированную стуктуру заглушек для контроля типов контейнера. Ну и плюс сам язык не поддерживает статическую типизацию в достаточной степени, так что я вообще ничего не теряю.
Re[6]: Анонимные алгебраические типы. Более сложный случай.
Здравствуйте, maxkar, Вы писали:
M>Известен только в рантайме этот тип.
То, что ты так сделал это одно.
Но то, что тип нельзя узнать на этапе компиляции... прости не верю.
M>Потому что берется из конфига.
Что берется из конфига?
M>Второй аргумент к функции может появиться в процессе эволюции. Весь код, который работал ранее с функцией от одного аргумента, будет с ней работать даже без перекомпиляции. А вот новая функциональность будет использовать и второй аргумент.
Что-то ты странное мутишь.
M>Словить интеграционную ошибку в рантайме и поправить вызов для меня проще (и быстрее), чем писать и поддерживать типизированную стуктуру заглушек для контроля типов контейнера.
Как я понял у тебя там какой-то IoC происходит.
Так вот я такое даже на С++ делал.
Динамика тут нужна как рыбке зонтик.
А что за заглушки тебе понадобились я так и не понял.
M>Ну и плюс сам язык не поддерживает статическую типизацию в достаточной степени, так что я вообще ничего не теряю.
Это проблема языка.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн