Coder Social home page Coder Social logo

functional-javascript-workshop's Introduction

Functional Javascript Workshop

Gitter NodeSchool Discussions

Teaching fundamental functional programming features of Javascript.

No libraries required (i.e. no underscore), just ES5.


Gittip

Mission

Many functional programming learning resources will teach you to write functional code, but it's often highly indirect, deeply abstracted, requires understanding complex relationships between custom library calls, and doesn't represent the reality of how people actually write JavaScript.

The goal of this workshop is to create realistic problems that can be solved using terse, vanilla, idiomatic JavaScript.

Please read the exercises thoroughly and obey all conditions, they are there to help you learn!

Installation & Update

$ npm install -g functional-javascript-workshop@latest

Some npm installations require use of sudo in the above command. Recommend to instead reinstall node/npm so you don't need sudo.

Usage Instructions

1. Selecting a problem to work on

Once the workshop is installed, run functional-javascript-workshop to print a menu where you can select a problem to work on.

$ functional-javascript-workshop

Problems are listed in rough order of difficulty. You are advised to complete them in order, as later problems will build on skills developed by solving previous problems.

2. Writing your solution

Once you have selected a problem, the workshop will remember which problem you are working on. Using your preferred editor, simply create a file to write your solution in. Most problems will supply some boilerplate with which to get started. Copy this from the problem description to your solution file.

3. Testing your solution

Use the workshop's run command to point the workshop at your solution file. Your solution will be loaded and passed the problem input. This usually won't perform any validation, it will only show the program output.

$ functional-javascript-workshop run mysolution.js

4. Verifying your solution

Your solution will be verified against the output of the 'official' solution. If all of the output matches, then you have successfully solved the problem!

$ functional-javascript-workshop verify mysolution.js

Stuck?

Feedback and criticism is welcome, please log your troubles in issues.

Full curriculum reviews like this one are incredibly helpful. More feedback like this please!

We're looking for more practical problems, so if you come across a problem in your day-to-day work which was solved simply and elegantly with some functional JavaScript techniques, please help us create an exercise out of it.

Screenshots

screen shot 2013-09-27 at 5 18 45 pm screen shot 2013-09-23 at 9 13 02 pm

Resources

A growing collection of quality functional javascript resources can be found in the wiki.

Thanks rvagg

This tutorial was built using rvagg's workshopper framework.

Summary

 project  : functional-javascript
 repo age : 7 months
 active   : 50 days
 commits  : 152
 files    : 70
 authors  :
    69	Tim                     45.4%
    67	Tim Oxley               44.1%
     3	Sequoia McDowell        2.0%
     2	ZJ                      1.3%
     1	Naor Biton              0.7%
     1	Pavel Kornilov          0.7%
     1	Steve Teo               0.7%
     1	Wei Lu                  0.7%
     1	Yoshua Wuyts            0.7%
     1	flakyfilibuster         0.7%
     1	Arvid Andersson         0.7%
     1	tim walker              0.7%
     1	Brendon Murphy          0.7%
     1	Lorcan Coyle            0.7%
     1	Matthew Hokanson        0.7%

License

MIT

functional-javascript-workshop's People

Contributors

artem-karpenko avatar arvida avatar bemurphy avatar bluechili avatar brianmanden avatar chentsulin avatar ellipsis753 avatar finnp avatar flakyfilibuster avatar gitter-badger avatar hexicle avatar jhecking avatar lorcan avatar marocchino avatar martinheidegger avatar nbiton avatar orion- avatar satanas avatar sequoia avatar stevepotayteo avatar tdd avatar techdubb avatar timoxley avatar tongrhj avatar trott avatar twalker avatar weilu avatar xiaodaigh avatar yoshuawuyts 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  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

functional-javascript-workshop's Issues

Decide whether to tackle async

Should possibly go in another workshop, but as much as functional programming books like to ignore it, async is invariably an issue for js developers (esp. node). Would be good to at least touch on it.

Considering including problems:

  • Implement own async map (ensuring sort order makes things harder).
  • Use Async/map/reduce using async library.

Inheritance without Object.create.

Since the test doesn't check for other properties than the .name and .age (which are setup in the constructor), the trivial solution can be achieved by just not inheriting from User like so

module.exports = function(User) {
    function BetterUser() {
        User.apply(this, arguments);
    }

    BetterUser.prototype.toString = function() {return "[BetterUser: " + this.name + " (" + this.age + ")]"};

    return BetterUser;
}

The test can be improved to test for inheriting properties NOT defined in the constructor like so..

  User.prototype.isUser = function () {
      return true;
   }

  var BetterUser = extend(User)

  console.log('creating new BetterUsers:')

  console.log("new BetterUser('alice', 21)")
  var alice = new BetterUser('alice', 21)
  console.log(typeof alice.isUser == 'function' ? "Inherits from User" : "Doesn't inherit all from User" )
  console.log('')

I will make a branch of the working code I have.

Basic Recursion: Simpler solution

I may have found a simpler solution to the recursion problem:

function reduce(arr, fn, initial) {
    if (arr.length === 0) {
        return initial;
    }

    return fn(initial, arr.shift(), 0, arr);
}

module.exports = reduce;

I'm not sure how this solution compares to the one provided, perhaps it's less efficient, or maybe it doesn't work on all cases, but it makes more sense in my head, mostly because it seems a bit simpler. It also passes the test successfully.

Additionally, I had to read the problem description like 10 times before I thought I understood what was required.
i.e. Part of the description reads: "... and an initial value which will return an object containing the counts for each word found in the array ...".
That sounds like the initial value will return an object? So my first thought was: is the initial value a function as well?
Eventually I figured it out. Maybe I'm the only one that struggled with the description, otherwise, perhaps we could improve it slightly? Just a thought...

Trampolining operation()

In the given solution, the first time that

function repeat(operation, num) {
}

is called, no operation() is performed, since the actual operation() call is returned in the continuation being passed back. This seems puzzling.

Wouldn't it make more sense to perform an operation() for each call to repeat(), and just pass back the next step in the continuation? (i.e. move the operation() call up two lines?)

If, OTOH, I fail at understanding how this should be done, please be gentle :-)

Basic: Every Some, more efficent solution

Just working through your workshop. Thank you for creating it.

I stumbled across a solution which I think is actually more efficient - as soon as one bad user is found, it exits, rather than processing every single submittedUser:

module.exports = function checkUsersValid(goodUsers) {
  return function(submittedUsers) {
      return !submittedUsers.some(function(submittedUser){
          return !goodUsers.some(function(goodUser){
              return goodUser.id == submittedUser.id
          })
      })
  };
}

Make problem texts more consistent.

Use ##### around all headings.

e.g.
###############
## Resources ##
###############

Ensure there's Boilerplate

Decide on Input/Output headings.

Update to workshopper v1

I noticed that this was using a pre-v1 version of workshopper because the ACTUAL/EXPECTED output was harder to read.

Let me know if you're interested in switching over, I'd be happy to help.

make exercises more fun

create a 'scenario' for each one (keep it short though) perhaps we can tell some kind of post apocalyptic story set in space where PHP runs in the browser and windows is the only OS.

Better prototype introduction

Current one totally sucks.

Proposal: implement prototype inheritance in raw JS with:
New(Type, arg1, arg2, etc) (perhaps at first setting some pretend proto from Type.prototype) and prototype chain lookup with Lookup(context, propertyName) that uses the dummy chain.

update text for Partial Application with Bind

The problem text for Partial Application with Bind includes "Hint: console.log and Function#apply", this seems pretty confusing when the using bind makes it possible to avoid using apply. Also the problem still passes without making any changes to the code from the previous problem, not sure if this is avoidable or not.

I love the problems, and the sample solution does make the advantage of bind clear, so this is a pretty minor issue =)

The description of the Recursion problem is a little misleading

Implement a recursive function that prints all of the unique dependencies, and sub-dependencies of a module, sorted alphabetically.

I misunderstood that as we are supposed to print the result by

console.log(dependencies)

but the grader is actually expecting

return dependencies

Hope this will be fixed

Partial Application without bind (simpler solution)

Given the little understanding an user might have of the apply/call handling I think that the provided solution might be confusing. I would switch from :

var slice = Array.prototype.slice

  function logger(namespace) {
    return function() {
      console.log.apply(console, [namespace].concat(slice.call(arguments)))
    }
  }

  module.exports = logger

to something simpler like

var slice = Array.prototype.slice;

function logger(namespace) {
  return function(){
    console.log(namespace, slice.call(arguments).join(' ') );
  }
}

 module.exports = logger;

Any thoughts?

Illegible number literals

This workshop is awesome, and I learned a lot. I have one little issue, though. In the Windows Command Window (cmd.exe), the numberic literals are colored in a very dark blue. They are nearly illegible on the black background, and therefore should be somewhat lighter.

Thx!

Function Spies: preservation of 'this'

In the Function Spies exercise the official solution is:

function Spy(target, method) {
    var originalFunction = target[method]
    var result = {
      count: 0
    }

    target[method] = function() {
      result.count++
      return originalFunction.apply(target, arguments)
    }

    return result
  }

  module.exports = Spy

Isn't it better to have the 9th line as return originalFunction.apply(this, arguments) instead, to preserve the 'this' context in case the spied-on method might be called by unconventional means (call/apply etc)?

Need help getting started.

Hello,
Im completely new to this, just tell how to get going for the first hello world question.
Please post the answer here. I have done the following but I just get only errors.

module.exports= function(input){
var input="Lorem ipsum dolor sit amet";
var out = input.toUpperCase();
console.log(out);

}
I get some "expected ..." errors.
What should I do?

Offline Docs

I moved to a new apartment and I don't have internet yet. I downloaded the functional-javascript-workshop before I left my old apartment because nodeschool courses usually work offline, and I wanted something to do, but the docs are all MDN links (using my phone for docs).

Is this something I can help you with? When I get internet, I'll work on including some documentation and submit a pull request if you'd like.

Recursion: no tree is passed but an array

I'm writing the solution for "Recursion". And I can't test the solution because an array is passed as tree.
The value of tree is:

[ 'consequat',
'id',
'proident',
'exercitation',
'deserunt',
...
'et' ]

This is what I'm doing to show the value of tree:

function getDependencies(tree) {
  console.log(tree)
  return
}
module.exports = getDependencies

Thanks in advance for your help.

Inconsistent syntax for exporting functions

Some do this:

function repeat(operation, num) {
  // SOLUTION GOES HERE
}
module.exports = repeat

Some do this:

module.exports = function(input) {
  // SOLUTION GOES HERE
}

Some do this:

module.exports = function getShortMessages(messages) {
  // SOLUTION GOES HERE
}

There's not a functional issue here, and maybe these are intentionally written to expose the learner to multiple syntaxes for CommonJS exports, but I think this could trip up & confuse a beginner: "Why are there three ways to do this? Which one's better?" etc..

In my opinion either:
a) an explanation of modules/exports & their syntax should be included early on (probably via a lesson) or
b) these should all be standardized to one syntax, so the learner can focus on the lesson at hand and not "why is this boilerplate different from the last lesson"

I'm happy to fix these up and create a PR if such a change is welcome - just let me know. 👍

question about Basic:Recursion

I was fascinated by the solution of reduce function. Can anyone tell me about your thoughts here? How you analysis this problem and tackle it step by step? Thank you!

multi-step exercises

Exercises that perhaps have multiple 'levels of winning' of increasing difficulty/robustness/elegance.

Function Spies instructions say not to define any additional functions

The instructions for this exercise say that we do not need to define any additional functions, and I was stuck trying to do it with this condition.
When looking at the official solution, however, I see that it uses an anonymous function.
Would you be able to clarify the instructions for this problem in future?

Fix stumbling points

  • Fix bug in filter example
  • Make simpler reduce exercise to introduce concept
  • Add a chaining example with all functions supplied, just need to chain them up
  • Hint at chaining with .filter() and .map() in basic-filter exercise. (may be redundant if do previous item)
  • Make arguments/apply exercise to introduce Array.prototype.slice
  • Explain map/reduce/filter etc in the text and give an example as the simple mdn examples are hard to find or non-existent.
  • New exercise for Function.bind/call/apply and this
  • Remove second argument to map callback in reduce exercise or explain it better
  • Specify no for loops or additional functions required unless in boilerplate
  • Explain run/verify/menu process better?
  • Explain every method required for every exercise.

Currying Verification

Edited to avoid confusing innocent bystanders: the premises of this comment may be incorrect.

Partial application, if this is even partial application, passes the test for currying. To clarify, something like this will pass,

function notSureIfCurryOrPartialApply(fn, n) {
  n = n || fn.length

  return function(arg) {
    if (--n <= 0) return fn(arg)

    return notSureIfCurryOrPartialApply(fn.bind(fn, arg), n)
  }
}

which yields the expected result for addition but not division (maybe - see below).

P.S. Am loving this entire series. Thank you.

Every Some: checking on name passes sometimes, fails others

I wasn't reading the instructions carefully, so in my first go at it I checked on name and not on id. The submission passed sometimes and failed other times.

This may be intentional. If it is not intentional, would it make sense to make it fail all the time if you check on name instead of id?

Curriculum Review by @brianloveswords

Hello World

Before starting...

  • "$input", hmmm confused about this
  • "program" or "module"? Should I be exporting a function or writing a
    program that looks at process.argv?
  • META: there should probably be more explanation as to why I'm
    doing this. I don't yet understand what this has to do with
    functional javascript. NOTE that it doesn't necessarily have to
    do with functional js, but some text saying "hey, this is just to
    get your feet wet, make sure you got the basics, etc" would be great!

During...

  • Okay, I'm trying process.argv[2]. I'm getting back a string, but
    that string is wrapped in quotes. That's weird, but maybe okay?
  • Verify doesn't like it. It looks like I'm getting the right
    string, but verify wants it without the quotes.
  • I guess I'll just .replace(/"/g, '') the string, even though I
    know that's not not correct, just so I can see what the solution is.

After finishing...

  • AH okay, so $input is a global that gets injected into the
    script. That is weird to me – I think it'd be better if either
    A) it used (and expected) process.argv[2] OR
    B) it expected a module with exactly one function that does what is expected.
    • But to counter my own point, this is functional javascript not
      functional node.js. So maybe the global injection is the right
      move? Not sure...

Higher Order Functions

Before starting...

  • Ah ha, so I see the global injection is going to be a common
    theme. I don't really like that – it feels to magical, I like the
    method used in levelmeup of building modules or taking things
    on argv. This isn't a dealbreaker by any means, but I think it
    does encourage better real-world practices.

After finishing...

  • Oh, I solved it totally differently:

     function repeat(fn, n) {
       if (n <= 0) return;
       fn()
       return repeat(fn, --n)
     }
    
     repeat($operation, 5)

    I do feel like this might be slightly less "clever" – and it
    teaches good recursion principles (always check your end
    condition first, always make sure your input converges on the end
    condition).

Basics: Map

Before starting...

  • The introduction could use a little more explanatory text as to
    what a map is and why it's useful – something like the following:

    "We often have to take a set of data and modify it before we
    output it. For example, say we get this back from our database:
    [{first: 'Brian', last: 'Brennan'}, {first: 'Alex', last:
    'Sexton'}]

    And we want a list of full names. We can do this with a for loop,
    but we have to manually keep track of indices and push to a new
    array on our own. A better way to handle this is by using a
    map. A map is a higher order function that operates each
    element of an array and returns a new array with each element
    transformed

    So to get our list of full names, our mapping function would be:
    function fullName(item) { return item.first + ' ' + item.last }

    And we'd call it like so: var fullNames = entries.map(fullName)

    Notice that the map function returns a new array – it doesn't
    modify the array in place. This is a very important principle in
    functional programming: it's always better to take input and
    return new output rather than modify things in place.

    Your exercise is to take an array of numbers and return a new
    array with each number replaced by itself * 2..."

After finishing...

  • I think this might be cleaner and help illustrate the power of
    passing function references around

     function double(n) { return n * 2 }
     console.log($input.map(double))

    I think the solution could also then explain the power of
    creating small, generically useful functions and then using them
    in maps to transform sets of data.

Basics: Filter

Before starting...

  • [workshopper] – is there a way to get code fences working in
    workshopper so that when the instructions are printed out the
    things fenced in ```js are syntax highlighted? (That'd be a rad
    module, and there's like a 90% chance substack has already
    written it).

After finishing

  • Again, I like seperating out the functions rather than using
    anonymous functions:

     function isShort(txt) {
       return txt.length < 50
     }
    
     function getMessage(obj) {
       return obj.message
     }
    
     function getShortMessages(arr) {
       return arr.map(getMessage).filter(isShort)
     }
    
     console.log(getShortMessages($input))

    I think it better illustrates composition.

Basics: Reduce

Before starting...

  • Some illumination for why a reduce is useful would be
    good. Perhaps even something that explains it in terms of mapping:

    "A reduce (also known as a "fold left") is useful when you want
    to take a bunch of values and turn it into just one. A good
    example of this is taking the sum of a series:

     [1,2,3,4,5].reduce(function sum(accum, value){
       return accum + value
     }, 0) // 0 + 1 + 2 + 3 + 4 + 5 = 15

    The first argument to the reduce functor is known as the
    accumulator – this keeps track of a value as the functor
    processes values. The second argument to .reduce is known as
    the seed value. This is useful for priming the accumulator so
    the functor doesn't have to do conditional checking against it to
    see whether or not it's the first value.

    It's important to choose the correct seed value for the operation
    you are performing! For example, 0 works well for addition, but
    if we wanted to get the factorial rather than the sum, we would
    want to use 1 instead:

     [1,2,3,4,5].reduce(function factorial(accum, value){
       return accum * value
     }, 1) // 1 * 1 * 2 * 3 * 4 * 5 = 120

    (Fun fact: this has to do with 0 being the identity value for the
    addition operation and 1 being the identity value for the
    multiplication operation [citation needed])"

  • Woah, the boilerplate is confusing to me! I think to properly
    explain reduce, the operation needs to be transparent – I think
    part of doing reduce properly involves selecting the proper
    seed. That's an important lesson to teach, and one that gets
    obscured if the operation is opaque. It's also a lesson about
    reduce but the boilerplate function says map.

    • AH I missed the part "i.e. Use Array#reduce to implement
      Array#map." – I think this is should be after a basic reduce
      lesson. This is more advanced reduce, I think.

After finishing...

  • I felt cheated by the "extra credit". None of the previous
    lessons taught the optional arguments, and the lesson instructions
    didn't say that we were supposed to implement
    Array.prototype.map exactly. The function signature in the
    "boilerplate" is also indicating that we should only implement
    something with 2-arity.
  • Again I think the solution is too clever – I'm not sure we should
    expect people to understand fn.call and fn.apply unless we
    make a lesson about it earlier on.

Partial Application without Bind

Before starting...

  • Should probably explain partial application a little bit
    first. Remind people about higher-order functions and tell them
    that in this case, we want to make a function that takes input and
    returns a new function.
  • If people have to do that argument variable "turn to a real array"
    hacking, that might be A) be a bad thing, or B) need to be
    explained.

After finishing

  • Yeah, doing the arguments trick without explanation isn't
    great. This should either be explained in an earlier lesson (along
    with call and apply), or there should be a solution that doesn't
    require it. I vote for the former. Here is my solution for
    reference, though I think the published one is probably better
    because Array.prototype.concat is rad and I don't use it nearly
    enough.

     function logger(namespace) {
       return function logFn() {
         var args = [].slice.call(arguments)
         args.unshift(namespace)
         return console.log.apply(console, args)
       }
     }
    
     $test(logger)

Partial Application with Bind

Before starting...

  • Function arity should be explained (in an earlier lesson)

After finishing

  • Pretty good!

Function spies

Before starting...

  • I think the purpose of spies – testing, debugging – should be
    explained upfront. Also that spies should probably only be used
    for testing, debugging because the behavior is opaque to anyone
    down the line. (I am very open to debate on this issue!)

After finishing

  • Ah, I was confused by the naming – Spy with an uppercase S – and
    I was expecting to build a constructor. I guess in a way it is?
    I'm torn on this one. My solution was this:

     function Spy(object, methodName) {
       if (!(this instanceof Spy))
           return new Spy(object, methodName)
    
       this.count = 0
       var originalFn = object[methodName]
    
       object[methodName] = function secretAgent() {
         this.count++
         return originalFn.apply(object, arguments)
       }.bind(this)
     }
    
     $test(Spy)

Conclusion

This is awesome. I think with some interstitial lessons about call
and apply, maybe one about reduce before implementing map with
reduce, this can be a super rad workshopper! I'm definitely willing
to help with creating/editing the intro text to add more
theory/reasons behind why someone would want to use FP techniques in
JS – I think that's important. Thank you so much for getting this
started!

TypeError: object is not a function

In Functional Javascript's » Higher Order Functions problem, I keep getting a "TypeError: object is not a function" error.

If I simply node run the following version of my answer, it runs as I expect

function repeat(operation, num) {
    if (num > 0) { 
        operation(num);
        return repeat(operation, num-1);
    };
}

function operation(num){console.log(num)};

repeat(operation, 5);

But if I strip out the feedback in the operation function, thusly:

function repeat(operation, num) {
    if (num > 0) { 
        operation();
        return repeat(operation, num-1);
    };
}

function operation(){};

repeat(operation, 5);

... and run it as functional-javascript run HOF.js, then I get the following terminal feedback:

undefined:2
  repeat(input[0], input[1])
  ^
TypeError: object is not a function
    at out (eval at <anonymous> (/usr/local/lib/node_modules/functional-javascript-workshop/input.js:14:29), <anonymous>:2:3)
    at Function.module.exports.init (/usr/local/lib/node_modules/functional-javascript-workshop/input.js:41:3)
    at Object.<anonymous> (/usr/local/lib/node_modules/functional-javascript-workshop/node_modules/workshopper/exec-wrapper.js:5:5)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:902:3

As I understand it, repeat is a function, as demonstrated in the first example. So why am I being told it's not a function when I try to run it as functional-javascript run?

rename the executable to repo name

maybe change repo name to something cooler, or maybe just create alias fjw, but having functional-javascript as the executable is bad.

Blocking Event Loop Boiler Plate Passes

I pasted the boiler plate code for the blocking event loop challenge and decided to see what would happen, and it passed!

Aside from that obvious problem, I'm confused by this challenge in other ways. I read about timers in general and setTimeout() specifically, but even after seeing the (real) solution, I don't understand what setTimeout() does in this context. I'm familiar with its use and what its purpose is, but I don't understand what setTimeout does to the event loop and why it is being used as it is or what a real world use case for this type of thing would be.

combinators exercises

get people to derive the combinators themselves, then in other exercises have them passed in so they can use them to achieve some goal.

async loop solution does not pass

I use your solution code for async-loops but still does not pass. The exercise (run or verify) haaaangs.

code:

function loadUsers(userIds, load, done) {
  var completed = 0
  var users = []
  userIds.forEach(function(id, index) {
    load(id, function(user) {
      console.log(user) // logs out one or two user objects
      users[index] = user
      if (++completed === userIds.length) return done(users)
    })
  })
}

module.exports = loadUsers

not passing for me

Higher Order Function

Higher order function:

stdin code:

var foo, bar, foobar, path;

path = require("path");
/*
Had to require the path module to require the module
 --which the code is shown below this code-- 
to run the program to make sure everything is working
*/
foo = require(
path.join(process.argv[1], "/../", "functional-javascript/",
"./", "program1module.js"));
function bar(x){
    return(console.log(x));
}

console.log(foo("function", 0));

module code:

            if(y >= 8){
                return;
            }else{
                console.log("Called function " + y + " times.");
                y++;
                arguments.callee("function", y);
            }

stdout:

l2l2l@starter:/home/ubuntu/workspace $ functional-javascript verify functional-javascript/program1.js
Verifying "Higher Order Functions"...

ACTUAL                             EXPECTED
------                             --------
"Called function 1 times."         "Called function 1 times."     
"Called function 2 times."         "Called function 2 times."     
"Called function 3 times."         "Called function 3 times."     
"Called function 4 times."         "Called function 4 times."     
"Called function 5 times."         "Called function 5 times."     
"Called function 6 times."         "Called function 6 times."     
"Called function 7 times."         "Called function 7 times."     
"Called function 8 times."         "Called function 8 times."     
"undefined"                     != ""                             
# FAIL

Your solution to Higher Order Functions didn't match the expected output.
Try again!
l2l2l@starter:/home/ubuntu/workspace $ 

I keep getting undefined at the end.
Note: I cut and clean the code up to peresent
to you. If you would like to see the original
code, just ask. I did something interest with the ternary.

Couple of typos

A couple of typos I've found in the course:

In blocking_event_loop/setup.js, the test code performs the operation 100,000 times but afterwards only checks if count === 10000 I guess this is a typo.

Also, in the description for "Function Call", it has this example at the end:

var myFunction() {
  console.log('called my function')
}

Function.prototype.call.call(myFunction) // => "called my function"

I think that first line's meant to be: function myfunction() {

higher order function js error

Hi,

Can you tell me why I am getting this error..
i dint show me any error in run command..
but when i verify it failed
providing my code below in the fiddle..

http://jsfiddle.net/utbsgnzu/2/

C:\Users\Desktop> functional-javascript-workshop verify higher-order.js
Verifying "Higher Order Functions"...

ACTUAL EXPECTED


"testing" != "Called function 1 times."
"testing" != ""
"testing" != null
"testing" != null
"testing" != null
"testing" != null
"testing" != null
"testing" != null
"testing" != null
"Called function 1 times." != null
"" != null

FAIL

Excercise markdown not rendering

Is the markdown here supposed to be rendered? This:

Arguments:

* messages: an Array of 10 to 100 random objects that look something like this:

```js

{
  message: 'Esse id amet quis eu esse aute officia ipsum.' // random
}

```

It's not rendering for me (fedora/putty/windows). Is this a workshopper issue?

funk

State that recursive reduce doesn't need to cater for undefined init (07 Basic: Recursion)

The initialValue argument in the standard Array reduce method is optional, and the method's behaviour in both cases (present vs. absent) is documented in the problem's Resource link.

In Problem 7 (Basic: Recursion) it's not explicitly specified (or maybe it's not clear enough) that our implementation of reduce need not replicate initialValue's optionalness. Some users may mistakenly assume their solution must cater for a potentially missing initial value, since the spirit of the question seems to be about fully replicating Array.prototype.reduce's functionality (this mistaken assumption increased the problem's difficulty for me).

Past me would have preferred if either:

  1. There is a line such as "init: Initial value of the reduction. Unlike regular Array#reduce you can safely assume that this value is definitely provided", or
  2. The final solution is able to correctly handle undefined init arguments.

As it stands the current solution will break if init is not specified. Here is a test case:

// Run `node <filename>.js` on this file.

// 1. This is the official solution for functional-javascript 07) Basic Recursion.
function reduce(arr, fn, initial) {
  return (function reduceOne(index, value) {
    if (index > arr.length - 1) return value
    return reduceOne(index + 1, fn(value, arr[index], index, arr))
  })(0, initial)
}


// 2. Setting up a comparison between our recursive reduce and the standard array reduce.
var testData = [1, 5, 2, 7, 1, 9]
var testFunction = function(prev, curr) {
  return prev + curr
}

var tests = [
  "reduce(testData, testFunction)",
  "reduce(testData, testFunction, 0)",
  "reduce(testData, testFunction, 10)",
  "testData.reduce(testFunction)",
  "testData.reduce(testFunction, 0)",
  "testData.reduce(testFunction, 10)"
]

tests.forEach(function(entry) {
  console.log("Here's the value of " + entry + ": " + eval(entry))
})


/* 3. Generates the following output. There is a discrepency when no initial value is supplied (lines 1 & 4).
Here's the value of reduce(testData, testFunction): NaN
Here's the value of reduce(testData, testFunction, 0): 25
Here's the value of reduce(testData, testFunction, 10): 35
Here's the value of testData.reduce(testFunction): 25
Here's the value of testData.reduce(testFunction, 0): 25
Here's the value of testData.reduce(testFunction, 10): 35
*/

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.