4 kyu

Default Arguments

1,252 of 1,326xcthulhu
Description
Loading description...
Functional Programming
Metaprogramming
  • Please sign in or sign up to leave a comment.
  • jerrybuks Avatar

    hey guys, whenever add_ is called it keeps using old defaults, any idea whats wrong

  • piakapi Avatar

    This comment has been hidden.

  • jpssj Avatar

    This comment has been hidden.

  • toadslop Avatar

    This requires accessing the closure to get values accessible to the function in its closure scope. This does not appear to be possible with modern JavaScript. I spent several hours researching this and the answer that I got from any resource more recent than a year old is "this is not possible".

  • Tariqali13 Avatar

    function add(a,b) { return a+b;};

    var add_ = defaultArguments(add,{b:9}); add_(10); // returns 19 add_(10,7); // returns 17 add_(); // returns NaN

    add_(10); // returns 13 now add_(); // returns 5

    add_(10,10); // returns 20

    That's my solution which passed all the tests except getting this error any one know? should work on a func without a name

  • liorean Avatar

    This comment has been hidden.

  • mediv0 Avatar

    good kata! thanks

  • Blind4Basics Avatar

    the description is missing most of the weirdest requirements... x/

    • needs to handle comments in the arguments (SSsssseriously...?)
    • needs to handle undefined passed as a used argument
  • Voile Avatar

    Oh yeah, this kata needs random tests.

  • mbahSimak Avatar

    This comment has been hidden.

  • andres-uris Avatar

    This comment has been hidden.

  • maxgonzalez Avatar

    I got this to work for every case, except for the one with the closure. Are there any lesser known functions or properties out there that might be helpful in dealing with this? I understand exactly why my approach isn't working with a closure, but I'm at a total loss as to how I can make it work with one. I don't want to give up yet, but if anyone has any resources about specific things I should maybe know about, it would be appreciated.

  • crankaman Avatar

    There's a typo in the HINT. Should say "Function".

  • johnsmith0209 Avatar

    This comment has been hidden.

  • NagyBandi Avatar

    Hi, I'm a bit unclear on the exact specification. What should it do if the number of arguments supplied when calling the returned function is higher than the number of "defaultless" arguments, but lower than the total number of arguments? Should it start filling them in from the first argument, or first fill in the defaultless ones and somehow proceed with the others?

    Example: if I have a function add4(a, b, c, d) { return a + b + c + d; } and add4WithDefaults = defaultArguments(add4, {a:1, c:3}); , then what should add4WithDefaults(2, 4, 5) return? Should in this case make it a = 1, b = 2, c = 3, d = 4 and disregard the third argument? Or should it be a = 2, b = 4, c = 3 and d = ??? (resulting in NaN)? Neither seems right.

  • husheric Avatar

    I'm getting this error on test 23 it says ReferenceError: five is not defined at eval at /home/codewarrior/index.js:90:52 at /home/codewarrior/index.js:115:5 at Object.handleError and the func passed into default arguments is var timesFive = function () { var five = 5; return function (a) { return five * x; }; }(); function (n) { return five * n; } which seems wrong.

  • Tipster Avatar

    Are these tests correct? I fail at 4 of them which are passing when I try it on the sample tests and they seem very common with the others, can't figure out what the issue is

  • osofem Avatar

    How does func function (_id) { return _id; } and params { _id: 'test' } returns undefined? I believe that should have returned test. The only test failing.

  • hufftheweevil Avatar

    Initial thought: 'What a silly kata. What's the point of this? :/' Final thought: 'What a fun and interesting kata! :D'

  • Voile Avatar

    This comment has been hidden.

  • ovvn Avatar

    There's a typo in the HINT "Fuction.prototype.toString()" should be changed to "Function.prototype.toString()"

  • IRus Avatar

    This comment has been hidden.

  • user5200009 Avatar

    This is a fool's kata as it requires Function.prototype.toString. You cannot depend on the names of the parameters in JavaScript. Especially with common use of tools like Babel and Uglify.

  • leevigilstroy Avatar

    I think the (undefined) test is bs. great problem otherwise though. Thanks

  • saadtazi Avatar

    I have the exact same problem as gbedardsice (see below): I think test #29 is wrong. The arguments for that test are (when I add some logs):

    >>>func: function (_id) { return _id; }
    >>>params: { _id: 'test' }
    

    The assertion failure is: defaultArguments(id,{id:"test"})(undefined) - Expected: undefined, instead got: test

    So it seems that "something" is replacing {id: 'test'} by {_id: test}?

    Note: I tried with node 6 and node 0.10: same issue.

  • mickeyboston Avatar

    so this i found a small mistake in your test case

    function add(a,b) { return a+b; } var add_ = defaultArguments(add,{b:9}); Test.assertEquals(add_(10), 19); Test.assertEquals(add_(10,5), 15);

    This here var add_ = defaultArguments(add_,{b:3});

    should have not a add_ as an argument but just add because add_ was already created var add_ = defaultArguments(add,{b:9}); that's why I am getting NaN in my final test.

    Test.assertEquals(add_(10), 13);

    the Same thing is probably in final test case set, I would tell for sure but Kata doesn't let me through;

  • user6361752 Avatar

    Got no honor for solving this kata, y?

  • mickeyboston Avatar

    Yes Tests won't pass at all I don't know maybe it is es6 but my jsbin tells me I did my code right. This was a fair challenge but for tests. So One more time - testing your cases by hand I have absolutely correct results but half an hour ago the last one of final tests told me expected - 13 got 19 and after another half an hour he said he gets NaN. Though I don't get those in my console. Do something with your tests finally!!

  • ipalladin Avatar

    It is a mistake in last chek in var add_ = defaultArguments(add_, {b:3}); Test can not pass with what params (add_, {b:3})!!!!

  • fden Avatar

    I am failing at test case 23 and looks like the it is failing for function

    var timesFive = function () { var five = 5; return function (a) { return five * x; }; }();
    

    I am getting x is undefined error.

    I do not know how it is invoked but isn't it "return function (x)" instead of "return function (a)"? Please check.

    It is a great kata and helped me learn some less known components in javascript (y)

  • gbedardsice Avatar

    This comment has been hidden.

  • plainOldCode Avatar

    this kata smash my head. I do not know javascript!

  • hhz_plst Avatar

    This comment has been hidden.

  • BruceLee Avatar

    I'd suggest adding the following test case:

    function add(a,b) { return a+b; }
    var add_ = defaultArguments(add,{a:2,b:3});
    // a's default value is still 2, b's, of cause, 10
    add_ = defaultArguments(add_,{b:10});
    Test.assertEquals(add_(), 12);
    

    Which is used to test overriding of default values.

  • imanuelr Avatar

    I'm all the way down to test 28. Where the function declared is var id = function (id) { return id; } But when I print the given function I actually get function id(_id) { return _id; } The argument passed into the defaultArguments is { id: 'test' } My first question is: Is there a special meaning to parameters prefixed with _?

    Second, when I work around this test by ignoring any _ prefix. The second test which calls the exact same function, and passes the exact same argument into defaultArguments expects the method not to return a default. Is this a broken test or am I missing something?

    My test output with some logging: var id = function (id) { return id; }

    function id(_id) { return _id; } Args: { id: 'test' } Test Passed: Value == test

    function id(_id) { return _id; } Args: { id: 'test' } defaultArguments(id,{id:"test"})(undefined) - Expected: undefined, instead got: test

  • hbakhtiyor Avatar

    When I refactored my solution, got failed with this test case. Even with my past solution!

    console.log("var id = function (id) { return id; }");
    var id = function (id) { return id; }
    Test.assertEquals(defaultArguments(id,{id:"test"})(), "test", 'defaultArguments(id,{id:"test"})()');
    

    I got this function declaration with console.log

    function id(_id) {
    return _id;
    }
    
    defaultArguments(id,{id:"test"})() - Expected: test, instead got: undefined
    
  • user7973327 Avatar

    Wow...I thought I got the answer until 'timesFive' and 'closure_counter' cases.

    Can anyone point me in the right direction to pass these test cases?

    Thanks in advance!!

  • ralphcallaway Avatar

    This comment has been hidden.

  • kevrom Avatar

    This comment has been hidden.

  • Dolphin_Wood Avatar

    I suggest adding test case for variable length arguments like this :

    function add() {
        return [].slice.call(arguments).reduce(function(p, c) {
            return p + c;
        }, 0);
    }
    
    var add_ = defaultArguments(add);
    Test.assertEquals(add_(1,2,3), 6);
    
    add_ = defaultArguments(add_);
    Test.assertEquals(add_(2,3), 5);
    
  • MentalAtom Avatar

    This was an awesome challenge! I got there in the end, but looking at some of the solutions I went a bit OTT...

    It's totally against best practices, but that makes it all the more interesting!

  • computerguy103 Avatar

    This is possible, but it's really poor form to even try to do this IMHO.

    You're not supposed to care what a function's arguments are named. Nothing outside of add should care whether it calls its 1st argument a or its 2nd argument b. Javascript itself makes it really annoyingly hacky and ugly to get the names of a function's arguments (the fact that you have to grep its toString should be your clue).

    Furthermore, you're relying on a language syntax that might change in the future, breaking all of your code. Trying to get the argument names from toString will be even further complicated when the ECMAScript 6 proposal is adopted and Javascript allows default values in function definitions, such as function add(a,b=9){return a+b;} (only Chrome and Firefox currently support this syntax).

    The "best practice" way to do this would be if defaultArguments didn't care about the names of the arguments, and you just passed it an array, similar to how you'd call apply(thisObj, arguments):

    function add(a, b) { return a + b; }
    var add_ = defaultArguments(add, [, 9]);
    add_(10); // returns 19
    add_(10, 7); // returns 17
    add_(); // returns NaN
    

    Or you could do something with the Function prototype, like:

    add.applyDefaults(this, [10], [, 9]); // returns 19, similar to add.apply(this, [10, 9]);
    var add_ = add.applyDefaults([, 9]); // returns a function which implements add with defaults of [, 9]
    add_(10); // returns 19
    
  • sra448 Avatar

    This comment has been hidden.

  • Arheus Avatar

    Now THAT was challenging and interesting! Kudos on an excellent kata!

  • scopevale Avatar

    It would be nice if someone would respond to my plea for help!

  • scopevale Avatar

    Help please I'm stuck on this, I have it working for all test cases where the function params are (a, b) - because I define my returned function as

    return function (a, b) {

    But when the params are (x, y) for example it fails unless I change it to return function (x, y) { - I cannot work out how to abstract the returned function parameters

    I can post my solution if necessary

  • scheffield Avatar

    Hi, cool kata. As some already mentioned, the function.toString method is not widely known. I know that something is possible due to the use of AngularJS. I think you should mention this as a hint.

    Additionally, the last test is a little bit mean. It is a kata for its own.

    Aaand just one note to the description: I think it's a hash or object and not a JSON. JSON would look like {"c": 3}

  • ferlio Avatar

    Hello guys,

    @xcthulhu, nice kata!
    But could you please explain this part? add_ = defaultArguments(add_,{b:3, a:2});

    I'm having some trouble in understanding why add_ is being called here.
    Am I supposed to extract the callback from a previously declared variable?

    Thanks!

  • Charlespwd Avatar

    The solution has got to be witchcraft.

  • qed2000 Avatar

    OK, this has gotten ridiculous! I just failed a test with: function add2(x,y) { return x+y; } ; add2_ = defaultArguments(add,{y:9})

    For the love of God, add doesn't take a y, so why is NaN wrong for add2_(10)?!?

  • cjuehring Avatar

    I have been defeated.

  • stevematney Avatar

    This comment has been hidden.

  • lloop Avatar

    Someone please throw a dog a bone. Hung up on the nested test. Just a keyword to search for? I'm stuck.

  • joechee Avatar

    This comment has been hidden.

  • tonygoold Avatar

    I think line 5 in the test case has a typo:

    var add_ = defaultArguments(add_,{b:3});
    

    Considering add_ is my function and doesn't have any named arguments, it doesn't make sense. Unfortunately, that test also appears to be part of the acceptance test for the solution, so my only option is to 'cheat'.

  • kharandziuk Avatar

    Can somebody explain, why add_() should returns undefined when add() returns NaN?

  • taralx Avatar

    This comment has been hidden.

  • jacobb Avatar

    Okay, now I'm hung up on nesting.

  • jacobb Avatar

    I'm wondering whether this may be easier than I first assumed. Do the defaults always apply to the first n arguments, or if you had arguments of (a, b, c) could you set defaults to a and c, but not b? And if you called the defaultArgs version with values for all three, would the defaults be filled in first or the original ordering?

  • young-steveo Avatar

    If you want to ratchet up the difficulty one notch, add a test case with comments in the function definition:

    function addComments(/* comments */ a,b) { return a+b; }
    var addComments_ = defaultArguments(addComments,{b:9});
    Test.assertEquals(addComments_(10), 19, "addComments_(10)");
    
  • OverZealous Avatar

    This comment has been hidden.