Thread overview
static opSlice is not possible
Feb 15, 2018
Alex
Feb 15, 2018
Jonathan M Davis
Feb 15, 2018
Adam D. Ruppe
Feb 15, 2018
Jonathan M Davis
Feb 16, 2018
Alex
Feb 16, 2018
Basile B.
Feb 16, 2018
Basile B.
Feb 16, 2018
Alex
February 15, 2018
Hi all,
a short question about an old bug:
https://issues.dlang.org/show_bug.cgi?id=11877

Are there reasons, which speaks against this feature?

And maybe another one, more general:
Is there any place, where it is documented, which operators can work in static mode and which cannot?
February 15, 2018
On Thursday, February 15, 2018 22:49:56 Alex via Digitalmars-d-learn wrote:
> Hi all,
> a short question about an old bug:
> https://issues.dlang.org/show_bug.cgi?id=11877
>
> Are there reasons, which speaks against this feature?
>
> And maybe another one, more general:
> Is there any place, where it is documented, which operators can
> work in static mode and which cannot?

The only overloaded operator that I'd expect to work as static would be opCall, which I expect works primarily because of functors but is useful for factory functions as well.

But the point of having overloaded operators is to make it so that user-defined types can act like built-in types. As such, it generally doesn't make any sense for them to be static. As for opSlice, it _really_ doesn't make sense, because that would conflict with arrays and AliasSeqs.

I'm not aware of anywhere in the spec that talks about static and overloaded operators, but I also haven't read through it recently. The spec does tend to be a bit sparse on some details though.

- Jonathan M Davis

February 15, 2018
On Thursday, 15 February 2018 at 23:20:42 UTC, Jonathan M Davis wrote:
> The only overloaded operator that I'd expect to work as static would be opCall, which I expect works primarily because of functors but is useful for factory functions as well.

static opCall is kinda weird in practice and frequently conflicts with non-static opCall as well as constructors. I don't suggest anyone try to use it (and in fact, I'd like to have it removed from the language)
February 15, 2018
On Thursday, February 15, 2018 23:22:17 Adam D. Ruppe via Digitalmars-d- learn wrote:
> On Thursday, 15 February 2018 at 23:20:42 UTC, Jonathan M Davis
>
> wrote:
> > The only overloaded operator that I'd expect to work as static would be opCall, which I expect works primarily because of functors but is useful for factory functions as well.
>
> static opCall is kinda weird in practice and frequently conflicts with non-static opCall as well as constructors. I don't suggest anyone try to use it (and in fact, I'd like to have it removed from the language)

If you use static opCall, then you don't use constructors, and you don't use a non-static opCall. There are times where that makes perfect sense, and plenty of times when it doesn't.

Personally, it's what I use when I need a factory function or in the rare case where I have a singleton (e.g. std.datete.timezone's UTC and LocalTime are both singletons that use static opCall to get at their single instance). It wouldn't surprise me if folks trying to avoid the GC used static opCall to create functors instead of using lambdas, but I don't recall ever doing that personally.

So, I like having static opCall and use it periodically, and as such, I'd hate to see it removed from the language, but it is true that its use is somewhat limited.

- Jonathan M Davis

February 16, 2018
On Thursday, 15 February 2018 at 23:31:23 UTC, Jonathan M Davis wrote:
> On Thursday, February 15, 2018 23:22:17 Adam D. Ruppe via Digitalmars-d- learn wrote:
>> On Thursday, 15 February 2018 at 23:20:42 UTC, Jonathan M Davis
>>
>> wrote:
>> > The only overloaded operator that I'd expect to work as static would be opCall, which I expect works primarily because of functors but is useful for factory functions as well.
>>
>> static opCall is kinda weird in practice and frequently conflicts with non-static opCall as well as constructors. I don't suggest anyone try to use it (and in fact, I'd like to have it removed from the language)
>
> If you use static opCall, then you don't use constructors, and you don't use a non-static opCall. There are times where that makes perfect sense, and plenty of times when it doesn't.
>
> Personally, it's what I use when I need a factory function or in the rare case where I have a singleton (e.g. std.datete.timezone's UTC and LocalTime are both singletons that use static opCall to get at their single instance). It wouldn't surprise me if folks trying to avoid the GC used static opCall to create functors instead of using lambdas, but I don't recall ever doing that personally.
>
> So, I like having static opCall and use it periodically, and as such, I'd hate to see it removed from the language, but it is true that its use is somewhat limited.
>
> - Jonathan M Davis

Ok, thanks you both for helping. I think, I can see your points.
February 16, 2018
On Thursday, 15 February 2018 at 22:49:56 UTC, Alex wrote:
> Hi all,
> a short question about an old bug:
> https://issues.dlang.org/show_bug.cgi?id=11877
>
> Are there reasons, which speaks against this feature?
>
> And maybe another one, more general:
> Is there any place, where it is documented, which operators can work in static mode and which cannot?

There's a hack to make static slicing working actually.
I've used it once to make a kind of set of character. Reduced example:


```
struct Foo
{
    static auto opSlice(int index)(size_t lo, size_t hi)
    if (index == 0)
    {
        return 42;
    }
    static auto opIndex(A...)(A a)
    {
        return 42;
    }
}

static assert(Foo[0..1337] == 42);
```

I don't know if it is possible by error, maybe they forgot to disable this form of slicing.
February 16, 2018
On Friday, 16 February 2018 at 13:23:09 UTC, Basile B. wrote:
> On Thursday, 15 February 2018 at 22:49:56 UTC, Alex wrote:
>> Hi all,
>> a short question about an old bug:
>> https://issues.dlang.org/show_bug.cgi?id=11877
>>
>> Are there reasons, which speaks against this feature?
>>
>> And maybe another one, more general:
>> Is there any place, where it is documented, which operators can work in static mode and which cannot?
>
> There's a hack to make static slicing working actually.
> I've used it once to make a kind of set of character. Reduced example:
>
>
> ```
> struct Foo
> {
>     static auto opSlice(int index)(size_t lo, size_t hi)
>     if (index == 0)
>     {
>         return 42;
>     }
>     static auto opIndex(A...)(A a)
>     {
>         return 42;
>     }
> }
>
> static assert(Foo[0..1337] == 42);
> ```
>
> I don't know if it is possible by error, maybe they forgot to disable this form of slicing.

Technically iy's a multi dimensional slicing but there's a constraint on the number of dimension allowed so that it looks exactly like a normal opSlice.

By the way, i reduced too much. This shows more how it works:

struct Foo
{
    static auto opSlice(int index)(size_t lo, size_t hi)
    if (index == 0)
    {
        return 41;
    }
    static auto opIndex(A...)(A a)
    {
        return opSlice!0(0,0) + 1;
    }
}

static assert(Foo[0..1337] == 42);
February 16, 2018
On Friday, 16 February 2018 at 13:35:03 UTC, Basile B. wrote:
>
> Technically iy's a multi dimensional slicing but there's a constraint on the number of dimension allowed so that it looks exactly like a normal opSlice.
>
> By the way, i reduced too much. This shows more how it works:
>
> struct Foo
> {
>     static auto opSlice(int index)(size_t lo, size_t hi)
>     if (index == 0)
>     {
>         return 41;
>     }
>     static auto opIndex(A...)(A a)
>     {
>         return opSlice!0(0,0) + 1;
>     }
> }
>
> static assert(Foo[0..1337] == 42);

Hey, cool!
Thanks :)