Lazy.jl
                                
                                
                                
                                    Lazy.jl copied to clipboard
                            
                            
                            
                        Regarding the returned type of `rest(::List)` and `drop(::List)`
In the current implementation the returned type of rest is LinkedList while drop returns LazyList,
> typeof(Lazy.rest(list(1,2,3)))
Lazy.LinkedList
> typeof(Lazy.drop(1, list(1,2,3)))
Lazy.LazyList
This not only seems inconsistent but also explains why the following code works unexpectedly,
> fibs = @lazy 0:1:(fibs + Lazy.rest(fibs));
> Lazy.take(5, fibs)
List:
  0
  1
If we convert the returned type of Lazy.rest to Lazy.LazyList it works correctly,
> fibs = @lazy 0:1:(fibs + @lazy Lazy.rest(fibs));
> Lazy.take(5, fibs)
List:
  0
  1
  1
  2
  3
Thus I suggest we change the returned type of rest(::List) to LazyList
Actually rest can return either:
julia> Lazy.rest(constantly(1)) |> typeof
Lazy.LazyList
Both LinkedList and LazyList are part of the same data structure, the List, and should behave in exactly the same way – so there is a bug here, but that would be the wrong fix.
I'll take a look at this anyway.
I think you're right that the issue here is that rest isn't lazily evaluated, although it doesn't always need to be lazy either. We can just overload it to be equivalent to drop when applied to a lazy list.
One could also argue that rest is defined as an eager version of drop and simply shouldn't be used here, but that's probably more confusing then helpful.