HaxeFoundation / haxe-evolution

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

Hint-conditional for compilation improvements #66

Closed Drakim closed 4 years ago

Drakim commented 4 years ago

My proposal for a hint-conditional for the Haxe. I am not very confident in my suggested solution, but this is a genuine issue I've encountered and this is the best way I have of presenting it. Very open to alternative ways of thinking about the issue and ways to solve it.

Rendered version

Simn commented 4 years ago

I don't understand that else case. If the thing only exists at compile-time, how can there be two branches?

Drakim commented 4 years ago

For example, let's say you have two clever integer division methods using bitwise logic. One of them is faster than the other but only works if you have a positive integer, while the other one is a tad slower but can take any integer, positive or negative. You could then use a "hint" which conditionally checks the integer, so that the slower division method is used whenever the compiler is unsure of the sign of the integer, while the faster division method is used when the compiler is certain it's holding a positive integer.

Without the hint functionality, you'd be forced to only use the slower division method for all inputs, or you'd be forced to have a runtime branch to pick one or the other (or use a macro, but then it only works on constant integers, not compiler-deduced integers).

nanjizal commented 4 years ago

Is there no current way to achieve this by creating an abstract over your js.lib.Float64Array ?

If not then could conditional compilation be extended to work with more complex patterns like structure matching and your use cases, certainly a # would be clearer for users reading code, just hint seems to mix normal code with compiler code.

hughsando commented 4 years ago

This is interesting, but I don't think the solution is normal haxe code. I this case, what it looks like you want is:

   if (@:compileTime x==0) ...

The 'if' would only be true if it was certain at compile time. This would be nice for inline functions:

inline function idiv(num:Int,denom:Int) {
   if ( @compileTime denom & (denom-1) == 0 )
       // do bit shift
   else
      // do long way
}

But it also looks like an optimization you are after here is based on not assigning new array values to 0 on certain targets. This could be done as a macro or another compiler pass without the need for annotation.

Drakim commented 4 years ago

Is there no current way to achieve this by creating an abstract over your js.lib.Float64Array ?

I'm fairly convinced this is utterly impossible, the abstract stuff is simply resolved at the wrong time in the compilation process to do anything useful here. If you have some crafty idea on how it could be done, I'd love to hear it.

If not then could conditional compilation be extended to work with more complex patterns like structure matching and your use cases, certainly a # would be clearer for users reading code, just hint seems to mix normal code with compiler code.

I agree, I don't really want there to be a "hint()" conditional exactly like I've suggested, honestly I don't know what would be the most fitting way of implementing it syntax wise, but I felt my proposal would be hard to understand if I didn't at the very least suggest something, as I would just be talking about a vague problem and nothing else.

But it also looks like an optimization you are after here is based on not assigning new array values to 0 on certain targets. This could be done as a macro or another compiler pass without the need for annotation.

Not assigning 0 to zero initialized memory is just one of the several use cases I have in mind. However, not even that can be solved by a macro, as a macro would only be able to do it with constant identifiers like = 55, it wouldn't work with "compiler deduced values" like the examples in my proposal.

But I'm curious about this "another compiler pass" you are talking about. What exactly is that, or are you talking about something theoretical?

Aurel300 commented 4 years ago

If I'm reading this right, this feature is similar to if constexpr in C++?

From the title I initially thought you were going to suggest hints such as "likely" branches, which can help C(++) compilers to optimise branching code.

Drakim commented 4 years ago

If I'm reading this right, this feature is similar to if constexpr in C++?

I only have skin-deep knowledge of C++ so I couldn't say. But in layman's terms, I simply want to be able to tell the compiler "If you are absolutely certain that \<condition> then do \<fast option> otherwise fall back to \<safe option>".

From the title I initially thought you were going to suggest hints such as "likely" branches, which can help C(++) compilers to optimise branching code.

It's more like helping the compiler pick between safe and unsafe code. Like removing a bounds check if the compiler can be 100% certain the index won't go above the bounds.

One example would be a theoretical paintPixel(color:Int) method. When invoked, it should paint a pixel upon a bitmap, but while doing so it should account for the alpha channel of the new pixel, so if alpha is 50% then the new pixel should be 50/50 blended with what's already there. Now, we want to optimize this so that if the alpha is completely opaque then the new color simply overwrites the old one without any unnecessary color blending mathematics.

In today's Haxe, we can solve this in a few ways, but they all have downsides:

Drakim commented 4 years ago

Honestly after much thinking and soul-searching I don't think I would vote in favor of my own proposal. While it does attempt to solve a very real problem I'm facing, my I can plainly see that my proposed solution is hacky and very "glued on", and wouldn't fit naturally into how the Haxe compiler does things. So I'm not putting this proposal up for a vote until something better can be figured out.

If somebody does have any ideas for how it could be implemented more smoothly, please leave a comment.

Drakim commented 4 years ago

Closing this for now