Ignore previous values sent by a CwlSignal - reactive-programming

I have a continuous parent signal that I derive various other signals from. Most of the subscribers are fine with the “continuous” semantics, meaning they do want to receive the last value upon subscribing. But with some subscribers I just want to receive the future values, no initial ones. Example:
import CwlSignal
let (input, signal) = Signal<Int>.create { s in s.continuous() }
input.send(value: 1)
input.send(value: 2)
let e1 = signal.subscribeValues { val in
print("A: \(val)")
}
let e2 = signal.subscribeValues { val in
print("B: \(val)")
}
input.send(value: 3)
input.close()
This prints:
A: 2
B: 2
A: 3
B: 3
Now I would like the second subscription not to receive the initial value, ie. the output should look like this:
A: 2
A: 3
B: 3
Is it possible to get that kind of behaviour without tweaking the parent signal?

I've never used CwlSignal, but it looks like it has a skip operator like most reactive frameworks. Does this work?
let e2 = signal.skip(1).subscribeValues { val in
print("B: \(val)")
}

This can be solved using multicast signals, quote reply from the library author:
let (input, multicastSignal) = Signal<Int>.create { s in s.multicast() }
let continuousSignal = multicastSignal.continuous()
input.send(value: 1)
input.send(value: 2)
let e1 = continuousSignal.subscribeValues { val in
print("A: \(val)")
}
let e2 = multicastSignal.subscribeValues { val in
print("B: \(val)")
}
input.send(value: 3)

Related

How can I elegantly return a map while doing work

I'm new to Scala, coming over from Java, and I'm having trouble elegantly returning Map from this function. What's an elegant way to rewrite this function so it doesn't have this awful repetition?
val data = getData
if (someTest(data)) {
val D = doSomething(data)
val E = doWork(D)
if (someTest2(E)) {
val a = A()
val b = B()
Map(a -> b)
} else {
Map.empty
}
} else {
Map.empty
}
If you have a problem with connecting too many conditions with &&, you can put everything into the natural short-circuiting monad (namely Option), perform bunch of filter and map-steps on it, replace the result by Map(A() -> B()) if all the tests are successful, and then unwrap the Option with a getOrElse in the end:
Option(getData)
.filter(someTest)
.map(doSomething andThen doWork)
.filter(someTest2)
.map(_ => Map(A() -> B()))
.getOrElse(Map.empty)
In this way, you can organize your code "more vertically".
Andrey's answer is correct, but the logic can also be written using a for statement:
(for {
data <- Option(getData) if someTest(data)
d = doSomething(data)
e = doWork(d) if someTest2(e)
} yield {
Map(A() -> B())
}).getOrElse(Map.empty)
This retains a bit more of the original form of the code, but it is a matter of taste which version to use. You can also put the if on a separate line if that makes it clearer.
Note that I have retained the values of d and e on the assumption that they are actually meaningful in the real code. If not then there can be a single if expression that does all the tests, as noted in other answers:
(for {
data <- Option(getData)
if someTest(data) && someTest2(doWork(doSomething(data)))
} yield {
Map(A() -> B())
}).getOrElse(Map.empty)
You may rewrite to take advantage of short circuit, if you are mentioning to the else blocks with Map.empty as repetition.
val data = getData
if (someTest(data) && someTest2(doWork(doSomething(data)))) {
val a = A()
val b = B()
Map(a -> b)
} else {
Map.empty
}
Second solution using lazy evaluation:
val data = getData
lazy val D = doSomething(data)
lazy val E = doWork(D)
if (someTest(data) && someTest2(E)) {
val a = A()
val b = B()
Map(a -> b)
} else {
Map.empty
}
D, E and someTest2(E) won't get evaluated if someTest(data) is false.

scala regex multiple integers

I have the following string that I would like to match on: 1-10 employees.
Here is my regex statement val regex = ("\\d+").r
The problem I have is Im trying to find a way to extract the matched data and determine which value returned is bigger.
Here is what IM doing to process it
def setMinAndMaxValue(currentCompany: CurrentCompany, matchIterator: Iterator[Regex.Match]): CurrentCompany = {
var max = 0
println(s"matchIterator - $matchIterator")
matchIterator.collect {
case regex(s: String) => println("found string")
case regex(IntConv(x)) =>
println("regex case")
if (x > max) max = x
}
val (minVal, maxVal) = rangesForMaxValue(max)
val newDetails = currentCompany.details.copy(minSize = Some(minVal), maxSize = Some(maxVal))
currentCompany.copy(details = newDetails)
}
object IntConv {
def unapply(s : String) : Option[Int] = Try {
Some(s.toInt)
}.toOption.flatten
}
I thought I was confused by your original question, then you clarified it with code and now I have no idea what you're trying to do.
To extract numbers from a string, try this.
val re = """(\d+)""".r
val nums = re.findAllIn(string_with_numbers).map(_.toInt).toList
Then you can just nums.min, and nums.max, and whatever number processing you need.

In Scala, how to define a `val` in a `if block`?

My Scala codes looks like this
if (true) {
val a = 1
}
else {
val a = 2
}
print(a)
print(a+100)
the print(a) will throw an error because a is out of scope when evaluating that line.. Then how can I define a val according to a conditional expression? Does anyone have ideas about this?
In scala if is expression - it returns value. So you could assign this value to val:
val a =
if (true) {
1
} else {
2
}
// for simple expressions:
val a2 = if (true) 1 else 2
print(a)
print(a+100)
It's good to note that this idiom can also be extended to declaring and setting multiple variables by taking advantage of destructuring assignment:
val (a, b) =
if (true) {
(1, 5)
} else {
(2, 10)
}
print(a)
print(b)
The above can further be extended to match statements and unpacking anything that can be unapply'd.
See also Programming in Scala/Built-in Control Structures

workaround for prepending to a LinkedHashMap in Scala?

I have a LinkedHashMap which I've been using in a typical way: adding new key-value
pairs to the end, and accessing them in order of insertion. However, now I have a
special case where I need to add pairs to the "head" of the map. I think there's
some functionality inside the LinkedHashMap source for doing this, but it has private
accessibility.
I have a solution where I create a new map, add the pair, then add all the old mappings.
In Java syntax:
newMap.put(newKey, newValue)
newMap.putAll(this.map)
this.map = newMap
It works. But the problem here is that I then need to make my main data structure
(this.map) a var rather than a val.
Can anyone think of a nicer solution? Note that I definitely need the fast lookup
functionality provided by a Map collection. The performance of a prepending is not
such a big deal.
More generally, as a Scala developer how hard would you fight to avoid a var
in a case like this, assuming there's no foreseeable need for concurrency?
Would you create your own version of LinkedHashMap? Looks like a hassle frankly.
This will work but is not especially nice either:
import scala.collection.mutable.LinkedHashMap
def prepend[K,V](map: LinkedHashMap[K,V], kv: (K, V)) = {
val copy = map.toMap
map.clear
map += kv
map ++= copy
}
val map = LinkedHashMap('b -> 2)
prepend(map, 'a -> 1)
map == LinkedHashMap('a -> 1, 'b -> 2)
Have you taken a look at the code of LinkedHashMap? The class has a field firstEntry, and just by taking a quick peek at updateLinkedEntries, it should be relatively easy to create a subclass of LinkedHashMap which only adds a new method prepend and updateLinkedEntriesPrepend resulting in the behavior you need, e.g. (not tested):
private def updateLinkedEntriesPrepend(e: Entry) {
if (firstEntry == null) { firstEntry = e; lastEntry = e }
else {
val oldFirstEntry = firstEntry
firstEntry = e
firstEntry.later = oldFirstEntry
oldFirstEntry.earlier = e
}
}
Here is a sample implementation I threw together real quick (that is, not thoroughly tested!):
class MyLinkedHashMap[A, B] extends LinkedHashMap[A,B] {
def prepend(key: A, value: B): Option[B] = {
val e = findEntry(key)
if (e == null) {
val e = new Entry(key, value)
addEntry(e)
updateLinkedEntriesPrepend(e)
None
} else {
// The key already exists, so we might as well call LinkedHashMap#put
put(key, value)
}
}
private def updateLinkedEntriesPrepend(e: Entry) {
if (firstEntry == null) { firstEntry = e; lastEntry = e }
else {
val oldFirstEntry = firstEntry
firstEntry = e
firstEntry.later = oldFirstEntry
oldFirstEntry.earlier = firstEntry
}
}
}
Tested like this:
object Main {
def main(args:Array[String]) {
val x = new MyLinkedHashMap[String, Int]();
x.prepend("foo", 5)
x.prepend("bar", 6)
x.prepend("olol", 12)
x.foreach(x => println("x:" + x._1 + " y: " + x._2 ));
}
}
Which, on Scala 2.9.0 (yeah, need to update) results in
x:olol y: 12
x:bar y: 6
x:foo y: 5
A quick benchmark shows order of magnitude in performance difference between the extended built-in class and the "map rewrite" approach (I used the code from Debilski's answer in "ExternalMethod" and mine in "BuiltIn"):
benchmark length us linear runtime
ExternalMethod 10 1218.44 =
ExternalMethod 100 1250.28 =
ExternalMethod 1000 19453.59 =
ExternalMethod 10000 349297.25 ==============================
BuiltIn 10 3.10 =
BuiltIn 100 2.48 =
BuiltIn 1000 2.38 =
BuiltIn 10000 3.28 =
The benchmark code:
def timeExternalMethod(reps: Int) = {
var r = reps
while(r > 0) {
for(i <- 1 to 100) prepend(map, (i, i))
r -= 1
}
}
def timeBuiltIn(reps: Int) = {
var r = reps
while(r > 0) {
for(i <- 1 to 100) map.prepend(i, i)
r -= 1
}
}
Using a scala benchmarking template.

method with angle brackets (<>)

Is it possible to have angle brackets in method names , e.g. :
class Foo(ind1:Int,ind2:Int){...}
var v = new Foo(1,2)
v(1) = 3 //updates ind1
v<1> = 4 //updates ind2
The real situation is obviously more complicated than this!!I am trying to provide a convenient user interface.
This response is not meant to be taken too seriously - just a proof that this can almost be achieved using some hacks.
class Vector(values: Int*) {
val data = values.toArray
def < (i:Int) = new {
def `>_=`(x: Int) {
data(i) = x
}
def > {
println("value at "+ i +" is "+ data(i))
}
}
override def toString = data.mkString("<", ", ", ">")
}
val v = new Vector(1, 2, 3)
println(v) // prints <1, 2, 3>
v<1> = 10
println(v) // prints <1, 10, 3>
v<1> // prints: value at 1 is 10
Using this class we can have a vector that uses <> instead of () for "read" and write access.
The compiler (2.9.0.1) crashes if > returns a value. It might be a bug or a result of misusing >.
Edit: I was wrong; kassens's answer shows how to do it as you want.
It is not possible to implement a method that would be called when you write v<1> = 4 (except, maybe, if you write a compiler plugin?). However, something like this would be possible:
class Foo {
def at(i: Int) = new Assigner(i)
class Assigner(i: Int) {
def :=(v: Int) = println("assigning " + v + " at index " + i)
}
}
Then:
val f = new Foo
f at 4 := 6
With a little trickery you can actually get quite close to what you want.
object Foo {
val a:Array[Int] = new Array(100)
def <(i:Int) = new Updater(a, i)
}
class Updater(a:Array[Int], i:Int) {
def update(x:Int) {
a(i) = x
}
def >() = this
}
Foo<1>() = 123
I am not sure why Scala requires the () though. And yes, this is a bit of a hack...