OberonCore
https://forum.oberoncore.ru/

"Стоимость", уровень языка и абстракций
https://forum.oberoncore.ru/viewtopic.php?f=27&t=3157
Страница 2 из 7

Автор:  Geniepro [ Пятница, 14 Январь, 2011 15:33 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Valery Solovey писал(а):
Наверное, можно так:
...
Проверки на (message != null) перед safeLogAppend(message) не нужны, так что можно немного упростить.
Главный недостаток имхо в том, что тут появляется дублирование кода
Код:
message = TCPStreamIO.ReceiveString(POSIPStream);
safeLogAppend(message);
Это может быть чревато в будущем, при каких-то изменениях/переделках...

Автор:  Geniepro [ Пятница, 14 Январь, 2011 15:44 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Вот такой вариант вроде бы более-менее, но всё равно смущает дублирование оператора
message = TCPStreamIO.ReceiveString(POSIPStream):
safeLogAppend(message);
Код:
            string message = TCPStreamIO.ReceiveString(POSIPStream);
            safeLogAppend(message);

            while (message != null && SrvIPStream != null && SrvIPStream.CanWrite)
            {
                TCPStreamIO.SendMsg(SrvIPStream, message + "\n");
                message = TCPStreamIO.ReceiveString(POSIPStream);
                safeLogAppend(message);
            }


Действительно ли исключение оператора break стоит всех этих усилий по его исключению? :roll:

ЗЫ. Чорд, отвлекают, аж путаюсь уже. Однозадачный я всё-таки ((

Автор:  albobin [ Пятница, 14 Январь, 2011 15:55 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Geniepro писал(а):
Действительно ли исключение оператора break стоит всех этих усилий по его исключению? :roll:

Рискую показаться навязчивым, но как вам безбрейковый вариант в предидущем сообщении, правда в словесах, а не в коде (не сишник я :( )

Автор:  Valery Solovey [ Пятница, 14 Январь, 2011 16:09 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Цитата:
дублирование оператора
Смотря что значит "дублирование" : ).

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

Код:
message = getAndProcess(POSIPStream)


Если допускается добавление дополнительной функции, куда можно инкапсулировать эти 2 действия, то проблема отпадёт. Но появятся накладные расходы на вызов функции. А также, появится необходимость понимания назначения функции (возможно помогут говорящее название и комментарий рядом; но возможно и не помогут : ) ).

Автор:  Geniepro [ Пятница, 14 Январь, 2011 16:15 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

albobin писал(а):
Рискую показаться навязчивым, но как вам безбрейковый вариант в предидущем сообщении, правда в словесах, а не в коде (не сишник я :( )

Не совсем понял -- нравится мне этот вариант или нет? Или как он работает?

Нравится или нет -- не могу определиться. Вроде бы достаточно прост, но дублирование кода не нравится. Хотя break тоже не особенно нравится.

А алгоритм там простой:

принимается сообщение из одного канала связи,
записывается в лог,
отправляется по другому каналу связи,
всё это повторяется, пока оба канала связи активны.

Автор:  albobin [ Пятница, 14 Январь, 2011 16:19 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

albobin писал(а):
А , если последний не отосланный message за пределами while не нужен, то можно написать функцию с параметрами: откуда однократно прочитать, логить?, куда передать. А возвращать флаг "эндец" (нет собщения или некому отправлять) и заwhileить её


Я имел ввиду вот это сообщение


Что-то вроде этого (на си не пишу :? )

Код:
bool TransferMessage (вход, логить,выход);
{
    string message;
    bool ok ;
    message = TCPStreamIO.ReceiveString(вход);
    ok=(message != null) ;
     if (ok && логить)
       safeLogAppend(message);
     if (ok && (SrvIPStream != null) && SrvIPStream.CanWrite)
       TCPStreamIO.SendMsg(выход, message + "\n");
     else
       ok=ложь ;
     return ok
}

while ( TransferMessage(POSIPStream,правда,SrvIPStream))

Автор:  Peter Almazov [ Пятница, 14 Январь, 2011 16:23 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Geniepro писал(а):
Нравится или нет -- не могу определиться. Вроде бы достаточно прост, но дублирование кода не нравится. Хотя break тоже не особенно нравится.
Все эти мучения описаны Кнутом в статье "Structured Programming with go to statements", которая есть в книге "Literate Programming" viewtopic.php?p=50865#p50865

Автор:  Alexey Veselovsky [ Пятница, 14 Январь, 2011 16:27 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Geniepro писал(а):
Geniepro писал(а):
32 цикла while, из них 1 с оператором break (можно переписать без break с небольшим ухудшением понятности)
Переписал вот такой код, вполне нормальный для сишника, но ужасно кривой для паскалиста:
Код:
            string message;

            while ((message = TCPStreamIO.ReceiveString(POSIPStream)) != null)
            {
                safeLogAppend(message);
                if (SrvIPStream != null && SrvIPStream.CanWrite)
                {
                    TCPStreamIO.SendMsg(SrvIPStream, message + "\n");
                }
                else
                    break; // Отправлять некому, закончим работу
            }

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

Автор:  Geniepro [ Пятница, 14 Январь, 2011 17:44 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Peter Almazov писал(а):
Все эти мучения описаны Кнутом в статье "Structured Programming with go to statements", которая есть в книге "Literate Programming" viewtopic.php?p=50865#p50865

Если попытаться переложить адский loop
Код:
loop
  …
  exit when (exit-cond)
  …
end loop
на сишный синтаксис:
Код:
loop
{
     ...
}
exit_when (exit-cond)
{
    ...
}
то получится что-то такое:
Код:
string message;

loop
{
    message = TCPStreamIO.ReceiveString(POSIPStream);
    safeLogAppend(message);
}
exit_when (message == null || SrvIPStream == null || !SrvIPStream.CanWrite)
{
    TCPStreamIO.SendMsg(SrvIPStream, message + "\n");
}

Автор:  Peter Almazov [ Пятница, 14 Январь, 2011 17:46 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

И что?

Автор:  Geniepro [ Пятница, 14 Январь, 2011 17:51 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Peter Almazov писал(а):
И что?

Ну что, что?
Жаль, что в С# нет такого оператора и возможностей его создания (путём макросов, например).

Автор:  Peter Almazov [ Пятница, 14 Январь, 2011 17:55 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

А чем break-то не подходит?

Автор:  Alexey Veselovsky [ Пятница, 14 Январь, 2011 17:58 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

А зачем там на каждой итерации проверяется SrvIPStream != null ? В цикле ничто его не меняет. Разве что из другого потока кто-то что-то поменяет... С другой стороны, ничто не мешает ссылку у себя сохранить, гарантируя что ссылка всегда будет не ноль, (ведь объект этот из памяти его никто не вышвырнет пока на него есть ссылки) и проверять просто может оно писать или нет.

Автор:  Сергей Прохоренко [ Пятница, 14 Январь, 2011 17:59 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

"exit when (exit-cond)" лучше, чем break :?:

Автор:  Илья Ермаков [ Пятница, 14 Январь, 2011 18:02 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Geniepro писал(а):
Valery Solovey писал(а):
Наверное, можно так:
...
Проверки на (message != null) перед safeLogAppend(message) не нужны, так что можно немного упростить.
Главный недостаток имхо в том, что тут появляется дублирование кода
Код:
message = TCPStreamIO.ReceiveString(POSIPStream);
safeLogAppend(message);
Это может быть чревато в будущем, при каких-то изменениях/переделках...


Евгений, при нормальном составлении циклов Вы не избежите этого дублирования, во многих случаях.
Потому что оно объективно есть. Если у Вас некоторое действие (например, попытка взятия очередного элемента при проходе по последовательности) выполняется на 1 раз больше, чем остальные действия цикла, то разумеется, что этот добавочный раз должен оказаться до (обычно) или после цикла. Противное (всякие break или лишние if) - просто хак, затуманивающий вот эту суть - действие вып. на 1 раз больше, чем сопряжённые с ним. И действие это не входит цикл, а выносится до или после него.

Автор:  Geniepro [ Пятница, 14 Январь, 2011 18:02 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Alexey Veselovsky писал(а):
Если я не ошибаюсь, такой код лучше всего запишется на хаскеле посредством какой-нибудь монады Maybe.

В данном случае монада Maybe не покажет всю свою крутизну, для неё нужны более запущенные случаи, где куча действий может иметь недопустимый результат, и последующие действия не могут из-за этого работать.
Чем больше таких действий, тем монада Maybe выгоднее (с учётом языковой поддержки do-синтаксиса, как в Хаскелле).

Имитация этой монады на C# вряд ли что даст, наверное. Там такой жуткий синтаксический оверхед будет... :lol:

Автор:  Geniepro [ Пятница, 14 Январь, 2011 18:04 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Peter Almazov писал(а):
А чем break-то не подходит?

Тем, что break нелюбим оберонщиками. Да в оберонах и нет никакого break...

Автор:  Alexey Veselovsky [ Пятница, 14 Январь, 2011 18:07 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Geniepro писал(а):
Peter Almazov писал(а):
А чем break-то не подходит?

Тем, что break нелюбим оберонщиками. Да в оберонах и нет никакого break...

Но есть RETURN и вложенные функции!
Правда в Oberon-07 RETURN'a уже нет... Как и массивов неизвестной на этапе компиляции длины.

Автор:  Geniepro [ Пятница, 14 Январь, 2011 18:07 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

Alexey Veselovsky писал(а):
А зачем там на каждой итерации проверяется SrvIPStream != null ? В цикле ничто его не меняет. Разве что из другого потока кто-то что-то поменяет... С другой стороны, ничто не мешает ссылку у себя сохранить, гарантируя что ссылка всегда будет не ноль, (ведь объект этот из памяти его никто не вышвырнет пока на него есть ссылки) и проверять просто может оно писать или нет.

Нет гарантии, что SrvIPStream не будет уничтожен в других процессах...

Автор:  Илья Ермаков [ Пятница, 14 Январь, 2011 18:11 ]
Заголовок сообщения:  Re: "Стоимость", уровень языка и абстракций

break, во-первых, нарушает "инкапсуляцию управления" (внутреннее содержание конструкции может влиять на её завершение) - это противоречит привычному стилю изучения программы "снаружи вглубь".
Во-вторых, break даёт программисту свободу и "искушение" писать "оригинальные" циклы, непохожие друг на друга, вместо того, чтобы разглядеть в задаче цикла её основную природу и организовать цикл какой-либо типичной структуры.
Если природа "не разглядывается", то надо абстрагироваться - скрыть какие-то технические детали за процедурами-типами.

Был пример на Компьютерре, одному участнику переписали код таким образом. Код был на С++.
См. вот это сообщение: http://www.computerra.ru/forum/index.ph ... age1136258
- задача,
и следующее за ним - её переделка.
(там одна опечатка есть, а именно - p переобъявлено внутри цикла...)

Страница 2 из 7 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/