Library / SDK
zero-to-mastery/JS_Fun_Practice avatar
zero-to-mastery/JS_Fun_Practice

JS_Fun_Practice and its seventy-nine function export contract

A list of small & fun functional programming exercises in JavaScript

728 stars575 forksJavaScriptMIT

At a glance

What is it?
JS_Fun_Practice is a list of small functional programming exercises in JavaScript, each graded by a mocha test suite that reads a single solution file. The exercise set is well organised, but the test script is written so that it always reports success.
Who is it for?
JS_Fun_Practice suits a learner who wants a fixed ladder of functional exercises with a test harness already wired to mocha, chai and sinon, and who is prepared to read the failing assertion rather than trust the exit code. It does not suit a working engineer looking for production code, since the repository ships exercises and a test runner but no library.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 5 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A ladder of exercises that starts with identity and ends with filterRecurse

The project is a list of small functional programming exercises in JavaScript, and the list itself is the product. There is no published package, no application and no service. The repository holds a Solutions directory, a test folder, an index.js entry point, an index.html page, a style.css file, and a package.json whose description calls it a testing utility for the fun javascript functions.

What makes it more than a list of prompts is the export contract. The project documentation asks you to write your solution in the Solutions folder, to keep the function names matching the ones listed, and to paste a fixed block of exports at the bottom of your solution file. That block names seventy-nine functions, starting with identity, addb, subb, mulb, minb and maxb, running through acc, accPartial, fill, set, curry, compose, the generator helpers and the liftm family, and ending with mapRecurse and filterRecurse.

The exercises are therefore sequential, and the documentation says so plainly: a lot of the tests depend on previous functions to run properly, so it is safer to write the functions in order. That is the pedagogical bet of the project. Instead of isolated kata, you get one growing module where a later exercise consumes what you built earlier.

The repository topics point at the same audience: hacktoberfest, javascript-practice-problems and javascript-puzzles.

test/tests.js picks your solution file, one string to change

The mechanism is small and worth understanding before you write anything. The test suite lives in test/tests.js, and the first documented step is to change the filename variable in that file to the name of your solution file, which the instructions mark as optional. Every test then pulls functions from that single module.

That is why the export block matters so much. A test file that requires a named function which is not exported fails at load time rather than at the assertion, and a missing export can therefore mask the behaviour you actually wanted to check. The documentation gives you an escape hatch: you can comment out function names in the module.exports that you have not written yet. It also gives you a warning, since the tests reference earlier functions.

The paste block at the bottom of your solution file looks like this at its opening:

js
module.exports = {
    identity,
    addb,
    subb,
    mulb,
    minb,
    maxb,
    add,
    sub,
    mul,
    min,
    max,

In the project documentation the block continues for every exercise through to filterRecurse, and the same list has to exist in your own file if you want the whole suite to run. Contributors are pointed at a separate CONTRIBUTING.md file for the contribution workflow.

The test script is mocha with || true, so failures do not fail

The package.json is short and one line in it changes the meaning of everything else:

json
  "scripts": {
    "test": "mocha || true"
  },

The shell operator means that if mocha exits with a failure status, the second command runs and the overall exit status is success. The test suite still prints failures, but the command itself cannot report a broken solution. Any automation you wrap around it, a continuous integration job or a script that checks the exit code, will read the run as green.

The dev dependencies explain what the suite is made of:

json
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^12.0.0",
    "mocha-sinon": "^2.1.2",
    "sinon": "^9.0.2"
  }

Chai provides the assertions, mocha runs them, mocha-sinon plugs Sinon into mocha so that spies and stubs are usable inside test cases, and Sinon itself stands in for time, randomness and other impure behaviour. That combination is what lets the later exercises be tested at all, since a functional exercise set drifts towards functions with side effects.

The practical consequence for a learner is simple. Run the tests, then read the output rather than the exit status. Treat a green command as no evidence and a printed failure as the actual signal.

Accumulators, currying, composition and the monad-shaped tail

The exercise list has visible families, and grouping them is the fastest way to understand the curriculum. The opening group is arithmetic on two arguments, addb through maxb, followed by generalised versions that accept any number of arguments, add, sub, mul, min and max, and then recursive twins of the same operations, addRecurse, mulRecurse, minRecurse and maxRecurse. Writing the same behaviour twice, once in a loop and once in recursion, is a deliberate way to make the difference visible.

The next group is about functions that return functions. identityf takes an argument and returns a function that returns that argument. addf adds across two invocations, liftf takes a binary function and makes it callable with two invocations, and acc takes a function and an initial value and returns a function that accumulates its result across arguments. accPartial restricts that accumulation to a range of indices, and accRecurse does the same job recursively. Further along come curryb and curry for partial application, twice, twiceUnary, doubl and square for repeated application, reverseb and reverse, and the composition group: composeuTwo, composeu, composeb and composeTwo.

The list then turns to lazy and stateful territory with genFrom, genTo, genFromTo, elementGen, element, collect, filter, filterTail, concatTwo, concat, concatTail, gensymf, gensymff, fibonaccif, counter, revocableb, revocable, extract, m, addmTwo, addm, liftmbM, liftmb, liftm, exp, expn, addg, liftg, arrayg, continuizeu, continuize, vector, exploitVector, vectorSafe and pubsub. The m, liftm and continuize names point at monadic style, and pubsub at an event pattern, though the project documentation gives each exercise only a sentence, so the intended semantics have to be inferred from the name and the test.

The package.json points at a different author and a different licence

Two fields in package.json deserve a second look before you build anything on top of this repository. The licence field says ISC, while the repository itself is identified as MIT and ships a LICENSE file. The package.json also names an author, hazamaswag, and its repository, bugs and homepage URLs all point to the hazamaswag/JS_Fun_Practice copy of the project rather than the zero-to-mastery location. In other words, the package file still describes the original author's fork or upstream, which is exactly the kind of drift you find when a project moves hosting but the manifest is never revisited.

The main entry point is index.js and the version is 1.0.0. The repository has no GitHub releases, so there is no changelog to read and no tag to pin. The last push was on 2026-10-18, so the exercise list is being worked on, but the work happens in the test suite and the Solutions directory rather than in versioned artefacts.

The licence question matters more than it looks. ISC and MIT are both permissive, but they are not the same text, and the two identifiers disagree about which one applies. Read the LICENSE file in the repository and decide for yourself, because a permissive licence in either form still requires the copyright notice and permission notice to be kept with the code.

Why the export contract beats a list of prompts

The realistic alternative to this repository is a plain list of exercise descriptions with no test harness, or a personal scratch project where you write a function and a throwaway assertion for it. The difference in approach is not the exercises themselves, it is the feedback loop and the coupling.

With a bare list, each function is an island. You decide what a reasonable answer looks like, and you can be quietly wrong about the arity, the return shape or the edge cases. With the export contract, the suite holds you to seventy-nine named functions and checks them against assertions someone else wrote, including cases for empty input and missing arguments that you would not think to write yourself.

The coupling cuts the other way too. Because later exercises reuse earlier functions, a mistake in acc propagates into the composition and accumulator exercises, and because every name must be exported, the module grows a shape that a real project would not have. A working engineer copying from this repository is better off taking the ideas and the test style, and writing an ordinary module with a normal export surface.

That is the honest use case. The repository is a teaching ladder with a working grader, not a component to install, and the value is in the seventy-nine problems and the mocha setup, not in the code itself.

Editorial conclusion

JS_Fun_Practice suits a learner who wants a fixed ladder of functional exercises with a test harness already wired to mocha, chai and sinon, and who is prepared to read the failing assertion rather than trust the exit code. It does not suit a working engineer looking for production code, since the repository ships exercises and a test runner but no library. Before you start, confirm which licence applies by reading the LICENSE file next to the ISC identifier in package.json, and check that your solution file is the one named in test/tests.js, because the test script swallows every failure.

Frequently asked questions

How do I run the tests in JS_Fun_Practice?

Install the dependencies with npm install, put your solution file in the Solutions folder, set the filename variable in test/tests.js to that file, then run npm run test. The script is defined as mocha with || true, so read the printed output rather than trusting the exit status.

Do I have to write all the functions in JS_Fun_Practice at once?

No. You can comment out the names in the module.exports block that you have not written yet, but the documentation warns that many tests depend on previous functions, so writing the exercises in order is safer.

Which licence applies to JS_Fun_Practice?

The repository is identified as MIT and includes a LICENSE file, while the licence field in package.json says ISC. Read the LICENSE file in the repository to see which text is actually attached, and keep the copyright and permission notices if you reuse the code.

What testing libraries does JS_Fun_Practice use?

The dev dependencies are chai for assertions, mocha as the runner, and mocha-sinon with sinon so that spies and stubs are available inside test cases. The root test script runs mocha across the repository.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. zero-to-mastery/JS_Fun_Practice on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zero-to-mastery-js-fun-practice.svg)](https://hysenlabs.com/projects/zero-to-mastery-js-fun-practice)

Was this useful?