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't have to imagine inserting the arg into the subsequent sexps, the _ shows you visually what's going on right away.
iain On Sat, Sep 19, 2020 at 2:06 PM Iain Duncan <[email protected]> wrote: > Oops, you're right I meant to start the example with the ~> macro. And I'm > not really attached to whether or not one has to write "eval" 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) > > 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) > > ~> random $i1 ~> + $i2 _ ~> * -1 _ > which could also be, if I'm thinking straight, written as: > ~> eval $i1 ~> random _ ~> + $i2 _ ~> * -1 _ > > 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's thread-as macro? > 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's > certainly not a big inconvenience, but it would be nice to support both > options. > > thanks for looking at this! > > On Sat, Sep 19, 2020 at 1:47 PM Christos Vagias <[email protected]> > wrote: > >> I kind of get it, but I think that your example should be >> (~> eval x ~> fun1 arg1 _ ~> fun2 _ arg2 arg3) >> >> To produce the same thing as you said, >> (fun2 (fun1 arg1 (eval x)) arg2 arg3) >> >> I realise that x in your case will always be incoming string data that >> you want to eval it, >> and for the sake of "syntactic sugar" you want to skip writing eval >> every time. >> >> But that would be a special case that is built upon the ~>. And for the >> ~> I think >> the modification I mentioned would be needed. Also, in this example, in >> the "eval x" form, >> the "_" would be nil to start with. >> >> So the first step is to agree on the syntax :) >> After that, could probably dig a bit into it next week (from Monday on) >> and will let you know >> in private. >> >> >> On Sat, 19 Sep 2020 at 22:23, Iain Duncan <[email protected]> >> wrote: >> >>> thanks Christos. I guess my one liner example was not clear, it's not >>> infix notation, it's still prefix notation, just as one whitespace and >>> token separated call. As in, the first slot in each ~> delimited s-exp is >>> still a function call, the parens are just implied. I imagine it'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: >>> >>> (x ~> fun1 arg1 _ ~> fun2 _ arg2 arg3) >>> would execute the same as >>> (chain (eval x) (fun1 arg1 _) (fun2 _ arg2 arg3) ) >>> which is also equivalent to >>> (fun2 (fun1 arg1 (eval x)) arg2 arg3) >>> >>> so it'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's built in tools. So it allows people to make s4m >>> "one-liners" that replace a whole wack of max objects for some use cases, >>> and have access to s4m variables. >>> >>> iain >>> >>> >>> On Sat, Sep 19, 2020 at 1:13 PM Christos Vagias < >>> [email protected]> wrote: >>> >>>> Hi Iain, >>>> >>>> Wasn't aware of the chain srfi. Interesting. >>>> Since I'm coming more from clojure I guess I'll focus a bit more on the >>>> "as->", "->" and "->>". >>>> Could try fiddling with these from Monday on and will keep you posted >>>> on the process. >>>> >>>> The "(x ~> a _ b ~> c _ )" form seems kinda too much though, adding >>>> infix notation to the mix >>>> >>>> On Sat, 19 Sep 2020 at 19:37, Iain Duncan <[email protected]> >>>> wrote: >>>> >>>>> Hi colleagues, I'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. >>>>> >>>>> I want to implement something like srfi-197, where it is called >>>>> "chain". (but srfi-197 uses syntax-case and syntax-rules) >>>>> >>>>> so from the docs there: >>>>> >>>>> (chain x (a b _)) ; => (a b x) >>>>> (chain (a b) (c _ d) (e f _)) ; => (let* ((x (a b)) (x (c x d))) (e f x)) >>>>> (chain (a) (b _ _) (c _)) ; => (let*-values (((x1 x2) (a)) ((x) (b x1 >>>>> x2))) (c x)) >>>>> >>>>> >>>>> But what I'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 ~> >>>>> >>>>> (x ~> a _ b ~> c _ ) >>>>> becomes something equivalent of: >>>>> (c (a (eval x) b)) >>>>> >>>>> Because Scheme for Max will take a max message and treat it as code to >>>>> be wrapped in outer parens and then eval'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: >>>>> >>>>> $i1 ~> + 10 _ ~> / $i2 _ >>>>> >>>>> If anyone has suggestions or feels like helping that would be amazing. >>>>> thanks! >>>>> _______________________________________________ >>>>> Cmdist mailing list >>>>> [email protected] >>>>> https://cm-mail.stanford.edu/mailman/listinfo/cmdist >>>>> >>>>
_______________________________________________ Cmdist mailing list [email protected] https://cm-mail.stanford.edu/mailman/listinfo/cmdist
