<div dir="ltr">As far as the regular full syntax threading version goes, I lean towards the chain syntax as being a nice general solution that is more readable as the reader doesn&#39;t have to imagine inserting the arg into the subsequent sexps, the _ shows you visually what&#39;s going on right away.<div><br></div><div>iain</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Sep 19, 2020 at 2:06 PM Iain Duncan &lt;<a href="mailto:iainduncanlists@gmail.com">iainduncanlists@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Oops, you&#39;re right I meant to start the example with the ~&gt; macro. And I&#39;m not really attached to whether or not one has to write &quot;eval&quot; or not, or even start with that clause. That thing could be whatever: variable, symbol, number, string.  It could just as usefully be (where $i1 is integer from an incoming max message)<div><br></div><div>So maybe this is a better example (albeit a bit contrived), where the message is triggered by a message with two values, that become $i1 and $i2 (max does this for us)</div><div><br></div><div>~&gt; random $i1 ~&gt; + $i2 _ ~&gt; * -1 _ </div><div>which could also be, if I&#39;m thinking straight, written as:</div><div>~&gt; eval $i1 ~&gt; random _ ~&gt; + $i2 _ ~&gt; * -1 _</div><div><br></div><div>Does that make more sense? I had originally been thinking of the clojure syntax for thread first and thread last, but then upon seeing the chain sfri, I thought the use of _ was going to be more generally readable, and more useful in cases where one might be interpolating to anywhere in arg positions. Just seems like an elegant version of Clojure&#39;s thread-as macro? </div><div>The issue in max is that one has to do something different when you have the parens in there, requiring more message objects in the patch. (you have to make it a symbol, and then pipe it to s4m as eval-string {symbol}. It&#39;s certainly not a big inconvenience, but it would be nice to support both options.</div><div><br></div><div>thanks for looking at this!</div><div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Sep 19, 2020 at 1:47 PM Christos Vagias &lt;<a href="mailto:chris.actondev@gmail.com" target="_blank">chris.actondev@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>I kind of get it, but I think that your example should be</div><div><div>(~&gt; eval x ~&gt; fun1 arg1 _ ~&gt; fun2 _ arg2 arg3)</div><div><br></div><div>To produce the same thing as you said, <br><div>(fun2 (fun1 arg1 (eval x)) arg2 arg3)</div><div><br></div><div>I realise that x in your case will always be incoming string data that you want to eval it,</div><div>and for the sake of &quot;syntactic sugar&quot; you want to skip writing eval  every time.</div><div><br></div><div>But that would be a special case that is built upon the ~&gt;. And for the ~&gt; I think</div><div>the modification I mentioned would be needed. Also, in this example, in the &quot;eval x&quot; form,</div><div>the &quot;_&quot; would be nil to start with.<br></div><div><br></div><div>So the first step is to agree on the syntax :)</div><div>After that, could probably dig a bit into it next week (from Monday on) and will let you know</div><div>in private.<br></div><div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 19 Sep 2020 at 22:23, Iain Duncan &lt;<a href="mailto:iainduncanlists@gmail.com" target="_blank">iainduncanlists@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">thanks Christos. I guess my one liner example was not clear, it&#39;s not infix notation, it&#39;s still prefix notation, just as one whitespace and token separated call. As in, the first slot in each ~&gt; delimited s-exp is still a function call, the parens are just implied. I imagine it&#39;s not of use to anyone outside of Max, but it will be very useful in that context. To clarify what I meant, this is probably a better example:<div><br></div><div>(x ~&gt; fun1 arg1 _ ~&gt; fun2 _ arg2 arg3)</div><div>would execute the same as </div><div>(chain (eval x) (fun1 arg1 _) (fun2 _ arg2 arg3) )</div><div>which is also equivalent to</div><div>(fun2 (fun1 arg1 (eval x)) arg2 arg3)</div><div><br></div><div>so it&#39;s really just a way to write chains without having parens in there, the reason being that lists in messages with max are very easy to work with when they are all whitespace separated tokens, and allow interpolation with max&#39;s built in tools. So it allows people to make s4m &quot;one-liners&quot; that replace a whole wack of max objects for some use cases, and have access to s4m variables.</div><div><br></div><div>iain</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Sep 19, 2020 at 1:13 PM Christos Vagias &lt;<a href="mailto:chris.actondev@gmail.com" target="_blank">chris.actondev@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi Iain,</div><div><br></div><div>Wasn&#39;t aware of the chain srfi. Interesting.</div><div>Since I&#39;m coming more from clojure I guess I&#39;ll focus a bit more on the &quot;as-&gt;&quot;, &quot;-&gt;&quot; and &quot;-&gt;&gt;&quot;.<br></div><div>Could try fiddling with these from Monday on and will keep you posted on the process.</div><div><br></div><div>The &quot;(x ~&gt; a _ b ~&gt; c _ )&quot; form seems kinda too much though, adding infix notation to the mix<font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px"><br></span></font></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, 19 Sep 2020 at 19:37, Iain Duncan &lt;<a href="mailto:iainduncanlists@gmail.com" target="_blank">iainduncanlists@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi colleagues, I&#39;m trying to figure out how to build a couple of threading macros that would be very helpful in Max/MSP for Scheme for Max, but it is frankly over my head right now. Working it out will be a good exercise but I figured I would post here in case this is trivial for some macro experts in S7 and they are willing to share something I can study. <div><br></div><div>I want to implement something like <span style="color:rgb(26,26,27);font-family:&quot;Noto Sans&quot;,Arial,sans-serif;font-size:14px">srfi-197, where it is called &quot;chain&quot;. (but srfi-197 uses syntax-case and syntax-rules)</span></div><div><span style="color:rgb(26,26,27);font-family:&quot;Noto Sans&quot;,Arial,sans-serif;font-size:14px"><br></span></div><div><span style="color:rgb(26,26,27);font-family:&quot;Noto Sans&quot;,Arial,sans-serif;font-size:14px">so from the docs there: </span></div><div><div><span style="color:rgb(26,26,27);font-family:&quot;Noto Sans&quot;,Arial,sans-serif;font-size:14px"></span></div><div><pre style="border-color:inherit;box-sizing:inherit;font-family:Consolas,&quot;Liberation Mono&quot;,Menlo,Courier,monospace;font-size:13.6px;margin-top:0px;margin-bottom:0px;padding:16px;background-color:rgb(246,248,250);color:rgb(31,31,31);direction:ltr;line-height:1.45;overflow:auto;border-radius:3px"><code style="border:0px none;box-sizing:inherit;font-family:Consolas,&quot;Liberation Mono&quot;,Menlo,Courier,monospace;font-size:13.6px;padding:0px;border-radius:3px;direction:ltr;line-height:inherit;margin:0px;overflow:visible;word-spacing:normal;word-break:normal;display:inline;background:none 0% 0% repeat scroll transparent;color:inherit"><span style="border-color:inherit;box-sizing:inherit"><span style="border-color:inherit;box-sizing:inherit;margin-bottom:0px">(chain x (a b _)) </span><span style="border-color:inherit;box-sizing:inherit;color:rgb(106,115,125);margin-bottom:0px">; =&gt; (a b x)</span></span><br style="border-color:inherit;box-sizing:inherit"><span style="border-color:inherit;box-sizing:inherit"><span style="border-color:inherit;box-sizing:inherit;margin-bottom:0px">(chain (a b) (c _ d) (e f _)) </span><span style="border-color:inherit;box-sizing:inherit;color:rgb(106,115,125);margin-bottom:0px">; =&gt; (let* ((x (a b)) (x (c x d))) (e f x))</span></span><br style="border-color:inherit;box-sizing:inherit"><span style="border-color:inherit;box-sizing:inherit"><span style="border-color:inherit;box-sizing:inherit;margin-bottom:0px">(chain (a) (b _ _) (c _)) </span><span style="border-color:inherit;box-sizing:inherit;color:rgb(106,115,125);margin-bottom:0px">; =&gt; (let*-values (((x1 x2) (a)) ((x) (b x1 x2))) </span><span style="border-color:inherit;box-sizing:inherit;color:rgb(106,115,125);margin-bottom:0px">(c x))</span></span></code></pre></div></div><div><br></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">But what I&#39;d really to make on top of that is a version for allows one to use this for one liners in Max without inner parens, so something like this, where the macro is ~&gt;</span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px"><br></span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">(x ~&gt; a _ b ~&gt; c _ )</span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">becomes something  equivalent of:</span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">(c (a (eval x) b))</span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px"><br></span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">Because Scheme for Max will take a max message and treat it as code to be wrapped in outer parens and then eval&#39;d, this will let people do very useful things in one short max message (where say $i and $i2 come from another max message sending to it:</span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px"><br></span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">$i1 ~&gt; + 10 _ ~&gt; / $i2 _ </span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px"><br></span></font></div><div><font face="Noto Sans, Arial, sans-serif" color="#1a1a1b"><span style="font-size:14px">If anyone has suggestions or feels like helping that would be amazing. thanks!</span></font></div></div>
_______________________________________________<br>
Cmdist mailing list<br>
<a href="mailto:Cmdist@ccrma.stanford.edu" target="_blank">Cmdist@ccrma.stanford.edu</a><br>
<a href="https://cm-mail.stanford.edu/mailman/listinfo/cmdist" rel="noreferrer" target="_blank">https://cm-mail.stanford.edu/mailman/listinfo/cmdist</a><br>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>
</blockquote></div>