I have generic question about scheme and lisp. How fold
and reduce
functions should work?
In guile scheme using (use-modules (srfi srfi-1))
you can use this:
guile> (fold cons '() '(1 2 3 4))
> (4 3 2 1)
guile> (fold cons '(1 2 3 4) '())
> (1 2 3 4)
I'm working on fold function in my lisp in JavaScript, I want to create single function for both reduce and fold (the function will return one of those functions).
But how they should work? In my code I'm checking if first list is not null or if it did not ended but here you pass empty list (first code). Does fold work on second list instead and check if that not ended or on both since reverse also works? How many times fold got executed when called with '() as init value, ones or it process whole first argument?
Here is my reduce function:
function reduce(fn, list, init = nil) {
if (isEmptyList(list) || isNull(list)) {
return list;
}
let result = init;
let node = list;
if (init === null) {
result = list.car;
node = list.cdr;
}
return (function loop() {
function next(value) {
result = value;
node = node.cdr;
return loop();
}
if (node === nil || !(node instanceof Pair)) {
if (typeof result === 'number') {
return LNumber(result);
}
return result;
}
const item = node.car;
const value = fn(result, item);
if (isPromise(value)) {
return value.then(next);
} else {
return next(value);
}
})();
}
does below results are correct for reduce
?
lips> (reduce cons '(1 2 3 4) nil)
((((nil . 1) . 2) . 3) . 4)
lips> (reduce list '(1 2 3 4) nil)
((((nil 1) 2) 3) 4)
lips>
How should fold function work and look like in JavaScript? What is exact logic for fold
and reduce
in scheme?
Here is another example for guile:
guile> (fold-right append '(1 2 3 4) '())
(1 2 3 4)
lips> (reduce append '(1 2 3 4) '())
(1 2 3 4)
it works the same in my lisp, does it mean that my reduce is correct? How to test if my function works right?
I have one issue this, in Guile:
guile> (fold-right list '(1 2 3 4) '())
> (1 2 3 4)
guile> (fold list '(1 2 3 4) '())
> (1 2 3 4)
but in my lisp:
lips> (reduce list '(1 2 3 4) '())
((((() 1) 2) 3) 4)
is fold-right in fact reduce? Because this code in guile give the same result in as my reduce:
guile> (list (list (list (list '() 1) 2) 3) 4)
> ((((() 1) 2) 3) 4)