<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div><br></div><div>On Aug 29, 2017, at 14:31, Slava Pestov <<a href="mailto:spestov@apple.com">spestov@apple.com</a>> wrote:<br><br></div><blockquote type="cite"><div><meta http-equiv="Content-Type" content="text/html charset=utf-8"><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 29, 2017, at 2:21 PM, David Sweeris <<a href="mailto:davesweeris@mac.com" class="">davesweeris@mac.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Aug 29, 2017, at 1:49 PM, Slava Pestov <<a href="mailto:spestov@apple.com" class="">spestov@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class=""><br class=""><blockquote type="cite" class="">On Aug 29, 2017, at 11:03 AM, David Sweeris via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:<br class=""><br class="">Hi everyone! I'm trying to implement literal values as generic types.<br class=""></blockquote><br class="">Can you briefly explain what you mean by this?<br class=""><br class="">Are you referring to let-polymorphism, like<br class=""><br class="">let fn = { $0 }<br class="">let f1: (Int) -> Int = fn<br class="">let f2: (Float) -> Float = fn<br class=""></div></div></blockquote></div><br class=""><div class="">No, I mean so that a vector's or matrix's dimensions can be part of its type (strawman syntax and protocol name, but this is pretty much what I'll be trying to support, at least at first):</div></div></div></blockquote><div><br class=""></div><div>I think instead of modeling these generic parameters as types, you should look into generalizing GenericSignatures to contain ‘literal requirements’. Right now, we have four kinds of requirements:</div><div><br class=""></div><div>- A is a subclass of B</div><div>- A conforms to B</div><div>- A is the same type as B</div><div>- A has a known layout</div><div><br class=""></div><div>All of these except for the last one have a generic parameter as their right hand side. All of them have a generic parameter on their left hand side. I think what you want is to add a new ‘value parameter’ that is not a type, but instead has a value. Requirements would be placed on these to constrain them to known kinds of literals (integers, strings, etc).</div></div></div></blockquote><div><br></div><div>Thanks, will do!</div><div><br></div><br><blockquote type="cite"><div><div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(127, 135, 207); background-color: rgb(0, 57, 70);" class=""><span style="color: #de5194" class="">struct</span><span style="color: #a4b0b1" class=""> Vector<T: </span>ExpressibleByIntegerLiteral<span style="color: #a4b0b1" class="">, L: </span>IntegerLiteralExpr<span style="color: #a4b0b1" class="">> {</span></div><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(164, 176, 177); background-color: rgb(0, 57, 70);" class=""> <span style="color: #de5194" class="">var</span> elements: [<span style="color: #7f87cf" class="">T</span>]</div><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(164, 176, 177); background-color: rgb(0, 57, 70);" class=""> <span style="color: #de5194" class="">init</span>() {</div><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; background-color: rgb(0, 57, 70);" class=""><span style="color: rgb(164, 176, 177);" class=""> <span style="color: #2fafa9" class="">elements</span> = [<span style="color: #7f87cf" class="">T</span>](repeating: <span style="color: #e5493d" class="">0</span>, count: </span><font color="#7f87cf" class="">L</font><font color="#a4b0b1" class="">)</font></div><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(164, 176, 177); background-color: rgb(0, 57, 70);" class=""> }</div><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(164, 176, 177); background-color: rgb(0, 57, 70);" class="">}</div><div style="margin: 0px; line-height: normal; background-color: rgb(0, 57, 70); min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(164, 176, 177); background-color: rgb(0, 57, 70);" class=""><span style="color: #de5194" class="">let</span> vect = <span style="color: #7f87cf" class="">Vector</span><span style="text-decoration: underline" class=""><</span><span style="color: #7f87cf" class="">Int</span>, <span style="text-decoration: underline ; color: #e5493d" class="">5</span>>()</div></div><div class=""><br class=""></div><div class="">And, once that's working, I'm going to add support simple "type functions":</div><div class=""><div style="margin: 0px; font-size: 18px; line-height: normal; font-family: 'Fantasque Sans Mono'; color: rgb(164, 176, 177); background-color: rgb(0, 57, 70);" class=""><span style="color: #de5194" class="">func</span> join <T, L1, L2> (<span style="color: #de5194" class="">_</span> lhs: <span style="color: #7f87cf" class="">Vector</span><<span style="color: #7f87cf" class="">T</span>, <span style="color: #7f87cf" class="">L1</span>>, <span style="color: #de5194" class="">_</span> rhs: <span style="color: #7f87cf" class="">Vector</span><<span style="color: #7f87cf" class="">T</span>, <span style="color: #7f87cf" class="">L2</span>>) -> <span style="color: rgb(127, 135, 207);" class="">Vector</span><<span style="color: rgb(127, 135, 207);" class="">T</span>, <span style="color: rgb(127, 135, 207);" class="">L1</span> + <span style="color: rgb(127, 135, 207);" class="">L2</span> > {...}</div></div><div class="">I think restricting the supported "type functions" to expressions that could be evaluated by the compiler's "constant folding" code would be a reasonable place to start,</div></div></div></blockquote><div><br class=""></div><div>The compiler’s constant folding operates on SIL instructions, not Exprs directly. However constant folding is not generally what you want for this, because constant folding is a ‘best effort’ kind of optimization (it may or may not fold your calculation down to a constant) and also it produces code that evaluates the result (even if its a constant) and not the result itself.</div></div></div></blockquote><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><div><span style="background-color: rgba(255, 255, 255, 0);">Yeah, I didn't mean I was going to <i>literally</i> use constant-folding (is that a pun? The world may never know...) for exactly the reasons you mentioned. I just meant "the kinds of expressions that constant-folding would reasonably be expected to probably optimize". The only two that I think are pretty much necessary are "+" and "-" on integer literals, so that functions can combine and break-up types like "vector" and "matrix". String concatenation with "+" seems pretty reasonable, too. Speaking of which...</span></div><div><span style="background-color: rgba(255, 255, 255, 0);"><br></span></div><blockquote type="cite"><div>I think if you want to explore type-level computation like this, you should define a very small subset of the language which can be computed by the type checker like this.</div></blockquote><div><br></div>I do want to do that. My initial thoughts on the matter is that such a subset would probably essentially be "any function that can be evaluated a compile-time and returns a type", but then that requires having a good notion of "pure" / "constexpr" / "whateverWeCallIt", and I'm not sure I want to open two cans of worms at once.<div><br></div><div>That said, I'm a huge fan of the approach the core team has taken WRT defining everything in the stdlib and minimizing "compiler magic". It might be more than I want to bite off in a single proposal, but getting the supported functions out of the compiler and allowing user-defined functions to get a type is an obvious next step.</div><div><br></div><div>- Dave Sweeris<br><br><div><br></div></div></body></html>