Re: [swift-evolution] Preparing Swift compiler stage reentrancy in preparation for "constexpr"

2017-08-23 Thread Douglas Gregor via swift-evolution

> On Aug 19, 2017, at 12:27 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> [I’m not sure which list should cover this.]
> 
> I once thought of having a “#protocols(SomeTypeOrProtocol)” that was a type 
> alias to a composition of all protocols the given type/protocol conforms to 
> (or “Any” if none). It seems simple, but all current uses of protocols 
> requires explicit mentions by the user, while this new facility would require 
> looking back at the table of existing protocols.

This is plausible to implement at run-time by inspecting the table of protocol 
conformances. It won’t be a static result, though, because one could dlopen() a 
shared library that introduces new conformances for existing types.

> 
> It seems that implementing something like C++’s “constexpr” would have the 
> same problem. The compiler stages can’t be one way anymore; a non-literal 
> that’s needed for a compile-time context has to be deferred until its 
> components can be evaluated in compile-time contexts (down to literals). So 
> we would partially evaluate down to SIL, run the SIL in the compiler’s 
> environment to determine all the compile-time data (not a big deal for 
> discrete data, but we’ll have to ignore differences between the compiler’s 
> environment and the target platform’s environment w.r.t. floating-point 
> processing), then go back to the semantic phase to fill in the “constexpr” 
> constants and evaluate the SIL again, possibly taking several cycles 
> depending how deep “constexpr” is needed.

You’re thinking in C++ terms. In Swift, it might be more reasonable to think of 
“constexpr” as something that will be guaranteed to become a constant at some 
point in the SIL pipeline (as part of the “guaranteed” transformations we 
perform for diagnostic generation from SIL), but that the actual constexpr 
value would be kept as an abstract expression in earlier stages of the 
pipeline. John McCall made this point better than I in the earlier discussions 
of constexpr (a few weeks ago).

> 
> As an example, take a mythical function that converts a mythical 
> one-dimensional fixed-size array to a tuple:
> 
> func tuple(from: [N; T]) -> ( #dup(N ; T) )
> 
> We would have to defer the return type until each call of “tuple(from:)”, 
> where we look at the input’s type’s shape to determine N, then expand the 
> #dup, then run the semantic phase again with the final type. What if N itself 
> was based off a “constexpr” function? Then we would need (at least) two 
> passes.
> 
> Should we start preparing the compiler stages for loopback now? Or do we have 
> to figure out what exactly we want “Swift constexpr” to mean first?

The latter. We should consider that it might be absolutely fine for Swift to 
effectively be dependently-typed up until some point in the pipeline, and that 
might fit better in the language model than introducing circularity.

- Doug


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Preparing Swift compiler stage reentrancy in preparation for "constexpr"

2017-08-19 Thread Daryle Walker via swift-evolution
[I’m not sure which list should cover this.]

I once thought of having a “#protocols(SomeTypeOrProtocol)” that was a type 
alias to a composition of all protocols the given type/protocol conforms to (or 
“Any” if none). It seems simple, but all current uses of protocols requires 
explicit mentions by the user, while this new facility would require looking 
back at the table of existing protocols.

It seems that implementing something like C++’s “constexpr” would have the same 
problem. The compiler stages can’t be one way anymore; a non-literal that’s 
needed for a compile-time context has to be deferred until its components can 
be evaluated in compile-time contexts (down to literals). So we would partially 
evaluate down to SIL, run the SIL in the compiler’s environment to determine 
all the compile-time data (not a big deal for discrete data, but we’ll have to 
ignore differences between the compiler’s environment and the target platform’s 
environment w.r.t. floating-point processing), then go back to the semantic 
phase to fill in the “constexpr” constants and evaluate the SIL again, possibly 
taking several cycles depending how deep “constexpr” is needed.

As an example, take a mythical function that converts a mythical 
one-dimensional fixed-size array to a tuple:

func tuple(from: [N; T]) -> ( #dup(N ; T) )

We would have to defer the return type until each call of “tuple(from:)”, where 
we look at the input’s type’s shape to determine N, then expand the #dup, then 
run the semantic phase again with the final type. What if N itself was based 
off a “constexpr” function? Then we would need (at least) two passes.

Should we start preparing the compiler stages for loopback now? Or do we have 
to figure out what exactly we want “Swift constexpr” to mean first?

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution