<p dir="auto">This issue was raised at <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="205039508" data-permission-text="Title is private" data-url="https://github.com/JuliaLang/julia/issues/20421" data-hovercard-type="pull_request" data-hovercard-url="/JuliaLang/julia/pull/20421/hovercard?comment_id=99267449&amp;comment_type=review_comment" href="https://github.com/JuliaLang/julia/pull/20421#discussion_r99267449">#20421 (comment)</a>. We should define clear rules regarding when it's OK to use <code class="notranslate">@inbounds</code> in Base code. Currently the code seems to be inconsistent.</p>
<p dir="auto"><a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/JeffBezanson/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/JeffBezanson">@JeffBezanson</a> mentioned this: "only use <code class="notranslate">@inbounds</code> when you can be certain, from local information, that all accesses are in bounds." In a strict interpretation, that would mean <code class="notranslate">@inbounds for i in eachindex(a)</code> is not correct when <code class="notranslate">a::AbstractArray</code>, since an incorrect array implementation could return invalid indices, which would crash Julia.</p>
<p dir="auto">This strict interpretation is problematic since (as <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/stevengj/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/stevengj">@stevengj</a> noted) often a generic <code class="notranslate">AbstractArray</code> method is also used for <code class="notranslate">Array</code>: if we cannot use <code class="notranslate">@inbounds</code> there, performance suffers in the common case just to avoid possible crashes in rare cases. A mechanism to enable <code class="notranslate">@inbounds</code> only for trusted types could help, but it would still be too bad that custom array types wouldn't benefit from bounds checking removal even when they implemented everything correctly: that would defeat the goal of making user-defined type as efficient as Base types. So I would say we need to trust custom array types, or at least allow them to opt out of bounds checking by stating that they are safe. Cf. <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="137267325" data-permission-text="Title is private" data-url="https://github.com/JuliaLang/julia/issues/15291" data-hovercard-type="pull_request" data-hovercard-url="/JuliaLang/julia/pull/15291/hovercard" href="https://github.com/JuliaLang/julia/pull/15291">#15291</a>.</p>
<p dir="auto">When one changes the language, it forces packages to choose between using a new feature and only working on new versions of Julia or not using the feature but supporting new and old versions. For non-syntactic changes, you can often work around this with fairly simple conditional definitions. For syntax changes (which are blessedly rare), this doesn't work. To allow code to gracefully handle new syntax while still parsing in older versions of Julia, we're going to introduce, ironically, a new syntax feature: pragmas. The first pragma will be the <code class="notranslate">feature</code> pragma, used as follows:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="%if feature conditional_modules
# write code that uses the conditional_modules feature
%else
# fallback code that doesn't use the conditional_module feature
%end"><pre class="notranslate"><span class="pl-k">%</span><span class="pl-k">if</span> feature conditional_modules
<span class="pl-c"><span class="pl-c">#</span> write code that uses the conditional_modules feature</span>
<span class="pl-k">%</span><span class="pl-k">else</span>
<span class="pl-c"><span class="pl-c">#</span> fallback code that doesn't use the conditional_module feature</span>
<span class="pl-k">%</span><span class="pl-k">end</span></pre></div>
<p dir="auto">A Julia parser will have a list of feature names. If the parser recognizes a feature name, it parses the file as if the source were the code between the <code class="notranslate">%if</code> and <code class="notranslate">%else</code> or if there is no <code class="notranslate">%else</code> until the <code class="notranslate">%end</code>. If the parser doesn't recognize the feature name, it parses the file as if the source were the code between the <code class="notranslate">%else</code> and the <code class="notranslate">%end</code> or as if the source were empty if there is no <code class="notranslate">%else</code>.</p>
<p dir="auto">In general, <code class="notranslate">%if</code> pragmas nest:</p>
<div class="highlight highlight-source-julia notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="%if A
  %if B
    # A and B
  %else
    # A but not B
  %end
%else
  # neither A nor B
%end"><pre class="notranslate"><span class="pl-k">%</span><span class="pl-k">if</span> A
  <span class="pl-k">%</span><span class="pl-k">if</span> B
    <span class="pl-c"><span class="pl-c">#</span> A and B</span>
  <span class="pl-k">%</span><span class="pl-k">else</span>
    <span class="pl-c"><span class="pl-c">#</span> A but not B</span>
  <span class="pl-k">%</span><span class="pl-k">end</span>
<span class="pl-k">%</span><span class="pl-k">else</span>
  <span class="pl-c"><span class="pl-c">#</span> neither A nor B</span>
<span class="pl-k">%</span><span class="pl-k">end</span></pre></div>
<p dir="auto">There should probably also be a <code class="notranslate">%ifelse</code> to handle the classic ambiguity here. Other pragmas, should we introduce them are single-line.</p>