I'm having trouble understanding the behavior of the code below:
function multiplier(factor){
return number => number * factor;
}
let twice = multiplier(2);
console.log(twice(5));
At the function call multiplier(2), the value of 2 is returned to the binding twice, which is 2, but how so? This implies that the return statement would evaluate to 1 * 2, but the parameter number was never assigned a value. I was expecting undefined * 2, instead which would return undefined. Why is the parameter number assigned a value of 1?
What let twice = multiplier(2); does is stored following function in twice variable
function(number) {
// factor variable value was set here
return number * 2;
}
When you called
console.log(twice(5));
It runs function stored in twice variable as following
function(5) {
return 5 * 2;
}
Hence you got 10 on console.
Related
I have a function that takes a vector as a parameter, scan this vector and generates a random word. It's expected from me that the generated words' letters are different from each other. So, I want to check it with a simple if-else condition inside the same function. If all letters are different, function returns this word. If not, I need to use the same function which I am already inside while using conditions. But first parameter that I used in the main function doesn't work when I attempt to use it for the second time. Here the generateaRandomWord(vector a) function:
vector<string> currentVector;
string generateaRandomWord(vector<string> a) {
currentVector = a;
string randomWord;
int randomNumber = rand() % currentVector.size();
randomWord = currentVector.at(randomNumber);
if (hasUniqueChars(randomWord)) {
return randomWord;
}
else {
generateaRandomWord(currentVector);
}
}
I thought that it is a good idea to keep a vector (currentVector) outside of the function. So, for the first time I use the function this vector will be defined and I will be able to use it if using recursion is necessary. But that didn't work either.
The main problem you have is that your recursive case doesn't return anything -- it throws away the returned value from the recursive call, then falls off the end of the function (returning garbage -- undefined behvaior). You need to actually return the value returned by the recursive call:
return generateaRandomWord(currentVector);
Consider the following pseudocode snippet:
int c = 2;
int bar(int a)
{
c = c + 2;
return a * 2;
}
int foo(void)
{
return(bar(c + 1));
}
I'm asked to determine what the return value of foo(); will be, assuming that the language used passes all parameters by name.
My reasoning is that, since parameters are passed by name, c+1 won't be evaluated when bar(c+1) is called, but only when the first instance of the formal parameter a is encountered in bar, that is in the return a*2 line, after bar has modified the global variable c, so, since c+1 has to be evaluated in the caller's environment, that is in foo's environment and foo has only the global c in its scope it will be evaluated as 4+1, giving a fine return value of 10.
My doubt is whether this should be 6 instead, if I blindly apply a syntactical substitution rule, as passing by name requires the fifth line should be interpreted as return c+1*2, instead of return (c+1)*2, so what is the correct approach here?
For reference I'm using the definition of passing by name provided in section 7.1.2 of Programming Languages:Principles and Paradgigms by Gabbrielli and Martini
I tried to rely on type inference for a function with signature:
proc mode(data: [?]int)
but the compiler said it could not resolve the return type (which is a warning in in itself I guess given there are only two return statements). I tried:
proc mode(data: [?]int): [?]int
but the compiler then said there was an internal error:
internal error: CAL0057 chpl Version 1.13.1.518d486
What is the correct way of specifying that the length of an array returned by a function can only be known at run time?
If the domain/size of the array being returned cannot be described directly in the function prototype, I believe your best bet at present is to omit any description of the return type and lean on Chapel's type inference machinery to determine that you're returning an array (as you attempted). For instance, here is a procedure that reads in an array of previously unknown size and returns it:
proc readArrFromConsole() {
var len = stdin.read(int);
var X: [1..len] real;
for x in X do
x = stdin.read(real);
return X;
}
var A = readArrFromConsole();
writeln(A);
Running it and typing this at the console:
3 1.2 3.4 5.6
Generates:
1.2 3.4 5.6
Your question mentions multiple return statements, which opens up the question about how aggressively Chapel unifies types across distinct arrays. A simple example with multiple arrays of the same type (each with a unique domain, size, and bounds) seems to work:
proc createArr() {
var len = stdin.read(int);
if (len > 0) {
var X: [1..len] real;
return X;
} else {
var Y: [-1..1] real;
return Y;
}
}
var A = createArr();
writeln(A);
To understand why the compiler couldn't resolve the return type in your example may require more information about what your procedure body / return statements contained.
I've come across this from time to time in recursive functions, in situations where omitting the return type fails; in this case I create a record which is an array with its domain, e.g.:
record stringarray {
var D: domain(1);
var strs : [D] string;
}
and then define the recursive array to return one of those records:
proc repeats() : stringarray {
var reps: stringarray;
//...
for child in children do {
childreps = child.repeats();
for childrep in childreps do
reps.push_back(childrep);
}
//...
return reps;
}
I want to get some data out of my MySQL database using Koa and the mysql node package. I was looking at co-mysql, but the readme suggests to use thunkify directly. So I did the following:
const query = thunkify(connection.query.bind(connection));
Which seems to work, as I now can do:
app.use(function * main() {
const races = yield query(
"SELECT * FROM `races` where '2016-01-19' between start_date and end_date"
)(function(err, rows) {
// rows is the data I need
});
});
However, I cannot find a way to return/yield the row data from the thunk into my races variable. I log it, and it displays the correct data, but when I try to pass it back, it always returns undefined. I've tried a couple of ways from inside the callback, but I can't seem to figure it out:
return rows
yield rows (made the callback a generator function)
return yield rows
...
I'm often getting: TypeError: You may only yield a function, promise, generator, array, or object, but the following object was passed: "undefined"
races is an array because you are using thunkify for query. co returns an array for any thunks that call their callback with more than one value (ie. callback(null, 1, 2, 3) returns [1, 2, 3].
If you were to Promisify query instead, races will be assigned to the first returned value only, which appears to be inline with what you're looking for.
Here's a code example showing it in practice:
var co = require("co")
var promisify = require("bluebird").promisify
var thunkify = require("thunkify")
function async(callback) {
callback(null, 1, 2, 3)
}
var p = promisify(async)
var t = thunkify(async)
co(function*() {
let x = yield p()
let y = yield t()
console.log(x)
console.log(y)
}).then(() => {})
When run, the value of x will be 1 and the value of y will be the array [1, 2, 3].
You can run it with Tonic here: https://tonicdev.com/56ab7cfc879afb0c002c1d49/56ab7cfc879afb0c002c1d4a
Here is coding from Couchbase Document and I dont understand it
function(key, values, rereduce) {
var result = {total: 0, count: 0};
for(i=0; i < values.length; i++) {
if(rereduce) {
result.total = result.total + values[i].total;
result.count = result.count + values[i].count;
} else {
result.total = sum(values);
result.count = values.length;
}
}
return(result);
}
rereduce means the current function call has already done the reduce or not. right?
the first argument of the reduce function, key, when will it be used? I saw a numbers of examples, key seems to be unused
When does rereduce return true and the array size is more than 1?
Again, When does rereduce return is false and the array size is more than 1?
Rereduce means that the reduce function is called before and now it is called again with params that were returnd as a result in first reduce call. So if we devide it into two functions it will look like:
function reduce(k,v){
// ... doing something with map results
// instead of returning result we must call rereduce function)
rereduce(null, result)
}
function rereduce(k,v){
// do something with first reduce result
}
In most cases rereduce will happen when you have 2 or more servers in cluster or you have a lot of items in your database and the calculation is done on multiple "nodes" of the B*Tree. Example with 2 servers will be easier to understand:
Let's imagine that your map function returned pairs: [key1-1, key2-2, key6-6] from 1st server and [key5-5,key7-7] from 2nd. You'll get 2 reduce function calls with:
reduce([key1,key2,key6],[1,2,6],false) and reduce([key5,key7],[5,7],false). Then if we just return values (do nothing in reduce, just return values), the reduce function will be called with such params: reduce(null, [[1,2,6],[5,7]], true). Here values will be an array of results that came from first reduce calls.
On rereduce key will be null. Values will be an array of values as returned by a previous reduce() function.
Array size depends only on your data. It not depends on rereduce variable. Same answer for 4th question.
You can just try to run examples from Views basics and Views with reduce. I.e. you can modify reduce function to see what it returns on each step:
function reduce(k,v,r){
if (!r){
// let reduce function return only one value:
return 1;
} else {
// and lets see what values have came in "rereduce"
return v;
}
}
I am also confused by the example from the official couchbase website as well, and below is what i thought.
confusion: the reduce method signature
1) its written as
function (keys, values, rereduce)
2) its written as function(key, values, rereduce)
What exactly is the first param, key or keys
For all my understand from my previous exp on the map/reduce, the key the key that emit from the map function and there is a hidden shuffle method that will aggregate the value into a value list for the same key.
So the key param can be an array under the circumstances that you emit an array as key (which you can use group by level control the level of aggregation)
So i am not agree with the example that given by #m03geek, it should not be a list of different keys, correct me if i am wrong.
My assumption:
Both reduce and rereduce work on the SAME key only.
eg:
reduce is like:
1)reduce(keyA, [1,2,3]) this is precalculated, and stored in Btree structure
2) rereduce(keyA, [6, reduce(keyA, [4,5,6])]), 6 is the sum of [1,2,3] from the first reduce method, then we add a new doc into couchbase, which will trigger the reduce method again, instead of calculating the whole thing again as the original map/reduce will do, couchbase get the precalculated data out from the btree which is 6, and run reduce from the key-value pairs from the map method (which is triggered by adding a new doc), then run re-reduce on the precalculated value + new value.