I have a java method to create a constraintstream out of all TeamCalendar objects (planning entity with pinned=true) that do not follow a given Preference.
As a result I would like to have a constraint stream that denotes for each department how many of these discrepancies exist. This is the java code:
private BiConstraintStream<Department, Integer> violatedPreferredTeamDays(ConstraintFactory constraintFactory) {
return constraintFactory.from(TeamCalendar.class)
.ifNotExists(Preference.class,
Joiners.equal(TeamCalendar::getDate, Preference::getDate),
Joiners.equal(TeamCalendar::getDepartment, Preference::getDepartment))
.filter((tc) -> {
return true;
})
.groupBy(TeamCalendar::getDepartment, count())
.filter((dep, count) -> {
return true;
});
}
When running this in Debug mode, the first filter (tc -> {return true;}) is entered a total of 20 times, 5 times for each of the 4 departments.
However, after groupBy, the result set seems to be empty. The debugger does not break code execution in that filter, and the penalize function used on this BiConstraintStream does not penalize anything.
I tried some trivial alternatives:
.groupBy(tc -> tc.getDepartment(), count())
.groupBy(tc -> { return tc.getDepartment(); }, count() )
as well as alternatives for the count method:
.groupBy(TeamCalendar::getDepartment, sum(tc -> 1) )
.groupBy(TeamCalendar::getDepartment, sum(tc -> {return 1;})
But without any improvement.
Am I overlooking something here?
The underlying engine applies the first filter directly on the TeamCalendar and pre-empts the ifNotExists call. Therefore you can not use the filter to check whether or not the ifNotExists has triggered or not.
Constraint Streams are not imperative, and the execution of individual building blocks need not happen in sequence. Constraint Streams can not be inspected using the debugger, unless you understand how the underlying Drools engine evaluates the constraints, and adjust your expectations accordingly.
As to why the groupBy result is empty - probably because the Preference instance actually exists. If that is not the case, please file a JIRA, attach a minimal executable code reproducer, and we will look into it.
Related
We have an API service call that returns a bunch of validation messages. In each message there is a string that contains an error code.
Our implementation converts the validation string into an enum value and then we process the enumeration as there are some error code we just don't care about.
The question becomes, how to handle the loop of messages in a Kotlin way:
response.validationErrors?.forEach {
val mediaFailure = decodeValidationMessage(it.message)
if (mediaFailure != MediaFailure.Unknown) {
return when (mediaFailure) {
MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
MediaFailure.NotSupported -> Response.validationFailed()
MediaFailure.InternalError -> Response.serviceFailed()
else -> throw NotImplementedError()
}
}
}
Here we loop through all the messages, then once the message error is not "Unknown" it returns the necessary response to the caller.
However, IntelliJ wants the else path, even though the if prevents that from happening.
Is there a proper Kotlin way of implementing this kind of loop?
From what I understood, you want to return a response for the first mediaFailure which is not MediaFailure.Unknown and you don't want that throw NotImplementedError() part in your function.
One way to fix this is to remove the if condition and continue the forEach loop when MediaFailure.Unknown is found.
response.validationErrors?.forEach {
val mediaFailure = decodeValidationMessage(it.message)
return when (mediaFailure) {
MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
MediaFailure.NotSupported -> Response.validationFailed()
MediaFailure.InternalError -> Response.serviceFailed()
MediaFailure.Unknown -> return#forEach // continue the loop
}
}
I think this is one of the many cases when it pays to step back from the code a bit and try to look at the big picture. To ask “What's the ultimate goal here? What am I trying to achieve with this code?”
(In traditional, lower-level languages, almost anything you want to do with a list or array requires a loop, so you get into the habit of reaching for a for or while without thinking. But there are often alternative approaches in Kotlin that can be more concise, clearer, and harder to get wrong. They tend to be more about what you're trying to achieve, rather than how.)
In this case, it looks you want to find the first item which decodes to give a known type (i.e. not MediaFailure.Unknown), and return a value derived from that.
So here's an attempt to code that:
val message = response.validationErrors?.asSequence()
?.map{ decodeValidationMessage(it.message) }
?.firstOrNull{ it != MediaFailure.Unknown }
return when (message) {
MediaFailure.Encrypted -> DomainResponse(ErrorReasonCode.ERR_DOCUMENT_ENCRYPTED)
MediaFailure.NotSupported -> Response.validationFailed()
MediaFailure.InternalError, null -> Response.serviceFailed()
else -> throw NotImplementedError()
}
This is still fairly similar to your code, and it's about as efficient. (Thanks to the asSequence(), it doesn't decode any more messages than it needs to.) But the firstOrNull() makes clear what you're looking for; and it's obvious that you go on to process only that one message — a fact which is rather lost in the original version.
(If there are no valid messages, message will be null and so this will return serviceFailed(), as per comments.)
There are of course many ways to skin a cat, and I can think of several variations. (It's often a worthwhile exercise to come up with some — if nothing else, it gives you more confidence in the version you end up with!) Try to pick whichever seems clearest, simplest, and best matches the big picture of what you're doing; that tends to work out best in the long run.
I'm pretty new with Kotlin and I'm trying to figure out Kotlin's scope functions.
My code looks like this:
with(something) {
when {
equals("test") -> var1 = "test123"
startsWith("test2") -> var2 = "test456"
contains("test3") -> myNullableVar?.let { it.var3 = "test789" }
}
}
So before I entered the third check with the .let function my with function does not need to be exhaustive (I'm not returning something, I'm only doing assignments). In my third check I'm using .let as a null-check ... but only for an assignment of it.var3 (if it is not null). I don't need to return anything while I know that Kotlin's .let function returns the result of the body by standard.
Nevertheless now my with/when needs to be exhaustive otherwise it won't compile anymore.
This got me thinking and trying out different things. I found these ways to solve this issue:
I can add an else to my with/when so it becomes exhaustive but actually I don't need an else and I don't want to use it in this case.
I can add another .let, so it looks like this: myNullableVar?.let { it.var3 = "test789" }.let{} .... but this looks kinda hacky to me. Is it supposed to work like this?
Use If(xy==null){...}else{...} stuff but I thought I can solve this with Kotlin differently
Because I'm new with Kotlin I'm not really sure how to handle this case properly. I would probably just go with my second idea because "it works". Or should I don't use .let for null-checks? Add another empty .let{}? Or did I not get the null-safety concept at all? I feel a little bit lost here. Thanks for any help.
This seems to be an unfortunate combination of features…
A when can be non-exhaustive only when it doesn't return a value. The problem is that the with() function does return a value. And since the when is at the bottom, its value is what gets returned, so in this case it must be exhaustive.
So why doesn't it insist on an else branch even if you omit the "test3" branch? That's because assignments don't yield a value. (They evaluate to Unit, which is Kotlin's special type for functions that don't return a useful value.) If every branch gives Unit, then Kotlin seems* to be happy to infer a default branch also giving Unit.
But the "test3" branch returns something else — the type of myNullableVar. So what type does the when infer? The nearest common supertype of that type and Unit, which is the top type Any?. And now it needs an explicit else branch!
So what to do?
You've found a few options, none of which is ideal. So here are a few more, ditto!
You could return an explicit Unit from that branch:
contains("test3") -> { myNullableVar?.let { it.var3 = "test789" }; Unit }
You could return an explicit Unit from the with():
contains("test3") -> myNullableVar?.let { it.var3 = "test789" }
}
Unit
}
You could give an explicit type for the with(). (It has two type parameters, so you'd need to give both, starting with the type of its parameter):
with<String, Unit>("abc") {
I haven't found a single obvious best answer, I'm afraid…
And to answer your last question: yes, ?.let{ is perfectly idiomatic and common for null checks. In this particular case, replacing it with an if happens to solve the type problem:
contains("test3") -> { if (myNullableVar != null) myNullableVar.var3 = "test789" }
But as well as being long-winded, if myNullableVar is a property and not a local variable, then it opens up a race condition (what if another thread sets it to null in between the test and the assignment?) so the compiler would complain — which is exactly why people use let instead!
(* I can't find a reference for this behaviour. Is there an official word on it?)
Let's say I want to connect to two package repositories, make a query for a package name, combine the result from the repos and process it (filter, unique, prioritize,...), What is a good way to do that?
What I though about is creating Array of two Cro::HTTP::Client objects (with base-uri specific to each repo), and when I need to make HTTP request I call #a>>.get, then process the result from the repos together.
I have attached a snippet of what I'm trying to do. But I would like to see if there is a better way to do that. or if the approach mention in the following link is suitable for this use case! https://perl6advent.wordpress.com/2013/12/08/day-08-array-based-objects/
use Cro::HTTP::Client;
class Repo {
has $.name;
has Cro::HTTP::Client $!client;
has Cro::Uri $.uri;
has Bool $.disable = False;
submethod TWEAK () {
$!client = Cro::HTTP::Client.new(base-uri => $!uri, :json);
}
method get (:$package) {
my $path = <x86_64?>;
my $resp = await $!client.get($path ~ $package);
my $json = await $resp.body;
return $json;
}
}
class AllRepos {
has Repo #.repo;
method get (:$package) {
# check if some repos are disabled
my #candidate = #!repo>>.get(:$package).unique(:with(&[eqv])).flat;
# do furthre processign of the data then return it;
return #candidate;
}
}
my $repo1 = Repo.new: name => 'repo1', uri => Cro::Uri.new(:uri<http://localhost:80>);
my $repo2 = Repo.new: name => 'repo2', uri => Cro::Uri.new(:uri<http://localhost:77>);
my #repo = $repo1, $repo2;
my $repos = AllRepos.new: :#repo;
#my #packages = $repos.get: package => 'rakudo';
Let's say I want to connect to two package repositories, make a query for a package name, combine the result from the repos and process it (filter, unique, prioritize,...), What is a good way to do that?
The code you showed looks like one good way in principle but not, currently, in practice.
The hyperoperators such as >>:
Distribute an operation (in your case, connect and make a query) ...
... to the leaves of one or two input composite data structures (in your case the elements of one array #!repo) ...
... with logically parallel semantics (by using a hyperoperator you are declaring that you are taking responsibility for thinking that the parallel invocations of the operation will not interfere with each other, which sounds reasonable for connecting and querying) ...
... and then return a resulting composite data structure with the same shape as the original structure if the hyperoperator is a unary operator (which applies in your case, because you applied >>, which is an unary operator which takes a single argument on its left, so the result of the >>.get is just a new array, just like the input #!repo) or whose shape is the hyper'd combination of the shapes of the pair of structures if the hyperoperator is a binary operator, such as >>op<< ...
... which can then be further processed (in your case it is, with .unique, which will produce a resulting Seq) ...
... whose elements you then assign back into another array (#candidate).
So your choice is a decent fit in principle, but the commitment to parallelism is only semantic and right now the Rakudo compiler never takes advantage of it, so it will actually run your code sequentially, which presumably isn't a good fit in practice.
Instead I suggest you consider:
Using map to distribute an operation over multiple elements (in a shallow manner; map doesn't recursively descend into a deep structure like the hyperoperators, deepmap etc., but that's OK for your use case) ...
... in combination with the race method which parallelizes the method it proceeds.
So you might write:
my #candidate =
#!repo.hyper.map(*.get: :$package).unique(:with(&[eqv])).flat;
Alternatively, check out task 94 in Using Perl 6.
if the approach mention in the following link is suitable for this use case! https://perl6advent.wordpress.com/2013/12/08/day-08-array-based-objects/
I don't think so. That's about constructing a general purpose container that's like an array but with some differences to the built in Array that are worth baking into a new type.
I can just about imagine such things that are vaguely related to your use case -- eg an array type that automatically hyper distributes method calls invoked on it, if they're defined on Any or Mu (rather than Array or List), i.e. does what I described above but with the code #!repo.get... instead of hyper #!repo.map: *.get .... But would it be worth it (assuming it would work -- I haven't thought about it beyond inventing the idea for this answer)? I doubt it.
More generally...
It seems like what you are looking for is cookbook like material. Perhaps a question posted at the reddit sub /r/perl6 is in order?
I populate an object based on the users input from the commandline.
The object needs to have a certain amount of data to proceed. My solution so far is nested if-statements to check if the object is ready. Like below example.
Maybe 3 if-statements aren't so bad(?) but what if that number of if-statements starts to increase? What are my alternatives here? Let's say that X, Y and Z are three completely different things. For example let's say that object.X is a list of integers and object.Y is a string and maybe Z is some sort of boolean to return true only if object.Y has a certain amount of values?
I'm not sure polymorhism will work in this case?
do
{
if (object.HasX)
{
if (object.HasY)
{
if (object.HasZ)
{
//Object is ready to proceed.
}
else
{
//Object is missing Z. Handle it...
}
}
else
{
//Object is missing Y. Handle it...
}
}
else
{
//Object is missing X. Handle it...
}
} while (!String.IsNullOrEmpty(line));
For complex logic workflow, I have found, it's important for maintainability to decide which level of abstraction the logic should live in.
Will new logic/parsing rules have to be added regularly?
Unfortunately, there isn't a way to avoid having to do explicit conditionals, they have to live somewhere.
Some things that can help keep it clean could be:
Main function is only responsible for converting command line arguments to native datatypes, then it pushes the logic down to an object builder class, This will keep main function stable and unchanged, except for adding flag descriptions, THis should keep the logic out of the domain, and centralized to the builder abstraction
Main function is responsible for parsing and configuring the domain, this isolates all the messy conditionals in the main/parsing function and keeps the logic outside of the domain models
Flatten the logic, if not object.hasX; return, next step you know has.X, this will still have a list of conditionals but will be flatter
Create a DSL declarative rule language (more apparent when flattening). This could be a rule processor, where the logic lives, then the outer main function could define that states that are necessary to proceed
I often come to this question when coding.
Which of the following examples is a better practice? I am aware that other factors will influence whether one or the other one is better. But in general, what are the advantages of one over the other.
if(object.getA().Value != null) {
return object.getA().Value;
}
return null;
Vs.
string x = string.null;
x = object.getA().Value;
return (x != null) ? x : null;
Here is another similar example:
var a = object.method(x).Value;
var b = object.method(x).Key;
Vs.
var y = object,method(x);
var a = y.Value;
var b = y.Key;
In other words my question is:
Is it better to call a method twice and have one less variable?
or
Is it better to save it into a variable and call the method twice?
Of course if the method results in a lot of processing it might be smart to call it once, but for general cases where the method is not too demanding and the space of the variable is not too big, which one is better and why? or which are the advantages of one or the other?
The difference between them might not make a big difference but I am trying to find better practices and will like to hear the input of some experienced programmers.
Many thanks
Caching the value in a variable is a basic optimization (related to memoizing).
When it becomes truly necessary is if the second call to the function is on the stack a significant percent of the time.
For example, if that second call is on the stack 10% or 20% of the time, then that's how much overall time you can save by caching the first result.
You can keep doing things like that, until the code is as fast as possible.
If I can give an example, ages ago I worked on an app that had code like this:
if (!Done()){
do some stuff
}
....
if (!Done()){
do some other stuff
}
Since Done() was such a short, clean, and simple function to call, it got called a lot.
Never mind that it did a lot including querying a ton of stuff from a DB and throwing most of it away.
Stackshots found the problem instantly.
It depends if you want to be thread safe and if the function could change between calls.
e.g. with
if(object.getA().Value != null) {
return object.getA().Value;
}
return null;
if the implementation of the property getter Value returned a null on the second call you would have a different answer. It could return null on the second call either by implementation of the method or if another thread casused an update between the if and the return statement that made the result of the property null.
This test is actually redundant because you are returning null if it is null. I'm guessing that you meant if (object.getA() != null). Then the previous paragraph still applies but to getA() instead of Value but the if body would throw an null reference exception if getA() returned null on the second call.
So its all down to whether you are worried about the values changing between calls.
General rule: Avoid extra variables (needlessly introduces states).
(Break the rule if calling the function twice adds too much overhead)