<snapdata remixID="8180532"><project name="Pattern matching" app="Snap! 5.0, http://snap.berkeley.edu" version="1"><notes>See inside the project.&#xD;&#xD;In pattern matching, we attempt to match values against patterns and, if so desired, bind variables to successful matches.&#xD;</notes><thumbnail>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4CAYAAAB1ovlvAAAEQUlEQVR4Xu3Yv0vVcRTG8XMvBddLhlsZihQEmv9ARBe3aGjoCkK1OdUQDUWKi4QRTgVtURjRVBBEKC7alBZCUVtQV+huVkMYBnqt+40cpMxffeVyTj7vZj/fc87zvLAokyRJYvwhAacEMgB0Sp6xSwkAEAiuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAxADrgkA0DV+hgMQA64JANA1foYDEAOuCQDQNX6GAzCFgXK5bC0tLSle8mRlAgBMYWJhfsHe1T2ySv6H3T8yYTfHbqf4Ck9+JQDAlA7KpQ82d/D58utF+26fGufs9blZ6+3vS/lVvWcA3ELnkw1D1jBbt+oXrtc/tLtfn2zh6xpPAZiy5wt7z9jZjyeWX4/XvbL9QwU7VjxuuVwu5Vf1ngEwRed3btyyA1cSe9E9Yxev9Vp+Vz7FV3jCvwFTGqhWq5bNZlO+5tnvCfAbEA+uCQDQNX6GAxADrgkAsIbxnz/dbXsevLUvDVlr7Dtpl3t6ajjt//w0ANfora2tzQYGBqyrq2tLzZ6qO2Tt87v/+MbUzs/W+/SeFQqFLX17OzwG4DotdnZ2WpIkSz9RKpVsdHTUmpub/7n3q5nDq76p5nbYs/bExl9O/vM3t8sDAG7QZLFY/OsnMpmMLS4u2vDw8IYOVuKb2PfNHr+fsnye/zvk/wE35GO2FsBKpWIjIyPrfqG//qi9WZixS2ND1tHRsYlpej/Cb8BN/hU8PT299FdwU1OTnpIaXgzANcJtbW21wcHBVX8D1rAPuU8DUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAcDMFYfctsAUK7yWAf/BFmmTre60arnAAAAAElFTkSuQmCC</thumbnail><stage name="Stage" width="480" height="360" costume="0" color="255,255,255,1" tempo="60" threadsafe="false" lines="round" ternary="true" codify="false" inheritance="true" sublistIDs="false" scheduled="false" id="1"><pentrails>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAFoCAYAAACPNyggAAAOhUlEQVR4Xu3VwQkAAAjEMN1/abewn7jAQRC64wgQIECAAIF3gX1fNEiAAAECBAiMAHsCAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQICLAfIECAAAECgYAAB+gmCRAgQICAAPsBAgQIECAQCAhwgG6SAAECBAgIsB8gQIAAAQKBgAAH6CYJECBAgIAA+wECBAgQIBAICHCAbpIAAQIECAiwHyBAgAABAoGAAAfoJgkQIECAgAD7AQIECBAgEAgIcIBukgABAgQIHLFxAWmhEwHPAAAAAElFTkSuQmCC</pentrails><costumes><list struct="atomic" id="2"></list></costumes><sounds><list struct="atomic" id="3"></list></sounds><variables></variables><blocks></blocks><scripts></scripts><sprites><sprite name="Explanation" idx="1" x="0" y="0" heading="90" scale="1" rotation="1" draggable="true" costume="0" color="80,80,80,1" pen="tip" id="8"><costumes><list struct="atomic" id="9"></list></costumes><sounds><list struct="atomic" id="10"></list></sounds><blocks></blocks><variables></variables><scripts><comment x="20" y="20" w="390" collapsed="false">Pattern Matching in Snap!, inspired by Haskell.</comment><comment x="20" y="74" w="390" collapsed="false">Patterns are represented as predicates that, when evaluated, can either return false, or set some upvars and return true. You can replace these with custom patterns of your own, or even arbitrary procedures that return boolean values.</comment><comment x="20" y="152" w="390" collapsed="false">Most, if not all, of these have &quot;help&quot; comments, so if you&apos;re confused about any block, you can right-click it and click &quot;help&quot;.</comment><comment x="20" y="218" w="390" collapsed="false">Note: Patterns are predicates, not boolean values. The boolean inputs below accept predicates, or procedures that report booleans, and the boolean blocks below report predicates. This is so that upvars in nested patterns are still accessible, because the patterns themselves are evaluated immediately and report a procedure, instead of being unevaluated comparison procedures.</comment><script x="20" y="320"><custom-block s="match %s with %mult%anyUE"><l></l><list><l></l></list></custom-block></script><script x="20" y="353"><custom-block s="%b then %anyUE"><l/><l></l></custom-block></script><script x="20" y="386"><custom-block s="%upvar"><l>value</l></custom-block></script><script x="20" y="424"><custom-block s="any value"></custom-block></script><script x="20" y="454"><custom-block s="%mult%b : %b"><list><l/></list><l/><comment w="320" collapsed="false">Based on Haskell&apos;s list constructor syntax. Ideally, you&apos;d be able to use &quot;in front of&quot; to create a pattern, like you can to create a list.</comment></custom-block></script><script x="20" y="523"><custom-block s="split %b %b"><l/><l/><comment w="320" collapsed="false">This went through several iterations of being several blocks before I tried to generalize them, and this resulted.</comment></custom-block></script><script x="20" y="592"><custom-block s="item %upvar = %b"><l>#</l><l/><comment w="320" collapsed="false">This one is implemented via &lt;split &lt;&gt; &lt;&gt;&gt;. It splits the list just before an item, and then uses the &lt;&lt;&gt; : &lt;&gt;&gt; pattern.</comment></custom-block></script><script x="20" y="661"><custom-block s="just %b"><l/></custom-block></script><script x="20" y="692"><custom-block s="where %b and %b"><l/><l/></custom-block></script><script x="20" y="723"><custom-block s="%s"><l></l></custom-block></script></scripts></sprite><sprite name="More Testing" idx="3" x="21" y="32" heading="90" scale="1" rotation="1" draggable="true" costume="0" color="211.64999999999998,0,165.08700000000005,1" pen="tip" id="43"><costumes><list struct="atomic" id="44"></list></costumes><sounds><list struct="atomic" id="45"></list></sounds><blocks></blocks><variables></variables><scripts></scripts></sprite><sprite name="Testing" idx="2" x="50" y="5" heading="90" scale="1" rotation="1" draggable="true" costume="0" color="130.05,0,54.620999999999995,1" pen="tip" id="49"><costumes><list struct="atomic" id="50"></list></costumes><sounds><list struct="atomic" id="51"></list></sounds><blocks></blocks><variables></variables><scripts><script x="20" y="20"><custom-block s="match %s with %mult%anyUE"><block s="reportNewList"><list><l>1</l><l>2</l><l>3</l></list></block><list><custom-block s="%b then %anyUE"><custom-block s="%mult%b : %b"><list><custom-block s="%s"><l>1</l></custom-block><custom-block s="%s"><l>2</l></custom-block></list><custom-block s="%s"><block s="reportNewList"><list><l>3</l></list></block></custom-block></custom-block><l>success</l></custom-block><custom-block s="%b then %anyUE"><custom-block s="any value"></custom-block><l>failure</l></custom-block></list></custom-block></script><script x="20" y="97"><custom-block s="match %s with %mult%anyUE"><block s="reportNewList"><list><l>1</l><l>2</l><l>3</l></list></block><list><custom-block s="%b then %anyUE"><custom-block s="split %b %b"><custom-block s="%s"><block s="reportNewList"><list><l>1</l><l>2</l></list></block></custom-block><custom-block s="%s"><block s="reportNewList"><list><l>3</l></list></block></custom-block></custom-block><l>success</l></custom-block><custom-block s="%b then %anyUE"><custom-block s="any value"></custom-block><l>failure</l></custom-block></list></custom-block></script><script x="20" y="183"><custom-block s="match %s with %mult%anyUE"><block s="reportNewList"><list><block s="reportNewList"><list><l>name</l><l>John</l></list></block><block s="reportNewList"><list><l>age</l><l>23</l></list></block></list></block><list><custom-block s="%b then %anyUE"><custom-block s="split %b %b"><custom-block s="any value"></custom-block><custom-block s="%mult%b : %b"><list><custom-block s="%mult%b : %b"><list><custom-block s="%s"><l>age</l></custom-block><custom-block s="%upvar"><l>age</l></custom-block></list><custom-block s="%s"><block s="reportNewList"><list></list></block></custom-block></custom-block></list><custom-block s="any value"></custom-block></custom-block></custom-block><block var="age"/></custom-block><custom-block s="%b then %anyUE"><custom-block s="any value"></custom-block><l>failure</l></custom-block></list></custom-block></script></scripts></sprite></sprites></stage><hidden></hidden><headers></headers><code></code><blocks><block-definition s="just %&apos;v&apos;" type="reporter" category="operators"><comment x="0" y="0" w="327" collapsed="false">Used for procedures which may not report a value. Instead of reporting a value, they report (just (...)), and instead of not reporting a value, they report (nothing).&#xD;&#xD;This prevents the &quot;reporter didn&apos;t report&quot; error, while ensuring that if the procedure reports a false-ish value like an empty string or false itself, that it won&apos;t be confused with reporting no value.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input></inputs><script><block s="doReport"><block s="reportNewList"><list><block var="v"/></list></block></block></script></block-definition><block-definition s="nothing" type="reporter" category="operators"><comment x="0" y="0" w="327" collapsed="false">Used for procedures which may not report a value. Instead of reporting a value, they report (just (...)), and instead of not reporting a value, they report (nothing).&#xD;&#xD;This prevents the &quot;reporter didn&apos;t report&quot; error, while ensuring that if the procedure reports a false-ish value like an empty string or false itself, that it won&apos;t be confused with reporting no value.</comment><header></header><code></code><translations></translations><inputs></inputs><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block-definition><block-definition s="just %&apos;pattern&apos;" type="predicate" category="operators"><comment x="0" y="0" w="196" collapsed="false">Matches any value created with (just (...)), which is, by default, represented as a one-item list, that matches the given pattern.</comment><header></header><code></code><translations></translations><inputs><input type="%b"></input></inputs><script><block s="doReport"><block s="reifyReporter"><autolambda><custom-block s="if %b then %anyUE else %anyUE"><block s="reportAnd"><block s="reportIsA"><block var="value"/><l><option>list</option></l></block><block s="reportEquals"><block s="reportListLength"><block var="value"/></block><l>1</l></block></block><block s="evaluate"><block var="pattern"/><list><block s="reportListItem"><l>1</l><block var="value"/></block></list></block><block s="reportBoolean"><l><bool>false</bool></l></block></custom-block></autolambda><list><l>value</l></list></block></block></script></block-definition><block-definition s="where %&apos;a&apos; and %&apos;b&apos;" type="predicate" category="operators"><comment x="0" y="0" w="185" collapsed="false">Matches any value which matches both patterns.&#xD;&#xD;When used in conjunction with &lt;any (value)&gt;, allows for something similar to Haskell&apos;s &quot;value@pattern&quot;.</comment><header></header><code></code><translations></translations><inputs><input type="%b"></input><input type="%b"></input></inputs><script><block s="doReport"><block s="reifyPredicate"><autolambda><block s="reportAnd"><block s="evaluate"><block var="a"/><list><l></l></list></block><block s="evaluate"><block var="b"/><list><l></l></list></block></block></autolambda><list></list></block></block></script></block-definition><block-definition s="%&apos;value&apos;" type="predicate" category="operators"><comment x="0" y="0" w="179" collapsed="false">Matches the specific value only, using the regular equality operator.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input></inputs><script><block s="doReport"><block s="reifyPredicate"><autolambda><block s="reportEquals"><l></l><block var="value"/></block></autolambda><list></list></block></block></script></block-definition><block-definition s="if %&apos;condition&apos; then %&apos;true&apos; else %&apos;false&apos;" type="reporter" category="control"><header></header><code></code><translations></translations><inputs><input type="%b"></input><input type="%anyUE"></input><input type="%anyUE"></input></inputs><script><block s="doIf"><block var="condition"/><script><block s="doReport"><block s="evaluate"><block var="true"/><list></list></block></block></script></block><block s="doReport"><block s="evaluate"><block var="false"/><list></list></block></block></script></block-definition><block-definition s="append %&apos;lists&apos;" type="reporter" category="lists"><comment x="0" y="0" w="287" collapsed="false">Take any number of input lists, and create a new list containing the items of the input lists.  So&#xD;              APPEND [A B] [C D]&#xD;where the [,,,] are lists reports the list&#xD;              [A B C D]&#xD;not [[A B] [C D]].</comment><header></header><code></code><translations></translations><inputs><input type="%mult%l"></input></inputs><script><block s="doWarp"><script><block s="doIf"><block s="reportEquals"><block var="lists"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doIf"><block s="reportEquals"><block s="reportListLength"><block var="lists"/></block><l>1</l></block><script><block s="doReport"><block s="reportListItem"><l>1</l><block var="lists"/></block></block></script></block><block s="doIf"><block s="reportEquals"><block s="reportListItem"><l>1</l><block var="lists"/></block><block s="reportNewList"><list></list></block></block><script><block s="doReport"><custom-block s="append %mult%l"><block s="reportCDR"><block var="lists"/></block></custom-block></block></script></block><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block s="reportListItem"><l>1</l><block var="lists"/></block></block><custom-block s="append %mult%l"><block s="reportCONS"><block s="reportCDR"><block s="reportListItem"><l>1</l><block var="lists"/></block></block><block s="reportCDR"><block var="lists"/></block></block></custom-block></block></block></script></block></script></block-definition><block-definition s="reverse %&apos;data&apos;" type="reporter" category="lists"><comment x="0" y="0" w="223" collapsed="false">Reports a new list containing the items of the input list, but in the opposite order.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doDeclareVariables"><list><l>helper</l></list></block><block s="doSetVar"><l>helper</l><block s="reifyScript"><script><block s="doIf"><block s="reportEquals"><block var="input"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block var="result"/></block></script></block><block s="doReport"><block s="evaluate"><block var="helper"/><list><block s="reportCDR"><block var="input"/></block><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="input"/></block><block var="result"/></block></list></block></block></script><list><l>input</l><l>result</l></list></block></block><block s="doWarp"><script><block s="doReport"><block s="evaluate"><block var="helper"/><list><block var="data"/><block s="reportNewList"><list></list></block></list></block></block></script></block></script></block-definition><block-definition s="remove duplicates from %&apos;data&apos;" type="reporter" category="lists"><comment x="0" y="0" w="209" collapsed="false">Reports a new list whose items are the same as in the input list, except that if two or more equal items appear in the input list, only the last one is kept in the result.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doWarp"><script><block s="doIf"><block s="reportEquals"><block var="data"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doIfElse"><block s="reportListContainsItem"><block s="reportCDR"><block var="data"/></block><block s="reportListItem"><l>1</l><block var="data"/></block></block><script><block s="doReport"><custom-block s="remove duplicates from %l"><block s="reportCDR"><block var="data"/></block></custom-block></block></script><script><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="data"/></block><custom-block s="remove duplicates from %l"><block s="reportCDR"><block var="data"/></block></custom-block></block></block></script></block></script></block></script></block-definition><block-definition s="sort %&apos;data&apos; ordering with %&apos;function&apos;" type="reporter" category="lists"><comment x="0" y="0" w="204" collapsed="false">Reports a sorted version of the list in its first input slot, using the comparison function in the second input slot.  For a list of numbers, using &lt; as the comparison function will sort from low to high; using &gt; will sort from high to low.</comment><header></header><code></code><translations></translations><inputs><input type="%l"></input><input type="%predRing"></input></inputs><script><block s="doDeclareVariables"><list><l>even items</l><l>odd items</l><l>merge</l></list></block><block s="doSetVar"><l>odd items</l><block s="reifyScript"><script><block s="doIf"><block s="reportEquals"><l></l><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><l/></block><block s="evaluate"><block var="even items"/><list><block s="reportCDR"><l/></block></list></block></block></block></script><list></list></block></block><block s="doSetVar"><l>even items</l><block s="reifyScript"><script><block s="doIf"><block s="reportEquals"><l></l><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doReport"><block s="evaluate"><block var="odd items"/><list><block s="reportCDR"><l/></block></list></block></block></script><list></list></block></block><block s="doSetVar"><l>merge</l><block s="reifyScript"><script><block s="doIf"><block s="reportEquals"><block var="#1"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block var="#2"/></block></script></block><block s="doIf"><block s="reportEquals"><block var="#2"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block var="#1"/></block></script></block><block s="doIfElse"><block s="evaluate"><block var="function"/><list><block s="reportListItem"><l>1</l><block var="#1"/></block><block s="reportListItem"><l>1</l><block var="#2"/></block></list></block><script><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="#1"/></block><block s="evaluate"><block var="merge"/><list><block s="reportCDR"><block var="#1"/></block><block var="#2"/></list></block></block></block></script><script><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="#2"/></block><block s="evaluate"><block var="merge"/><list><block var="#1"/><block s="reportCDR"><block var="#2"/></block></list></block></block></block></script></block></script><list><l>#1</l><l>#2</l></list></block></block><block s="doIf"><block s="reportEquals"><block var="data"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doIf"><block s="reportEquals"><block s="reportCDR"><block var="data"/></block><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block var="data"/></block></script></block><block s="doReport"><block s="evaluate"><block var="merge"/><list><custom-block s="sort %l ordering with %predRing"><block s="evaluate"><block var="odd items"/><list><block var="data"/></list></block><block var="function"/></custom-block><custom-block s="sort %l ordering with %predRing"><block s="evaluate"><block var="even items"/><list><block var="data"/></list></block><block var="function"/></custom-block></list></block></block></script></block-definition><block-definition s="assoc %&apos;key&apos; %&apos;a-list&apos;" type="reporter" category="lists"><comment x="0" y="0" w="289.3333333333333" collapsed="false">The second input is an &quot;association list,&quot; a list of two-item lists.  Each of those smaller lists has a &quot;key&quot; as its first item and a &quot;value&quot; as its second.  ASSOC reports the first key-value pair in the association list whose key matches the first input.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%l"></input></inputs><script><block s="doIf"><block s="reportEquals"><block var="a-list"/><block s="reportNewList"><list></list></block></block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doIf"><block s="reportEquals"><block var="key"/><block s="reportListItem"><l>1</l><block s="reportListItem"><l>1</l><block var="a-list"/></block></block></block><script><block s="doReport"><block s="reportListItem"><l>1</l><block var="a-list"/></block></block></script></block><block s="doReport"><custom-block s="assoc %s %l"><block var="key"/><block s="reportCDR"><block var="a-list"/></block></custom-block></block></script></block-definition><block-definition s="%&apos;#&apos; map %&apos;function&apos; over %&apos;lists&apos;" type="reporter" category="lists"><header></header><code></code><translations></translations><inputs><input type="%upvar"></input><input type="%repRing"></input><input type="%mult%l"></input></inputs><script><block s="doWarp"><script><block s="doDeclareVariables"><list><l>mapone</l><l>mapmany</l></list></block><block s="doSetVar"><l>mapone</l><block s="reifyScript"><script><block s="doIf"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doSetVar"><l>#</l><block var="count"/></block><block s="doReport"><block s="reportCONS"><block s="evaluate"><block var="function"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="evaluate"><block var="mapone"/><list><block s="reportCDR"><block var="data"/></block><block s="reportSum"><block var="count"/><l>1</l></block></list></block></block></block></script><list><l>data</l><l>count</l></list></block></block><block s="doSetVar"><l>mapmany</l><block s="reifyScript"><script><block s="doIf"><custom-block s="empty? %l"><block s="reportListItem"><l>1</l><block var="data lists"/></block></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doSetVar"><l>#</l><block var="count"/></block><block s="doReport"><block s="reportCONS"><block s="evaluate"><block var="function"/><custom-block s="%upvar map %repRing over %mult%l"><l>#</l><block s="reifyReporter"><autolambda><block s="reportListItem"><l>1</l><l/></block></autolambda><list></list></block><list><block var="data lists"/></list></custom-block></block><block s="evaluate"><block var="mapmany"/><list><custom-block s="%upvar map %repRing over %mult%l"><l>#</l><block s="reifyReporter"><autolambda><block s="reportCDR"><l/></block></autolambda><list></list></block><list><block var="data lists"/></list></custom-block><block s="reportSum"><block var="count"/><l>1</l></block></list></block></block></block></script><list><l>data lists</l><l>count</l></list></block></block><block s="doIfElse"><custom-block s="empty? %l"><block s="reportCDR"><block var="lists"/></block></custom-block><script><block s="doReport"><block s="evaluate"><block var="mapone"/><list><block s="reportListItem"><l>1</l><block var="lists"/></block><l>1</l></list></block></block></script><script><block s="doReport"><block s="evaluate"><block var="mapmany"/><list><block var="lists"/><l>1</l></list></block></block></script></block></script></block></script></block-definition><block-definition s="empty? %&apos;data&apos;" type="predicate" category="lists"><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doReport"><block s="reportEquals"><block var="data"/><block s="reportNewList"><list></list></block></block></block></script></block-definition><block-definition s="%&apos;#&apos; keep items such that %&apos;pred&apos; from %&apos;data&apos;" type="reporter" category="lists"><header></header><code></code><translations></translations><inputs><input type="%upvar"></input><input type="%predRing"></input><input type="%l"></input></inputs><script><block s="doDeclareVariables"><list><l>keep-helper</l></list></block><block s="doSetVar"><l>keep-helper</l><block s="reifyScript"><script><block s="doWarp"><script><block s="doIf"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block><block s="doSetVar"><l>#</l><block var="count"/></block><block s="doIfElse"><block s="evaluate"><block var="pred"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><script><block s="doReport"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="data"/></block><block s="evaluate"><block var="keep-helper"/><list><block s="reportCDR"><block var="data"/></block><block s="reportSum"><block var="count"/><l>1</l></block></list></block></block></block></script><script><block s="doReport"><block s="evaluate"><block var="keep-helper"/><list><block s="reportCDR"><block var="data"/></block><block s="reportSum"><block var="count"/><l>1</l></block></list></block></block></script></block></script></block></script><list><l>data</l><l>count</l></list></block></block><block s="doReport"><block s="evaluate"><block var="keep-helper"/><list><block var="data"/><l>1</l></list></block></block></script></block-definition><block-definition s="%&apos;#&apos; for each %&apos;item&apos; of %&apos;data&apos; %&apos;action&apos;" type="command" category="lists"><header></header><code></code><translations></translations><inputs><input type="%upvar"></input><input type="%upvar"></input><input type="%l"></input><input type="%ca"></input></inputs><script><block s="doSetVar"><l>#</l><l>1</l></block><block s="doUntil"><custom-block s="empty? %l"><block var="data"/></custom-block><script><block s="doSetVar"><l>item</l><block s="reportListItem"><l>1</l><block var="data"/></block></block><block s="doRun"><block var="action"/><list><block s="reportListItem"><l>1</l><block var="data"/></block></list></block><block s="doSetVar"><l>data</l><block s="reportCDR"><block var="data"/></block></block><block s="doChangeVar"><l>#</l><l>1</l></block></script></block></script></block-definition><block-definition s="match %&apos;value&apos; with %&apos;cases&apos;" type="reporter" category="other"><comment x="0" y="0" w="294" collapsed="false">Tries to match the given value against each case, which consists of a pattern and a value to report if the match succeeds. Reports the value from the first case that succeeds.</comment><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%mult%anyUE"></input></inputs><script><block s="doIf"><block s="reportLessThan"><block s="reportListLength"><block var="cases"/></block><l>1</l></block><script><block s="doStopThis"><l><option>this block</option></l></block></script></block><block s="doIf"><block s="evaluate"><custom-block s="just %b"><custom-block s="%upvar"><l>x</l></custom-block></custom-block><list><block s="evaluate"><block s="evaluate"><block s="reportListItem"><l>1</l><block var="cases"/></block><list></list></block><list><block var="value"/></list></block></list></block><script><block s="doReport"><block var="x"/></block></script></block><block s="doReport"><custom-block s="match %s with %mult%anyUE"><block var="value"/><block s="reportCDR"><block var="cases"/></block></custom-block></block></script></block-definition><block-definition s="%&apos;pattern&apos; then %&apos;result&apos;" type="reporter" category="other"><comment x="0" y="0" w="160" collapsed="false">If the current value matches the given pattern, reports the given value.</comment><header></header><code></code><translations></translations><inputs><input type="%b"></input><input type="%anyUE"></input></inputs><script><block s="doReport"><block s="reifyScript"><script><block s="doIf"><block s="evaluate"><block var="pattern"/><list><l></l></list></block><script><block s="doReport"><custom-block s="just %s"><block s="evaluate"><block var="result"/><list></list></block></custom-block></block></script></block><block s="doReport"><custom-block s="nothing"></custom-block></block></script><list></list></block></block></script></block-definition><block-definition s="%&apos;value&apos;" type="predicate" category="other"><comment x="0" y="0" w="175" collapsed="false">Matches any value, and sends it.</comment><header></header><code></code><translations></translations><inputs><input type="%upvar"></input></inputs><script><block s="doReport"><block s="reifyScript"><script><block s="doSetVar"><l>value</l><l></l></block><block s="doReport"><block s="reportBoolean"><l><bool>true</bool></l></block></block></script><list></list></block></block></script></block-definition><block-definition s="any value" type="predicate" category="other"><comment x="0" y="0" w="141" collapsed="false">Matches any value without sending it.&#xD;&#xD;Used for &lt;&lt;&gt; : &lt;&gt;&gt;, a list-matching pattern, if you don&apos;t care about the rest of the list at all.</comment><header></header><code></code><translations></translations><inputs></inputs><script><block s="doReport"><custom-block s="%upvar"><l>value</l></custom-block></block></script></block-definition><block-definition s="%&apos;firstItems&apos; : %&apos;rest&apos;" type="predicate" category="lists"><comment x="0" y="0" w="145" collapsed="false">Matches a list whose first N items each match their respective pattern, and whose rest of the items as a sublist matches the rightmost pattern.</comment><header></header><code></code><translations></translations><inputs><input type="%mult%b"></input><input type="%b"></input></inputs><script><block s="doReport"><block s="reifyPredicate"><autolambda><block s="reportAnd"><block s="reportAnd"><block s="reportIsA"><block var="list"/><l><option>list</option></l></block><block s="reportNot"><block s="reportLessThan"><block s="reportListLength"><block var="list"/></block><block s="reportListLength"><block var="firstItems"/></block></block></block></block><custom-block s="if %b then %anyUE else %anyUE"><block s="reportEquals"><block var="firstItems"/><block s="reportNewList"><list></list></block></block><block s="evaluate"><block var="rest"/><list><block var="list"/></list></block><block s="reportAnd"><block s="evaluate"><block s="reportListItem"><l>1</l><block var="firstItems"/></block><list><block s="reportListItem"><l>1</l><block var="list"/></block></list></block><block s="evaluate"><custom-block s="%mult%b : %b"><block s="reportCDR"><block var="firstItems"/></block><block var="rest"/></custom-block><list><block s="reportCDR"><block var="list"/></block></list></block></block></custom-block></block></autolambda><list><l>list</l></list></block></block></script></block-definition><block-definition s="split %&apos;pattern a&apos; %&apos;pattern b&apos;" type="predicate" category="lists"><comment w="329" collapsed="false">Matches a list that can be split into two sublists, where the pattern for each sublist can be matched.</comment><header></header><code></code><translations></translations><inputs><input type="%b"></input><input type="%b"></input></inputs><script><block s="doDeclareVariables"><list><l>step</l></list></block><block s="doSetVar"><l>step</l><block s="reifyPredicate"><autolambda><block s="reportOr"><block s="reportAnd"><block s="evaluate"><block var="pattern a"/><list><block var="list a"/></list></block><block s="evaluate"><block var="pattern b"/><list><block var="list b"/></list></block></block><block s="reportAnd"><block s="reportNot"><custom-block s="empty? %l"><block var="list b"/></custom-block></block><block s="evaluate"><block var="step"/><list><custom-block s="reverse %l"><block s="reportCONS"><block s="reportListItem"><l>1</l><block var="list b"/></block><custom-block s="reverse %l"><block var="list a"/></custom-block></block></custom-block><block s="reportCDR"><block var="list b"/></block></list></block></block></block></autolambda><list><l>list a</l><l>list b</l></list></block></block><block s="doReport"><block s="reifyReporter"><autolambda><block s="evaluate"><block var="step"/><list><block s="reportNewList"><list></list></block><l></l></list></block></autolambda><list></list></block></block></script></block-definition><block-definition s="item %&apos;#&apos; = %&apos;pattern&apos;" type="predicate" category="lists"><comment w="156" collapsed="false">Matches any list with an item that matches the given patten.</comment><header></header><code></code><translations></translations><inputs><input type="%upvar"></input><input type="%b"></input></inputs><script><block s="doReport"><block s="reifyScript"><script><block s="doIf"><block s="evaluate"><custom-block s="split %b %b"><custom-block s="%upvar"><l>before</l></custom-block><custom-block s="%mult%b : %b"><list><block var="pattern"/></list><custom-block s="%upvar"><l>after</l></custom-block></custom-block></custom-block><list><l></l></list></block><script><block s="doSetVar"><l>#</l><block s="reportSum"><block s="reportListLength"><block var="before"/></block><l>1</l></block></block><block s="doReport"><block s="reportBoolean"><l><bool>true</bool></l></block></block></script></block><block s="doReport"><block s="reportBoolean"><l><bool>false</bool></l></block></block></script><list></list></block></block></script></block-definition><block-definition s="sum %&apos;list&apos;" type="reporter" category="operators"><header></header><code></code><translations></translations><inputs><input type="%l"></input></inputs><script><block s="doReport"><custom-block s="match %s with %mult%anyUE"><block var="list"/><list><custom-block s="%b then %anyUE"><custom-block s="%mult%b : %b"><list><custom-block s="%upvar"><l>n</l></custom-block></list><custom-block s="%s"><block s="reportNewList"><list></list></block></custom-block></custom-block><block var="n"/></custom-block><custom-block s="%b then %anyUE"><custom-block s="%mult%b : %b"><list><custom-block s="%upvar"><l>n</l></custom-block></list><custom-block s="%upvar"><l>ns</l></custom-block></custom-block><block s="reportSum"><block var="n"/><custom-block s="sum %l"><block var="ns"/></custom-block></block></custom-block></list></custom-block></block></script></block-definition></blocks><variables></variables></project><media name="Pattern matching" app="Snap! 5.0, http://snap.berkeley.edu" version="1"></media></snapdata>