npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

funkatron

v0.0.1

Published

Javacript Functional Programming Experiment

Downloads

7

Readme

Funkotron

Javascript Performant Functional Programming Experiment in Typescript

JUST WHY?

I'm glad you asked. This started when I was interviewing potential candidates for our development team.

As any interview, I would ask questions about their experience, their passions, education, etc, and then move on to do a simple and fairly well-known in-person coding test: FizzBuzz. I like using this test as it's simple enough that any developer should be able to do it on the spot in any language the developer is most comfortable with. It's a great way to gauge the interviewees creative process, if they can read/understand the problem fully, then ask questions about why they chose to do it one way vs another and bring up any potential issues and how they would solve those.

The test gives a simple problem which follows:

  • Iterate from numbers 100 to 1
  • For numbers that are divisible by 3, print "Fizz"
  • For numbers that are divisible by 5, print "Buzz"
  • For numbers that are divisible by 3 and 5, print "FizzBuzz"
  • For any other number, simply print the number

That's it. Like any problem, there's a lot of different interpretations, perspectives and possible solutions which gives a keen insight on what type of developer they are. This experiment started once I met one particular developer that was so keen on functional programming that he solved the issue like so:

console.log(
    Array.from(new Array(100))                      
        .map((v, index) => index)                   
        .reverse()                                  
        .map(v => v%5 + v%3 === 0 ? 'fizzbuzz': v)  
        .map(v => v%3 === 0 ? 'fizz': v)            
        .map(v => v%5 === 0 ? 'buzz': v)            
        .join('\n')                                 
)

It worked and in my opinion is an easily understandable and succinct solution, however, it's horribly inefficient since there are essentially 7 different loops:

console.log(
    Array.from(new Array(100))                      // Loop 1 - Create array
        .map((v, index) => index)                   // Loop 2 - Set index as value
        .reverse()                                  // Loop 3 - Reverse index order from 100 to 1
        .map(v => v%5 + v%3 === 0 ? 'fizzbuzz': v)  // Loop 4 - Check divisibility for both 3 and 5
        .map(v => v%3 === 0 ? 'fizz': v)            // Loop 5 - Check divisibility for 3
        .map(v => v%5 === 0 ? 'buzz': v)            // Loop 6 - Check divisibility for 5
        .join('\n')                                 // Loop 7 - Combine all items with newline separator for print
)

It got me thinking, functional programming is super readable but often times not practical since a single for loop will be much more performant or you can use a single map which makes it less readable.

OR

I can just create a small library that takes all of these beautiful functional methods and makes them performant by not looping through every item every time, but going item by item for every functional method essentially making it a single loop.

Clearly, I've gone mad.

Usage

There are 2 ways to use this library, either by importing it:

import funk from "funkotron";

const array = [1, 2, 3, 4];
const result = funk(Array.from(new Array(100)))
				.map((_, index) => 100 - index)
				.map(v => v % 5 + v % 3 === 0 ? "fizzbuzz" : v)
				.map(v => v % 3 === 0 ? "fizz" : v)
				.map(v => v % 5 === 0 ? "buzz" : v)
				.done()

Or by setting the Array.prototype globally:

import "funkotron/prototype";
const result = Array.from(new Array(100))
				.funk()
				.map((_, index) => 100 - index)
				.map(v => v % 5 + v % 3 === 0 ? "fizzbuzz" : v)
				.map(v => v % 3 === 0 ? "fizz" : v)
				.map(v => v % 5 === 0 ? "buzz" : v)
				.done()

Disclaimer

This is not production ready code and would need a much better way to do things. This was simply an experiment on how to potentially make functional programming much faster. It is not a complete library and only supports 3 functions (map, forEach and filter) and there needs lots of typing improvements to make it easier to work with in Typescript.

Use at your own peril.