Kotlin infinity loop on list in recursion - kotlin

This follows infinite loop, in clojure such things just fine
tailrec fun passHeaders (xH: List<Int>)
{
while (xH.isNotEmpty())
{
passHeaders(xH.drop(1))
}
}

List.drop does not mutate the List, but rather produces a new List instance. Thus, you're while loop is infinite.

You don't provide a base case, that's why. Because in each call to passHeaders, xH is it's own copy, it will NEVER not be empty. Remember, when you call drop(), a new list is created.
while (xH.isNotEmpty())
What this says is "while my copy of xH is not empty, call passHeaders.
On the other hand:
if (xH.isNotEmpty())
Will probably do what you intend.

The first call to this function will never terminate if xH isn't empty. .drop() doesn't modify the original list.

Related

Why does Iterator::next return an Option instead of just an item?

It seems to me that whether an option is the right type to return should be up to the implementor.
I notice that it goes away when I try to filter or using other collection methods on the items. Is this simply a replacement for has_next? Won't it have potential performance/memory implications?
Because it needs some way to communicate to the caller that there's nothing left to output.
fn main() {
let mut it = vec![1, 2, 3].into_iter();
assert_eq!(it.next(), Some(1));
assert_eq!(it.next(), Some(2));
assert_eq!(it.next(), Some(3));
assert_eq!(it.next(), None); // End of iterator.
}
As for a hypothetical has_next, that can complicate some iterator designs because it requires the iterator to know whether there is another element. This might require the iterator to compute the next element, then store it somewhere. It's also possible to forget to call has_next, or call it but ignore the result.
With next returning an Option, none of this is an issue; an iterator can compute the next item and return it whilst making it impossible for a caller to forget to ensure the returned value actually has something in it.
One thing this does not let you do is "peek" at the iterator to see if there's something more and then change logic based on that answer, without actually consuming the next item. However, that's what the peekable combinator is for, which gives you what amounts to a traditional has_next: peek().is_some().
On your concerns about performance: I've never seen anything to suggest there is any penalty. Anything using an iterator correctly has to check to see if it's reached the end. As for space, a Rust iterator doesn't need to cache the next item, so they're likely to be the same size or smaller than an iterator for a language that uses has_next.
Finally, as noted in comments, Option is not heap allocated. A None is equivalent to a false followed by some uninitialised space (since there's nothing in it), and a Some(v) is equivalent to a true followed by v.

How to mutate another item in a vector, but not the vector itself, while iterating over the vector?

It is quite clear to me that iterating over a vector shouldn't let the loop body mutate the vector arbitrarily. This prevents iterator invalidation, which is prone to bugs.
However, not all kinds of mutation lead to iterator invalidation. See the following example:
let mut my_vec: Vec<Vec<i32>> = vec![vec![1,2], vec![3,4], vec![5,6]];
for inner in my_vec.iter_mut() { // <- or .iter()
// ...
my_vec[some_index].push(inner[0]); // <-- ERROR
}
Such a mutation does not invalidate the iterator of my_vec, however it is disallowed. It could invalidate any references to the specific elements in my_vec[some_index] but we do not use any such references anyway.
I know that these questions are common, and I'm not asking for an explanation. I am looking for a way to refactor this so that I can get rid of this loop. In my actual code I have a huge loop body and I can't modularize it unless I express this bit nicely.
What I have thought of so far:
Wrapping the vector with Rc<RefCell<...>>. I think this would still fail at runtime, since the RefCell would be borrowed by the iterator and then will fail when the loop body tries to borrow it.
Using a temporary vector to accumulate the future pushes, and push them after the loop ends. This is okay, but needs more allocations than pushing them on the fly.
Unsafe code, and messing with pointers.
Anything listed in the Iterator documentation does not help. I checked out itertools and it looks like it wouldn't help either.
Using a while loop and indexing instead of using an iterator making use of a reference to the outer vector. This is okay, but does not let me use iterators and adapters. I just want to get rid of this outer loop and use my_vec.foreach(...).
Are there any idioms or any libraries which would let me do this nicely Unsafe functions would be okay as long as they don't expose pointers to me.
You can wrap each of the inner vectors in a RefCell.
use std::cell::RefCell;
fn main() {
let my_vec : Vec<RefCell<Vec<i32>>> = vec![
RefCell::new(vec![1,2]),
RefCell::new(vec![3,4]),
RefCell::new(vec![5,6])];
for inner in my_vec.iter() {
// ...
let value = inner.borrow()[0];
my_vec[some_index].borrow_mut().push(value);
}
}
Note that the value binding here is important if you need to be able to push to the vector that inner refers to. value happens to be a type that doesn't contain references (it's i32), so it doesn't keep the first borrow active (it ends by the end of the statement). Then, the next statement may borrow the same vector or another vector mutably and it'll work.
If we wrote my_vec[some_index].borrow_mut().push(inner.borrow()[0]); instead, then both borrows would be active until the end of the statement. If both my_vec[some_index] and inner refer to the same RefCell<Vec<i32>>, this will panic with RefCell<T> already mutably borrowed.
Without changing the type of my_vec, you could simply use access by indexing and split_at_mut:
for index in 0..my_vec.len() {
let (first, second) = my_vec.split_at_mut(index);
first[some_index].push(second[0]);
}
Note: beware, the indices in second are off by index.
This is safe, relatively easy, and very flexible. It does not, however, work with iterator adaptors.

Non-destructively iterating over a Rust collection, but not by reference

I can write the following two ways, the second is inspired by What is the idiomatic way to create a collection of references to methods that take self?:
channels.iter().flat_map(|c|c.to_uppercase()).collect(),
channels.clone().into_iter().flat_map(char::to_uppercase).collect(),
The second line has to clone the collection because char::to_uppercase doesn't accept a reference as it's argument and .iter() provides references and .into_iter() moves the collection.
Is there a way to do this that doesn't need to clone the collection or create a closure? I don't hate closures, I promise, and I know they're just turned into (usually inline) function calls in LLVM anyway, but I like the cleanness of referring to a function like in the second line and would prefer to use it if it can be done without the clone.
Iterator has a cloned method which is equivalent to .map(|x| x.clone()) which, in case of Copy types is equivalent to .map(|&x| x). This way you can write
channels.iter().cloned().flat_map(char::to_uppercase).collect()
You can define a function that takes a reference. You can even put it inside another function, if you want to keep it close to its usage.
fn foobar() {
fn to_uppercase(c: &char) -> ::std::char::ToUppercase {
c.to_uppercase()
}
// [...]
let channels_upper = channels.iter().flat_map(to_uppercase).collect();
}

How to make function wait to return after getResult from SQL Statement is available?

I'm just trying to make a simple function that will return all the data from my SQLITE database as an array. But it looks like when my function is returning the array, the SQL statement is actually still executing... so it's empty... Does anyone have a suggestion? Or am I just going about this whole thing wrong.
I know I could just have the event listener functions outside this function, and they could then set the data. But i'm trying to make a AS3 Class that holds all my SQL functions, and It would be nice to have everything for this particular function just in one function, so it can return an array to me.
public function getFavsGamesArray():Array
{
getFavsArraySql.addEventListener(SQLEvent.RESULT, res);
getFavsArraySql.addEventListener(SQLErrorEvent.ERROR, error);
getFavsArraySql.text = "SELECT * FROM favGames";
getFavsArraySql.execute();
var favsArr:Array = new Array();
function res(e:SQLEvent):void
{
trace("sql good!");
favsArr=getFavsArraySql.getResult().data;
}
function error(e:SQLEvent):void
{
trace("sql error!");
}
trace(favsArr);
return favsArr;
}
Assuming I understood your question, Instead of expecting getFavsGamesArray() to actually return the results from an asynchronous event (which it likely never will), consider passing a function (as an argument) to call within your res() function that would then process the data.
In your SQL helper class, we'll call it SQLHelper.as:
private var processResultsFun:Function;
public function getFavsGamesArray(callBackFun:Function):void
{
processResultsFun = callBackFun;
...
} //Do not return array, instead leave it void
function res(e:SQLEvent):void
{
trace("sql good!");
if(processResultsFun != null)
{
processResultsFun(getFavsArraySql.getResult().data);
}
}
In the class(es) that call your SQL helper class:
function processRows(results:Array):void {
//Make sure this function has an Array argument
//By the time this is called you should have some results
}
...
SQLHelper.getFavsGamesArray(processRows);
You can optionally pass an error handling function as well.
Your problem is that your task is asynchronous.
favsArris a temporary variable, and you return its value directly when getFavsGamesArray completes. At that time, the value will always be null, because the listener methods are called only after the SQL statement is complete - which will be at some time in the future.
You need some way to delay everything you are going to do with the return value, until it actually exists.
The best way to do it is to dispatch your own custom event, and add the value as a field to the event object, or to add a listener method outside of your SQL class directly to the SQLStatement - and have it do stuff with event.target.getResult().data. That way you can always be sure the value exists, when processing occurs, and you keep your SQL behavior decoupled from everything on the outside.
I would also strongly encourage you not to declare your event listeners inside functions like this: You can't clean up these listeners after the SQL statements completes!
True: Declaring a function inside a function makes it temporary. That is, it exists only for the scope of your function, and it is garbage collected when it's no longer needed - just like temporary variables. But "it is no longer needed" does not apply if you use it as an event listener! The only reason this works at all is that you don't use weak references - if you did, the functions would be garbage collected before they are even called. Since you don't, the listeners will execute. But then you can't remove them without a reference! They continue to exist, as will the SQL statement, even if you set its references to null - and you've successfully created a memory leak. Not a bad one, probably, but still...
If you really want to encapsulate your SQL behavior, that is a good thing. Just consider moving each SQL statement to a dedicated class, instead of creating one giant SQLHelper, and having your listener methods declared as member functions - it is much easier to prevent memory leaks and side effects, if you keep references to everything, and you can use these in a destroy method to clean up properly.

Is there some clever way to write a lua object so that it doubles up as an iterator?

Lets say I have some "object" that I've defined elsewhere. Maybe it represents a set of items, but is more complex than a simple table. Whatever it may be, it would be logical to iterate over it.
As such, it has a iterator method defined. So I can write this:
local myObject = AbstractObject:new()
for obj in myObject:iterator() do
obj:foo()
end
What I'm wondering is if there is some metamethod trickery that I can do, which will allow me to write this:
local myObject = AbstractObject:new()
for obj in myObject do
obj:foo()
end
So is there?
One slight change to your example would make the semantics a lot less painful:
local myObject = AbstractObject:new()
for obj in myObject() do
obj:foo()
end
That way, you can use a metatable to define the __call metamethod to return myObject:interator(), with code that looks something like this in AbstractObject:new():
setmetatable(newobject, {__call = function() return newobject:iterator() end})
Without the iterator construction, you'll be effectively reusing a single iterator for multiple iterations, which means you'll need to keep the iterator state in the object/creation closure, and reset it after it finishes so the next call will restart the iteration again. If you really want to do this, the best solution would really be to write something for the specific iteration implementation, but this would perform the generic iteration:
local iterator
--table.pack is planned for 5.2
local pack = table.pack or function(...)
local t = {...}
t.n = select('#',...)
return t
end
--in 5.1 unpack isn't in table
local unpack = table.unpack or unpack
function metamethods.__call(...)
if not iterator then
iterator = newobject:iterator()
end
local returns = pack(iterator(...))
if returns[1] == nil then
--iteration is finished: next call will restart iteration
iterator = nil
end
return unpack(returns, 1, returns.n)
end
Again: This should really be adjusted to fit your use case.
The object used after in must be a function, which will be called repeatedly by the generic for loop.
I'm not sure if you can make a table or user object callable like a function, but even then the problem would be that your object can only have one internal iterator state - i.e. it would not allow multiple iterations over the same object (neither concurrently nor sequentially), unless you are somehow explicitly resetting it.
As answered by Stuart, you could use the __call metamethod suitably to return the iterator, but then you would have to write
for obj in myObject() do
obj:foo()
end
This is not quite what we want.
Reading a bit more in PiL, I see that there are more components used in the for loop: the invariant loop state, and the current value of the control variable, which are passed to the iterator function in each call. If we don't provide them in the in expression, they are initialized to nil.
Thus, my idea would be to use these values to distinguish the individual calls.
If you can create a next(element) function for your collection which returns for each element the next one, the implementation would be simple:
metatable.__call = function(_state, _last)
if(_last == nil) then
return obj:first()
else
return obj:next(_last)
end
end
But often we would not have something like this, then it gets more complicated.
I thought about using coroutines here, but these still need a factory method (which we want to avoid).
It would result in something similar like what Stuart wrote (i.e. saving the iterator state somewhere in the object itself or in some other variable related to the object), and using the parameter and/or the iterators result to decide when to create/clean the iterator object/state.
Nothing won here.