# computed A `computed` is a [subscribable](./subscribable.md), computed value expression. It takes any number of dependent inputs and provides one output. Subscribers are only notified if the computed value changes. `computed` forms the core of a logic graph. ## Behavior A `computed` takes any kind of dependency but if a dependency is a [subscribable](./subscribable.md) then the `computed` will subscribe to it such that the `computed` will be marked as _dirty_ when any that subscribable value changes. Whenever the `computed` is read from, if will recompute its result if the _dirty_ flag has been set, otherwise it just return the stored result from the last time it computed. Unlike [KnockoutJS](http://knockoutjs.com/) and [Vuejs](https://vuejs.org), Reactimal's `computed` requires explicit dependency expression to help avoid dependency loops and allow code retain readability as it grows. ## Usage ### Creation Creates a computed instance. Internally the passed computation function is called once to establish the initial value. ```js const showDialog = computed( (inVP, shouldShow) => inVP && shouldShow, // computation function [inViewport, shouldShow] // array of subscribable dependencies ); ``` Note: Property and container dependencies are "locked" while the computation function is run. If there are any out-of-band updates to a dependency, the value will be set but will not propagate until after the computation function is complete and the computed's subscribers are notified. ### Read Call the computed to receive the computed value. The value will be computed if any upstream dependencies have changed. ```js if (showDialog()) { /* showDialog() is truthy */ } ``` ### Provide a hash function for complex result types When the computed result is a type that is not determined to be equal with simple equality (===), provide a hash function to the `hashableComputed` type to create a computed that will reduce the result value to a value that can be compared with the identity operator before comparison. The computed result value will still be stored unmodified. ```js function hashSet(_a) { if (_a instanceof Set) { return Array.from(_a.keys()) .sort() .map(k => `${(typeof k).substr(0, 1)}:${encodeURIComponent(k)}/`) .join('?'); } return _a; } const computedSet = hashableComputed(hashSet); function _intersection(a, b) { return new Set([...a].filter(x => b.has(x))); } const a = prop(new Set([1, 2]), hashSet); const b = prop(new Set([2, 3]), hashSet); const intersection = computedSet(_intersection, [a, b]); ```