Code Monkey home page Code Monkey logo

you-dont-need-loops's Introduction

English | 简体中文

You Don't Need

Logo

People choose popular projects, often not because it applies to their problems.

Awesome

Contents

Packages

JavaScript Packages

Languages

Programming Practices

  • You Don't Need Loops ➿ - Loops are bullshit. Let's embrace wholemeal programming!
  • You Probably Don't Need Derived State (React) - As a general rule, derived state should be used sparingly. All problems with derived state that we have seen can be ultimately reduced to either unconditionally updating state from props or updating state whenever props and state don't match.
  • You Might Not Need to Transpile Your JavaScript - In other words if you're transpiling your JavaScript to ES5, you're making your code unnecessarily big and slow to support a minority of the users who will probably upgrade their system by the time you manage to configure your Webpack and Babel! 😉

Miscellaneous

you-dont-need-loops's People

Contributors

cht8687 avatar horridmodz avatar lai-yt avatar rewrite0w0 avatar richardeschloss avatar stevemao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

you-dont-need-loops's Issues

Times when you may need loops (re: performance)

Hi, I just submitted a pull request #7 that shows a significant performance improvement with some simple code changes. However, even with this performance improvement, the for loop still performs much better, or at least in my environment. My environment: Chromium 73 (linux).

Consider the following test:

const unfold = (f, seed) => {
  const next = (f, val, acc) => {
    if (!f(val)) return acc
    const [currVal, nextVal] = f(val);
    acc.push(currVal)
    return next(f, nextVal, acc); 
  }
  return next(f, seed, [])
}

const rangeCorecursion = (start, end) =>
  unfold(val => (val <= end) 
    ? [val, val + 1]
    : null
, start);

const rangeLoop = (start, end) => {
  const acc = []
  for (let i = start; i <= end; i++) {
    acc.push(i)
  }
  return acc
}

const end = 5000
console.time('range_(corecursion)')
const range_test1 = rangeCorecursion(0, end)
console.timeEnd('range_(corecursion)')

console.time('range_(loop)')
const range_test2 = rangeLoop(0, end)
console.timeEnd('range_(loop)')
// Results:
range_(corecursion): 31.378173828125ms
range_(loop): 2.19482421875ms

As soon as I bump up the "end" to anything over 5000, chromium encounters "max call size errors". Using the for loop, not only do I not encounter that error, I can bump up the end range all the way to about 135,000 and have it finish before the corecursion method finishes 5000 iterations.

Is the performance different on Safari? What do those numbers look like?

Python version

Is there a way to get the examples rewritten for python ? Currently, it seems to be written for Javascript (actually i can't even say which language)

Feedback from Rob Howard

I'm not here to dunk, but
Impress your loved ones with catamorphisms, anamorphisms, bifunctors, fix points, f-algebras, co-recursion, and more.
immediately makes me sub in "Worry / annoy your co-workers with ...".
My take (sorry) is that your current flow of writing is throwing people off before they get anywhere near learning anything. Currently, the article's progression seems to go from:
"Loops are bullshit. Loops are bullshit." and "dreadful loops"
A big table and list of stuff that seems impenetrable if you don't already know what half of it refers to.
Then a too-brief explanation of why loops can cause problems; you've already lost your not-hate-reading audience by this point.
Then "You can immediately avoid off-by-one error and state by using recursions."
Then dunking on recursion with "Recursion is too low-level. Not low-level in the sense of direct access to the machine but low-level in the sense of language design and abstraction. Both loops and recursions do a poor job of signalling intent."
I'm appreciating this from a restatement of combinators in JS form, as I sometimes struggle with Haskell -> JS translation (getting my Haskell intuition back out of my head and into JS), but I worry that you've put a bunch of effort in and have the writing throw people off within the first twenty seconds. (edited)
I know there's controversy about this, but I think having jargon as the headlining item with no explanation doesn't help when introducing concepts, eg.
Paramorphism (which is just a header with no explanation), in the context of arrays/iterators, could be summarised as " map where the 'callback' function has access to the original array as well". I had to look up the definition and compare it to Catamorphism (which I already happen to know) to figure out what was meant by it.
There are ways of introducing the concepts in a way that includes the jargon/terminology for later reading, but without just giving you the name and code definition.

Original link: https://viewsource.slack.com/archives/C055CAFMT/p1575853626091300

Got issue running the code, due to wrong position of parameters

Hi folks,

Thanks for the great works You-dont-need series.
When I try to running the code in the md file, I actually got an issue, for example, like the code sum:

const reduce = function(iterable, reduceFn, accumulator){
  for (let i of iterable){
    accumulator = reduceFn(accumulator, i)
  }
  return accumulator
}

const sum = xs => 
  reduce((acc, x) => x + acc, 0, xs)

sum([1,2,3])  

it throws an error:

TypeError: iterable is not iterable

I found that the xs and anonymous function (acc, x) => x + acc are in the wrong position, to fix it, like below:

const reduce = function(iterable, reduceFn, accumulator){
  for (let i of iterable){
    accumulator = reduceFn(accumulator, i)
  }
  return accumulator
}

const sum = xs => 
  reduce(xs, (acc, x) => x + acc, 0);  // fix here!

sum([1,2,3]) // works!!

Hope it helps.
Thanks.

Precision about recursion

Hi,
I just stumbled upon this repo (somehow) and something tickled me while looking at the limitations table for recursion.

Sure, you might not need a for loop when recursion can do the trick better / in a more convenient manner, but it does (usually) have one limitation that for loops never have: execution limits.

For instance, Python has a max recursion depth of 1000. Yes you can change it, there's usually a simple way to do it in most languages - but still, it's a limitation that should be considered in some cases.

Don't get me wrong, you should absolutely optimize your algorithm in order not to create another problem like this one.
Let's say, you have an algorithm that scales exponentially and you didn't consider it before, it might sound fine at first but as time goes by, you could hit this limit faster without even noticing.

I'm wondering if you think it would be relevant to add it to the table.
It might not be the most useful thing to add to this doc, but it could be a nice to have. I'm not sure haha.

Adding more motivation on Corecursion and the following abstractions

From Mårten Rånge

I enjoy that page but I wonder if it could been helped by adding more motivation on Corecursion and the following abstractions. I think most devs follows up to that point but might end up confused by Corecursion, Transducers and F-Algebra. Also related to transducers maybe worth mentioning Church Encoded Lists?

Question about statefullness

Hi Steve!

Thanks for the write-up, I like it very much and it's very relevant! 👍

What confuses me is the promise of having no statefulness in recursive implementations.
I probably don't know what I'm talking about, but as far as I understand there's an option to have a state in functions that allow collection traversal by leveraging recursion.

function statefulTraverse(list, state) {
  // Sorry for the naive example,
  // just trying to come up with some illustration
  return statefulTraverse(list, nextState)
}

In JavaScript or other languages allowing access by a reference, recursive functions can even share mutable state.

[ 1, 2, 3 ].reduce((acc, curr) => {
  performSomeMutationsOnNestedState(acc.someOtherState)
  acc.counter += curr
  return acc
  },
  {
    counter: 0,
    someOtherState: { /* some object */ }
  }
)

I completely understand, that this example might look contrived, but I've seen this happening in my personal professional experience a few times. Deep cloning might solve the issue, but it gets less efficient as the object gets more nested stuff to the point where it's tempting to mutate it.

That's why I feel like raising awareness of the fact that using recursion does not guarantee the absence of the mutable state in JavaScript.

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.