<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 28, 2016 at 9:25 PM, Erica Sadun <span dir="ltr">&lt;<a href="mailto:erica@ericasadun.com" target="_blank">erica@ericasadun.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><span class="">On Apr 28, 2016, at 8:11 PM, Xiaodi Wu &lt;<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>&gt; wrote:<br><div><blockquote type="cite"><br><div><div dir="ltr" style="font-family:Palatino-Roman;font-size:14px;font-style:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra">Sorry, stripped out a little too much, I guess. Let me expand a little:</div><div class="gmail_extra"><br></div><div class="gmail_extra">In this example, `PortedTransform` has, by virtue of how it works, an upper bound and lower bound for valid input (among other interesting methods and properties). Exceed those bounds for your input and `PortedTransform` regurgitates garbage but does not throw any kind of error. Obviously, linear transform does not care about such silly things because it can transform essentially any FP input value, while the log transform simply traps when it encounters a negative value (which, as a precondition, it should never encounter).</div><div class="gmail_extra"><br></div><div class="gmail_extra">BLAS is an accelerated linear algebra library; Apple has implemented a very nicely optimized one as part of its Accelerate framework. I use BLAS to sum, for example, two arrays of floating point values--it&#39;s very, very highly optimized. In that situation, there&#39;s no trapping when a single value is out of bounds (I get NaNs instead), and thus I must determine bounds in order to anticipate when the output will be garbage or NaN. (There are, as part of the Accelerate framework, accelerated functions to clamp entire arrays to given bounds with maximal efficiency).</div><div class="gmail_extra"><br></div><div class="gmail_extra">For accelerated scaling and unscaling, then, it is essentially always necessary to compute upper and lower bounds even when that&#39;s unnecessary for non-accelerated scaling and unscaling, which operates on one value at a time. For that reason, `AcceleratedTransform` requires methods that compute upper and lower bounds, and provides a default implementation of accelerated clamping that calls those bound-computing methods and then uses the results as parameters when calling functions in Accelerate.framework. Methods for the computation of bounds already exist in `PortedTransform` but not in my own transforms. With your proposal, how would I retroactively model this requirement without touching code for `PortedTransform` and without compiling this one class into its own library? I&#39;d like to be able to take advantage of the maximum possible compiler optimization, and optimizing across module boundaries is (as far as I understand) a little dicier. (Moreover, for MyLinTransform, I override the clamping method to return the input without calling out to any framework functions because I know a priori that the bounds are -infinity and infinity. I think that override will still be possible under your proposal, though.)</div></div></div></blockquote></div><br></span><div>Without actually trying to understand the details of your math stuff:</div><div><br></div><div>* If you add a required member in a declaration or extension that declares conformance, it is &#39;required&#39;. </div><div>* If it is already defaulted, it is `override required`. </div><div>* If it is already defaulted but not required, it is `override`</div><div>* If someone else implements the stuff, you still have to pull it in somehow, but if you do so by conforming to another protocol with an extension, it&#39;s not your business, so you don&#39;t use any keywords.</div><div><br></div><div>You use keywords only for stuff that you specifically write, that clarifies the context in which you are writing it. If you do not own a protocol, an extension, or an implementation, you do not change or markup the protocol, extension, or implementation. You&#39;re just offering the compiler hints that your otherwise questionable decisions are fully intentional: when overriding an existing implementation and when conforming by supplying a required member.</div><div><br></div><div>-- E, who still probably missed your point and again apologizes</div></div></blockquote><div><br></div><div>I do not own the code, I do not write the code, but I am compiling it. The compiler does not know I do not own the code, and it will try to force me to edit it. Which it is physically possible for me to do, but perhaps not legally so, or perhaps it is not best practice because it&#39;s third-party code and I cannot upstream that change (nor would it make sense to do so without also upstreaming the actual extensions I am writing, which are out-of-scope for the upstream project).<br></div></div><br></div></div>