Re[40]: Что вас останавливает от изучения нового языка?
От: dimgel Россия https://github.com/dimgel
Дата: 24.04.11 14:38
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, dimgel, Вы писали:


A>>>http://www.rsdn.ru/forum/philosophy/4246786.1.aspx
Автор: adontz
Дата: 23.04.11

D>>Ок, каюсь. Возвращаемся к истокам, с которых всё началось: ты же не будешь спорить с тем, что шаблоны C++ — далеко не самый удачный пример статической типизации, и что по ним нельзя утверждать о том, что проблемы со 100% контролем типов в обобщённом программировании присущи всей статике как таковой?

A>Я утверждаю, что:

A>1) Статическая типизация не гарантия относительной лёгкости построения средств рефакторинга.
A>2) Динамическая типизация не гарантия относительно сложности построения средств рефакторинга.
A>и надо каждый язык рассматривать отдельно.

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

1) В конкретном C++ статическая типизация не гарантия относительной лёгкости построения средств рефакторинга, потому что она там реализована криво и не полностью. Это недостаток не статики, это недостаток языка, одна из подсистем которого отрабатывает почти так же тупо, как текстовый препроцессор, и никакой статикой в момент её отработки не пахнет, как не пахнет ею во время работы препроцессора — несмотря на то, что ошибки в текстовых макросах вылезут на более поздних этапах.

В качестве контрпримера
Автор: dimgel
Дата: 24.04.11
я привожу скалу, где реализация generics даёт 100% гарантии согласованности типов. Вот здесь — статическая типизация в полный рост: компилятор имеет достаточно информации для проверок и внутри generic-классов, и в контексте, где эти классы используются.

Ещё один хороший пример плохой статики в generics — это java; в ней разработчики языка намеренно шли на нарушение математической строгости ради упрощения и снижения порога вхождения. В результате на java generics нельзя сделать и десятой доли того, что можно сделать в scala, и на java очень часто приходится обращаться к existential types (generic от произвольного типа). Проверка типов, естественно, сосёт.

2) По второму пункту ты неправ. Динамическая типизация — именно что гарантия сложности построения средств рефакторинга. Потому что у IDE нет надёжной информации о типах во всех частях системы. Свой опыт я описал здесь
Автор: dimgel
Дата: 23.04.11
.
Re[9]: Что вас останавливает от изучения нового языка?
От: vdimas Россия  
Дата: 24.04.11 17:04
Оценка:
Здравствуйте, Ziaw, Вы писали:


Z>По сравнению с Nemerle, C# ограниченный императивный язык.


От задач зависит. По сравнению с Прологом на некоторых задачах Nemerle — макро-ассемблер.
Re[37]: Что вас останавливает от изучения нового языка?
От: FR  
Дата: 24.04.11 17:11
Оценка: 19 (2)
Здравствуйте, dimgel, Вы писали:

D>А generics с вариантностью и upper/lower bounds в окалме есть?


Сложный вопрос, без шуток.

Проблема в том что в OCaml объекты и интерфейсы структурно типизированы, а понятие класс практически синтаксический сахар для удобства
наследования реализации.

Вторая проблема в OCaml нет выделенного понятия generic, но есть несколько своих механизмов их заменяющих.

Во первых параметизированые классы http://caml.inria.fr/pub/docs/manual-ocaml/manual005.html#toc27 это как раз очень близко
по свойствам к генерикам или шаблонам классам C++, но там засада в том что в терминах C++ это скорее ближе не к шаблоному классу,
а к классу с шаблонным конструктором.

Во вторых у объектов методы могут быть параметризованными http://caml.inria.fr/pub/docs/manual-ocaml/manual005.html#toc28, что в совокупности
с предыдущим позволяет изобразить что-то похожее на генерики.

В третьих обычные методы и функции у которых параметры объекты из-за структурной типизации ведут себя как генерики, например функция

let f o = o#put


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

В четвертых кроме этого есть параметизированные модули (модули в ML не связанны с единицами компиляции) http://caml.inria.fr/pub/docs/manual-ocaml/manual004.html#toc16 на них тоже можно изобразить что-то похожее на генерики.

D>Пример lower bound на скале:


D>
D>trait Animal {
D>    def feed(...)
D>}
D>class Elephant extends Animal {
D>    def feed(...) {
D>        // ...
D>    }
D>}
D>class ZooCage[A <: Animal] (a: A) {
D>    // ....
D>    a.feed(...)
D>}
D>new ZooCage(new Elephant)
D>


D>Здесь запись [A <: Animal] означает "generic-тип A, являющийся подтипом Animal". Благодаря этому внутри generic-класса ZooCage компилятор имеет информацию о супертипе A и в состоянии проверить корректность вызова метода a.feed(). А при инстанциировании ZooCage с конкретным аргументом выполняется проверка, что A=Elephant удовлетворяет условию A <: Animal. Полный контроль, в отличие от шаблонов C++.


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

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

open Printf


class elephant = 
  object
    method say = printf "elephant\n"
  end

(* с точки зрения компилятора этот класс совпадает с elephant *)
class mamont = 
  object
    method say = printf "mamont\n"
  end


class dog = 
  object    
    method say = printf "dog\n"
    method dog_id = ()
  end

class wolf = 
  object
    method say = printf "wolf\n"
    method wolf_id = ()
  end

(* этот класс совсем левый, метода say нет *)
class troll = 
  object
    method hollow = printf "bla-bla\n"    
  end


(* инициализируем объекты *)
let elephant_ = new elephant
let mamont_ = new mamont
let dog_ = new dog
let wolf_ = new wolf

let troll_ = new troll

(* максимально обобщенная функция *)
let say o = o#say

let _ = say elephant_
let _ = say mamont_
let _ = say dog_
let _ = say wolf_

(* тут если раскомметировать будет ошибка компиляции у класса нет метода say *)
(*let _ = say troll_*)


(* 
  переопределяем, теперь принимаются только типы полностью структурно совпадающие
  с elephant, то есть elephant_ и mamont_ то что закомментированно ошибка 
  компиляции.
*)
let say (o : elephant) = o#say

let _ = say elephant_
let _ = say mamont_
(* let _ = say dog_ *)
(* let _ = say wolf_ *)
(*let _ = say troll_*)


(* 
  переопределяем, теперь принимаются только типы полностью структурно 
  совпадающие с dog.
*)
let say (o : dog) = o#say

(*let _ = say elephant_*)
(*let _ = say mamont_*)
let _ = say dog_
(* let _ = say wolf_ *)
(*let _ = say troll_*)


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

FR>>Я ничего, пытаюсь отбиться от тролля, чистая самозащита.


D>Лучший способ избавиться от тролля — это перевести разговор в конструктивное русло, давать грамотные аргументы. Поскольку ты себя этим не отягощаешь, троллем выступаешь именно ты. Но я очень надеюсь, что аргументы рано или поздно наконец появятся. Итак?


Ладно чушь про С++ замнем. Динамику тоже, мне про нее спорить давно обрыдло, так по инерции в очередной срач влетаю.
В общем предлагаю перестать нападать друг на друга
Re[10]: Что вас останавливает от изучения нового языка?
От: Ziaw Россия  
Дата: 24.04.11 17:37
Оценка:
Здравствуйте, vdimas, Вы писали:

Z>>По сравнению с Nemerle, C# ограниченный императивный язык.


V>От задач зависит. По сравнению с Прологом на некоторых задачах Nemerle — макро-ассемблер.


Аналогия не верна. ПМ используется во всех проектах и используется очень широко. Логический решатель — узкая ниша.

Впрочем Nemerle тут тоже рулит, если в проекте требуется делать логические выводы, вполне можно прикрутить пролог и использовать его, бесшовно встраивая в основной код.
Re[18]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.04.11 17:43
Оценка: +1
Здравствуйте, Undying, Вы писали:

U>Если мыслишь заученными конструкциями, то заучив новые конструкции, станешь всего лишь более знающим бараном. К умению думать владение заученными конструкциями не имеет никакого отношения. А умение думать строится на совершенно других принципах, в частности на принципе минимума сущностей. Но само по себе изучение других языков никак освоить эти принципы не помогает.


Умение думать — это очень похвальное качество. Я сам всегда повторяю, что во всех случаях надо думать голой. Вот только все своей головой не придумаешь. И будь твоя голова хоть трижды золотая ты не изобретешь и тысячной доли того, что смогло придумать человечество в области программирование за какие-то 50 лет. Потому кроме умения думать надо еще уметь развиваться. Познавать новые подходы (знания добытые и обобщенные другими для нас), перенимать практики. В том числе изучать передовые языки.

U>Пример со string.Join показывал, что очень часто проблема мусорности кода может быть решена средствами имеющегося языка.


Да, КО. Но это подтверждает или опровергает? Это так же верно, как утверждать, что иногда грязь на улице можно убрать нагнувшись и подняв ее. Но не ужели это отрицает того факта, что для уборки большой и замусоренной улицы лучше применять машину или хотя бы метлу?

U>Но в силу привычки думать заученными конструкциями программисты просто не замечают, что данный код является мусорным, и соответственно не ищут способа избавиться от этого мусорного кода.


Я уверен, что тот же Лойд прекрасно осознает что можно написать фуннкцию которая сделает код чище и лучше. Но не делает он это чисто из лени. Конкатенация строк с помощью string.Join ему нужна раз в два года и ему просто лень создавать новую функцию.

Если же человек такой ламер, что не понимает этого, то ему конечно и дела не должно быть ни до новых языков, ни до малейшего саморазвития. Но не все же такие?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[38]: Что вас останавливает от изучения нового языка?
От: dimgel Россия https://github.com/dimgel
Дата: 24.04.11 17:49
Оценка:
Здравствуйте, FR, Вы писали:

Идею про статическую структурную типизацию уловил, спасибо, но оценить в сравнении с номинативной не могу. И раньше как-то пропускал мимо ушей, если оно обсуждалось. Я правильно понимаю, что классы как синтаксический сахар нужны, чтобы не описывать повторяющуюся сигнатуру параметров? Т.е. если у нас есть, например, несколько фасадных методов, выполняющих сложные действия над однотипными параметрами и соответственно требующих, чтобы у типа параметра была объявлена прорва методов, описывать каждый раз эту прорву охренеешь, а класс — как раз шоткат для этой прорвы, так?

Кстати, на duck typing смахивает. Это оно и есть, или чем-то отличается? Duck typing я не люблю: им легко злоупотреблять, как и динамикой. Вот в этом adontz-овом примере
Автор: adontz
Дата: 23.04.11
видно, что переименование метода в одном классе потянет за собой переименование метода в другом, никак с не связанном с исходным. Ещё пример: мне не так давно доводилось рефакторить сложную развесистую структуру (одних классов штук 30) — мапить на ORM вместо сериализации в блоб. Там один из классов оказался вне своей иерархии из-за желания разработчика приктунть в него на тяп-ляп какую-то специфическую хрень, с базовым классом несовместимую. Был заюзан duck typing. При мапинге, разумеется, полезли проблемы с подгрузкой полиморфных ссылок. Пришлось расхерачивать логику, вместо чисто механического рефакторинга.

Вообще, как по мне, чем больше ограничений, тем лучше. Дисциплинирует. И самое смешное, что результат, как ни странно, на статике выходит качественней, при всех её ограничениях. Свою lib.web forms, разработанную для скалы, я без проблем перенёс на PHP один в один; она потеряла в компактности синтаксиса (например, мои валидаторы на скале используются так: VRequired & VInt & VRange(0, 100)) и в контроле типов (в примере с валидаторами их невозможно даже местами поменять; к примеру, компилятор ругнётся на VRange перед VInt; так что ошибиться при использовании моих валидаторов на скале просто невозможно :-P ), но сохранила расширяемость: я потом на неё довешивал клиентскую валидацию, зависимости (транзитивные и рекурсивные), ajax-подгрузку зависимых полей в одном запросе — чего я только с ней не делал, архитектура выдержала. Обратно — хрен, мой тогдашний шеф PHP-шник, избалованный динамикой, начал пытаться валидацию на скале сделать — и хихикал-плакался "блин, сложно-то как, всюду ограничения". Повторюсь, к структурной типизации это может и не иметь никакого отношения, я её не юзал. Просто что знаю, то и пишу.

FR>В общем предлагаю перестать нападать друг на друга


Мир.
Re[34]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.04.11 17:59
Оценка: 8 (1)
Здравствуйте, FR, Вы писали:

D>>4) когда тебя попросили привести пример заявленных тобой проблем статики, ты привёл пример шаблонов C++.


FR>Который вполне релевантный.


Да не очень то. Проблемы динамики носят системный характер (потеря информации о типах вызвана самой динамикой). Проблемы шаблонов С++ вызваны проектным решением. По сути это ошибка дизайна. Можно было бы выбрать дизайн не приводящий к проблемам.

К тому же в следствии того, что С++ статически-типизированный язык все же получать информацию о типах в шаблонах таки можно. Просто делать это придется в рамках конкретных воплощений. Рефакторинг для С++ так же возможен (и даже имеется кое где), хотя и сложен. Но сложности эти в основном носят вычислительный характер.

D>>5) два C++ника ответили, что шаблоны в C++ — это не статика.


FR>Нет, один из них такого не говорил, ну и плюс я сам C++ник, а ты можешь пока постоять в сторонке.


Да и первый тоже. Вольфхаунд сказал загадочную фразу о нитипизированости типов в С++. Это совсем не то что С++ не типизированн.

На самом деле все встает на свои места когда начинаешь думать о шаблонах С++ не как об обобщенных типах (которыми они являются с большой натяжкой), а как о синтаксическом препроцессоре. Фактически шаблоны не используются как тип. Воплощение шаблона (часто называемое дебильным словом "инстанциация") ни что иное как процесс копирования АСТ шаблона и замена параметров типов на реальные значения. Таким образом речь идет о процессе чуть более вменяемом чем текстуальная подстановка. Такой процесс нормален для метапрограммирования (тех же макросов), но не для системы типов. Отсюда и все проблемы.

Однако воплощенный шаблон — это вполне себе законченный тип в котором можно делать проверки типов.

Вольфхаунд указывает на то, что такие проверки делаются не на самом шаблоне, а на его воплощении, что приводит к тому, что сообщения об ошибках появляются не тогда когда компилируется шаблона, а в совсем в другое время. Зачастую у пользователя шаблона.

Именно это препятствует созданию полноценного рефакторинга для С++. Но все же это усложняет задачу, а не делает ее невозможной. Ну, и слабая типизация, конечно, в следствии которой в С++ спокойно можно обмануть систему типов.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[39]: Что вас останавливает от изучения нового языка?
От: FR  
Дата: 24.04.11 18:24
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Идею про статическую структурную типизацию уловил, спасибо, но оценить в сравнении с номинативной не могу. И раньше как-то пропускал мимо ушей, если оно обсуждалось. Я правильно понимаю, что классы как синтаксический сахар нужны, чтобы не описывать повторяющуюся сигнатуру параметров? Т.е. если у нас есть, например, несколько фасадных методов, выполняющих сложные действия над однотипными параметрами и соответственно требующих, чтобы у типа параметра была объявлена прорва методов, описывать каждый раз эту прорву охренеешь, а класс — как раз шоткат для этой прорвы, так?


Ну можно и так наверно сказать.
Еще они нужны для наследования (включая и множественное) реализации и когда нужна параметризация.
База же в ОО системе OCaml'а это объект, например можно спокойно объявлять анонимные объекты.

D>Кстати, на duck typing смахивает. Это оно и есть, или чем-то отличается? Duck typing я не люблю: им легко злоупотреблять, как и динамикой. Вот в этом adontz-овом примере
Автор: adontz
Дата: 23.04.11
видно, что переименование метода в одном классе потянет за собой переименование метода в другом, никак с не связанном с исходным. Ещё пример: мне не так давно доводилось рефакторить сложную развесистую структуру (одних классов штук 30) — мапить на ORM вместо сериализации в блоб. Там один из классов оказался вне своей иерархии из-за желания разработчика приктунть в него на тяп-ляп какую-то специфическую хрень, с базовым классом несовместимую. Был заюзан duck typing. При мапинге, разумеется, полезли проблемы с подгрузкой полиморфных ссылок. Пришлось расхерачивать логику, вместо чисто механического рефакторинга.


Я раньше тоже с утиной типизацией путал, но все-таки это разные вещи, хотя структурная типизация некоторую динамику все-равно привносит.
Насчет примера adontz, проблема в С++ в том что из описания шаблона параметризующий тип T вывести практически невозможно, шаблон работает наоборот
методом подстановки, в OCaml же тип выводится компилятором, он известен хоть и сильно обобщен. Дальше остается проблема какие именно из несвязанных
друг с другом классов нужно переименовывать, понятно что те что вызываются нашим "шаблоном" необходимо, а вот что делать с теми которые структурно
соответствуют, но сейчас "шаблоном" не вызываются мне не очень понятно. Но при этом после такого рефакторинга все останется в нормальном компилируемом
состоянии, в C++ это обеспечить будет намного сложнее.

D>Вообще, как по мне, чем больше ограничений, тем лучше. Дисциплинирует. И самое смешное, что результат, как ни странно, на статике выходит качественней, при всех её ограничениях. Свою lib.web forms, разработанную для скалы, я без проблем перенёс на PHP один в один; она потеряла в компактности синтаксиса (например, мои валидаторы на скале используются так: VRequired & VInt & VRange(0, 100)) и в контроле типов (в примере с валидаторами их невозможно даже местами поменять; к примеру, компилятор ругнётся на VRange перед VInt; так что ошибиться при использовании моих валидаторов на скале просто невозможно :-P ), но сохранила расширяемость: я потом на неё довешивал клиентскую валидацию, зависимости (транзитивные и рекурсивные), ajax-подгрузку зависимых полей в одном запросе — чего я только с ней не делал, архитектура выдержала. Обратно — хрен, мой тогдашний шеф PHP-шник, избалованный динамикой, начал пытаться валидацию на скале сделать — и хихикал-плакался "блин, сложно-то как, всюду ограничения". Повторюсь, к структурной типизации это может и не иметь никакого отношения, я её не юзал. Просто что знаю, то и пишу.


По мне нужно уметь писать по разному, и почти без ограничений и на жестких языках.
Ну и для меня прототипы намного приятней писать используя динамику.
Re[35]: Что вас останавливает от изучения нового языка?
От: FR  
Дата: 24.04.11 18:53
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Да не очень то. Проблемы динамики носят системный характер (потеря информации о типах вызвана самой динамикой). Проблемы шаблонов С++ вызваны проектным решением. По сути это ошибка дизайна. Можно было бы выбрать дизайн не приводящий к проблемам.


Угу, но учти историю развития этого добра. Там же все по Дарвину фактически

VD>К тому же в следствии того, что С++ статически-типизированный язык все же получать информацию о типах в шаблонах таки можно. Просто делать это придется в рамках конкретных воплощений. Рефакторинг для С++ так же возможен (и даже имеется кое где), хотя и сложен. Но сложности эти в основном носят вычислительный характер.


Проблема в том что похоже задача теоретически или неразрешима или очень сложна.
На практике да кое-что получается.

FR>>Нет, один из них такого не говорил, ну и плюс я сам C++ник, а ты можешь пока постоять в сторонке.


VD>Да и первый тоже. Вольфхаунд сказал загадочную фразу о нитипизированости типов в С++. Это совсем не то что С++ не типизированн.


Угу куда-то в метатипы забрался.

VD>На самом деле все встает на свои места когда начинаешь думать о шаблонах С++ не как об обобщенных типах (которыми они являются с большой натяжкой), а как о синтаксическом препроцессоре. Фактически шаблоны не используются как тип. Воплощение шаблона (часто называемое дебильным словом "инстанциация") ни что иное как процесс копирования АСТ шаблона и замена параметров типов на реальные значения. Таким образом речь идет о процессе чуть более вменяемом чем текстуальная подстановка. Такой процесс нормален для метапрограммирования (тех же макросов), но не для системы типов. Отсюда и все проблемы.


Как аналогия да похоже, в реале там еще сложнее есть зависимость от контекста, SFINAE и т. п.

VD>Однако воплощенный шаблон — это вполне себе законченный тип в котором можно делать проверки типов.


VD>Вольфхаунд указывает на то, что такие проверки делаются не на самом шаблоне, а на его воплощении, что приводит к тому, что сообщения об ошибках появляются не тогда когда компилируется шаблона, а в совсем в другое время. Зачастую у пользователя шаблона.


VD>Именно это препятствует созданию полноценного рефакторинга для С++. Но все же это усложняет задачу, а не делает ее невозможной. Ну, и слабая типизация, конечно, в следствии которой в С++ спокойно можно обмануть систему типов.


Ну тут уровень сложности похоже не меньше чем для динамики.
На практике точно, тот же PyDev в среднем получше рефакторит чем VA.
Re[7]: Что вас останавливает от изучения нового языка?
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 24.04.11 19:22
Оценка: +1 -1 :)
Здравствуйте, WolfHound, Вы писали:

V>>Профессорство за знание языков, слава богу, не дают.

WH>Человек, преподающий программирование обязан знать множество языков.

Тебя и Влада послушать, так получится, что любое множество изученных языков без Nemerle является нерепрезентативным.

WH>И ответ "не хочу" на предложение прочитать статью, описывающую техники переднего края должен быть не мыслим.

WH>Но Дворкин мне именно это и заявил.
WH>Лаптев на предложение почитать про немерле сказал примерно тоже самое но другими словами.

Лаптев сказал, если я не путаю, что синтаксическим макросам сто лет в обед.

V>>Язык реализации — это последнее, что интересует. Вернее, не интересует никогда.

WH>Ну да... конечно.
WH>И после того как человек в это начинает верить получается всякая байда типа компиляторов на С.

Кто куда чем стоял?

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

WH>Ага, конечно.

Угу, именно так.

WH>Вот тебе кусочек кода. https://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Optimizer/Optimizer.OptimizeRule.n

WH>Прикинь как он будет выглядеть на С++.

За такую лапшу нужно отлучать от клавиатуры. Вложенные match доставляют особо. Не, знаешь, такой ценой добиваться сокращения объёма кода — это себе дороже. Пусть код будет втрое длиннее, но хоть сгруппировали бы по ветвлениям одного уровня. Это был раз. А два, я, например, не вижу принципиальной разницы между:

| Not(Not(rule))                => optimize(Rule.And(r.Location, rule))


и совершенно банальным:

else if (match(rule, Not(Not())) { return optimize(And(r.Location, rule)); }


Совпадения имён случайные, ни один кролик во время прикидок не пострадал.

Так что, подозреваю, что в изображении подобного кода на C++ ничего чудовищного не будет.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[7]: Что вас останавливает от изучения нового языка?
От: vdimas Россия  
Дата: 24.04.11 22:16
Оценка: 59 (5) +1 -1 :)
Здравствуйте, WolfHound, Вы писали:

WH>И ответ "не хочу" на предложение прочитать статью, описывающую техники переднего края должен быть не мыслим.


А ну-ка, что у нас тут на передовом крае:

Gandy, Robin O. The simple theory of types. In Logic Colloquium 76, volume 87 of Studies in Logic and the Foundations of Mathematics, pages 173–181. North Holland, 1976.
Whitehead, Alfred North and Bertrand Russell. Principia Mathematica. Cambridge University Press, Cambridge, 1910. Three volumes (1910; 1912; 1913).
Ramsey, Frank P. The foundations of mathematics. Proceedings of the London Mathematical Society, Series 2, 25 (5): 338–384, 1925. Reprinted in (Braithwaite, 1931).
Church, Alonzo. A formulation of the simple theory of types. Journal of Symbolic Logic, 5: 56–68, 1940.
Martin-Löf, Per. An intuitionistic theory of types: predicative part. In H. E. Rose and J. C. Shepherdson, editors, Logic Colloquium, ’73, pages 73–118. North-Holland, Amsterdam, 1973.
Martin-Löf, Per. Intuitionistic Type Theory. Bibliopolis, 1984.
Berardi, Stefano. Towards a mathematical analysis of the Coquand-Huet calculus of constructions and the other systems in Barendregt’s cube. Technical report, Department of Computer Science, CMU, and Dipartimento Matematica, Universita di Torino, 1988.
Barendregt, Henk P. Lambda calculi with types. In Abramsky, Gabbay, and Maibaum, editors, Handbook of Logic in Computer Science, volume II. Oxford University Press, 1992.

Причем предпоследнее — это скорее классификация имеющихся знаний, чем что-то новое. А последнее — тем более, довольно-таки прикладной репорт на основе имеющегося материала. В общем, что-то скорее нафталиновое, чем передовое. Да и есть ML-языки, которые пытаются реализовать эти наработки. И что эти яыки из себя представляют мы прекрасно знаем: неудобство для общеприкладных задач и тормозной получаемый код, требующий дохрена памяти. Был бы этот сыр бесплатный, весь этот материал давно был бы в мейнстриме.


Ну и опять же. Про узость самой области исследований языков ты похоже не въезжаешь абсолютно. Давай я тебя с утра до ночи алгоритмами обработки сигналов грузить буду? Это же круто! И даже область применения на многие порядки шире. Это настолько повсеместно используется, что вы просто не замечаете. Оно "работает и всё". Но в ней как раз "передних краев" дофига, т.е. гораздо больше свежака (катализованного спросом на сетевые технологии), в отличие от всего этого нафталина в области ФП и доказательства теорем.

Ну и по последнему писку моды тоже хватае тпроблем и они известны. Для зависимых типов — это ввод значений, требующий в общем случае техники суперкомпиляции (а не того подобия техники динамического приведения, что ты когда-то предлагал), а uniqueness типы имеют проблемы в многопоточном окружении. Собственно, эта практика еще допиливается, исследования идут именно в направлении как сделать это полезным на практике, и до мейнстрима прямо сейчас еще далеко. Такова се ляви.


WH>Лаптев на предложение почитать про немерле сказал примерно тоже самое но другими словами.


Дык, Немерле ведь от всего вышеупомянутого страшно далек, ты его сюда не приписывай. Он просто динозавр, родившийся поздно. Представляет из себя сугубо практическую попытку собрать несколько полезных наработок в одном языке на основе имеющейся мощной платформы, угу. В общем, вовсе не "край", а сугубо практическая попытка найти приемлемый компромисс м/у обилием фич и привносимыми ими помехами. Кстати, я не отрицаю полезность этой попытки. Скорее наоборот, обоими руками ЗА. Ведь макросы в С несколько сдали назад по тем временам и подорвали доверие к этой технике. Например, даже возможности макроассемблера на порядок превосходят возможности препроцессора С, не говоря уже о 50-летнем Лиспе или 40-летнем Форте. Пора вернуть макросы на заслуженное место, снабдив их типобезопасностью. Возможно, Немерле своим примером поможет сделать это в следующих версиях интересных мне языков. Хотя, справедливости ради, чрезмерное увлечение макросами всегда считалось плохим тоном во всех перечисленных языках. Элегантности кода не нужно приносить в жертву очевидность происходящего. Иначе бывает больно, вплоть до полного выкидывания и переписывания заново. В общем, моё ИМХО по этому вопросу умеренное, не приемлет обе крайности.


V>>Нужно нечто более полезное из прикладных IT-областей.

WH>Бла-бла-бла.

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


V>>Язык реализации — это последнее, что интересует. Вернее, не интересует никогда.

WH>Ну да... конечно.
WH>И после того как человек в это начинает верить получается всякая байда типа компиляторов на С.

А что не так с С? Отличная абстракция ассемблера. Настоящий нейтив во-плоти, без встроенных фокусов (если сравнивать с Паскалем, например). Что получится в итоге известно фактически до бит, что и требуется для ПО, непосредственно общающегося с кодом. С этого языка "взлетают" все современные аппаратные платформы, и уже поверх него работают все эти джавы, дотнеты и прочие экзотичности. Поверх него — т.е. поверх кода, созданного компилятором С. Фактически весь современный нейтивный код написан на С/С++, от операционок, офиса и БД, до дотнета и игрушек.

V>>Защитите хотя бы кандидатскую...

WH>И нахрена оно мне надо?

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

Например, ты прямо сейчас способен обосновать, почему нерекурсивные алгебраические типы представлены ссылочными типами, хотя дотнет позволяет оперировать value-type? А ведь ML-языки умеют делать такие оптимизации уже черти сколько лет. Пяток подобных вопросов без убедительных ответов, и можно идти допиливать диссер, а лучше сам язык.


V>>Ну и самое главное — будущего инженера надо научить учиться, а остальное — шелуха и болтовня. Дотнетов, джав и прочих технологий будет еще много, заранее всему не научишь. А классика — она вечна.

WH>И что есть классика?
WH>С++?

Для императивных — Фортран/С/Паскаль. Функциональный — Лисп, логический — Пролог. Отличные языки для изучения парадигм. Почему отличные? — а ничего лишнего, никаких понтов, шелухи и синтаксического сахара. Да, в этом и проблема Пролога например, что у него плохая стыковка с "общепрограммисткими" задачами, типа ГУИ, БД, сетка и т.д. Но для целей изучения логического програмимрования — это наоборот, мега-плюс. Бо ничего лишнего.


V>>Во-первых, в 20 раз меньше кода — это ты переборщил.

WH>1)Читай что написано.
WH>2)Это факты.
WH>Причем даже без макросов.

Пока я не видел примеров. Все, что многократно приводились на этом сайте и по сто раз обсуждались в течении 5-ти лет, не дают такой разницы. Ну и домашние заготовки под определенные классы задач в любом более-менее универсальном языке накрутить можно.

V>>Насчет простоты поддержки... Чем более решение высокоуровневое, тем более дорогая нужна поддержка, то бишь требующая более дорогих спецов. Я пока сталкиваюсь ровно с противоположным, что мои более-менее неординарные снипетты кода ругаются более молодыми коллегами за "сложность и непонятность".

WH>Неординарные? Ты имеешь в виду лапшу?

Define "лапшу"?

WH>Не мудрено.

WH>Вот тебе кусочек кода. https://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Optimizer/Optimizer.OptimizeRule.n

А вот и оно, спасибо. Типичный индусокод. Ни малейшего понятия о декомпозиции и тестопригодности. Развязаться через независимые ф-ии видно не судьба.

Насчет тестопригодности. Ты должен будешь на один метод завязать как кучу низкоуровневых независимых тестов по проверке каждого отдельного вычисления, так и комплексные тесты, проверяющие их комбинации. А это залёт, курсант.

И где там пуля, ткни пальцем. 90% — ветвления идет по единичному тагу размеченного объединения.
Или в этих строках, что ли:
        | Not(Not(rule))                => optimize(Rule.And(r.Location, rule))
        | And(Not(rule))                => optimize(Rule.Not(r.Location, rule))
        | Not(And(rule))                => optimize(Rule.Not(r.Location, rule))
        | And(And(rule))                => optimize(Rule.And(r.Location, rule))

В факте предпросмотра на один уровень вперед (тоже самое тут: Fsm(a)::Fsm(b)::rest)? Да еще через ж... динамическую типизацию в реализации Nemerle? Издеваешься или как?

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

Далее, вот это ленивые вычисления или энергичные?
| Choice(rules)                 =>
          def rules = rules.Map(optimize);
          def rules = rules.Map(
            fun(_)
            {
              | Rule.Choice(rules) => rules
              | rule               => [rule]
            });
         def rules = rules.Flatten();
         ...

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

Тоже самое с Sequence(rules). Заметь, на плюсах тут вполне можно было обобщить на шаблонах оба случая. Но на немерле или C# — это надо было бы городить огород из паттерна "Стратегия" для целей обобщения, и овчинка выделки не стоила бы.

Собственно 90% функциональности метода рассмотрено. Проходишь по всем вложенным конструкциям и вызываешь оптимизацию правил для вложенных правил, если есть. Самих оптимизаций по сути две — это оптимизация последовательностей Not/And, и вызов FsmBuilder для цепочек символов и автоматов.

Далее. Есть предложение для обоих случаев насчет возможности построения оптимизированного варианта сразу, по мере парсинга правил, а не "потом", за вот этот проход оптимизации. Это как разница в подходах построения ДКА — сначала можно строить по регулярным выражениям НКА, приводить его к ДКА, а затем минимизировать, но ведь можно строить сразу минимизированный ДКА — это порой на порядок быстрее, т.к. на каждом шаге обработке подвергается множество меньшей мощности. Хоть алгоритм и чуть более сложный, угу. К автомату, в свою очередь генерируемому вызываемым тут FSMBuilder это тоже относится.

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

В общем, подкинь что-нить посущественнее, что ли...


WH>Прикинь как он будет выглядеть на С++.


Кое в чем буков будет больше, кое в чем меньше. Разницы в разы не будет. А после декомпозиции вообще будет фактически 1-в-1. Исключение составляют ленивые вычисления на IEnumerable, но это тогда на каком-нить C# надо воспроизводить. Или на плюсах таки сразу строить минимизированный вариант и не париться с последующей ленивой обработкой.
Отредактировано 16.03.2015 9:19 vdimas . Предыдущая версия .
Re[11]: Что вас останавливает от изучения нового языка?
От: vdimas Россия  
Дата: 24.04.11 22:21
Оценка: 7 (1) -1
Здравствуйте, Ziaw, Вы писали:

Z>Аналогия не верна. ПМ используется во всех проектах и используется очень широко. Логический решатель — узкая ниша.


Я же смайл поставил.

А если по делу, мне крайне не нравится реализация алгебраических типов в Немерле. Она там одинакова для рекурсивных и нерекурсивных АглТД, т.е. явно была сделано "на скорую руку". Но нынешняя команда сим вопросом заниматься не будет.
Re[36]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.04.11 23:11
Оценка:
Здравствуйте, FR, Вы писали:

FR>Ну тут уровень сложности похоже не меньше чем для динамики.

FR>На практике точно, тот же PyDev в среднем получше рефакторит чем VA.

Еще раз. Нельзя сравнивать уровень сложности (какой бы он не был) с отсутствием возвожности в следствии потери информации.

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

Так что для динамики можно говорить исключительно о шаманстве и попытках вывести хоть что-то.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 24.04.11 23:59
Оценка:
Здравствуйте, gandjustas, Вы писали:

VD>>Они появились лет пять назад:

VD>>http://nemerle.org/wiki/Tutorials
VD>>http://nemerle.org/wiki/Courses

Да, еще конечно http://nemerle.org/wiki/Grokking_Nemerle
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[31]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.04.11 00:02
Оценка:
Здравствуйте, dimgel, Вы писали:

D>Ты действительно дурак, или только притворяешься?


Так брэк, уважаемые. Ни то забаню обоих.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.04.11 00:21
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

ГВ>Лаптев сказал, если я не путаю, что синтаксическим макросам сто лет в обед.


Лаптев много говорит. Но по его же словам отчетливо видно, что он не понимает то о чем говорит. Его уровень — это императивный язык. К сожалению подняться выше он не то что не может, но даже не хочет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.04.11 01:06
Оценка:
Здравствуйте, Геннадий Васильев, Вы писали:

https://code.google.com/p/nemerle/source/browse/nemerle/trunk/snippets/peg-parser/Nemerle.Peg.Macros/Optimizer/Optimizer.OptimizeRule.n
WH>>Прикинь как он будет выглядеть на С++.

ГВ>За такую лапшу нужно отлучать от клавиатуры. Вложенные match доставляют особо.




Да ты шутник, однако. Только форумом ошибся. Тебе нужно в юмор.

2 WolfHound: Когда ты поймешь, что показывать примеры кода можно только тем, кто их понимает. Ты думешь, что что-то там обосновываешь, а человек тупо нихрена не понимает. Он в жини только if-ы освоил. И твои примеры для него — это еще один енпонятный набор крокозябр.

ГВ>Не, знаешь, такой ценой добиваться сокращения объёма кода — это себе дороже.


Ген, это те когда не знаешь что читаешь, то не выступай. А то ну совсем же ведь ламером себя выставляешь. В этом коде никто не пытался сделать что-то нарочито коротко. В нем, просто, решается весьма не тривиальная задача — оптимизация гамматик. В нормальном виде эту задачу на простом языке не описать. Тут единственное нормальное решение было бы создание специализированного ДЛС-я с поддержкой паттерн-матчинга в терминах прикладной задачи. А на if-ах или ООП тут будет просто жопа. Кода будет раз в 5 больше и он будет абсолютно не читаем. А этот код ты прочесть не можешь только потому, что не знаешь ПМ и язык.

ГВ>Пусть код будет втрое длиннее, но хоть сгруппировали бы по ветвлениям одного уровня. Это был раз. А два, я, например, не вижу принципиальной разницы между:


ГВ>
| Not(Not(rule))                => optimize(Rule.And(r.Location, rule))


ГВ>и совершенно банальным:


ГВ>
else if (match(rule, Not(Not())) { return optimize(And(r.Location, rule)); }



Ген. Не моли чушь просто от того, что ты не понимашь написанного. Ну это же бред.

Я тебе сейчас переведу этот код. Вот как это будет выглядеть на доступных для тебя языках:
if (r is Rule.Not)
{
  var rNot = (Rule.Not)r;
  if (rNot.rule is Rule.Not)
  {
    var rule = (Rule.Not)rNot.rule;
    return optimize(new Rule.And(r.Location, rule));
  }
}

Но тут есть пара особенностей.
1. В привычных тебе языках оптимизация концевой рекурсии не гарантируется, так что для корректной реализации тебе придется заменить вложенную функцию на цикла и стек (с ручной манипуляцией этим стеком).
2. Компилятор немерла работает не с объектами, а свариантами. Это позволяет ему контролировать, что match-и обрабатывают все возможные сочетания. В твоем случае такая проверка невозможна в приципе.

Так что описанная выше прямая трансляция является плохим стилем. Стало быть ее, по уму, нужно заменить на использование паттерна посетитель. Но как только ты это сделашь распознование вложенных паттернов (Not вложенный в Not, как в данном примере) превратится в мучение. Кода станет уже не в 5, а в 10-20 раз больше.

Так что насмехаешься и горлопанишь ты тут исключительно от своей невежественности. Ну, а приведенный тобой "код" просто нерабочий.

ГВ>Так что, подозреваю, что в изображении подобного кода на C++ ничего чудовищного не будет.


Ну, ты давай подтяни ФП. Тогда и подозревать не придется.

Так для справки. Обрезанный компилятор C# (из SS CLI) написанный на С++ Майрософтом занимает 5 мег. Компилятор Немерле ~2. И это при том, что язык сложнее в разы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Что вас останавливает от изучения нового языка?
От: VladD2 Российская Империя www.nemerle.org
Дата: 25.04.11 01:09
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А ну-ка, что у нас тут на передовом крае:

V>

V>Gandy, Robin O. The simple theory of types. In Logic Colloquium 76, volume 87 of Studies in Logic and the Foundations of Mathematics, pages 173–181. North Holland, 1976.
V>Whitehead, Alfred North and Bertrand Russell. Principia Mathematica. Cambridge University Press, Cambridge, 1910. Three volumes (1910; 1912; 1913).
V>Ramsey, Frank P. The foundations of mathematics. Proceedings of the London Mathematical Society, Series 2, 25 (5): 338–384, 1925. Reprinted in (Braithwaite, 1931).
V>Church, Alonzo. A formulation of the simple theory of types. Journal of Symbolic Logic, 5: 56–68, 1940.
V>Martin-Löf, Per. An intuitionistic theory of types: predicative part. In H. E. Rose and J. C. Shepherdson, editors, Logic Colloquium, ’73, pages 73–118. North-Holland, Amsterdam, 1973.
V>Martin-Löf, Per. Intuitionistic Type Theory. Bibliopolis, 1984.
V>Berardi, Stefano. Towards a mathematical analysis of the Coquand-Huet calculus of constructions and the other systems in Barendregt’s cube. Technical report, Department of Computer Science, CMU, and Dipartimento Matematica, Universita di Torino, 1988.
V>Barendregt, Henk P. Lambda calculi with types. In Abramsky, Gabbay, and Maibaum, editors, Handbook of Logic in Computer Science, volume II. Oxford University Press, 1992.


Какой, к чертям, это передний край? Это до ML-ная эра. И дажее ее наши професоры не осилили пока что. Так о чем ты говоришь то?
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Что вас останавливает от изучения нового языка?
От: alexeiz  
Дата: 25.04.11 01:19
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А теперь представь, что есть язык который позволяет большую часть таких паттернов (в том числе и паттернов-проектирования) запихнуть в библиотеки и использовать где надо. Вместо тщательного выпиливания канонов паттерна ты просто декларируешь его применение и задаешь (тоже декларативно) нужные параметры. А все остальное автоматически выпиливает компилятор по программе называемой "макрос" (не путать с сишными текстуальными макросами). И более того, такие "программы" для компилятора ты можешь создавать сам.


VD>Не уж-то это не стоит того, чтобы хотя бы ознакомиться с таким языком?


А что где-то есть библиотека реализации паттернов на Немерле? Пока что, то что я вижу, это 6 маленьких библиотечек макросов на nemerle.org и какая-то масса разрозненного кода на google code. А солидной, готовой для использования, хорошо документированной библиотеки я не вижу.

Или предлагается самому писать себе макросы на каждый конкретный случай?

Макросы — это, конечно, круто и все дела. Только пусть кто-нибудь другой их напишет, хорошо оттестирует, отдокументирует, и сделает тривиальным для использования. Вот тогда-то Немерле и будет представлять существенный интерес. А пока это просто хобби для тех, кому интересно возиться с макросами.
Re[12]: Что вас останавливает от изучения нового языка?
От: Ziaw Россия  
Дата: 25.04.11 01:20
Оценка:
Здравствуйте, vdimas, Вы писали:

V>А если по делу, мне крайне не нравится реализация алгебраических типов в Немерле. Она там одинакова для рекурсивных и нерекурсивных АглТД, т.е. явно была сделано "на скорую руку". Но нынешняя команда сим вопросом заниматься не будет.


А чем должна отличаться реализация для нерекурсивных?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.