<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I just posted <a href="http://stackoverflow.com/q/27992566/465378" class="">a question on Stack Overflow asking about using racket/match</a>. Since I’m not sure how active the racket tag is on SO, I figured I’d also post it here. For those who don’t want to look at the SO question, here’s the question’s contents.<div class=""><div class=""><br class=""></div><div class=""><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class="">In a <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">racket/match</code> pattern, I want to match some values, then create a struct that wraps them. For example, take the following (contrived) code:</p><pre class="prettyprint prettyprinted lang-lisp" style="margin-top: 0px; padding: 5px; border: 0px; font-size: 13px; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(238, 238, 238);"><code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: inherit;" class=""><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">struct foo </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">a b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">

</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(138, 74, 11);">define</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">foo-from-string str</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
  </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">match str
    </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">[</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">pregexp </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">#</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">px</span><span class="str" style="margin: 0px; padding: 0px; border: 0px; color: rgb(128, 0, 0);">"^(.+)<a href="smb://s(.+)//s(.+)$" class="">\\s(.+)\\s(.+)$</a>"</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> a b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
     </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">foo a b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">]</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
    </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">[</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">_ </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">#</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">f</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">]</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">))</span></code></pre><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class="">I frequently find myself matching this list of three elements in other patterns, then creating a struct from it. Therefore, I wanted to simplify this by writing a custom match expander. Ideally, it would work like this:</p><pre class="prettyprint prettyprinted lang-lisp" style="margin-top: 0px; padding: 5px; border: 0px; font-size: 13px; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(238, 238, 238);"><code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: inherit;" class=""><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">struct foo </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">a b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">

</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(138, 74, 11);">define</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">foo-from-str str</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
  </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">match str
    </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">[</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">foo-string value</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> value</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">]</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
    </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">[</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">_ </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">#</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">f</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">]</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">))</span></code></pre><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class="">That is, it should automatically match a string that satisfies the regex, then store the values into a <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">foo</code> struct on success and bind it to <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">value</code>. I tried writing something like the following to implement this:</p><pre class="prettyprint prettyprinted lang-lisp" style="margin-top: 0px; padding: 5px; border: 0px; font-size: 13px; overflow: auto; width: auto; max-height: 600px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; color: rgb(57, 51, 24); word-wrap: normal; background-color: rgb(238, 238, 238);"><code style="margin: 0px; padding: 0px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: inherit;" class=""><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; color: rgb(138, 74, 11);">define</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">-match-expander foo-string
  </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">λ</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">stx</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
    </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">syntax-case stx </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
      </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">[</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">_ result</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
       </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">#</span><span class="lit" style="margin: 0px; padding: 0px; border: 0px; color: rgb(149, 56, 56);">'</span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">and </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">pregexp </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">#</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">px</span><span class="str" style="margin: 0px; padding: 0px; border: 0px; color: rgb(128, 0, 0);">"^(.+)<a href="smb://s(.+)//s(.+)$" class="">\\s(.+)\\s(.+)$</a>"</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> a b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">
              </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">app </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">λ</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">v</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> </span><span class="opn" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);">foo a b c</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">))</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; color: rgb(0, 0, 0);"> result</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">))</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">]</span><span class="clo" style="margin: 0px; padding: 0px; border: 0px; color: rgb(20, 86, 128);">)))</span></code></pre><p style="margin: 0px 0px 1em; padding: 0px; border: 0px; font-size: 15px; clear: both; color: rgb(34, 34, 34); font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; line-height: 19.5px; background-color: rgb(255, 255, 255);" class="">Unfortunately, this fails because <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">a</code>, <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">b</code>, and <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">c</code>, are unbound when the function passed to the <code style="margin: 0px; padding: 1px 5px; border: 0px; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif; white-space: pre-wrap; background-color: rgb(238, 238, 238);" class="">app</code> pattern gets called. Is there any way to implement such a match expander so that it can perform some arbitrary procedure on the matched values?</p></div></div></body></html>