Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread Alexandru Pătrănescu
On Sat, Oct 2, 2021 at 6:07 PM G. P. B.  wrote:

> Hello internals,
>
> I'm proposing a new RFC to make 'null' usable as a standalone type.
>
> RFC: https://wiki.php.net/rfc/null-standalone-type
> GitHub PR: https://github.com/php/php-src/pull/7546
>
> Best regards,
>
> George P. Banyard
>

Hey George, thank you for driving the effort forward.

This looks good to me and I think having null as a return type makes it a
bit more clear.
I think the difference between a function returning void vs null will be
clear enough.


But there is one more small elephant in the RFC that I believe should be
discussed.
null|false type will not be a nullable named type but it will be an union
between two named types.

It's not totally unexpected. All types that are combined with false are a
union type so far.

But also, related to null, it will be the first case that will be different.
So far, all types that are combined with null are not necessarily union but
their other type that has an allowsNull() that returns true.

One could argue that we can also have it as a ReflectionNamedType with
getName() = 'false' and  allowsNull() = true.

I feel that the preferred solution will push more towards the general
desire to represent the nullable types notations more and more like an
union.
I can see how what was initially proposed in
https://wiki.php.net/rfc/nullable_intersection_types for (X&Y)|null
might end up being UnionType(IntersectionType(NamedType(X), NamedType(Y)),
NamedType(null))
instead of the originally proposed  IntersectionType(NamedType(X),
NamedType(Y) with allowsNull() = true.

I mean, that's not necessarily a bad thing in my opinion. But maybe it's
good to discuss the future plans as well.
For any new nullable construct should we use a ReflectionUnionType with
ReflectionNamedType for null and not use the allowsNull method?
Should we have a plan to convert current nullable constructs to a
ReflectionUnionType and eventually drop the allowsNull method in PHP 9.0?

On the other hand, while we have the allowsNull method maybe we can keep
the pattern and not have a BC break and use it everywhere.
With an union, you need to iterate over all elements in the union and check
that one is a named reflection for null.
Is there something we cannot achieve if we do it like this?

I don't have a strong preference for either. But I think it would be good
to discuss it.


While writing this, I realize that the RFC should probably specify in the
Reflection section also the simple use case, null, not just the null|false
combination.
I assumed it would be a ReflectionNamedType for null but I think that it
should be clearly specified along with what the getName method will return.
Also, what will the allowsNull method return? If false, should the
recommended pattern for checking if null is allowed be
($reflectionType->allowsNull() || $reflectionType->getName() === 'null')
Or maybe the name should be 'NULL', to match the result of gettype(null)?
If not, maybe we can mention the difference to the gettype function.


Regards,
Alex


Re: [PHP-DEV] Function list declaration syntax?

2021-10-05 Thread Dan Ackroyd
On Tue, 5 Oct 2021 at 18:47, Mike Schinkel  wrote:

> Consider the `Type` class[3] in the `SebastianBergmann\Type` namespace. It 
> contains 60 lines of function declaration to define 14 functions that all 
> return `false`.

PHP allows you to define functions on one line:

function isCallable(): bool { return false; }
function isFalse(): bool { return false; }
function isGenericObject(): bool { return false; }

If you don't like having functions take up lots of lines, it's easier
to just not follow that PSR guide line on formatting, rather than
modify the language.

cheers
Dan
Ack

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread David Gebler
On Tue, Oct 5, 2021 at 3:45 PM Nikita Popov  wrote:

> On Tue, Oct 5, 2021 at 4:08 PM Côme Chilliet  wrote:
>
> > Le lundi 4 octobre 2021, 10:09:12 CEST Nikita Popov a écrit :
> > > If we make this change, I would however suggest to also support "false"
> > as
> > > a standalone type. I think this change primarily has benefits from a
> > > typesystem completeness perspective rather than a strong practical
> need.
> > > From that angle, it would be nice if all types that are usable in a
> union
> > > are also usable as standalone types, rather than shifting the special
> > case
> > > from null to false.
> >
> > It feels weird/wrong to slowly add values in the type system like this,
> > rather than directly supporting static values as type hints.
> >
> > Why would function a(): null|false {} be legal but function b(): null|0
> > would not?
> >
> > This is inconsistent to me. And adding null, then false, then true for
> the
> > sake of completeness feels like avoiding to treat the static value as
> type
> > hint subject.
> >
>
> Both null and false are already part of the type system. They're not being
> added, neither by the RFC in question, nor by my quoted suggestion. This
> discussion is only about relaxing restrictions on standalone types.
>

I always thought false was part of the type system just to accommodate the
legacy of internal functions which can return a (non-boolean) value or
false. I mean, I've never written code that's type hinted something|false
as a return type, to me a function/method return should either be type
hinted bool or not. Even with union types, if I was writing something|bool
there might be conceivable occasions it's justified, but I'd at least be
asking myself if it could be a design smell in whatever I'm building. I
guess I'm saying I've always considered the fact you *can* do this with
false more a legacy of necessity than a feature which should be built on.
Null is distinctly a type as well as a value so I can see the justification
for the RFC; it seems harder to make that argument for false, beyond saying
"well in PHP, it just is"...but...is that a good thing?


>
> So to answer your question: "null|false" would be legal because
> "string|false" already is. "null|0" would be illegal because there is no
> such thing as a "0" type (in our current type system).


> Regards,
> Nikita
>


[PHP-DEV] Function list declaration syntax?

2021-10-05 Thread Mike Schinkel
Hi all,

This email proposes a shorthand syntax for declaring a list of 
single-expression functions. 

A similar albeit more verbose attempt to provide short functions[1] failed late 
last year, but I was recently inspired by Sebastian Bergmann's Type library[2] 
that he referenced in a comment on another thread.

Consider the `Type` class[3] in the `SebastianBergmann\Type` namespace. It 
contains 60 lines of function declaration to define 14 functions that all 
return `false`.  Even though it really is a simple class it is rather hard to 
wrap one's head around quickly because of all the bloating boilerplate 
required. At least IMO.

Consider instead if we had the following syntax?

public function list: bool
{
  isCallable() => false,
  isFalse() => false,
  isGenericObject() => false,
  isIntersection() => false,
  isIterable() => false,
  isMixed() => false,
  isNever() => false,
  isNull() => false,
  isObject() => false,
  isSimple() => false,
  isStatic() => false,
  isUnion() => false,
  isUnknown() => false,
  isVoid() => false,
}

The idea here is to group a 'list' of functions — in this case of the same type 
— and then use shortened single expression fn() syntax for each function. And 
with a monospace font in your editor of choice this code could be made even 
easier to grok by left-aligning the return values.

I chose the keyword `list` because it is already a reserved word, but the word 
`case` could also be used for the same reason, if people prefer that.

Further, instead of `function list` or `function case` we could have `fn list`, 
`fn case`, `fn() list` or `fn() case`, whichever feels best to the most people.

This could also work for abstract functions noting that the typehint is applied 
to each function instead of the list declaration, e.g.:

abstract public function list 
{
  isAssignable(self $other): bool;
  name(): string;
  allowsNull(): bool;
}

Those two changes shorten Type.php from 140 lines down to 90 lines, and IMO, 
make the class much easier to read. You can see it here[4].

One more example, this time his `NullType` class[5] using mixed type hints and 
going from a total of 38 lines down to 26 lines[6]:

public function list
{
name(): string => 'null',
asString(): string => 'null',
allowsNull(): bool => true,
isNull(): bool => true,
}

What do you think?  Is this approach any more appealing than the last one 
proposed?

-Mike

[1] https://wiki.php.net/rfc/short-functions
[2] https://github.com/sebastianbergmann/type
[3] https://github.com/sebastianbergmann/type/blob/master/src/type/Type.php
[4] https://gist.github.com/mikeschinkel/6f8c9cf6700a75e75e2725db1ed4da61
[5] https://github.com/sebastianbergmann/type/blob/master/src/type/NullType.php
[6] https://gist.github.com/mikeschinkel/a93aabd61127b0c3ba28c5caf4ebe005
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread Mike Schinkel
> On Oct 2, 2021, at 11:06 AM, G. P. B.  wrote:
> 
> Hello internals,
> 
> I'm proposing a new RFC to make 'null' usable as a standalone type.
> 
> RFC: https://wiki.php.net/rfc/null-standalone-type

Regarding the RFC's proposed disallowing of `?null`, is that really needed?

Obviously it doesn't make sense for a developer to write that, but I could see 
that a code generator would have add special-case logic to avoid outputting `?` 
with the type `null`.

Does it hurt anything if it is allowed?

-Mike

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Unbreak git.php.net links?

2021-10-05 Thread Hans Henrik Bergan
@Ayesh thanks, added support for those url (
https://github.com/divinity76/git-php-net-redirector/commit/072a579d140a7481e76e95bd8c2d120ee2f71565
), also it looks like version numbers got mixed up in your example #2 ,
"8.0.0RC2" vs "8.1.0RC3", that is surely a typo?

>It is the name of the git repository on git.php.net. There were
several other repos for PECL, bug tracker, docs in multiple languages,
etc. I have added support for a static list that maps git.php.net
names to GitHub repo under `php` organization namespace.

oh i see.

fwiw, your implementation looks more professional / enterprise-y :)


On Tue, 5 Oct 2021 at 15:43, Ayesh Karunaratne  wrote:

> > here is an initial implementation:
> >
> https://github.com/divinity76/git-php-net-redirector/blob/main/src/redirector.php
> > it is just a minimum-effort implementation, anyone feel free to make
> > something better (also i have no idea how the "p" argument is supposed to
> > be parsed, so i just guessed)
> >
> > it passes "Stanislav Malyshev"'s initial sample url, but it probably
> fails
> > on any other formats, if anyone has test urls, share em
> >
> >
> >
> > On Mon, 4 Oct 2021 at 08:38, Hans Henrik Bergan 
> > wrote:
> >
> > > >So who's going to work on it? Doesn't make sense to have 5 people work
> > > > on it independently from each other ;-)
> > >
> > > if nobody else wants to do it, i can make an initial implementation on
> > > october 9th (6 days from now),
> > >
> > > but wouldn't surprise me at all if someone else wants to do it ^^
> > >
> > >
> > > On Mon, 4 Oct 2021 at 08:01, Andreas Heigl  wrote:
> > >
> > >> Hey all.
> > >>
> > >> On 04.10.21 07:52, Hans Henrik Bergan wrote:
> > >> > there's also plenty of broken links on reddit to git.php.net , ref
> > >> > https://www.google.com/search?q=git.php.net+site%3Areddit.com
> > >> >
> > >> > it wouldn't be hard to set up a redirector parsing commit ids out
> of the
> > >> > url and redirecting to github,
> > >> > +1 from me.
> > >>
> > >> So who's going to work on it? Doesn't make sense to have 5 people work
> > >> on it independently from each other ;-)
> > >>
> > >> Cheers
> > >>
> > >> Andreas
> > >> --
> > >>,,,
> > >>   (o o)
> > >>
> +-ooO-(_)-Ooo-+
> > >> | Andreas Heigl
>  |
> > >> | mailto:andr...@heigl.org  N 50°22'59.5" E
> 08°23'58" |
> > >> | https://andreas.heigl.org
>  |
> > >>
> +-+
> > >> | https://hei.gl/appointmentwithandreas
>  |
> > >>
> +-+
> > >>
> > >
>
>
> Hi Stanislav/Hans,
> Thanks for opening this conversation and the initial implementation.
>
> Having worked with a few cgit repositories before, I happen to recall
> some of the other URL patterns. I worked on a similar implementation
> to Hans's at https://github.com/Ayesh/git-php-redirect
>
> > something better (also i have no idea how the "p" argument is supposed to
> > be parsed, so i just guessed)
>
> It is the name of the git repository on git.php.net. There were
> several other repos for PECL, bug tracker, docs in multiple languages,
> etc. I have added support for a static list that maps git.php.net
> names to GitHub repo under `php` organization namespace.
>
> In addition to the URL patterns Hans have covered
> (p=php-src;h=HEX{40}), I thought to add a few more patterns:
>
> - FROM: http://git.php.net/?p=php-src.git;a=commit;h=5af586be (
> `/[a-z0-9]{7,}$/` )
>   TO:   https://github.com/php/php-src/commit/5af586be
>
> - FROM:
> https://git.php.net/?p=php-src.git;a=shortlog;h=refs/tags/php-8.0.0RC2
>   TO:   https://github.com/php/php-src/releases/tag/php-8.1.0RC3
>
> - FROM:
> https://git.php.net/?p=php-src.git;a={tree,log,shortlog};h=refs/heads/master;hb=refs/heads/master
>   TO:   https://github.com/php/php-src/{tree,commits,commits}/master
>
> - FROM: http://git.php.net/?p=php-src.git;a=log
>   TO:   https://github.com/php/php-src
>
> Cheers,
> Ayesh.
>


Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread Lynn
On Tue, Oct 5, 2021 at 4:08 PM Côme Chilliet  wrote:

>
> Why would function a(): null|false {} be legal but function b(): null|0
> would not?
>
> This is inconsistent to me. And adding null, then false, then true for the
> sake of completeness feels like avoiding to treat the static value as type
> hint subject.
>

I'm not opposed to having values that aren't objects. Feels like a
shorthand notation of enums, or the subset thereof.

```php
function getType(): 'dropdown'|'textfield';
function getExitCode(): 0|1|255;
```


Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread Nikita Popov
On Tue, Oct 5, 2021 at 4:08 PM Côme Chilliet  wrote:

> Le lundi 4 octobre 2021, 10:09:12 CEST Nikita Popov a écrit :
> > If we make this change, I would however suggest to also support "false"
> as
> > a standalone type. I think this change primarily has benefits from a
> > typesystem completeness perspective rather than a strong practical need.
> > From that angle, it would be nice if all types that are usable in a union
> > are also usable as standalone types, rather than shifting the special
> case
> > from null to false.
>
> It feels weird/wrong to slowly add values in the type system like this,
> rather than directly supporting static values as type hints.
>
> Why would function a(): null|false {} be legal but function b(): null|0
> would not?
>
> This is inconsistent to me. And adding null, then false, then true for the
> sake of completeness feels like avoiding to treat the static value as type
> hint subject.
>

Both null and false are already part of the type system. They're not being
added, neither by the RFC in question, nor by my quoted suggestion. This
discussion is only about relaxing restrictions on standalone types.

So to answer your question: "null|false" would be legal because
"string|false" already is. "null|0" would be illegal because there is no
such thing as a "0" type (in our current type system).

Regards,
Nikita


Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread Levi Morrison via internals
On Tue, Oct 5, 2021 at 8:08 AM Côme Chilliet  wrote:
>
> Le lundi 4 octobre 2021, 10:09:12 CEST Nikita Popov a écrit :
> > If we make this change, I would however suggest to also support "false" as
> > a standalone type. I think this change primarily has benefits from a
> > typesystem completeness perspective rather than a strong practical need.
> > From that angle, it would be nice if all types that are usable in a union
> > are also usable as standalone types, rather than shifting the special case
> > from null to false.
>
> It feels weird/wrong to slowly add values in the type system like this, 
> rather than directly supporting static values as type hints.
>
> Why would function a(): null|false {} be legal but function b(): null|0 would 
> not?
>
> This is inconsistent to me. And adding null, then false, then true for the 
> sake of completeness feels like avoiding to treat the static value as type 
> hint subject.
>
> Côme
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
>

Null is both a type and a value. It's odd that we don't support null
as a standalone type, because it's the only case I can think of where
we have a value without a type in the type system. You could possibly
argue the same about `resource`, but that's a legacy type we are
working on removing (and special thanks to everyone who has
participated).

Integers are not the same. If you want to support integer literals and
probably all forms of literals as types, I suggest that as a separate
RFC. I really don't think they are the same.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] [RFC] Allow null as standalone type

2021-10-05 Thread Côme Chilliet
Le lundi 4 octobre 2021, 10:09:12 CEST Nikita Popov a écrit :
> If we make this change, I would however suggest to also support "false" as
> a standalone type. I think this change primarily has benefits from a
> typesystem completeness perspective rather than a strong practical need.
> From that angle, it would be nice if all types that are usable in a union
> are also usable as standalone types, rather than shifting the special case
> from null to false.

It feels weird/wrong to slowly add values in the type system like this, rather 
than directly supporting static values as type hints.

Why would function a(): null|false {} be legal but function b(): null|0 would 
not?

This is inconsistent to me. And adding null, then false, then true for the sake 
of completeness feels like avoiding to treat the static value as type hint 
subject.

Côme

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Unbreak git.php.net links?

2021-10-05 Thread Ayesh Karunaratne
> here is an initial implementation:
> https://github.com/divinity76/git-php-net-redirector/blob/main/src/redirector.php
> it is just a minimum-effort implementation, anyone feel free to make
> something better (also i have no idea how the "p" argument is supposed to
> be parsed, so i just guessed)
>
> it passes "Stanislav Malyshev"'s initial sample url, but it probably fails
> on any other formats, if anyone has test urls, share em
>
>
>
> On Mon, 4 Oct 2021 at 08:38, Hans Henrik Bergan 
> wrote:
>
> > >So who's going to work on it? Doesn't make sense to have 5 people work
> > > on it independently from each other ;-)
> >
> > if nobody else wants to do it, i can make an initial implementation on
> > october 9th (6 days from now),
> >
> > but wouldn't surprise me at all if someone else wants to do it ^^
> >
> >
> > On Mon, 4 Oct 2021 at 08:01, Andreas Heigl  wrote:
> >
> >> Hey all.
> >>
> >> On 04.10.21 07:52, Hans Henrik Bergan wrote:
> >> > there's also plenty of broken links on reddit to git.php.net , ref
> >> > https://www.google.com/search?q=git.php.net+site%3Areddit.com
> >> >
> >> > it wouldn't be hard to set up a redirector parsing commit ids out of the
> >> > url and redirecting to github,
> >> > +1 from me.
> >>
> >> So who's going to work on it? Doesn't make sense to have 5 people work
> >> on it independently from each other ;-)
> >>
> >> Cheers
> >>
> >> Andreas
> >> --
> >>,,,
> >>   (o o)
> >> +-ooO-(_)-Ooo-+
> >> | Andreas Heigl   |
> >> | mailto:andr...@heigl.org  N 50°22'59.5" E 08°23'58" |
> >> | https://andreas.heigl.org   |
> >> +-+
> >> | https://hei.gl/appointmentwithandreas   |
> >> +-+
> >>
> >


Hi Stanislav/Hans,
Thanks for opening this conversation and the initial implementation.

Having worked with a few cgit repositories before, I happen to recall
some of the other URL patterns. I worked on a similar implementation
to Hans's at https://github.com/Ayesh/git-php-redirect

> something better (also i have no idea how the "p" argument is supposed to
> be parsed, so i just guessed)

It is the name of the git repository on git.php.net. There were
several other repos for PECL, bug tracker, docs in multiple languages,
etc. I have added support for a static list that maps git.php.net
names to GitHub repo under `php` organization namespace.

In addition to the URL patterns Hans have covered
(p=php-src;h=HEX{40}), I thought to add a few more patterns:

- FROM: http://git.php.net/?p=php-src.git;a=commit;h=5af586be (
`/[a-z0-9]{7,}$/` )
  TO:   https://github.com/php/php-src/commit/5af586be

- FROM: https://git.php.net/?p=php-src.git;a=shortlog;h=refs/tags/php-8.0.0RC2
  TO:   https://github.com/php/php-src/releases/tag/php-8.1.0RC3

- FROM: 
https://git.php.net/?p=php-src.git;a={tree,log,shortlog};h=refs/heads/master;hb=refs/heads/master
  TO:   https://github.com/php/php-src/{tree,commits,commits}/master

- FROM: http://git.php.net/?p=php-src.git;a=log
  TO:   https://github.com/php/php-src

Cheers,
Ayesh.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php



Re: [PHP-DEV] Adding `final class Deque` to PHP

2021-10-05 Thread Nikita Popov
On Tue, Oct 5, 2021 at 12:47 AM tyson andre 
wrote:

> Hi Nikita Popov,
>
> > 1. There would be the possibility of having an interface Deque that is
> > backed by a VecDeque/ArrayDeque implementation. I'm not convinced this
> > would actually make sense, but I wanted to throw it out there, given that
> > the class is final (which is without any doubt the correct decision).
>
> Do you mean ArrayDeque for a hardcoded max capacity?
> I'm also not convinced there's a use case.
>
> > 2. How do set() / offsetSet() work with an out of range index? Is it
> > possible to push an element with $deque[count($deque)] = x? I would
> assume
> > that throws, but want to make sure. On a related note, why do we need
> both
> > get()/set() and offsetGet()/offsetSet()? These APIs seem redundant.
>
> It isn't possible to set an out of range index - both throws
> `\OutOfBoundsException`
>
> In order to support the ArrayAccess `$deque[$offset] = $value;` or
> `$deque[$offset]` shorthand,
> the offsetGet/offsetSet needed to be implemented to follow conventions.
> (because of ArrayAccess, offsetGet must accept mixed offsets)
>
> Those aren't type safe, though, so get()/set() are provided for a type
> safe alternative
> that will throw a TypeError for use cases that would benefit from runtime
> type safety.
>

offsetGet() and offsetSet() can (and should) still throw if the offset is
not an integer. We just can't actually declare that type. This is a
weakness of the PHP type system, so nominally "violating" LSP is fine here.


> > 3. I believe it's pretty standard for Deque implementations to provide
> > insert() / remove() methods to insert at any position (these would be
> O(n)).
>
> https://www.php.net/manual/en/class.splqueue.php didn't offer that
> functionality.
>
> https://www.php.net/manual/en/class.ds-deque.php did, apparently.
>
> > 4. The design of getIterator() here is rather unusual, and deserves some
> > additional justification. Normally, we let getIterator() see concurrent
> > modifications to the structure, though the precise behavior is
> unspecified.
> > I would also like to know how this will look like on a technical level
> (it
> > doesn't seem to be implemented yet?) This seems like something that will
> > require a check on every write operation, to potentially separate the
> > structure in some form.
>
> The original plan was to copy the entire array on iterator creation,
> to imitate the immediate copy nature of foreach on arrays.
>

There is no immediate copy with arrays though. The copy is just a refcount
increment and no actual copy will happen unless the array is modified
during iteration, which is a rare case. I'd expect the Deque implementation
(with those semantics) to do the same -- but we don't have a convenient
mechanism for it. Adding an indirection and a refcount to the underlying
storage would be possible, but also feels like overkill. The other approach
I see would be to track all the registered iterators, so we can explicitly
separate them on write.


> This was assuming that `foreach` over a Deque without removing elements
> would be a rare use case.
>
> That may have been a mistake since `foreach (clone $deque as $key =>
> $value)` can be done to explicitly do that.
> There're around 4 approaches I could take with different tradeoffs
>
> 1. Iterate over $offset = 0 and increment offset in calls to
> InternalIterator->next() until exceeding the size of the deque, not copying
> the deque.
>
>That's the **actual** current implementation, but would be unintuitive
> with shift()/unshift()
>
>This would repeat elements on unshift(), or skip over elements when
> shift() is called.
>
>The current implementation of `Ds\Deque` seems to do the same thing,
> but there's a similar discussion in its issue tracker in
> https://github.com/php-ds/ext-ds/issues/17
>
>
> 2. Similar iteration behavior, but also have it relative to a uint64
> indicating the number of times elements were added to the front of the
> deque minus the number of elements were removed from the back of the deque.
>
> (e.g. if the current Deque internalOffset is 123, the InternalIterator
> returned by getOffset would start with an offset of 123 and increase it
> when advancing.
> Calls to shift would raise the Deque internalOffset, calls to unshift
> would decrease it (by the number of elements).
> This would be independent of the circular buffer offset.
> And the InternalIterator would increase the internalOffset to catch up
> if the signed offset difference became negative, e.g. by calling shift()
> twice in a foreach block)
>

Something to keep in mind here is that there might be multiple iterators at
the same time, so I don't think the suggestion from the last sentence would
work. Though I think the general idea does work, as long as we're working
with a delta between the offset in the iterator and the deque.


> 3. Behave as if the entire Deque was copied when iteration starts (either
> by actually copyin