_mutate

trait _mutate[A]
class java.lang.Object
trait scala.Matchable
class Any
trait _build
object Stream

Def

inline def enablePreview: Stream[A] & Stream.Preview[A]

Enables preview capabilities

Enables preview capabilities

Returns Stream.Preview, which allows to pre-load and inspect elements, even before they are read

  def strm : Stream[String] = ???

  if(strm.enablePreview.previewSize > 1000) "Stream is over 1K".TP
Source
_mutate.scala
inline def enableSize: Stream[A] & Able.Size

Adds sizing information

Adds sizing information

If Stream already has sizing, this method is a simple cast, otherwise, the elements might be buffered and counted.

Source
_mutate.scala
inline def hideSizeData: Stream[A]

Loose size information

Loose size information

Many streams return ''sizeLongOpt'', knowing their current size

hideSizeData drops sizing information, so some optimizations will not be available

This is primarily for testing and debugging

Source
_mutate.scala
inline def load: Stream[A] & Able.Size

Preload all

Preload all

Immediately loads all stream elements into memory, so they are no longer dependent on underlying sources.

  def s : Stream[String] = ???

  s.load

  // is functionally same as

  s.toBuffer.stream
Source
_mutate.scala
@targetName("nonEmptyOpt")
inline def nonEmptyOpt: Opt[Stream[A]]
inline def raw(using sp: Specialized.Primitive[A]): s.Stream

Specialize

Specialize

Converts current stream into specialized on underlying primitive type. If stream is already specialized, the conversion is a simple cast.

   val s  : Stream[Int]     = 1 <> 10

   val ss : Int.Stream = s.raw

Note: If underlying type is not primitive, the method will not compile

Source
_mutate.scala
inline def ref: Stream[A]

Generalize

Generalize

If stream is specialized it will be up-cast to general Val.Stream type, and further operations will be general (unless they are specialized, like map)

  val special : Int.Pack  = (1 <> 10).stream.pack

  val general : Pack[Int] = (1 <> 10).stream.ref.pack

  special.getClass.tp // Prints class scalqa.lang.int.g.Pack

  general.getClass.tp // Prints class scalqa.val.pack.z.ArrayPack

Note: This is a true zero cost operation. It does not change byte code (only compiler context)

Source
_mutate.scala
inline def replaceSequence(seq: Stream[A], to: Stream[A]): Stream[A]
inline def replaceSequenceBy[B](f: A => B, seq: Stream[B], to: Stream[A]): Stream[A]
inline def reverse: Stream[A]

Reverse order

Reverse order

Re-arranges all elements is reverse order

('A' <> 'F').stream.reverse.tp  // Prints Stream(F, E, D, C, B, A)
Source
_mutate.scala
inline def reverseEvery(size: Int): Stream[A]

Reverse order in segments

Reverse order in segments

Reverses order of elements within segments of fixed size

(1 <> 15).stream.reverseEvery(5).tp

(1 <> 15).stream.reverseEvery(5).reverseEvery(3).reverseEvery(7).tp

// Output
Stream(5, 4, 3, 2, 1, 10, 9, 8, 7, 6, 15, 14, 13, 12, 11)

Stream(7, 2, 1, 10, 5, 4, 3, 12, 11, 6, 15, 14, 9, 8, 13)

Use Case: Predefined Shuffle

For testing purposes it is often required to get elements in random order. However the order cannot be completely random, if we want to replicate bugs

reverseEvery can shuffle elements in a predefined order which looks random

Source
_mutate.scala
inline def shuffle: Stream[A]

Randomize order

Randomize order

Re-arranges elements is random order

Note. "reverseEvery" might be a better choice if need repeatable randomness

Source
_mutate.scala
inline def synchronize: Stream[A]

Synchronize access

Synchronize access

Nothing fancy, just a convenience "synchronized" wrapper

 val nonSyncStream: Stream[Int] = (0 <>> 10000).stream

 (1 <> 10000).stream.parallel.map(_ => nonSyncStream.read ).stream.sort.takeDuplicates.count.tp  // Prints 0 to few hundred count

 val syncStream: Stream[Int] = (0 <>> 10000).stream.synchronize

 (1 <> 10000).stream.parallel.map(_ => syncStream.read ).stream.sort.takeDuplicates.count.tp    // Prints 0
Source
_mutate.scala
inline def transpose[B](using f: A => Stream[B]): Stream[Stream[B]]

Transpose

Transpose

Transposes matrix where rows become columns

 def stream : Stream[Stream[Int]] = Stream(11 <> 15,
                             List(21, 22, 23, 24, 25),
                             Vector(31, 32, 33, 34, 35))

 stream.print

 stream.transpose.print

 // Output
 ---------------------
 ?
 ---------------------
 Stream(11, 12, 13, 14, 15)
 Stream(21, 22, 23, 24, 25)
 Stream(31, 32, 33, 34, 35)
 ---------------------

 -------------
 ?
 -------------
 Stream(11, 21, 31)
 Stream(12, 22, 32)
 Stream(13, 23, 33)
 Stream(14, 24, 34)
 Stream(15, 25, 35)
 -------------
Source
_mutate.scala