Bug in b88: Stack Overflow when changing a Supplier to a lambda using LazySeq

Samir Talwar samir at noodlesandwich.com
Mon May 27 05:26:21 PDT 2013


You guys are quick. That's great to hear.

— Samir.

On Mon, May 27, 2013 at 12:47 PM, Maurizio Cimadamore
<maurizio.cimadamore at oracle.com> wrote:
> Fixed. Thanks for the report.
>
> Maurizio
>
>
> On 26/05/13 19:58, Samir Talwar wrote:
>>
>> The attachments were stripped, so here they are inline. (Thanks to
>> Brian for pointing that out.)
>>
>> Crashing with a stack overflow:
>>
>> // START
>>
>> import com.blogspot.nurkiewicz.lazyseq.LazySeq;
>>
>> class MergeSortCrashing {
>>      public static <T extends Comparable<T>> LazySeq<T>
>> mergeSorted(LazySeq<T> a, LazySeq<T> b) {
>>          if (a.isEmpty()) {
>>              return b;
>>          }
>>
>>          if (b.isEmpty()) {
>>              return a;
>>          }
>>
>>          if (a.head().compareTo(b.head()) <= 0) {
>>              return LazySeq.cons(a.head(), () -> mergeSorted(a.tail(),
>> b));
>>          } else {
>>              return LazySeq.cons(b.head(), () -> mergeSorted(a,
>> b.tail()));
>>          }
>>      }
>> }
>>
>> // END
>>
>> Compiles fine without lambdas:
>>
>> // START
>>
>> import java.util.function.Supplier;
>> import com.blogspot.nurkiewicz.lazyseq.LazySeq;
>>
>> class MergeSortWithoutLambdas {
>>      public static <T extends Comparable<T>> LazySeq<T>
>> mergeSorted(LazySeq<T> a, LazySeq<T> b) {
>>          if (a.isEmpty()) {
>>              return b;
>>          }
>>
>>          if (b.isEmpty()) {
>>              return a;
>>          }
>>
>>          if (a.head().compareTo(b.head()) <= 0) {
>>              return LazySeq.cons(a.head(), new Supplier<LazySeq<T>>() {
>>                  @Override public LazySeq<T> get() {
>>                      return mergeSorted(a.tail(), b);
>>                  }
>>              });
>>          } else {
>>              return LazySeq.cons(a.head(), new Supplier<LazySeq<T>>() {
>>                  @Override public LazySeq<T> get() {
>>                      return mergeSorted(a, b.tail());
>>                  }
>>              });
>>          }
>>      }
>> }
>>
>> // END
>>
>> Compiles fine with an explicit comparator instead and the <T extends
>> Comparable<T>> business changed to <T>:
>>
>> (If you change the type parameter back to <T extends Comparable<T>>,
>> it crashes, even with this version.)
>>
>> // START
>>
>> import java.util.Comparator;
>> import com.blogspot.nurkiewicz.lazyseq.LazySeq;
>>
>> class MergeSortSafe {
>>      public static <T> LazySeq<T> mergeSorted(LazySeq<T> a, LazySeq<T>
>> b, Comparator<T> comparator) {
>>          if (a.isEmpty()) {
>>              return b;
>>          }
>>
>>          if (b.isEmpty()) {
>>              return a;
>>          }
>>
>>          if (comparator.compare(a.head(), b.head()) <= 0) {
>>              return LazySeq.cons(a.head(), () -> mergeSorted(a.tail(),
>> b, comparator));
>>          } else {
>>              return LazySeq.cons(b.head(), () -> mergeSorted(a,
>> b.tail(), comparator));
>>          }
>>      }
>> }
>>
>> // END
>>
>> — Samir.
>>
>> On Sun, May 26, 2013 at 6:29 PM, Samir Talwar <samir at noodlesandwich.com>
>> wrote:
>>>
>>> I wrote some code using the LazySeq library (
>>> https://github.com/nurkiewicz/LazySeq ) which implements merge sort
>>> given two already-sorted lists. It crashes with a stack overflow.
>>>
>>> That works well. If I try and use lambdas, javac crashes with a stack
>>> overflow.
>>>
>>> Lambdas code (MergeSortCrashing.java):
>>>
>>>      public static <T extends Comparable<T>> LazySeq<T>
>>> mergeSorted(LazySeq<T> a, LazySeq<T> b) {
>>>          if (a.isEmpty()) {
>>>              return b;
>>>          }
>>>
>>>          if (b.isEmpty()) {
>>>              return a;
>>>          }
>>>
>>>          if (a.head().compareTo(b.head()) <= 0) {
>>>              return LazySeq.cons(a.head(), () -> mergeSorted(a.tail(),
>>> b));
>>>          } else {
>>>              return LazySeq.cons(b.head(), () -> mergeSorted(a,
>>> b.tail()));
>>>          }
>>>      }
>>>
>>> This is attempting to build against b88. Crashes in both IntelliJ and
>>> Maven.
>>>
>>> Two things: if an explicit comparator is passed in rather than having
>>> T be Comparable, it works. (See attachment: MergeSortSafe.java). It
>>> also works if I replace the lambdas with explicit instantiations of
>>> Supplier<LazySeq<T>> (see MergeSortWithoutLambdas.java).
>>>
>>> I'm pretty sure this is a bug. I hope this is the right place to
>>> report it. Cheers for all your hard work, guys. I hope this one gets
>>> fixed soon.
>>>
>>> — Samir.
>
>


More information about the lambda-dev mailing list