Replies: 8 comments 24 replies
-
Implemented in #83 |
Beta Was this translation helpful? Give feedback.
-
this might be another way to combine patterns #53 |
Beta Was this translation helpful? Give feedback.
-
This looks all really good. Let me write down some lists to help my brain a bit: 1. there are 2 main aspects of
2. strategies to merge
There are shorthand pattern methods to 3. strategies to merge
for 4. pattern composers = combination of 2 and 3 Using both strategies for
5. Thoughts I'm not sure if I like the
Also, it would be easier to think about this stuff if we had some better wording for "strategy to merge values" + "stategy to merge structure" 6. How does Are those siblings to '' / 7. default pattern methods for structure? With We could use Pattern.prototype.reset = Pattern.prototype.keepReset;
Pattern.prototype.restart = Pattern.prototype.keepRestart; |
Beta Was this translation helpful? Give feedback.
-
Let's collect words for combining two patterns:
|
Beta Was this translation helpful? Give feedback.
-
I'll try to rephrase my idea with struct here:
I meant, instead of (or in addition to) trying to come up with a single function name with the form "0 1".add("1 2 3") // structure from left
"0 1".structWith("1 2 3", add) // structure from right
"0 1".mergeWith("1 2 3", add) // merge structure
"0 1".resetWith("1 2 3", add) // reset structure
"0 1".restartWith("1 2 3", add) // restart structure For me, this feels pretty consistent with the existing API design, as many functions come with an added "0 1".structWith("1 2 3", (l,r) => l**r) |
Beta Was this translation helpful? Give feedback.
-
So for operation
to make At the moment I prefer 3 or 7, but quite like 1 as well |
Beta Was this translation helpful? Give feedback.
-
Not sure where to put this, I just took some notes while rereading These are the composers: const composers = [
'set',
'keep',
'keepif',
'add',
'sub',
'mul',
'div',
'mod',
'pow',
'_and',
'_or',
'_xor',
'_lshift',
'_rshift',
'lt',
'gt',
'lte',
'gte',
'eq',
'eqt',
'ne',
'net',
'and',
'or',
'func',
]; they are used to programatically define Pattern.prototype methods for different pattern aligment strategies: ['In', 'Out', 'Mix', 'Squeeze', 'SqueezeOut', 'Trig', 'Trigzero']; Example: '0 1 2 1'.addOut('1 2'); // = "1 3"
'0 1 2 1'.addIn('1 2'); // = "1 2 4 3" then there are these curried transformation functions (further called transforms): const transforms = [
'add',
'chop',
'chunk',
'chunkBack',
'div',
'early',
'echo',
'every',
'fast',
'inv',
'invert',
'iter',
'iterBack',
'jux',
'juxBy',
'late',
'linger',
'mask',
'mul',
'off',
'ply',
'range',
'rangex',
'range2',
'rev',
'slow',
'struct',
'sub',
'superimpose',
'set',
'when',
]; these can be used as transformation methods like '0 1 2'.superimpose(fast(2)); Let's look at how the two lists overlap: composers.filter((c) => transforms.includes(c));
['set', 'add', 'sub', 'mul', 'div']; In this list are functions you can use for both: note('c3 d3 e3').addOut('1 2'); // works
note('c3 d3 e3').superimpose(add('1 2')); // works
note('c3 d3 e3').superimpose(addOut('1 2')); // what about? These are functions you can only use as composer: // transforms that are not composers
composers.filter((c) => !transforms.includes(c));
[
'keep',
'keepif',
'mod',
'pow',
'_and',
'_or',
'_xor',
'_lshift',
'_rshift',
'lt',
'gt',
'lte',
'gte',
'eq',
'eqt',
'ne',
'net',
'and',
'or',
'func',
]; example: note('c3 d3 e3').powOut('1 2'); // composer: works
note('c3 d3 e3').superimpose(pow(2)); // does not work At last, let's look at functions that can only be used as transforms and not as composers: // composers that are not transforms
transforms.filter((c) => !composers.includes(c));
[
'chop',
'chunk',
'chunkBack',
'early',
'echo',
'every',
'fast',
'inv',
'invert',
'iter',
'iterBack',
'jux',
'juxBy',
'late',
'linger',
'mask',
'off',
'ply',
'range',
'rangex',
'range2',
'rev',
'slow',
'struct',
'superimpose',
'when',
]; Example note('c3 d3 e3').superimpose(fast('<1 2>')); // transform: works
note('c3 d3 e3').fastOut('1 2'); // composer: doesnt work Additionally, there is the large list of control params which would also need composed variants e.g. General questions:
I still think it might be a nice thing to have an alternative (possibly coexisting) to the matrix style function generation. Like this: note('c3 d3 e3').structWith(add, '1 2');
note('c3 d3 e3').squeezeWith(add, '1 2'); ( With those, we could also solve the transforms that also do alignment thing with: s("bd sd").superimpose(x=>x.structWith(speed, "1 2 3")) |
Beta Was this translation helpful? Give feedback.
-
There are already a few ways to compose two patterns together by matching events and merging their values,
union
,add
,mul
,sub
, andadd
.union
isn't a good name for this, because they all do a union. The distinguishing feature is that when doing the union,a.union(b)
it replaces values from patterna
with values fromb
. So I propose renaming it toset
(as in, set the values to, not set theory).A variant that keeps values in
a
could be calledconst
.Where matching events don't have the same timespan but do overlap, currently you end up with the intersection as a fragment of the pattern on the left (pattern
a
in the above). We can also have variantssetRight
,addRight
,mulRight
etc. This is a bit ambiguous though, especially forconstRight
, because there's confusion about whether it's the fragment structure, or the value that we're taking from the rightmost pattern. MaybesetFlip
,constFlip
etc for 'flipping' the structure is better? This assumes that taking wholes from the left is default.Then there is the variant where the intersections of matching events are treated as whole events. E.g. where
"1 2 3"
+"10 20"
gives11 [12 22] 23
. One possibility is using the suffix 'Sect' for intersection.setSect
,addSect
etc. I quite like this because you can also think about it dividing events into sections.(In Tidal, this is done with operators like
|>
forset
,>|
forsetFlip
|<
forconst
,|<|
forconstSect
,|+
foradd
,+|
foraddFlip
,+
or|+|
foraddSect
, etc. This works nicely, but because javascript doesn't support custom operators, and there aren't enough to overload, we have to find a reasonable way to do this with words instead. Still, it would be nice to alias+
foradd
)All of the variants so far assume that we're composing patterns by aligning cycles and seeing which events intersect, then combining them. There are more possibilities though! For example, squeeze, which aligns cycles on the right with event timespans on the left.
... and then we might want to flip and squeeze:
I think there could be a lot of uncharted possibilities for squeeze.. and probably other structural ways to combine patterns.
Beta Was this translation helpful? Give feedback.
All reactions