2 ms·
Using init/a constructor implies state, does it not?
by brnt 6y ago
Using init/a constructor implies state, does it not?
- raverbashing 6y agodef __init__(self): pass Not necessarily. Or the constructor is just setting some values that are later used by the calculation but are not modified and used later
- MaxBarraclough 6y agoI think that depends on what we understand by 'state'. Do we count immutable data? Consider faking a 'bind' with something like: var quadrupler = new ConstantMultiplier(4); var output = quadrupler.applyTo(42); The 'quadrupler' instance is stateless in that it's immutable, but it presumably has a (constant) member to store the value 4.
- yxhuvud 6y agoYes. If nothing else, the calculation of that immutable data may be costly enough to motivate not calculating it multiple times. Hence you want to treat it as state. But that doesn't mean you want to expose it to the user of the class which may have a nice simple interface of cheap operations after the init is done.
- mcv 6y agoAfter ES6, I jumped at the opportunity to write classes in javascript, but lately I've realised I barely write classes anymore, but I write a lot of functions that return functions. And this example is perfect for that. For example, I recently wrote this: const labelizeElement = ((element) => element.type.replace(/\s+/g, '')); const labelizeRelation = ((relation) => relation.type.toUpperCase().replace(/\s+/g, '_')); const groupByLabels = (labelizer) => (set, element) => ( set[labelizer(element)] ? { ...set, [labelizer(element)]: [element, ...set[labelizer(element)]] } : { ...set, [labelizer(element)]: [element] } ); const groupByElement = groupByLabels(labelizeElement); const groupByRelation = groupByLabels(labelizeRelation); I needed two functions that did almost the same thing, but not quite. I don't want to write a ton of nearly-duplicate code, so instead I extract the bits that are different, and write a function that I actually need. So yes, I'm inclined to say that only mutable state needs a class. And the more you get used to working with constants and immutables, the less mutable state you're going to find. I used to be a big fan of OO, but somehow experience seems to have landed me in the functional programming camp.
- MaxBarraclough 6y agoPersonally I'd avoid currying and go with a function with three params, like: const labelizeElement = ... const labelizeRelation = ... const groupByLabels = (labelizer, set, element) => .... const groupByElement = (set, element) => groupByLabels(labelizeElement, set, element); const groupByRelation = (set, element) => groupByLabels(labelizeRelation, set, element); This makes it slightly simpler to create a binding function around groupByLabels which fixes, say, the middle argument. I also think that avoiding the chained use of the => operator makes the code more readable to the average JavaScript dev. C++ has (strange looking) support for the bind pattern in its standard-library now [0], and Python3 has functools.partial but it only supports left-to-right binding [1] (not that there's any particular reason to avoid lambdas). [0] https://en.cppreference.com/w/cpp/utility/functional/bind https://en.cppreference.com/w/cpp/utility/functional/bind [1] https://docs.python.org/3/library/functools.html https://docs.python.org/3/library/functools.html