Asana Engineering Challenge - FRP
by ephekt
HTML
<script src="http://asana.com/challenge/engineering_challenge_1_lib.js"></script>
<script src="http://asana.com/challenge/engineering_challenge_1_sample_app.js"></script>
<h1>Asana Engineering Challenge - FRP</h1>
<!-- -->
<p>
For this challenge, we will build a Functional Reactive
Programming system ("FRP"), which allows us to declare
reactive values ("re-values") that are dependent <em>only<em> on other
re-values and/or on mutable values ("mu-values", imagine
these being values stored in a database). Sort of like a
generalized spreadsheet.
This system should allow us to recompute re-values in an
efficient manner when mu-values change.
</p>
<p>
We start with the most naive implementation possible -- one
in which re-values are always recomputed on every access.
The code is structured in a way to measure a certain "cost"
of computation based on the number of times a re-value is
computed. The initial cost is 95 and your goal is to bring
it down to 19 while preserving general correctness.
</p>
<p>
<b>Notes:</b>
<ol>
<li>
This fiddle includes two Javascript files:
<a target="_blank"
href="http://asana.com/challenge/engineering_challenge_1_lib.js">
engineering_challenge_1_lib.js</a> and
<a target="_blank"
href="http://asana.com/challenge/engineering_challenge_1_sample_app.js">
engineering_challenge_1_sample_app.js</a>.
</li>
<li>
JSFiddle <b>does not</b> automatically save your
file! If you refresh you <b>will</b> lose your work!
Use 'Save' and then 'Update' to save the current
version and get a new URL.
</li>
<li>
This challenge is in Javascript mainly because JSFiddle makes
it so easy. We tried to use as little Javascript syntax as
reasonably possible. If you're new to Javascript, you
might want to check out
...
CSS
h1 {
font-weight: 600;
}
p {
margin-top: 10px;
}
ol {
margin-left: 1.12em;
list-style-type: decimal;
}
JavaScript
/////////////////////////////////////////////////
// PLEASE READ THE INSTRUCTIONS TO YOUR RIGHT! //
/////////////////////////////////////////////////
FRP = {
///
/// Mutable Values
///
// Returns a newly created mutable value with a given
// initial value
makeMuValue: function(initial_value) {
return {
value: initial_value
};
},
// Returns the value of a given mutable value
readMuValue: function(mu_value) {
return mu_value.value;
},
// Changes the value of a given mutable value
changeMuValue: function(mu_value, new_value) {
mu_value.value = new_value;
},
///
/// Reactive Values
///
/**
* Returns a newly created re-value
*
* @param computeFunc {Function} A function that may compute
* other re-values and read other mu-values, returning
* the computed value of the newly created re-value
*/
makeReValue: function(computeFunc) {
return {
computeFunc: computeFunc
};
},
// Return the computed value of a given reactive value
computeReValue: function(re_value) {
return re_value.computeFunc();
}
};
window.onload = function() {
SampleApp.run();
};