supercollider-quarks / JITLibExtensions

Some extensions to the common JITLib classes
GNU General Public License v2.0
11 stars 9 forks source link

Dictionary.blendUni is identical with Dictionary.blend and both seem redundant in SC 3.10+ #15

Open eleses opened 4 years ago

eleses commented 4 years ago

I don't understand what is the point of Dictionary.blendUni in extDictBlend.sc. It has the exact same implementation as blend in the same file.

Furthermore, looking at the default implementation of Dictionary.blend in SC 3.10+ (and might be true even in some earlier versions), the whole functionality of extDictBlend has apparently been merged in the SC mainline classlib. The Dictionary.blend implementation in classlib is somewhat different as it relies on merge, but I don't see any big differences in functionality now between what extDictBlend provides and what classlib provides for Dictionary.blend.

Actually, on closer look, there is one difference that I found, which is might be considered a bug in extDictBlend that's been removed in classlib (or a feature added in the latter). extDictBlend does:

            commonKeys.do { |key|
                var spec = specs[key], val;

which bombs with error for the (2nd) example from the current SC help page, copied below:

d = (a: 500, b: 0.001);
e = (a: 300, b: 0.1);
blend(d, e, 0.3, specs: (a: \freq, b: \rq));

but this example works ok with the classlib blend implementation because the latter adds/does an asSpec

            var spec = if (specs.notNil) { specs[key].asSpec };

And there's one semantic difference too, extDictBlend does:

        if (blend == 0.0) { ^this };
        if (blend == 1.0) { ^that };

so regardless of fill value at the extreme ends uncommon keys are added unconditionally but directionally. In contrast, with blend from classlib

blend ( (foo: 1), (bar: 2), 1, false) // -> ( ) with classlib
blendUni ( (foo: 1), (bar: 2), 1, false) // -> ( 'bar': 2 )
blend ( (foo: 1), (bar: 2), 1, true) // -> ( 'bar': 2, 'foo': 1 ) with classlib
blendUni ( (foo: 1), (bar: 2), 1, true) // -> ( 'bar': 2 )

The classilib implementation is more consistent, but it only does inner (fill=false) and outer joins (fill=true) in database terms. extDictBlend does left- and right- joins at the extremes.

adcxyz commented 3 years ago

@eleses - thanks for spotting that, and you are right, they are obsolete and can actually be removed now.

For curiosity, I made a blend2 method which has left, right, sect, union merge modes, and runs ca 5x faster than blend does at the moment. Curious to hear your opinion on this one :-)

/* \freq.asSpec.blend(20, 2000); // 200

a = (freq: 20, amp: 0.5, dist: 23); b = (freq: 2000, pan: 0.2, dist: 12);

bench { 10000.do { a.blend2(b, 0.5, \left, nil, false) } } bench { 10000.do { a.blend(b, 0.5) } };

a.blend2(b, 0.5, \sect) a.blend2(b, 0.5, \right) a.blend2(b, 0.5, \union)

*/