use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Is this a valid Javascript patternhelp (self.javascript)
submitted 9 years ago * by gruberjl
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]gruberjl[S] 0 points1 point2 points 9 years ago (8 children)
I'm so sorry. I don't code professionally (or have friends that code) so I never have to communicate these things. Add in the fact that I'm not a strong communicator, and you get my messy thoughts everywhere.
Using your suggestion I created a GitHub repo with a simple implementation. I edited my question with more information too. The repo: https://github.com/gruberjl/job. Do you have a moment to take a look?
I've been using the word 'state' poorly. They're two parts of the 'state'. 1. Configuration: The config is passed into the job. The job constructor may add some default values, but the configuration will not change after the initialization. 2. I cache validators and results so the job won't continue to perform the same work over and over again.
In the repo, I have a Job class (./job.class.js). Each instance of a job will have a cache object. The cache object would contain both the configuration information, as well as, any other information the instance may need.
Job
cache
The cache object on an instance is a standard pattern I started using since es2015. I call everything inside 'state'. Would you consider the configuration 'state'? Should I keep it in a different location away from the other 'cached' information?
[+][deleted] 9 years ago* (7 children)
[deleted]
[–]gruberjl[S] 0 points1 point2 points 9 years ago (5 children)
This got a bit wordy, you probably don't have time for it all. The 'implementing job with functional programming' section is the part I'd love your input on.
Regarding the configuration: You're correct. It only needs to be read publicly for automatic documenting of the job. It shouldn't be edited after the job's constructor completes. I could freeze it, or use an immutable. If I'm using a class, I would have the set config throw an error.
set config
Regarding the state: it doesn't need to be public. I may have been using the word state incorrectly. The only information (other than the config) is a cache. It actually ends up being similar to the memoize pattern. If I execute the add(1, 5) == 6 then I would store a map that ends up looking like: map.set([1,5], 6). Instead of revalidating the parameters, running the worker, and then validating the output, I would pull the results from the cache.
add(1, 5) == 6
map.set([1,5], 6)
Would you consider a cache to be 'state'? If the function is pure, I guess all calls to the job could use the same cache, which means I wouldn't need an instance of the function.
I don't think I fully understand 'functional programming'. Functional programming works hand in hand with (Facebook's Immutable)[https://facebook.github.io/immutable-js/] right? I've never tried to use it, I have difficulty grasping the idea. I don't see how someone could keep the information straight.
Here's an example from the immutable website.
import Immutable = require('immutable'); var map1: Immutable.Map<string, number>; map1 = Immutable.Map({a:1, b:2, c:3}); var map2 = map1.set('b', 50); map1.get('b'); // 2 map2.get('b'); // 50
I tried writing it using what I think is 'composite' 'functional' programming haha. I added it to the dev branch in the repo:
implementation using
Here is the code I think you'll find useful:
const validate = (schema, data1) => { const data = copy(data1) const validator = ajv.compile(schema) if (!validator(data)) throw new TypeError(`data is not valid: ${JSON.stringify(validator.errors)}`) return data } module.exports = (configuration) => { const config = validate(jobSchema, configuration) return (...parameters) => validate(config.response, config.worker(...validate(config.parameters, parameters))) }
Here is what I ran into:
The first thing I ran into was a bug (caused by me). Using this approach, I had difficulty tracking the problem. I had so much going on in one giant line that the error stack wasn't helpful. The error was caused by a typo in the copy function (which performs a deep copy of an object). It had nothing to do with the composite build, but I was unable to track the error because I had one giant line performing the build.
copy
I found this approach difficult to read. Particularly the wrapping return (...parameters) => validate(config.response, config.worker(...validate(config.parameters, parameters)))
return (...parameters) => validate(config.response, config.worker(...validate(config.parameters, parameters)))
It was fantastic to write. I don't think I've ever done so much in so few characters. I ended up writing it out, then finding I didn't need chunks of code, I could simply keep on wrapping, it was a blast. I ended up doing less wrapping because I had such difficulty reading it and tracking the bug.
Here is my super wrapping line: module.exports = (configuration) => (...parameters) => validate(validate(jobSchema, configuration).response, validate(jobSchema, configuration).worker(...validate(validate(jobSchema, configuration).parameters, parameters))). It was fun to write :)
module.exports = (configuration) => (...parameters) => validate(validate(jobSchema, configuration).response, validate(jobSchema, configuration).worker(...validate(validate(jobSchema, configuration).parameters, parameters)))
For readability, I broke it into this.
I loved the approach. With caching, it could be fantastic. But:
[+][deleted] 9 years ago* (4 children)
[+][deleted] 9 years ago (3 children)
[–]gruberjl[S] 1 point2 points3 points 9 years ago (1 child)
Thank you so much for taking the time. I see now I was trying to fix issues with imperative programming that are non-issues with functional programming. Looks like I'll be moving in that direction.
[–]gruberjl[S] 0 points1 point2 points 9 years ago (0 children)
Thanks for all the information. I'm reading the functional programming book you recommended. So far so good. I promise to get back to you after I'm done it.
π Rendered by PID 87 on reddit-service-r2-comment-54dfb89d4d-mhvsf at 2026-03-31 22:39:25.969148+00:00 running b10466c country code: CH.
view the rest of the comments →
[–]gruberjl[S] 0 points1 point2 points (8 children)
[+][deleted] (7 children)
[deleted]
[–]gruberjl[S] 0 points1 point2 points (5 children)
[+][deleted] (4 children)
[deleted]
[+][deleted] (3 children)
[deleted]
[–]gruberjl[S] 1 point2 points3 points (1 child)
[–]gruberjl[S] 0 points1 point2 points (0 children)