fake an unlimited sequence?

129 views
Skip to first unread message

HamsterofDeath

unread,
Dec 20, 2012, 5:45:07 AM12/20/12
to scala...@googlegroups.com
is there a simple way to fake a sequence that returns the same object at
every index? i want to avoid streams since they would introduce a
memory-"leak" here....
access via index is a must have, otherwise i would just use an iterator.

thx :)

√iktor Ҡlang

unread,
Dec 20, 2012, 6:04:27 AM12/20/12
to HamsterofDeath, scala...@googlegroups.com
sequence as in "Seq" or as in "Iterator"?

What would an infinite Seq return for size? What would "foreach" do?

Cheers,
--
Viktor Klang

Director of Engineering
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

HamsterofDeath

unread,
Dec 20, 2012, 6:13:24 AM12/20/12
to √iktor Ҡlang, scala...@googlegroups.com
foreach would just loop forever, and size would return Integer.MAX_VALUE

i could pass an iterator creating function instead of a seq, but the access via index would be pretty slow then.
to answer your question: sequence as in seq.

√iktor Ҡlang

unread,
Dec 20, 2012, 6:24:37 AM12/20/12
to HamsterofDeath, scala...@googlegroups.com
Wow, that's a very toxic Seq. I'd recommend against going that road.

HamsterofDeath

unread,
Dec 20, 2012, 6:46:28 AM12/20/12
to scala...@googlegroups.com
there is a much better way:
(Int) => U

so obivous :D

Seth Tisue

unread,
Dec 21, 2012, 8:22:09 AM12/21/12
to scala...@googlegroups.com
On Thu, Dec 20, 2012 at 5:45 AM, HamsterofDeath <h-s...@gmx.de> wrote:
> is there a simple way to fake a sequence that returns the same object at
> every index? i want to avoid streams since they would introduce a
> memory-"leak" here....

A circular stream doesn't leak (so say the prophets).

Sadly, no method in the standard library will give us a circular
stream. Let's write one:

Welcome to Scala version 2.10.0-RC5

scala> def circular[T](xs: Stream[T]): Stream[T] = {
| lazy val knot: Stream[T] = xs #::: knot
| knot
| }
circular: [T](xs: Stream[T])Stream[T]

scala> circular(Stream(1)).take(10).mkString
res0: String = 1111111111

scala> circular(Stream.from(1).map{x => println(x); x}.take(3))
1
res1: Stream[Int] = Stream(1, ?)

scala> res1.take(12).mkString
2
3
res2: String = 123123123123

--
Seth Tisue | Northwestern University | http://tisue.net
developer, NetLogo: http://ccl.northwestern.edu/netlogo/

HamsterofDeath

unread,
Dec 21, 2012, 9:09:05 AM12/21/12
to scala...@googlegroups.com
+1 for the knot

Alec Zorab

unread,
Dec 21, 2012, 10:00:22 AM12/21/12
to HamsterofDeath, scala-user
It's somewhat surprising that Stream.continuously doesn't do that, but instead opts to allocate new cells as you iterate.

HamsterofDeath

unread,
Dec 21, 2012, 10:21:47 AM12/21/12
to scala...@googlegroups.com
i guess this happens to allow the passed element generator to behave like an iterator - it can generate different element every time

Seth Tisue

unread,
Dec 21, 2012, 11:47:21 AM12/21/12
to scala-user
On Fri, Dec 21, 2012 at 10:00 AM, Alec Zorab <alec...@googlemail.com> wrote:
> It's somewhat surprising that Stream.continuously doesn't do that, but
> instead opts to allocate new cells as you iterate.

Oh, but that's useful too:
Stream.continually(util.Random.nextInt)
Stream.continually(in.readLine()).takeWhile(_ != null)

It's not an accident that both these examples involve side effects. If
the argument to continually was known to be referentially transparent,
then there wouldn't be any need to keep making new cells.

Vlad Patryshev

unread,
Dec 21, 2012, 12:15:48 PM12/21/12
to Alec Zorab, HamsterofDeath, scala-user
On Fri, Dec 21, 2012 at 7:00 AM, Alec Zorab <alec...@googlemail.com> wrote:
It's somewhat surprising that Stream.continuously doesn't do that, but instead opts to allocate new cells as you iterate.

Not what I see:

scala> val x = new Object
x: java.lang.Object = java.lang.Object@15db386

scala> Stream.continually(x) take 3 mkString ","
res7: String = java.lang.Object@15db386,java.lang.Object@15db386,java.lang.Object@15db386
 

Luke Vilnis

unread,
Dec 21, 2012, 12:23:44 PM12/21/12
to Vlad Patryshev, Alec Zorab, HamsterofDeath, scala-user
It has multiple pointers to the same object, but I don't think that means it isn't allocating new cons cells to hold those pointers.

HamsterofDeath

unread,
Dec 21, 2012, 12:38:07 PM12/21/12
to Vlad Patryshev, Alec Zorab, scala-user
make it a def instead of a val and you will get a different object every time

Vlad Patryshev

unread,
Dec 21, 2012, 1:05:47 PM12/21/12
to HamsterofDeath, Alec Zorab, scala-user
There is a difference between def, lazy val and val, is not there?
Reply all
Reply to author
Forward
0 new messages