HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

From-to shortcuts #78

Closed vonagam closed 4 years ago

vonagam commented 4 years ago

Syntax for allowing from and to cast:

abstract Foo(Int) cast Int {}
// equals
abstract Foo(Int) from Int to Int {}

Syntax for referencing underlying type:

abstract Foo(Int) from this {}
// equals
abstract Foo(Int) from Int {}

Obviously for such short named types as std Int it doesn't make much sense, but for long named ones and for unnamed, like structures or functions, it would make a life more pleasant.

Render.

Edit: moved from from to to cast.

grepsuzette commented 4 years ago

from to Int feels oddly like it's missing something... abstract Foo(Int) tofrom Int {} would feel more natural to me. And maybe abstract Foo(Int) from _ {} instead of abstract Foo(Int) from this {} though in that case I would question the necessity of having the first.

Simn commented 4 years ago

Regarding from this, you can always do something like this:

private typedef This = MoreComplicated<Type -> With, Parameters>
abstract Foo(This) from This

And I also think that from to Int looks like a syntax error...

vonagam commented 4 years ago

Yes, i know about typedef, but shortcut is shorter.

I though about including other candidates for from to - from-to, from and to, as and so on. from to - was the clearest and without additional words so went with this for initial proposal (in drawbacks i wrote that for some it will not look like an ideal). I am ok with other variant being chosen, no resistance from me in that regard.

grepsuzette commented 4 years ago

Regarding from and to, the time spent writing the first abstract line is not necessarily something that should be reduced.

Often you need to carefully think whether you really want to have both to and from because of problems it can create. If there is a short syntax, maybe the time spent typing can not be used to think and it can create a bad reflex. So when it comes to abstracts it is more important to think than type quickly.

Though if we think about readibility, I think maybe something like abstract Foo(UnderlyingType) from _ to _ can be good. It's certainly no big deal though.

RealyUniqueName commented 4 years ago

I think declaring a new abstract type is not something happening frequently. Existing solution with typedef is enough. Especially in terms of reusability because from and to mean that you have that type used somewhere else in your code.

vonagam commented 4 years ago

you have that type used somewhere else in your code

Not necessary if you depend on structural unification or paramed function variance. Example of last:

@:callable @:forward abstract Predicate<T>((value: T) -> Bool) from (value: T) -> Bool to (value: T) -> Bool {...}

// with typedef
private typedef This<T> = (value: T) -> Bool;
@:callable @:forward abstract Predicate<T>(This<T>) from This<T> to This<T> {...}

// with proposal
@:callable @:forward abstract Predicate<T>((value: T) -> Bool) from to this {...}

Some statistics - out of 34 abstracts in std that define at least one direct cast - 26 define from to cast to their underlying type.

vonagam commented 4 years ago

Closing as this proposal has no chance of passing right now. Sad that such common scenarios do not have more readable and concise syntax.

Simn commented 4 years ago

I'll give you "concise", but I'm not so sure about the "readable" part, especially the from to suggestion.

I don't completely hate the from this idea, but I have some reservations about introducing this at type-level. However, if we go for #36, something like that is going to be required anyway.

vonagam commented 4 years ago

Maybe cast can be used in place of from to. As from and to mean "cast from" and "cast to", simple cast will mean "cast from and to".

abstract Foo(Int) cast Int {}
kLabz commented 4 years ago

Would a syntax like abstract X(Y) from/to Y {} be possible?