4 kyu
Default Arguments
1,252 of 1,326xcthulhu
Loading description...
Functional Programming
Metaprogramming
View
This comment has been reported as {{ abuseKindText }}.
Show
This comment has been hidden. You can view it now .
This comment can not be viewed.
- |
- Reply
- Edit
- View Solution
- Expand 1 Reply Expand {{ comments?.length }} replies
- Collapse
- Spoiler
- Remove
- Remove comment & replies
- Report
{{ fetchSolutionsError }}
-
-
Your rendered github-flavored markdown will appear here.
-
Label this discussion...
-
No Label
Keep the comment unlabeled if none of the below applies.
-
Issue
Use the issue label when reporting problems with the kata.
Be sure to explain the problem clearly and include the steps to reproduce. -
Suggestion
Use the suggestion label if you have feedback on how this kata can be improved.
-
Question
Use the question label if you have questions and/or need help solving the kata.
Don't forget to mention the language you're using, and mark as having spoiler if you include your solution.
-
No Label
- Cancel
Commenting is not allowed on this discussion
You cannot view this solution
There is no solution to show
Please sign in or sign up to leave a comment.
hey guys, whenever add_ is called it keeps using old defaults, any idea whats wrong
This comment has been hidden.
This comment has been hidden.
Bad regex.
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".
it doesn't, and it is. (anyone reading in future should ignore)
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
This comment has been hidden.
good kata! thanks
the description is missing most of the weirdest requirements... x/
Oh yeah, this kata needs random tests.
This comment has been hidden.
This comment has been hidden.
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.
There's a typo in the HINT. Should say "Function".
This comment has been hidden.
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.
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 isvar timesFive = function () { var five = 5; return function (a) { return five * x; }; }(); function (n) { return five * n; }
which seems wrong.No.
You're not handling closures correctly.
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
Yes
How does func
function (_id) { return _id; }
and params{ _id: 'test' }
returnsundefined
? I believe that should have returnedtest
. The only test failing.When you get an error, you don't see the following tests. There are more tests after that. You probably solved this one but it is for others on the website.
Initial thought: 'What a silly kata. What's the point of this? :/' Final thought: 'What a fun and interesting kata! :D'
This comment has been hidden.
Added
There's a typo in the HINT "Fuction.prototype.toString()" should be changed to "Function.prototype.toString()"
This comment has been hidden.
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.I think the (undefined) test is bs. great problem otherwise though. Thanks
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):
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
andnode 0.10
: same issue.this is how babel compiles the code and is not an issue. You shouldn't have to create a special case to get around this..
Thanks for your reply. The test is expecting
undefined
... I am probably missing something, but I think that iffunc
isfunction (_id) { return _id; }
andparams
is{ _id: 'test' }
, thendefaultArguments(function (_id) { return _id; },{_id:"test"})
should equaltest
?because undefined is passed into the parameter
_id
Got it! Thank you so much for your help.
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;
I think this is to test that
You should be able to call defaultArguments repeatedly to change the defaults.
(from kata detailed instruction).Got no honor for solving this kata, y?
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!!
post your solution below and mark it as a spoiler so someone can help you :)
This comment has been hidden.
Not an issue
It is a mistake in last chek in var add_ = defaultArguments(add_, {b:3}); Test can not pass with what params (add_, {b:3})!!!!
I am failing at test case 23 and looks like the it is failing for function
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)
I have the same problem. Would someone help us?
What happens when you call toString on timesFive? You'll find it doesn't give "var timesFive = function () { var five = 5; return function (a) { return five * x; }; }();" so you'll need to find a solution that does.
It should be
var timesFive = function (x) { var five = 5; return function (a) { return five * x; }(x); };
. The test case is incorrect.What is the expected behavior of this test case? return NaN or throw exception?
No. This test case means that you also need to handle closures properly, i.e you shouldn't just create a new function and call it; you need to call the original function.
Even if you passed this test case, there are more tests that plays with closure. For example, this is the test after the above test case:
This comment has been hidden.
I am blocked with the exact same problem (reported today)... I am wondering if you are still blocked?
this is how babel compiles the code.
this kata smash my head. I do not know javascript!
This comment has been hidden.
I'd suggest adding the following test case:
Which is used to test overriding of default values.
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
Hey looks like there was an issue created by ES6 transpilation for one of the test cases, you can see the comment below for the resolution.
I think you were real close to finishing it, try submitting again :). Good luck!
When I refactored my solution, got failed with this test case. Even with my past solution!
I got this function declaration with
console.log
Very strange! When I run these codes, got different param names
All these codes run in the CW platform
Please help investigate it. Thanks. I also have similar problems.
Me too
+1
Ah, good call. Looks like adding ES6 transpilation messed that test case up.
In babel, it will rename your variables if your function and variable names match. You can check it out in action here: https://babeljs.io/repl/#?experimental=false&evaluate=true&loose=false&spec=false&code=var%20id%20%3D%20function(id)%20%7B%0A%20%20return%20id%3B%0A%7D
Fixed the test case so this should no longer be an issue.
I see no way to handle both 29th and 28th test case.
Having the same problem. Is there a way to get non-transpiled name of arguments? I don't see any.
I'm having the same problem. The test case isn't fixed.
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!!
Any hints? I'm stuck at
timesFive
This comment has been hidden.
This comment has been hidden.
Not an issue
I suggest adding test case for variable length arguments like this :
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!
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 argumenta
or its 2nd argumentb
. 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 itstoString
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 asfunction 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 callapply(thisObj, arguments)
:Or you could do something with the Function prototype, like:
The usual way to do this now seems to be using an object at the end of the arguments to store named arguments, kind of like
kwargs
dict in Python.Yeah, passing an object with key-value pairs would be the easiest (and proper) way to give a function "named arguments". I.e., you'd change the function from
function fnname(arg1, arg2)
tofunction fnname({arg1, arg2})
, and change the code that calls it fromfnname(val1, val2)
tofnname({arg1: val1, arg2: val2})
.However, the kata challenge here was to hotfix a pre-existing function that takes ordinary arguments, so it implies that you can't or aren't supposed to modify the function... you're just supposed to wrap it in a new anonymous function that figures out what arguments it expects and provides defaults.
This comment has been hidden.
How did you determine the arguments to the original argument in the first place?
What can you so that will work again?
Nice, thank you. I'm stuck though because the defaulted function I built doesn't excpect any particluar arguments. Using eval I could write the defaulted function with the parametersignature of the original, but that wouldn't be right, would it? :)
You might consider involving .toString() somehow (like I mention in the hint)
This comment has been hidden.
None of them?
I wrote this kata more than a year ago when I was first learning angular, which has this hackery built-in and center-place.
Now it's the future and I reject the idea that's it's good to use this crazy trick for anything.
Production code should be short, easy to read, and boring, like a Malcolm Gladwell novel. Not like this.
Now THAT was challenging and interesting! Kudos on an excellent kata!
It would be nice if someone would respond to my plea for help!
This is a 4 kyu kata. If you are completely stuck, perhaps you should consider doing some of the katas closer to your current kyu. If you still wish to proceed, then read the description carefully. It tells you how to extract the arguments from a function.
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 parametersI can post my solution if necessary
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}
I changed the description not to mention JSONs.
I already have the following hint in at the bottom of the description:
Is this okay?
Oh sorry, my fault. I missed that very line :/
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!
Well, if you change create some default arguments, you should be able to change them again if you change your mind.
You could try to extract the original
add
function somehow, but there are other approaches.The solution has got to be witchcraft.
It's not witchcraft. Just think:
Google around. Maybe this kata should be a 3 instead of a 4?
I've only solved four or five 4kyu problems at this point, but IMO the last test I can see (timesFive) pushes this into 3 territory. One man's opinion.
Now that I see test 25... :-O
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)?!?
Typo on my part. I changed the test output to read:
add2(x,y) { return x+y; } ; add2_ = defaultArguments(add2,{y:9})
Makes more sense?
I failed
I have been defeated.
Do you need help?
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
This comment has been hidden.
I don't think I can show you the solution since it hasn't been completed, yet. Apparently I'm doing this wrong, but I'm not sure how to do it correctly. :/
This comment has been hidden.
@schyzoo: I'm really pleased you totally get the spirit of my kata.
@stevematney: You can always post a partial solution if you want. Javascript has some functional programming bits, like the fact that a variable that is needed for a functions behavior might be defined in a scope that is neither global nor local to the function. Part of the challenge of this kata is that you aren't allowed to break these features.
Someone please throw a dog a bone. Hung up on the nested test. Just a keyword to search for? I'm stuck.
This comment has been hidden.
Okay, I'll try to add it to the tests
A little late, but done.
I think line 5 in the test case has a typo:
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'.I think that's part of the challenge.
After my latest revisions to the test suite, this doesn't work anymore.
Can somebody explain, why add_() should returns undefined when add() returns NaN?
Typo on my part. I was just checking that
add()
as falsy, but I now I check that it is NaN.This comment has been hidden.
This comment has been hidden.
Okay, so I test these now, and I also test the case of an empty param list. I use a variety of variable names, so I really don't think that having hard-coded variables
['a','b','c']
will work...Okay, now I'm hung up on nesting.
I did it!
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?
The example show that 'b' can be set a default in an argument list of "(a,b,c)". So any combination of defaults can be set. The majority of my work went into the 'reset' requirement, the rest should be fairly straight forward for you, Jacob.
If you want to ratchet up the difficulty one notch, add a test case with comments in the function definition:
Added.
Hmm... this appears to kill all but 3 of the solutions...
It's the future now and there are a lot of solutions again. Also, the quality of all of the solutions is much better.
This comment has been hidden.
Yeah, I got the idea from Angular too.
I'll work on making the test harness more elaborate to clearly demonstrate the design requirements. Thank you for your feedback.
The current tests allow you to blindly map only b, this is how I did it, and it passed. Then I saw you guys' complex solutions, and thought, "what am I missing here?".
@vmcnabb: Fixed.
I'm still unsure what you're trying to test. At the moment, it seems to be based on the order of the arguments, like, a is always first, and b is always second.
My updated solution passes your tests, and yet assumes that the default for A is always the first argument, and the default for B is always the second argument. Is this your intent?
If your intent is that the names are matched up, then you could do something like the following test
My current solution would return 2 for the second test.
@vmcnabb: No, it cannot assume that
a
is the first argument; it cannot assume thata
is an argument at all.