среда, 23 июня 2010 г.

[prog] Простая штука, за которую я очень благодарен Pascal-ю

В языке Pascal есть хорошая штука: с помощью блока type можно назначать имена своим типам

type
   TicketsArray : array[0..10] of Ticket;

И затем в программе использовать эти имена. Преимуществ у такого подхода было несколько. Во-первых, сокращается объем кода кода. Во-вторых, проще сопровождать код, т.к. при уточнении или изменении типа часто достаточно всего лишь изменить его описание.

Причем, насколько я помню, стиль программирования на Pascal не только поощрял подобное использование секции type, но и даже требовал этого. По крайней мере благодаря книжкам (среди которых замечательная тонкая книжица за авторством Вильвачева и Крисевич по Паскалю) и Лубочкину Александру Васильевичу, читавшему нам на первом курсе предмет “Языки программирования и конструирование программ”, я стал постоянно использовать этот прием.

В C/C++, к счастью, есть очень похожая возможность. Это старый добрый typedef. А вот в Java, например, typedef-а нет. Поэтому я на Java и не программирую ;) И в Eiffel так же typedef-а нет, и на Eiffel я так же не программирую ;) Но это уже “Остапа понесло” :)))

Так вот, к сожалению своему, приходится наблюдать, как многие C++ программисты игнорируют существование такой замечательной штуки, как typedef :(

Не могу я понять, как можно писать вот столько кода:

std::map< ticket_key_t, ticket_t > tickets;

void f( const std::map< ticket_key_t, ticket_t > & tickets )
   {
      std::map< ticket_key_t, ticket_t >::const_iterator oldest =
            find_oldest_ticket();
      for( std::map< ticket_key_t, ticket_t >::const_iterator
            it = tickets.begin() ... )
         ...
   }

Когда можно написать и меньше, и понятнее:

typedef std::map< ticket_key_t, ticket_t > ticket_map_t;
ticket_map_t tickets;

void f( const ticket_map_t & tickets )
   {
      ticket_map_t::const_iterator oldest = find_oldest_ticket();
      for( ticket_map_t::const_iterator
            it = tickets.begin() ... )
         ...
   }

Видимо, у этих C++ников не было опыта программирования на нормальном Pascal-е в молодости. Не было той школы. К сожалению.

Ну ничего, будем бить по рукам и приобщать к хорошему :)

11 комментариев:

night beast комментирует...

я думаю, основная причина этого -- трудно придумать нормальное название.
хорошо когда есть устоявшиеся названия (iterator, value_type и т.д.), а когда что-то специфичное вроде std::map< ticket_key_t, ticket_t >
то приходится поломать голову :)

Quaker комментирует...

Класс основан на некотором абстрактном типе данных и задает частичную или полную реализацию этого АТД.

eao197 комментирует...

2night beast: ну проблема выбора имен для программных сущностей является одной из самых сложных проблем в программировании.

eao197 комментирует...

2Quaker: а это вы сейчас с кем разговаривали? ;)

Alexey Romanov комментирует...

И в Scala есть. И в Haskell тоже :)

Rustam комментирует...

Alexey Romanov там где есть вывод типов и паттерн матчинг эта проблема не так остра :)

eao197 комментирует...

2Alexey Romanov:

Я уже подзабыл, в Scala есть возможность записать:

type TicketMap = Map[TicketKey,Ticket]

а затем использовать TicketMap:

def f(tickets: TicketMap) = ...

?

Unknown комментирует...

в Java типы деларировались до последнего времени на столько просто, что typedef не давал никакого выигрыша. Это теперь уже накидали всяких генериков, где появляются конструкции типа List>>. Вот для таких конструкций, наверное typedef тоже пригодился бы

eao197 комментирует...

>Это теперь уже накидали всяких генериков

Так я про теперь и говорю. Тем более, что этому "теперь" уже шесть годков. Не так уж и мало ;)

Alexey Romanov комментирует...

@Rustam: Не так остра, но всё равно это нередко бывает полезно.

@Евгений Охотников: Да, есть.

ShaggyOwl комментирует...

traits, опять же... typedef полезная вещь.