In kotlin-stdlib-common is there any source of randomness available out of the box? Whether it's some implementation of standard java.util.Random, kotlin.math.random* or basic current time millis that I can use to create my own random number generator? I can't find any.
If it's not there, how would you get the source of randomness without setting your own platform dependent implementations? This is the only method I need:
expect class Rng {
fun nextInt(): Int
}
I'm trying to make it platform agnostic.
The answer would be: wait for Kotlin 1.3 to get released where the common library will be enriched with classes and methods that can provide the source for random values.
https://kotlinlang.org/docs/reference/whatsnew13.html#multiplatform-random
This maybe a post with many links, which may cause the problem of Your answer is in another castle: when is an answer not an answer?, so I try my best to write the link description. And my understanding of Kotlin Multiplatform is Kotlin-Multiplatform = Kotlin-JVM + Kotlin-JS.
I believe that the random number of Kotlin-JVM is provided by java.util.Random, and Math.Random() if it is Kotlin-JS, with these following reasons:
How can I get a random number in Kotlin?, and there is an answer in that question said that Kotlin-JS can use Math.Random() to get random number.
Can't get any result of any random number related method of Kotlin-JVM, but there is a random() in Kotlin-JS.
The source code of Kotlin-JVM related file, while using Random(), there is a import java.util.*, or some file directly use java.util.Random for example kotlin/libraries/stdlib/jvm/src/kotlin/collections/MutableCollectionsJVM.kt#L78.
And, java.util.Random is designed as result platform-independent, and also implementation platform-independent, with these reason:
Is Java's RNG (using seeds) platform-independent?, though this question may be out-dated.
We can't find keyword "native" in the source of JDK8/java.util.Random or the source of JDK10/java.util.Random, and the RNG logic is clear in these source code, where seed is decided by nanoTime() if not provided, and RNG is the implementation of Volume 2, TAOCP.
So, I think,
How would you get the source of randomness without setting your own platform dependent implementations?
Maybe a random-enough seed and a random-enough (P)RNG.
Related
Comparing the pages for both methods scan and runningFold (from kotlin.collections), the two appear to be identical save for the name.
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/scan.html
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/running-fold.html
Apparently there is no difference, check this out:
runningFold() and runningReduce() are introduced as synonyms for
scan() and scanReduce(). Such names are more consistent with the
related functions fold() and reduce(). In the future, scan() will be
available along with runningFold() since it’s a commonly known name
for this operation. The experimental scanReduce(), however, will be
deprecated and removed soon.
source: https://blog.jetbrains.com/kotlin/2020/05/1-4-m2-standard-library/
From the docs that say,
Returns the self-reference to the instance itself:
my $b; # defaults to Any
say $b.serial.^name; # OUTPUT: «Any»
my $breakfast = 'food';
$breakfast.serial.say; # OUTPUT: «food»
I do not have the foggiest what this routine does, please can someone explain?
On Supplys, it is an informational method that is supposed to indicate whether there will never be any concurrent emit on that Supply.
On HyperSeq and RaceSeq, it returns a serialized Seq, so you could consider it the opposite of the hyper and race method.
In general, it appears to return itself, which seems to make sense from the HyperSeq and RaceSeq point of view.
And yes, these should be documented properly, so please create a documentation issue. Thank you!
In the doc example it does nothing. That is, if you remove it you get the same results:
my $b; # defaults to Any
say $b.^name; # OUTPUT: «Any»
my $breakfast = 'food';
$breakfast.say; # OUTPUT: «food»
More generally, I think you'd best ignore the serial method other than to open a doc issue pointing to this SO if you'd like to improve the doc.
The serial method does not appear to be in the official language
A search of the roast repo for "serial" yields zero matches.
Within Rakudo source code the method name serial has been overloaded to have one of three meanings:
A boolean declaring whether a Supply sequence is always serial. Rakudo source examples: 1, 2. This looks to me like an internal method that doesn't need to be documented.
A coercion of parallel sequence (hyper or race) to a serial version of the same sequence. This looks to me like an internal method that doesn't need to be documented.
A "no op" that returns its invocant. I suspect it would be best if it were not documented, at least until such time as its raison d'etre is clear; its official status viz-a-viz the spec (roast) is clear; and/or there's an attempt to systematically document which operations have the is nodal set on them.
None of the above seems to warrant ordinary users' attention or documentation.
The Any class definition of a serial method seems pointless
The Any class serial method returns self, i.e. when called it is a no op.
I don't currently understand why there is an Any class definition.
One possible point for it would be that there are .serial calls made by internal code on instances of an unknown and generally unknowable class and there thus needs to be a default definition of serial in the Any class.
But a search of the rakudo repo for ".serial" suggests that calls are only made to supplies or hyper/race seqs.
That said, I note the is nodal trait on the proto serial declaration in Any that immediately precedes the multi method serial declaration. Perhaps that is the reason it's in Any.
See also Arbitrary drift of methods to Mu and Any.
The documentation you quoted seems pointless
The definition and example seem to reflect someone's sense of humor. I applaud use of humor but in this case I suspect the best improvement would be to just remove the page you linked.
Could someone help me to understand the difference between:
Mono.defer()
Mono.create()
Mono.just()
How to use it properly?
Mono.just(value) is the most primitive - once you have a value you can wrap it into a Mono and subscribers down the line will get it.
Mono.defer(monoSupplier) lets you provide the whole expression that supplies the resulting Mono instance. The evaluation of this expression is deferred until somebody subscribes. Inside of this expression you can additionally use control structures like Mono.error(throwable) to signal an error condition (you cannot do this with Mono.just).
Mono.create(monoSinkConsumer) is the most advanced method that gives you the full control over the emitted values. Instead of the need to return Mono instance from the callback (as in Mono.defer), you get control over the MonoSink<T> that lets you emit values through MonoSink.success(), MonoSink.success(value), MonoSink.error(throwable) methods.
Reactor documentation contains a few good examples of possible Mono.create use cases: link to doc.
The general advice is to use the least powerful abstraction to do the job: Mono.just -> Mono.defer -> Mono.create.
Although in general I agree with (and praise) #IlyaZinkovich's answer, I would be careful with the advice
The general advice is to use the least powerful abstraction to do the job: Mono.just -> Mono.defer -> Mono.create.
In the reactive approach, especially if we are beginners, it's very easy to overlook which the "least powerful abstraction" actually is. I am not saying anything else than #IlyaZinkovich, just depicting one detailed aspect.
Here is one specific use case where the more powerful abstraction Mono.defer() is preferable over Mono.just() but which might not be visible at the first glance.
See also:
https://stackoverflow.com/a/54412779/2886891
https://stackoverflow.com/a/57877616/2886891
We use switchIfEmpty() as a subscription-time branching:
// First ask provider1
provider1.provide1(someData)
// If provider1 did not provide the result, ask the fallback provider provider2
.switchIfEmpty(provider2.provide2(someData))
public Mono<MyResponse> provide2(MyRequest someData) {
// The Mono assembly is needed only in some corner cases
// but in fact it is always happening
return Mono.just(someData)
// expensive data processing which might even fail in the assemble time
.map(...)
.map(...)
...
}
provider2.provide2() accepts someData only when provider1.provide1() does not return any result, and/or the method assembly of the Mono returned by provider2.provide2() is expensive and even fails when called on wrong data.
It this case defer() is preferable, even if it might not be obvious at the first glance:
provider1.provide1(someData)
// ONLY IF provider1 did not provide the result, assemble another Mono with provider2.provide()
.switchIfEmpty(Mono.defer(() -> provider2.provide2(someData)))
In Java Streams - what is the difference between stream.max(Comparator) and stream.collect(Collectors.maxBy(Comparator)) in terms of preformance. Both will fetch the max based on the comparator being passed. If this is the case why do we need the additional step of collecting using the collect method? When should we choose former vs latter? What are the use case scenarios suited for using both?
They do the same thing, and share the same code.
why do we need the additional step of collecting using the collect method?
You don't. Use max() if that's what you want to do. But there are cases where a Collector can be handy. For example:
Optional<Foo> result = stream.collect(createCollector());
where createCollector() would return a collector based on some condition, which could be maxBy, minBy, or something else.
In general, you shouldn't care too much about the small performance differences that might exist between two methods that do the same thing, and have a huge chance of being implemented the same way. Instead, you should make your code as clear and readable as possible.
There is a relevant quote in Effective Java 3rd Edition, page 214:
The collectors returned by the counting method are intended only for use as downstream collectors. The same functionality is available directly on Stream, via the count method, so there is never a reason to say collect(counting()). There are fifteen more Collectors with this property.
Given that maxBy is duplicated by Stream.max, it is presumably one of these sixteen methods.
Shortly after, same page, it goes on to justify the dual existence:
From a design perspective, these collectors represent an attempt to partially duplicate the functionality of streams in collectors so that downstream collectors can act as "ministreams".
Personally, I find this edict and explanation a bit unsatisfying: it says that it wasn't the intent for these 16 collectors to be used like this, but not why they shouldn't.
I suppose that the methods directly on stream are able to be implemented in specialized ways which could be more efficient than the general collectors.
According to java Documentation ,
the below are definition for maxBy , minBy From Collectors class ,
static <T> Collector<T,?,Optional<T>> maxBy(Comparator<? super T> comparator)
Returns a Collector that produces the maximal element according to a given Comparator, described as an Optional<T>.
static <T> Collector<T,?,Optional<T>> minBy(Comparator<? super T> comparator)
Returns a Collector that produces the minimal element according to a given Comparator, described as an Optional<T>.
where as max() and min() in Stream return the Optional<T>
every stream pipeline operation can be divided into terminal and non terminal operation .
so by definition from java doc , it is one thing clear that Stream provided max() ,min() are terminal operation and return Optional<T> .
but the maxBy() and minBy() are Collector producing operation , so they can be used for chaining computation .
They both use BinaryOperator.maxBy(comparator) and do a reducing operation to the elements (even though the implementation of how it is reduced is slightly different). Hence there are no changes in the output.
If you need to find the max among all the stream elements, I suggest using Stream.max because the code would look neat and also you do not really need to create a collector in this case.
But there are scenarios where Collectors.maxBy need to be used. Assume that you need to group your elements and need to find the max in each group. In such scenarios you cannot use Stream.max. Here you need to use Collectors.groupingBy(mapper, Collectors.maxBy(...)). Similarly you could use it for partitionBy and other similar methods where you need a collector.
I am used to "old fashioned" waterfall development cycles.
For a new project, continuous integration seems to better fit our need.
In waterfall, you have to specify the tests you will to implement in advance.
My questions:
What is the usual way with continuous integration development cycles regarding test specification?
If you don't specify the tests, can you imagine a way to specify them in advance?
Many thanks for your help.
At university we were taught that "test driven development" makes sense, especially if there is a proper coding specification.
If you're not able to write tests before coding -> the coding spec should be more specific / has issues.
I usually write unit-tests based on the coding spec for my java classes, which will afterwards be integrated and executed on our jenkins continuous integration server.
Forgive me if i am wrong but thats what i learned...
It always depends on the complexity of the required java classes, the trivial "domain" classes do not need a big specification info
In most cases we try to specify how the Classes or Methods should work (in words) and also write down the some example values.
Lets say you should write a method that should check if a value is in a specifig range:
// Example Specification:
// the method 'checkIfItsInRange' should return true when : the input lies within the range and it should be devidable by the distance value
// Lets say the range goes from -30,00 to +30,00 with a distance from 0,25
// valid values :30, -30, 15.25, 15.50, 17.75 etc. -> return true
// invalid : -31, -30.01, +30.08, 0.4 etc. -> return false
// MissingParameterException when one of the Parameters is null
public boolean checkIfItsInRange throws MissingParameterException (BigDecimal from, BigDecimal to, BigDecimal distance, BigDecimal input) {
// TODO implement depending on spec.
}
In this case you can already write some Unittests before you started to implement the method itself.
I hope that makes things a bit clearer.