Re[19]: Про типы и логику
От: Evgeny.Panasyuk Россия  
Дата: 09.03.15 21:49
Оценка:
Здравствуйте, Ikemefula, Вы писали:

EP>>То что примеры итерации или точек времени очевидны.

I>Да, когда нечего сказать, в ход идет аргумент "тут всё просто", "это очевидно"

Ты действительно никогда не использовал итераторы?
template<typename I, typename P>
I partition_point_m(I first, I last, P p)
{
    while(first != last)
    {
        I middle = first + (last - first)/2;
        //I middle = (last - first)/2; - Compile error
        if( p(*middle) )
            last = middle;
        else
            first = ++middle;
    }
    return first;
}


I>>>Покажи внятный пример использования.

EP>>
EP>>auto start = system_clock::now();
EP>>

I>Итого — примера нет.

Почему?

EP>>Я был убеждён в том, что предметная область применения библиотеки std::chrono очевидна

I>Попробуй выразить эту очевидность в терминах пользователя, сразу станет ясно. Вот скажем, редактор векторной графики — здесь всё предельно понятно.

Что именно понятно?

I>Попробуй придумать такой же пример,


Какой такой же? Что конкретно показывает твой пример "редактор векторной графики"?

I>только что бы демонстрировал профит от chrono


Boost.Asio подойдёт? http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/system_timer.html#boost_asio.reference.system_timer.examples

I>и сформулируй, почему именно от chrono будет максимум профита.


Смотри четыре пункта выше.
Re[20]: Про типы и логику
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 10.03.15 06:51
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Ты действительно никогда не использовал итераторы?


А ты бросил пить ?

I>>Итого — примера нет.


EP>Почему?


Потому что надо назвать внятно область применения.

EP>>>Я был убеждён в том, что предметная область применения библиотеки std::chrono очевидна

I>>Попробуй выразить эту очевидность в терминах пользователя, сразу станет ясно. Вот скажем, редактор векторной графики — здесь всё предельно понятно.

EP>Что именно понятно?


Область.

I>>Попробуй придумать такой же пример,


EP>Какой такой же? Что конкретно показывает твой пример "редактор векторной графики"?


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

I>>только что бы демонстрировал профит от chrono


EP>Boost.Asio подойдёт? http://www.boost.org/doc/libs/1_57_0/doc/html/boost_asio/reference/system_timer.html#boost_asio.reference.system_timer.examples


Разумеется, нет. Это еще одно название, а тебя просили область применения.

I>>и сформулируй, почему именно от chrono будет максимум профита.


EP>Смотри четыре пункта выше.


Можно подумать у метода с векторным пространством нет преимуществ, а у афинного нет недостатков, ога.
Re[21]: Про типы и логику
От: Evgeny.Panasyuk Россия  
Дата: 10.03.15 14:48
Оценка:
Здравствуйте, Ikemefula, Вы писали:

EP>>Ты действительно никогда не использовал итераторы?

I>А ты бросил пить ?

Ты чего пример partition_point удалил? Потому что области применения двоичного поиска очевидны, да?

I>>>Попробуй придумать такой же пример,

EP>>Какой такой же? Что конкретно показывает твой пример "редактор векторной графики"?
I>Показывает, где и как будет применяться либа для векторных операций всяких. Там же, кстати, применяется и афинное пространство. Если хочешь, можешь попробовать на этом примере объяснить, за счет чего афинное пространство зарулит векторное.

Уже объяснял. Разжёвывать не собираюсь, ибо интересуешься ты не в познавательных целях, а чисто ради упражнения в демагогии/троллинге

EP>>Смотри четыре пункта выше.

I>Можно подумать у метода с векторным пространством нет преимуществ

Я этого не говорил.
Re[22]: Про типы и логику
От: Ikemefula Беларусь http://blogs.rsdn.org/ikemefula
Дата: 11.03.15 12:23
Оценка: -1 :)))
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>>Ты действительно никогда не использовал итераторы?

I>>А ты бросил пить ?

EP>Ты чего пример partition_point удалил? Потому что области применения двоичного поиска очевидны, да?


Я сколько ни видел реализаций такого поиска, всё время было в лоб, безо всяких итераторов и тд и тд. Пудозреваю, твои итераторы не такая классная мулька, как тебе кажется.

I>>>>Попробуй придумать такой же пример,

EP>>>Какой такой же? Что конкретно показывает твой пример "редактор векторной графики"?
I>>Показывает, где и как будет применяться либа для векторных операций всяких. Там же, кстати, применяется и афинное пространство. Если хочешь, можешь попробовать на этом примере объяснить, за счет чего афинное пространство зарулит векторное.

EP>Уже объяснял. Разжёвывать не собираюсь, ибо интересуешься ты не в познавательных целях, а чисто ради упражнения в демагогии/троллинге


Примеров то как не было, так и нет. Я сдела твою работу — привел пример. И даже на нём тебе нечего сказать.

Вобщем, суммируя тобой сказаное, получается примерно так: "Вот в реальном мире точно всё по другому !"
Re: Про типы и логику
От: kaa_t Россия  
Дата: 19.03.15 15:12
Оценка: 61 (2)
Здравствуйте, Mamut, Вы писали:

M>Выношу из соседнего обсуждения
Автор: Mamut
Дата: 02.02.15
, так как там много флейма и отсутсвие конструктива.


M>Мне просто действительно интересно. Многие утверждают, что типы помогают (чуть ли не) во всем, вплоть до того, что «тайпчекер проверяет именно логику».


M>У меня есть простейшая задача, мне просто интересно, как она будет решаться типами, и/или как типы могут помочь ее решить. Самое главное, если вся логика упаковывается в типы, каким образом проверяется правильность реализации этой логики на типах? Свое решение «в лоб» я тоже напишу, естественно Языки программирования — любые Но желательно приближенные к реальному миру (то есть те, что хоть в какой-то мере используются в природе).


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


[ ЗаказМодель
    (
      Структура = ((Отправлен | Неотправлен) / ( Непредоплачен | Предоплачен ) ) / Риск,
      Операции  = 
      [ 
         Неотправлен(   СуммуУвеличить,СуммуУменьшить ),
         Непредоплачен (   СуммуУвеличить,СуммуУменьшить ),
         Отправлен ( СуммуУменьшить ),
      ]
      
      
    ) ]
  module Модель
  {
    
    
    шаблон_СуммуУвеличить_sum(sum:decimal,val:decimal):decimal
    {
      if (sum + val > 2000 ) sum else sum + val 
    }
    
    шаблон_СуммуУменьшить_sum(sum:decimal,val:decimal):decimal
    {
      sum - val
    }
  }


это декларативное описание макросом будет развернуто приблизительно в такой код:

  module Модель
  {
    [Record]
    public variant Заказ
    {
      | Отправлен
      {
        public ЗаказНепредоплачен():Заказ.ОтправленНепредоплачен
        {
          Заказ.ОтправленНепредоплачен(sum)
        }
        public ЗаказРиск():Заказ.ОтправленРиск
        {
          Заказ.ОтправленРиск(sum);
        }
        public СуммуУменьшить(val:decimal):Отправлен
        {
          def funct( sum:decimal,val:decimal):decimal
          {
            sum - val
          } 
          Отправлен(funct( sum, val ))
        }
      }
      | ОтправленНепредоплачен {  .... }
      | ОтправленРиск {  ... }

      .....    
      
      public Сумма:decimal {  get { sum } }
      
      private mutable sum:decimal;
      

      public static УменьшитьСумму( zlist : list[Заказ] , val:decimal ) : list[Заказ]
      {
        zlist.Map(z=> 
        {
          match(z)
          {
            | e is Отправлен =>  e.СуммуУменьшить(val);
        .....

            | _ => z;
          }
        })
      }
    }
  }


собственно основная сложность состоит не в реализации кода макроса. Сложно придумать декларативный язык, который адекватно опишет модель
Re[8]: Ах да, мое решение :)
От: Evgeny.Panasyuk Россия  
Дата: 09.04.15 18:29
Оценка:
EP>>>Вот твой изначальный пример:
EP>>>это можно трактовать как "можно уменьшать и увеличивать сумму заказа" — это функция change_amount, у которой есть предусловие "заказ не помечен как отправленный", которая безусловно изменяет сумму. Тебе как раз и показывали примеры форсирующие это предусловие в compile-time:
M>>Я перенес это «предусловие» внутрь функции change_amount.
EP>Нарушение предусловия это баг в программе, программа находится в том состоянии в котором не должна была по логике вещей, и как она туда попала неизвестно, лучше всего пристрелить такую программу как взбесившуюся собаку. Почитай наконец что такое precondition.
EP>Предусловия можно проверять, и как-то энфорсить, но отнюдь не обязательно. Например assert'ы энфорсящие предусловия часто используют только в отладочных режимах.
EP>Система типов позволяет энфорсить некоторые предусловия в compile-time, но не все. Я даже больше скажу, далеко не все предусловия можно проверить в runtime — попытка такой проверки попросту может поломать инварианты, и сделать невозможным достижение постусловий.

Кстати, вот выступление John Lakos из Bloomberg по поводу предусловий, assert'ов и defensive programming: "Defensive Programming Done Right"
http://www.youtube.com/watch?v=1QhtXRMp3Hg
http://www.youtube.com/watch?v=tz2khnjnUx8
Re[9]: Ах да, мое решение :)
От: Mamut Швеция http://dmitriid.com
Дата: 10.04.15 13:29
Оценка:
EP>Кстати, вот выступление John Lakos из Bloomberg по поводу предусловий, assert'ов и defensive programming: "Defensive Programming Done Right"

Я из другого лагеря

3.13 Do not program "defensively"

A defensive program is one where the programmer does not "trust" the input data to the part of the system they are programming. In general one should not test input data to functions for correctness. Most of the code in the system should be written with the assumption that the input data to the function in question is correct. Only a small part of the code should actually perform any checking of the data. This is usually done when data "enters" the system for the first time, once data has been checked as it enters the system it should thereafter be assumed correct.

...
The caller is responsible for supplying correct input.




dmitriid.comGitHubLinkedIn
Re[10]: Ах да, мое решение :)
От: Evgeny.Panasyuk Россия  
Дата: 10.04.15 14:35
Оценка:
Здравствуйте, Mamut, Вы писали:

EP>>Кстати, вот выступление John Lakos из Bloomberg по поводу предусловий, assert'ов и defensive programming: "Defensive Programming Done Right"

M>Я из другого лагеря

1. Ну то есть видео ты не смотрел, зато мнение имеешь
2. То есть у тебя всё-таки есть интуитивное понимание того что такое предусловие, и что предусловие не предполагает проверку этого условия внутри функции — но тем не менее обычные внутренние условия функции ты называешь предусловиями
Отредактировано 10.04.2015 14:37 Evgeny.Panasyuk . Предыдущая версия .
Re[11]: Ах да, мое решение :)
От: Mamut Швеция http://dmitriid.com
Дата: 12.04.15 07:33
Оценка:
EP>>>Кстати, вот выступление John Lakos из Bloomberg по поводу предусловий, assert'ов и defensive programming: "Defensive Programming Done Right"
M>>Я из другого лагеря

EP>1. Ну то есть видео ты не смотрел, зато мнение имеешь


Я его еще не посмотрел (не было времени), поэтому и смайлик


EP>2. То есть у тебя всё-таки есть интуитивное понимание того что такое предусловие, и что предусловие не предполагает проверку этого условия внутри функции — но тем не менее обычные внутренние условия функции ты называешь предусловиями


У меня есть объективное понимание того, что такое предусловие, а так же объективное понимание, что ты сам не понимаешь, о чем говоришь. Я тебе это даже на пальцах показал тут
Автор: Mamut
Дата: 05.03.15


dmitriid.comGitHubLinkedIn
Re[10]: Про типы и логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.04.15 09:40
Оценка:
Здравствуйте, alex_public, Вы писали:
_>Т.е. ты ограничиваешь свою задачу строго одной элементарной операцией на шаг (загрузка/сохранение БД)?
Это не он ограничивает, это реальность прикладной области. Если не делать сохранение в БД между элементарными операциями, то первый же fault приведёт к разнообразным и интересным результатам после рестарта. Мало кто ожидает, скажем, многократного списания денег со счёта из-за того, что длинная транзакция была прервана на полпути.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[11]: Про типы и логику
От: alex_public  
Дата: 14.04.15 11:36
Оценка:
Здравствуйте, Sinclair, Вы писали:

_>>Т.е. ты ограничиваешь свою задачу строго одной элементарной операцией на шаг (загрузка/сохранение БД)?

S>Это не он ограничивает, это реальность прикладной области. Если не делать сохранение в БД между элементарными операциями, то первый же fault приведёт к разнообразным и интересным результатам после рестарта. Мало кто ожидает, скажем, многократного списания денег со счёта из-за того, что длинная транзакция была прервана на полпути.

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

P.S. Да, кстати, а мне казалось, что как раз использование транзакций (которые в БД) и позволяет не беспокоиться о проблемах при сбоях посередине длинной последовательности операций. Ну да ладно...
Re[12]: Про типы и логику
От: Sinclair Россия https://github.com/evilguest/
Дата: 14.04.15 12:09
Оценка: +2
Здравствуйте, alex_public, Вы писали:

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

Но проблемы противоречивости-то никуда не делись.

Более-менее популярный пример: есть, скажем, банальный push-код типа:
public void PushDataToStream(StreamWriter w)
{
   var r = File.OpenRead("EULA.txt");
   try
   {
      foreach(var line in r.RealAllLines)
         w.WriteLine(r)
   }
   finally
   {
     r.Close(); // критический код, который мы хотим обязательно выполнить.
   }
}


Предположим, что мы хотим переписать его в pull-код, т.е. в пассивный режим.
На традиционных ЯП мы будем реализовывать интерфейс типа string GetNextLine(void).
И дупа — в том, как нам это сделать, сохранив гарантии про выполнение r.Close().

Конкретно C# конкретно эту проблему решает. Что показывает — несмотря на то, что монолитный код превратился в множество вызовов, по-прежнему можно вести речь об осмысленных гарантиях.
Так и в обработке ордеров: то, что обработка заказа — это не один метод с множеством ветвлений, а множество вызовов множества методов, никак не отменяет наличия интересных инвариантов, которые хочется контролировать статически.

_>P.S. Да, кстати, а мне казалось, что как раз использование транзакций (которые в БД) и позволяет не беспокоиться о проблемах при сбоях посередине длинной последовательности операций. Ну да ладно...

Да, вам казалось.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Про типы и логику
От: alex_public  
Дата: 14.04.15 13:45
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Так и в обработке ордеров: то, что обработка заказа — это не один метод с множеством ветвлений, а множество вызовов множества методов, никак не отменяет наличия интересных инвариантов, которые хочется контролировать статически.


В таком случае надо придумать какой-то контекст, в котором "хранились" бы инварианты. А с учётом того, что при таком раскладе эти инварианты теоретически должны переживать перезапуск приложения, очень сомнительно, что это можно реализовать через типы.
Re[10]: Ах да, мое решение :)
От: diez_p  
Дата: 17.04.15 15:39
Оценка:
Здравствуйте, Mamut, Вы писали:


EP>>Кстати, вот выступление John Lakos из Bloomberg по поводу предусловий, assert'ов и defensive programming: "Defensive Programming Done Right"


M>Я из другого лагеря


M>

M>3.13 Do not program "defensively"

M>A defensive program is one where the programmer does not "trust" the input data to the part of the system they are programming. In general one should not test input data to functions for correctness. Most of the code in the system should be written with the assumption that the input data to the function in question is correct. Only a small part of the code should actually perform any checking of the data. This is usually done when data "enters" the system for the first time, once data has been checked as it enters the system it should thereafter be assumed correct.

M>...
M>The caller is responsible for supplying correct input.


Данные монолитом не проходят по системе, и там где с 0 можно складывать, делить на 0 нельзя. Именно по этому каждому типу необходимо выполнять проверку того с чем он работает. Это касается ентерпрайза, в остальных областях такой метод может повлечь вычислительный оверхед, который не приемлим.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.