<?xml version="1.0"?>
<paste-with-annotations>
  <paste>
    <number>
      <integer>73896</integer>
    </number>
    <user>
      <string>cgay</string>
    </user>
    <title>
      <string>trim gf proposal for common-extensions -- please review</string>
    </title>
    <contents>
      <string>define open generic trim
    (sequence :: &lt;sequence&gt;, to-remove :: &lt;object&gt;, #key from)
 =&gt; (sequence :: &lt;sequence&gt;);

define method trim
    (sequence :: &lt;sequence&gt;, to-remove :: &lt;object&gt;, #key from = #&quot;both&quot;)
 =&gt; (sequence :: &lt;sequence&gt;)
  trim(sequence, curry(\=, to-remove), from: from)
end;

define method trim
    (sequence :: &lt;sequence&gt;, remove? :: &lt;function&gt;, #key from = #&quot;both&quot;)
 =&gt; (sequence :: &lt;sequence&gt;)
  let start-index :: &lt;integer&gt; = 0;
  let end-index :: &lt;integer&gt; = sequence.size;
  if (member?(from, #[left:, both:]))
    while (start-index &lt; end-index &amp; remove?(sequence[start-index]))
      start-index := start-index + 1;
    end;
  end;
  if (member?(from, #[right:, both:]))
    while (end-index &gt; start-index &amp; remove?(sequence[end-index - 1]))
      end-index := end-index - 1;
    end;
  end;
  if (start-index = 0 &amp; end-index = sequence.size)
    sequence
  else
    copy-sequence(sequence, start: start-index, end: end-index)
  end
end method trim;

define method trim
    (sequence :: &lt;sequence&gt;, to-remove :: &lt;collection&gt;, #key from = #&quot;both&quot;)
 =&gt; (sequence :: &lt;sequence&gt;)
  trim(sequence, rcurry(member?, to-remove), from: from)
end;
</string>
    </contents>
    <universal-time>
      <integer>3441394154</integer>
    </universal-time>
    <channel>
      <string>#dylan</string>
    </channel>
    <colorization-mode>
      <string>None</string>
    </colorization-mode>
    <maybe-spam>
      <null/>
    </maybe-spam>
    <is-unicode>
      <keyword>TRUE</keyword>
    </is-unicode>
    <deletion-requested>
      <null/>
    </deletion-requested>
    <deletion-requested-email>
      <null/>
    </deletion-requested-email>
    <expiration-time>
      <null/>
    </expiration-time>
  </paste>
  <annotation>
    <number>
      <integer>1</integer>
    </number>
    <user>
      <string>|Agent</string>
    </user>
    <title>
      <string>Alternate definition, if&#xE2;&#x80;&#xA6;</string>
    </title>
    <contents>
      <string>// If there were a version of find-key that used backwards-iteration-protocol called find-last-key,
// we could implement the main trim function like so. Presumably, iteration using find-key and
// find-last-key would be most optimized for the specific data structure being trimmed, rather than
// using explicit indexing.

define method trim
    (sequence :: &lt;sequence&gt;, remove? :: &lt;function&gt;, #key from = #&quot;both&quot;)
 =&gt; (sequence :: &lt;sequence&gt;)
  let keep? = complement(remove?);
  let start-index =
      if (member?(from, #[left:, both:]))
        find-key(sequence, keep?, failure: 0)
      else
        0
      end if;
  let end-index =
      if (member?(from, #[right:, both:]))
        find-last-key(sequence, keep?, failure: sequence.size - 1)
      else
        sequence.size - 1
      end if;
  if (start-index = 0 &amp; end-index = sequence.size)
    sequence
  else
    copy-sequence(sequence, start: start-index, end: end-index)
  end
end method trim;

</string>
    </contents>
    <universal-time>
      <integer>3441396930</integer>
    </universal-time>
    <channel>
      <string>#dylan</string>
    </channel>
    <colorization-mode>
      <string></string>
    </colorization-mode>
    <maybe-spam>
      <null/>
    </maybe-spam>
    <is-unicode>
      <keyword>TRUE</keyword>
    </is-unicode>
    <deletion-requested>
      <null/>
    </deletion-requested>
    <deletion-requested-email>
      <null/>
    </deletion-requested-email>
    <expiration-time>
      <null/>
    </expiration-time>
  </annotation>
  <annotation>
    <number>
      <integer>2</integer>
    </number>
    <user>
      <string>|Agent</string>
    </user>
    <title>
      <string>Corrected alt defn</string>
    </title>
    <contents>
      <string>define method trim
    (sequence :: &lt;sequence&gt;, remove? :: &lt;function&gt;, #key from = #&quot;both&quot;)
 =&gt; (sequence :: &lt;sequence&gt;)
  let keep? = complement(remove?);
  let start-index = member?(from, #[left:, both:]) &amp; find-key(sequence, keep?);
  let end-index = member?(from, #[right:, both:]) &amp; find-last-key(sequence, keep?);
  if (~start-index &amp; ~end-index)
    sequence
  else
    copy-sequence(sequence, start: start-index | 0, end: end-index | sequence.size)
  end
end method trim;</string>
    </contents>
    <universal-time>
      <integer>3441397556</integer>
    </universal-time>
    <channel>
      <string>#dylan</string>
    </channel>
    <colorization-mode>
      <string></string>
    </colorization-mode>
    <maybe-spam>
      <null/>
    </maybe-spam>
    <is-unicode>
      <keyword>TRUE</keyword>
    </is-unicode>
    <deletion-requested>
      <null/>
    </deletion-requested>
    <deletion-requested-email>
      <null/>
    </deletion-requested-email>
    <expiration-time>
      <null/>
    </expiration-time>
  </annotation>
  <annotation>
    <number>
      <integer>3</integer>
    </number>
    <user>
      <string>|Agent</string>
    </user>
    <title>
      <string>Corrected again. Blah.</string>
    </title>
    <contents>
      <string>define method trim
    (sequence :: &lt;sequence&gt;, remove? :: &lt;function&gt;, #key from = #&quot;both&quot;)
 =&gt; (sequence :: &lt;sequence&gt;)
  let keep? = complement(remove?);
  let start-index = member?(from, #[left:, both:]) &amp; find-key(sequence, keep?);
  let end-index = member?(from, #[right:, both:]) &amp; find-last-key(sequence, keep?);
  let end-index = if (end-index) end-index + 1 end; // Still #f if end-index is #f.
  if (~start-index &amp; ~end-index)
    sequence
  else
    copy-sequence(sequence, start: start-index | 0, end: end-index | sequence.size)
  end
end method trim;</string>
    </contents>
    <universal-time>
      <integer>3441398007</integer>
    </universal-time>
    <channel>
      <string>#dylan</string>
    </channel>
    <colorization-mode>
      <string></string>
    </colorization-mode>
    <maybe-spam>
      <null/>
    </maybe-spam>
    <is-unicode>
      <keyword>TRUE</keyword>
    </is-unicode>
    <deletion-requested>
      <null/>
    </deletion-requested>
    <deletion-requested-email>
      <null/>
    </deletion-requested-email>
    <expiration-time>
      <null/>
    </expiration-time>
  </annotation>
</paste-with-annotations>
