<div dir="ltr"><div>I've been bumping into (what I've found out to be) the need for HKT a lot while trying to write highly composable yet optimizable code for exploratory image (and audio (and video)) processing.</div><div><br></div><div>Using Core Image, vImage, vDSP, Metal, etc. directly is not an option here, since they are much too low level / specialized / non-composable. What I'm writing is a system that will let me try out new ideas very quickly by reusing as much code and concepts as possible. Ie I don't want to write specialized code for every slight variant of a concept. So a separable convolution should be _one_ generic implementation, and the compiler (not the programmer) should take care of specializing it for any given value type and dimensionality, same thing with positions, a position in space is no different from a position in a color space or a position in space&time, so they should share a common implementation. I need it to be as optimizable as possible, because it would be unusable even for just experimentation otherwise. If something needs to get faster still, we can then write a Metal version of it.</div><div><br></div><div>With the latest improvements in the optimizer (esp. loop unrolling) I have managed to get the basics of this working, the compiler will generate SIMD code from my high level code constructs (when possible of course, eg when doing separable convolution (in any number of dimensions) and the components are 4 or 4x4 Floats etc).<br></div><div><br></div><div>But I currently have to jump through hoops in order to write simple things like "static array types" with type-level count and specific memory footprint. I'm using Peano-esque natural-numbers-as-types for the Count, and a similar nested-structs-thing to get the proper storage of Count x Element. But it is impossible to parameterize them for both Count and Element, so I have to do eg this:</div><div><br></div><div>typealias MyFloat4 = StaticArrayOf<Float>.WithCount4</div><div><br></div><div>instead of the more straight forward:</div><div><br></div><div>typealias MyFloat4 = StaticArray<Float, Count4></div><div><br></div><div>So I wish it was possible to implement it like this:</div><div>struct StaticArray<Element, Count> { ... }</div><div>where</div><div>strideof(StaticArray<Float, Count4>) == 4 * strideof(Float) == strideof(float4)<br></div><div><br></div><div>But I've given up and accepted that such parameterization is not possible without HKT.</div><div><br></div><div>Perhaps it would become possible with the proposed generic typealiases, at least if that implied generic associated types (which I guess would be the same as HKT?).</div><div><br></div><div>Anyway, I'm very impressed by (open source master) Swift's ability to optimize very high level generic code. I just wish some of my abstractions could be written in a more straight forward way. I think HKT would make them simpler. (Sorry for not being more specific).</div><div><br></div><div>/Jens<br></div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 17, 2015 at 6:22 AM, Matthew Johnson via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">> Looking beyond functional programming abstractions, higher-kinded types are a fancy way of saying "template template parameters”.<br>
<br>
</span>Thanks for bringing that up. I almost mentioned it. I didn’t because I know the Swift team wants to avoid a lot of what has been done with templates and am not sure exactly where you draw the line. :)<br>
<div class="HOEnZb"><div class="h5"><br>
> A textbook motivation for those from C++ land is Andrei Alexandrescu's "policy pattern", stuff like this:<br>
><br>
> protocol RefStoragePolicy: <*: class> {<br>
> typealias Ref: class<br>
> init(ref: Ref)<br>
> var ref: Ref<br>
> }<br>
><br>
> struct Weak<T: class>: RefStoragePolicy { weak var ref: T }<br>
> struct Unowned<T: class>: RefStoragePolicy { unowned var ref: T }<br>
> struct Strong<T: class>: RefStoragePolicy { var ref: T }<br>
><br>
> class HeterogeneousRefConsumer<Storage: RefStoragePolicy> {<br>
> func consumeRef<T: class>(ref: T) {<br>
> let storage = Storage<T>(ref: ref)<br>
> doStuffWith(storage)<br>
> }<br>
> }<br>
><br>
> -Joe<br>
> _______________________________________________<br>
> swift-evolution mailing list<br>
> <a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature">bitCycle AB | Smedjegatan 12 | 742 32 Östhammar | Sweden<br><a href="http://www.bitcycle.com/" target="_blank">http://www.bitcycle.com/</a><br>Phone: +46-73-753 24 62<br>E-mail: <a href="mailto:jens@bitcycle.com" target="_blank">jens@bitcycle.com</a><br><br></div>
</div>