Райдеры (rider), т. е. считыватели и записыватели (reader и writer) могут быть либо последовательными (не позиционируемые), либо с произвольным доступом (позиционируемые). Программист может испытать затруднение при описании их типов, а именно не ясно стоит ли каждый раз заводить по два разных типа райдеров (позиционируемые и не позиционируемые) или же включить методы позиционирования (GetPosition, SetPosition,...) в один тип, но например выставлять некий булевский флаг возможности их использования. В первом случае получается слишком много типов (по 2 reader и по 2 writer), а во втором случае методы позиционирования иногда будут лишними, а тип громоздким.

Предлагаю иное решение. Вместо того чтобы включать методы позиционирования в типы reader и writer можно обзавестись типом скроллер (scroller), который и будет нести ответственность за прокрутку райдеров:

## Код:
```
Rider = POINTER TO ABSTRACT RECORD 
  (r: Rider) Available (): LONGINT, NEW, ABSTRACT
END;

Scroller = POINTER TO ABSTRACT RECORD 
  (s: Scroller) MinPosition (): LONGINT, NEW, ABSTRACT;
  (s: Scroller) MaxPosition (): LONGINT, NEW, ABSTRACT;
  (s: Scroller) GetPosition (r: Rider): LONGINT, NEW, ABSTRACT;
  (s: Scroller) SetPosition (r: Rider; position: LONGINT), NEW, EMPTY
END;
```


где метод Available (): LONGINT показывает сколько позиций доступно для продвижения вперёд, т. е. для reader - сколько доступно для считывания и для writer - сколько доступно для записи. Бинарные считыватель и записыватель, при этом, есть просто:

## Код:
```
Reader = POINTER TO ABSTRACT RECORD (Rider)
  (r: Reader) ReadByte (OUT a: BYTE), NEW, ABSTRACT;
  (r: Reader) ReadBytes (OUT a: ARRAY OF BYTE; offset, count: INTEGER), NEW, ABSTRACT
END;

Writer = POINTER TO ABSTRACT RECORD (Rider)
  (w: Writer) WriteByte (a: BYTE), NEW, ABSTRACT;
  (w: Writer) WriteBytes (IN a: ARRAY OF BYTE; offset, count: INTEGER), NEW, ABSTRACT
END;
```


Рассмотрим тип объекта-буфера. Кроме считывателей и записывателей буфер должен будет предоставлять ещё и скроллер:

## Код:
```
Buffer = POINTER TO ABSTRACT RECORD 
  (b: Buffer) NewReader (old: Reader): Reader, NEW, ABSTRACT;
  (b: Buffer) NewWriter (old: Writer): Writer, NEW, ABSTRACT;
  (b: Buffer) Scroller (): Scroller, NEW, ABSTRACT
END;
```


А вот, например, тип канал (channel) скроллера своих райдеров предоставлять не будет - они же у него не позиционируемые:

## Код:
```
Channel = POINTER TO ABSTRACT RECORD 
  (c: Channel) Reader (): Reader, NEW, ABSTRACT;
  (c: Channel) Writer (): Writer, NEW, ABSTRACT;
END;
```


Позиционируемость райдера зависит от его носителя (carrier).
Носитель либо предоставляет скроллер для своих райдеров либо не предоставляет, вот и всё.