Зачем два механизма ограничений?

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

Модератор: Модераторы

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

Лучше как сейчас
10
53%
Лучше так, как сейчас, и никак иначе!
2
11%
Лучше без private и strict (но с остальными секциями)
4
21%
Мне пофиг
1
5%
Лучше убрать interface и implementation
2
11%
 
Всего голосов : 19

Зачем два механизма ограничений?

Сообщение Дож » 23.10.2015 20:40:35

В паскале изначально поддерживались модули с возможностью указывать публичные и приватные объявления:
Код: Выделить всё
unit MyUnit;

interface

procedure MyPublicProc;

implementation

var
  X: Integer;

procedure MyPrivateProc;
begin
  X := 5;
end;

procedure MyPublicProc;
begin
  MyPrivateProc;
end;

end.


Потом в какой-то момент в паскаль были добавлены объекты (кем, кстати? Эпплом?). Объекты начали поддерживать свои собственные приватные и публичные секции:
Код: Выделить всё
unit MyUnit;

interface

type
TMyObject = object
private
  X: Integer;
  procedure MyPrivateMethod;
public
  procedure MyPublicMethod;
end;

implementation

procedure TMyObject.MyPrivateMethod;
begin
  X := 5;
end;

procedure TMyObject.MyPublicMethod;
begin
  MyPrivateMethod;
end;

end.


Ну и уродство!

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

interface

type
TMyObject = object
  procedure MyPublicMethod;
end;

implementation

type
TMyObject = object
  X: Integer;
  procedure MyPrivateMethod;
  begin
    X := 5;
  end;
  // это пример вынесения определения за секцию объекта
  procedure MyPublicMethod; forward;
end;

procedure TMyObject.MyPublicMethod;
begin
  MyPrivateMethod;
end;

end.


Могу привести пример: допустим, мы хотим реализовать кроссплатформенный объект-обёртку над сообщением в оконной системе для Linux/Windows, сейчас нужно писать как-то так (условному клиенту модуля трудно понять что требуется, потому что нужно вычленить среди кучи подробностей то, что реально нужно, да и детали эти размазаны):
Код: Выделить всё
unit MySuperMessages;

interface

uses
   {$IFDEF WINDOWS}windows{$ENDIF}
   {$IFDEF UNIX}SomeLinuxModules{$ENDIF};

type
TMyEvent = object
private
{$IFDEF WINDOWS}
  Msg, lParam, wParam: LongInt;
{$ENDIF}
{$IFDEF UNIX}
  BlaBlaBlaParam: Pointer;
{$ENDIF}
public
  function IsKeyDown: Boolean;
  function IsKeyUp: Boolean;
end;

implementation

{$IFDEF WINDOWS}
function TMyEvent.IsKeyDown: Boolean;
begin
  Result := Msg = WM_KEYDOWN;
end;

function TMyEvent.IsKeyUp: Boolean;
begin
  Result := Msg = WM_KEYUP;
end;
{$ENDIF}

{$IFDEF UNIX}
function TMyEvent.IsKeyDown: Boolean;
begin
  Result := BlablablaGetMeIsKeyDownPlease(BlaBlaBlaParam, nil, JUST_DO_IT or YES_I_ACTUALLY_WANT_IT, SizeOf(Boolean));
end;

function TMyEvent.IsKeyUp: Boolean;
begin
  Result := BlablablaGetMeIsKeyUpPlease(BlaBlaBlaParam, nil, JUST_DO_IT or YES_I_ACTUALLY_WANT_IT, SizeOf(Boolean));
end;
{$ENDIF}
...

end.


А вот здесь интерфейсная секция гораздо читабельнее! Да и секция реализации, на мой вкус, стала гораздо лучше.
Код: Выделить всё
unit MySuperMessages;

interface

type
TMyEvent = object
  function IsKeyDown: Boolean;
  function IsKeyUp: Boolean;
end;

implementation

uses
   {$IFDEF WINDOWS}windows{$ENDIF}
   {$IFDEF UNIX}SomeLinuxModules{$ENDIF};

type
{$IFDEF WINDOWS}
TMyEvent = object
  Msg, lParam, wParam: LongInt;

  function TMyEvent.IsKeyDown: Boolean;
  begin
    Result := Msg = WM_KEYDOWN;
  end;

  function TMyEvent.IsKeyUp: Boolean;
  begin
    Result := Msg = WM_KEYUP;
  end;
end;
{$ENDIF}

{$IFDEF UNIX}
TMyEvent = object
  BlaBlaBlaParam: Pointer;

  function TMyEvent.IsKeyDown: Boolean;
  begin
    Result := BlablablaGetMeIsKeyDownPlease(BlaBlaBlaParam, nil, JUST_DO_IT or YES_I_ACTUALLY_WANT_IT, SizeOf(Boolean));
  end;

  function TMyEvent.IsKeyUp: Boolean;
  begin
    Result := BlablablaGetMeIsKeyUpPlease(BlaBlaBlaParam, nil, JUST_DO_IT or YES_I_ACTUALLY_WANT_IT, SizeOf(Boolean));
  end;
end;
{$ENDIF}

...

end.


А теперь можете проголосовать и сказать что об этом думаете.
Последний раз редактировалось Дож 24.10.2015 13:56:13, всего редактировалось 2 раз(а).
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Зачем два механизма ограничений?

Сообщение vitaly_l » 23.10.2015 21:29:58

Вы поделили на два: приват и паблик... А там несколько больше вариантов, 7-мь кажется и каждый из них несёт свою нагрузку. Однако, никто Вам не мешает писать, так как Вам удобно. Ваш способ более экономичный, т.к. содержит меньше символов(отсутствуют объявления приват функций) и при программировании, после перехода по Ctrl+стрелка вверх, чел. сразу попадёт к телу приватной функции, а не к её объявлению. Что тоже удобнее. Но если нужны более сложные ограничения, нежели приват и паблик, то Ваш метод будет бессилен.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Зачем два механизма ограничений?

Сообщение zub » 23.10.2015 21:59:38

>>А теперь можете проголосовать и сказать что об этом думаете.
Ничего хорошего в голову не пришло. Насколько понял - весь смысл убрать ифдефы из interface. В сейчасном положении дел можно абсолютно также - в inteface одно абстрактное объявление, в implementation 2е разных реализации - разграниченые ифдефами.
Разве
Код: Выделить всё
TMyAbstractEvent = object
  function IsKeyDown: Boolean;
  function IsKeyUp: Boolean;
end;
и когданибудь потом
TMyEvent=object(TMyAbstractEvent)

Не то что вы хотели?
zub
долгожитель
 
Сообщения: 2884
Зарегистрирован: 14.11.2005 23:51:26

Re: Зачем два механизма ограничений?

Сообщение скалогрыз » 23.10.2015 22:36:59

Дож писал(а):Потом в какой-то момент в паскаль были добавлены объекты (кем, кстати? Эпплом?). Объекты начали поддерживать свои собственные приватные и публичные секции:

Делфи. Хотя у эппла что-то подобное было.
Но опять же у эппла, в то же obj-c интерфейс и приватная часть классов разделена, чтобы было красиво.

Но возможно это будет добавлено в FPC
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Зачем два механизма ограничений?

Сообщение Дож » 23.10.2015 23:20:54

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

И что из этих 7 вариантов реально необходимо?

zub писал(а):Насколько понял - весь смысл убрать ифдефы из interface.

Вопрос не в том «как сделать из того, что есть?», а «как концептуально лучше?». Задача — улучшить читаемость и логичность кода, а заодно и отбрасыванием лишних сущностей.

zub писал(а):Не то что вы хотели?

Нет, я не знаю как может работать предложенный вариант, а реализовать нечто похожее средствами языка можно (нужно иметь два модуля: клиентский MyUnit и приватный MyUnitImpl, в приватном реализуется объект как обычно, а в публичном пишется делегирующий класс над приватным) — но оно того заведомо не стоит.

скалогрыз писал(а):Делфи.

А как же Turbo/Borland Pascal? У эппла точно было, вопрос в том, с кого началась эта традиция.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Зачем два механизма ограничений?

Сообщение Sharfik » 23.10.2015 23:40:49

Дож, Анекдот про отца, сына и солнце знаешь?
Дож писал(а):Задача — улучшить читаемость и логичность кода, а заодно и отбрасыванием лишних сущностей.

Лишние они могут быть для понимания двух трех человек, а для оставшихся семи, которые могут молчать и не парится из-за "некрасиво" это очень не лишние вещи.
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 759
Зарегистрирован: 20.07.2013 01:04:30

Re: Зачем два механизма ограничений?

Сообщение Дож » 24.10.2015 00:21:06

Лишние они могут быть для понимания двух трех человек

А могут не быть
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Зачем два механизма ограничений?

Сообщение Kemet » 24.10.2015 00:22:07

Дож писал(а):Вопрос не в том «как сделать из того, что есть?», а «как концептуально лучше?».

Концептуально лучше -это Модула-3
Kemet
постоялец
 
Сообщения: 241
Зарегистрирован: 10.02.2010 19:28:32
Откуда: Временно оккупированная территория

Re: Зачем два механизма ограничений?

Сообщение скалогрыз » 24.10.2015 03:17:10

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

Во-первых, любые дополнительные типы, которые используются исключительно в private секции, в interface-е ничем не помогают, а только вредят. В Delphi, вместо вынесения private в implementation, придумали делать вложенные типы (которые только внутри класса). Но от этого страдает только секция interface, которая превращается в некую ёлочку. Ну и тут же можно вспомнить про неттизм в виде "strict private", который тоже нафиг не нужен.

Во-вторых, скрытие private секции в implementation-е, очень важно для динамически подгружаемых модулей. Хех. Особенно для модулей с закрытыми исходниками (читай комерческий). Например в делфи, можно подключить модуль только через dcu, т.к. dcu несёт в себе всю информацию о типах, но вот использовать такой модуль не очень удобно, т.к. смотреть в объявление интерфейса зачастую удобнее, чем в полуотсутствущую документацию. Или в случае вообще отстуствующей документации, что часто случается, когда приходится работать со старой версией библиотеки.

Почему бы FPC не позаимстовать из Модулы, вместо каких-нить лиспов, хаскелей и т.п.
Организаця кода на уровне языка, а не на уровне условий компиляции (кучи ifdef-ов), повышает читаемость и обслуживание кода.

куча $ifdef-ов с includ-ами, это может быть и используется и FPC и Лазарь, но больше походит на сионизм, нежели модульность.

Уверен, если написать этот вопрос куда-нить на fpc-maillist, выяснится что вича уже у кого-нить из "ядерных" разработчиков в "todo" листе :)
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Зачем два механизма ограничений?

Сообщение Лекс Айрин » 24.10.2015 09:40:12

Если писать код в interface секции, то нарушен будет один из основополагающих принципов паскаля -- код должен быть отделен от данных.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: Зачем два механизма ограничений?

Сообщение Снег Север » 24.10.2015 11:15:53

Если идти этим путем, то придем к чему-то вроде Оберона. Но Оберон уже есть - зачем еще один?
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2993
Зарегистрирован: 27.11.2007 16:14:47

Re: Зачем два механизма ограничений?

Сообщение Дож » 24.10.2015 13:18:22

Лекс Айрин писал(а):Если писать код в interface секции

А где предлагалось писать код в interface секции?

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

Основополагающий принцип паскаля? Как он действует, например, в следующем коде? Можно ли утверждать, что код и данные разделены, хотя var-секции идут в перемешку с определениями функций? Proc — это код или данные? В выражении вида "Proc := @SetX;" код тоже отделён от данных? А в выражении "Proc;"?
Код: Выделить всё
var
  X: LongInt;
  Proc: procedure;

procedure SetX;
var
  S: LongInt;
begin
  Proc;
  S := 107
  X := Sqr(S);
end;

var
  Y: LongInt;

procedure SetY;
var
  Q: LongInt;
begin
  Proc;
  Q := X;
  Y := Sqr(Q);
end;

...
if Random(100) > 50 then begin
  Proc := @SetX;
end else
  Proc := @SetY;


Kemet писал(а):Концептуально лучше -это Модула-3

Снег Север писал(а):Если идти этим путем, то придем к чему-то вроде Оберона. Но Оберон уже есть - зачем еще один?

Я, к сожалению, пока что не знаком ни с Модула-3, ни с Обероном, но не вижу ничего плохого в использовании хороших концепций в паскале, даже если они где-то уже есть. Но их нужно использовать обдуманно.
Последний раз редактировалось Дож 24.10.2015 13:31:09, всего редактировалось 1 раз.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Зачем два механизма ограничений?

Сообщение vitaly_l » 24.10.2015 13:30:40

В общем я всех почитал, узнал что, тот странный "Паскаль", код которого я разбирал и пытался осознать - месяц назад, оказывается называется Модула-3 и как выяснилось - это крутой системный язык...

Дож писал(а):Я, к сожалению, пока что не знаком ни с Модула-3, ни с Обероном, но не вижу ничего плохого в использовании хороших концепций в паскале, даже если они где-то уже есть. Но их нужно использовать обдуманно.


Но по теме, я, пришёл к такому выводу: Нужный мне ответ, в вопроснике голосования - отсутствует. Судя по ответам: предлагаемая конструкция, сейчас FPC - не поддерживается. Сказать что, она плохая, я не могу, т.к. есть некоторые плюсы. Но удалить спецификаторы: protected, published, private, public, strict private - это неправильно, т.к. при большом коде, они существенно снижают нагрузку. Соответственно, нужный мне ответ, отсутствует в вопроснике, а именно: "объединить предлагаемую топик стартером и существующие конструкции", но такого ответа в вопроснике нет :cry: . Хотя, такой ответ: расширит, но не урежет - возможности языка. Из вышесказанного следует что :roll: топик стартер, хотел устроить "геноцид" по отношению к спецификаторам: protected, published, private, public, strict private. А "геноцид" - художники допустить не могут :cry:, но идея конструкта интересная, жаль, что оказывается так ещё нельзя программировать.


.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Зачем два механизма ограничений?

Сообщение Дож » 24.10.2015 13:49:25

Но удалить спецификаторы: protected, published, private, public, strict private - это неправильно, т.к. при большом коде, они существенно снижают нагрузку.

Я предлагаю удалить не все, а только private и strict-версии. Это неявно подразумевается в ответе «Лучше без private, стоит оставить только protected», это неточно, но я просто не знаю как сформулировать его коротко.

На ситуацию можно посмотреть и с другой стороны: вот если private, public, published, protected, strict private и strict protected так хороши и полезны, и незаменимы, то не лучше ли упразднить такие строгие interface и implementation-секции? Скажем, что у всего модуля в целом тоже могут идти вперемешку public и private секции, будто бы это один большой объект. Тогда становится на два зарезервированных слова меньше, на две конструкции меньше, логичность языка повышается, а выразительная сила остаётся, казалось бы. :) Такой вариант ответа предложен последним.

Из вышесказанного следует что :roll: топик стартер, хотел устроить "геноцид" по отношению к спецификаторам: protected, published, private, public, strict private. А "геноцид" - художники допустить не могут :cry:,

"Геноцид" — это плохо, урезать уже устаявшийся и принятый язык нельзя. Зато полезно ответить на вопросы: 1) рассмотрим некоторый альтернативный гипотетический язык, в котором было бы вот так, то по каким параметрам этот гипотетический альтернативный язык был бы лучше, а по каким хуже? 2) если текущий язык дополнить фичами, чтобы на нём можно было писать как на гипотетическом альтернативном, то в чём текущий язык станет лучше, а в чём хуже?

Одним из аргументов в пользу interface-секций является то, что в interface-секции описано всё то, что нужно знать пользователю модуля. (Это даже можно назвать одним из «основополагающих принципов паскаля».) Заголовки функций, объявления типов/объектов/классов. К сожалению, из-за private-секций происходит утечка абстракции и в interface-модуле оказываются детали реализации, о чём также писал скалогрыз.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47

Re: Зачем два механизма ограничений?

Сообщение Лекс Айрин » 24.10.2015 13:59:05

Дож писал(а):А где предлагалось писать код в interface секции?


Сорри, не заметил. Но тогда у Вас получается объект описывается дважды. Причем, один раз в секции кода А вдруг описания не совпадут? Да и потеря компактности.

Дож писал(а):Как он действует, например, в следующем коде? Можно ли утверждать, что код и данные разделены, хотя var-секции идут в перемешку с определениями функций?


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


vitaly_l писал(а):Но удалить спецификаторы: protected, published, private, public, strict private - это неправильно, т.к. при большом коде, они существенно снижают нагрузку.


Имхо, как раз таки это правильно. Я удалил бы virtual и добавил бы own (собственный).

По умолчанию я бы сделал все методы виртуальными. Скрыл бы все методы/поля и организовал бы доступ только через property.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

След.

Вернуться в Компилятор / язык программирования

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

Рейтинг@Mail.ru