Doing this on kotlin is a bad practice? - kotlin

The second way is a little smaller but i dont know if this is okay, can i use also just for be able to use expression body and put the first line of the cod on the side of method name?
override fun findOrdensColeta() {
view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
override fun findOrdensColeta() = view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}

Yes, I think the second version is bad style. I see no good reasons to use also() like that, and several reasons not to:
also() is intended for use within expressions, where you don't have the option of adding a separate statement. (The classic case is logging a value before doing something with it.) That doesn't apply here, where two simple statements work just as well. So there's no benefit other than conciseness; using also() here is unnecessary complexity.
The second version has an expression body, which looks like it returns a useful value — but it actually returns the result of calling setProgressBarVisibility(), which is presumably Unit just like the first version. So the expression body is highly misleading.
Also, the only reason that the second version is shorter is that the first statement has been squeezed onto the same line. I don't think that's justified here* — it joins two things (the function signature and the call to setProgressBarVisibility()) that aren't directly related, and it makes the line too long for most people to read easily. (I'm surprised you find the second version easier to read. I tend to prefer conciseness, but even I find the first version a good deal easier to read — probably because it falls into a very familiar pattern that doesn't need any extra thought.)
If you cared only about reducing the number of lines, then the first version could be written like this (not recommended!):
override fun findOrdensColeta() { view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
(You could join even more lines, perhaps squeezing it all onto a single line if you wanted to make it completely unreadable!)
Conversely, if there were other good reasons for using the second version, it would be better if wrapped like this:
override fun findOrdensColeta()
= view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
So as you can see, the difference in length is mainly due to the (unjustified and confusing) line-joining, not the use of also().
So using also() here has no real benefit, as well as some significant drawbacks.
* I'm not saying you should never put the function body on the same line as its signature. That can work well if the body is an expression that's short enough to fit neatly all one line. For example:
override fun toString() = "MyClass(val1 = $val1)"
However, if that makes the line very long, or wraps onto further lines, or is a function body, then it's almost always more readable to start the body on the next line in the traditional fashion.

I believe the second one is a bad approach.
also is designed to provide the ability to modify or use the receiver and return it afterwards.
In your case, also is not containing any usages of its receiver (which is the result of view.setProgressBarVisibility(View.VISIBLE) ). Therefore it is not needed here

The second version is a bit confused to me - if you take the first one as the standard way to do things, a simple code block with two statements in it, what benefit does the second one really give you? You're basically using expression syntax to make it a one-liner - but it's not a one-liner, so you have to add a scope function just to give yourself back the curly braces so you can add another line of code!
So this:
override fun findOrdensColeta() {
view.setProgressBarVisibility(View.VISIBLE)
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
Does exactly the same thing as this:
override fun findOrdensColeta() = view.setProgressBarVisibility(View.VISIBLE).also {
model.findOrdensColeta {
handleFindOrdensColeta()
}
}
But with the latter
it appears to return a result from setProgressBarInvisibility because it's a single-expression function (the original clearly returns nothing)
the use of also which passes that result value through reinforces the idea that you're trying to return that result
the also block implies you're using that value for something (otherwise why's it there?) and it takes a moment to see that you're not
when you realise none of the above are true, now you might be wondering if you're missing something, or if the original coder intended something specific but made a mistake
Because the basic function block is so simple and readable and a natural fit for what you're doing, doing something else can throw up some questions, or be confusing to read. Sure the way it's formatted you've saved a single line, but now it's harder to understand, y'know?
This is something to watch out for in Kotlin I think (and I'm guilty of this myself) - being able to chain stuff together sometimes encourages people to go for "one-liners" that are hard to follow, but hey at least you didn't (explicitly) create a variable! That's not what you're doing here (you're creating an unnecessary variable actually!) but it feels like a similar thing - trying to make a single expression instead of doing things the old-school way.
Coding is about trying to strike that balance between simplicity and readability, and elegant efficiency, and a lot of it's about learning what tools and tricks are available, and knowing when to use them (and how best to do it) and when to avoid them. At the end of the day it's a style choice and this is just my opinion (although all the other commenters so far are saying similar things) but hopefully it's given you something to think about! I've been there too - including using expressions for functions that don't return a value at all - but I think that's all part of learning a language and the things it offers you

Related

Is there a use for the "with" function that I can't achieve by "apply", "run", "also" or "let" in Kotlin?

When would we ever need with in Kotlin if we can already use apply, run, also and let?
Can anyone give me a clear example?
In most situations, a with call can be transformed to a run like this:
with(foo) {
// some code ...
}
// is the same as:
foo.run {
// the same code ...
}
run and with will both return the lambda result, and will use foo as the lambda receiver.
However, I can think of one case where this wouldn't work - when foo declares its own run method that takes a lambda, e.g.
// having something like this isn't too uncommon, right?
fun run(x: () -> Unit) {}
The lambda type doesn't have to be exactly the same as the scope function run. Any function type should work. Then overload resolution wouldn't resolve to the built-in run.
You can force the resolution by doing some casts, but using with in this case is much better. Don't you agree?
I don’t think there’s any better example than with(context). Maybe it’s not clear if English isn’t one of your primary languages, but it semantically is translated into English much clearer than context.run when the object is being used to produce a result but isn’t the primary actor, so it makes code a little easier to read.
This of course raises the question of why run exists. Well, it semantically makes more sense in English when the object is the thing doing the action. In English, the context of an action is what you’re doing something with. But if the object is what is directly producing the result, then it is running the action.
Also, you can’t do ?.with.

Should I use an explicit return type for a String variable in Kotlin?

In Kotlin, We can declare a string read-only variable with type assignment and without type assignment (inferred) as below.
val variable_name = "Hello world"
or
val variable_name: String = "Hello world"
I'm trying to figure out what is the best in Kotlin and why it is the best way. Any idea?
If this is a public variable, using an explicit return type is always a good idea.
It can make the code easier to read and use. This is why your IDE probably shows the return type anyway, even when you omit it from the code. It's less important for simple properties like yours where the return type is easy to see at a glance, but when the property or method is more than a few lines it makes much more difference.
It prevents you from accidentally changing the type. With an explicit return type, if you change the contents of the property so that it doesn't actually return the correct type, you'll get an immediate compile error in that method or property. With an implicit type, if you change the contents of the method you could see cascading errors throughout your code base, making it hard to find the source of the error.
It can actually speed up your IDE! See this blog post from the JetBrains team for more information.
For private variables, explicit return types are much less important, because the above points don't generally apply.
Personally either one works and for me nothing is wrong, but I would choose the later if this is a team project, where project size increase and feature inheritance(members leaving, new hiring or worse shuffling people) is probable. Also I consider the later as more of a courtesy.
There are situations where regardless of the dogma every member follows, such as clean architecture, design-patterns or clean-coding, bloated codes or files are always expected to occur in such big projects occasionally, so the later would help anyone especially new members to easily recognize at first glance what data type they are dealing with.
Again this this is not about right or wrong, as kotlin is created to be idiomatic, I think this is Autoboxing, it was done in kotlin for codes to be shorter and cleaner as few of its many promise, but again regardless of the language, sometimes its the developer's discretion to have a readable code or not.
This also applies with function return types, I always specify my function return types just so the "new guy" or any other developer will understand my function signatures right away, saving him tons of brain cells understanding whats going on.
fun isValidEmail() : Boolean = if (condition) true else false
fun getValidatedPerson(): Person = repository.getAuthenticatedPersonbyId(id)
fun getCurrentVisibleScreen(): #Composable ()-> Unit = composables.get()
fun getCurrentContext(): Context if (isActivity) activityContext else applicationContext

Let vs run when it comes to check null

I've noticed most people use object?.let {} for checking if something is null.
But why they chose let instead of run ? We can achieve exactly the same using object?.run {}
I know only difference is this and it inside the scope, but it probably doesn't matter.
You said it : the difference comes from "this" and "it" !
Everybody uses let for a good reason : run should be used when you want to return something, just like let, where apply or also return the object it was called on.
But then, what is the difference between run and let ? Well, run should be used when you treat mostly the object as a receiver, on which you want to call a bunch of methods : as this can be used implicitely, it's faster to write and easier to read.
But when the object is used as a value, then let is preferable, because the value is named it, which is shorter to use as a value (2 letters instead of 4), but more importantly, it is more readable ! Try reading :
myComputationThatMightReturnNull()?.let { it * 2 }
and
myComputationThatMightReturnNull()?.run { this * 2 }
The first one sounds more like spoken english, where the second is longer and more difficult to understand.
Because often the nullable value is used as... a value when it isn't null, let is most likely to be used in this case than run. But don't be afraid to use the latter when it seems right to you to do so, it's just a rule of thumb.

Effectiveness of ?: , null-safety and Elvis operator?

I am referring to the Null-Safety in Kotlin:
A colleague of mine writes always like:
bob ?: return
bob.department ?: return
bob.department.head ?: return
bob.department.head.name()
Readability is his argument. This is for me not very Kotlin like and more overelaborated. Of course I prefer:
bob?.department?.head?.name()
Some arguments/docs/links not using upper way would be very helpful.
I would like to know if there are any disadvantages using upper way?
Also, I can imagine that some compiler optimization won't work very well, doing the upper way?
EDIT:
According to SVN the history tells:
if (bob != null) {
if (bob.department != null) {
if (bob.department.head != null) bob.department.head.name()
}
}
Your version means something different: if any of the relevant values are null, your version evaluates to null without evaluating the rest of the expression, while your colleague's returns immediately without executing the rest of the function.
(Of course, if that's the end of the function anyway, the effect may be the same; we can't tell without seeing some context.)
So which one to prefer depends on whether a null value should abort everything following.
In general, though, your version is much more common in my experience.  It also has two advantages: it's more concise (which, when all other things are equal, is a Good Thing™ IMHO) with less repetition (so following DRY); and it's less likely to cause surprises when someone later adds extra lines afterward, so they don't have to track back and find out why they're not being executed.
As for readability, lines like yours are a common idiom in Kotlin, and so developers really ought to find them readable enough.  In fact, the ability to avoid long chains of tests like your colleague's (as are needed in Java) is one of the main benefits of the ?. safe-call operator!

Boolean method naming readability

Simple question, from a readability standpoint, which method name do you prefer for a boolean method:
public boolean isUserExist(...)
or:
public boolean doesUserExist(...)
or:
public boolean userExists(...)
public boolean userExists(...)
Would be my prefered. As it makes your conditional checks far more like natural english:
if userExists ...
But I guess there is no hard and fast rule - just be consistent
I would say userExists, because 90% of the time my calling code will look like this:
if userExists(...) {
...
}
and it reads very literally in English.
if isUserExist and if doesUserExist seem redundant.
Beware of sacrificing clarity whilst chasing readability.
Although if (user.ExistsInDatabase(db)) reads nicer than if (user.CheckExistsInDatabase(db)), consider the case of a class with a builder pattern, (or any class which you can set state on):
user.WithName("Mike").ExistsInDatabase(db).ExistsInDatabase(db2).Build();
It's not clear if ExistsInDatabase is checking whether it does exist, or setting the fact that it does exist. You wouldn't write if (user.Age()) or if (user.Name()) without any comparison value, so why is if (user.Exists()) a good idea purely because that property/function is of boolean type and you can rename the function/property to read more like natural english? Is it so bad to follow the same pattern we use for other types other than booleans?
With other types, an if statement compares the return value of a function to a value in code, so the code looks something like:
if (user.GetAge() >= 18) ...
Which reads as "if user dot get age is greater than or equal to 18..." true - it's not "natural english", but I would argue that object.verb never resembled natural english and this is simply a basic facet of modern programming (for many mainstream languages). Programmers generally don't have a problem understanding the above statement, so is the following any worse?
if (user.CheckExists() == true)
Which is normally shortened to
if (user.CheckExists())
Followed by the fatal step
if (user.Exists())
Whilst it has been said that "code is read 10x more often than written", it is also very important that bugs are easy to spot. Suppose you had a function called Exists() which causes the object to exist, and returns true/false based on success. You could easily see the code if (user.Exists()) and not spot the bug - the bug would be very much more obvious if the code read if (user.SetExists()) for example.
Additionally, user.Exists() could easily contain complex or inefficient code, round tripping to a database to check something. user.CheckExists() makes it clear that the function does something.
See also all the responses here: Naming Conventions: What to name a method that returns a boolean?
As a final note - following "Tell Don't Ask", a lot of the functions that return true/false disappear anyway, and instead of asking an object for its state, you tell it to do something, which it can do in different ways based on its state.
The goal for readability should always be to write code the closest possible to natural language. So in this case, userExists seems the best choice. Using the prefix "is" may nonetheless be right in another situations, for example isProcessingComplete.
My simple rule to this question is this:
If the boolean method already HAS a verb, don't add one. Otherwise, consider it. Some examples:
$user->exists()
$user->loggedIn()
$user->isGuest() // "is" added
I would go with userExists() because 1) it makes sense in natural language, and 2) it follows the conventions of the APIs I have seen.
To see if it make sense in natural language, read it out loud. "If user exists" sounds more like a valid English phrase than "if is user exists" or "if does user exist". "If the user exists" would be better, but "the" is probably superfluous in a method name.
To see whether a file exists in Java SE 6, you would use File.exists(). This looks like it will be the same in version 7. C# uses the same convention, as do Python and Ruby. Hopefully, this is a diverse enough collection to call this a language-agnostic answer. Generally, I would side with naming methods in keeping with your language's API.
There are things to consider that I think were missed by several other answers here
It depends if this is a C++ class method or a C function. If this is a method then it will likely be called if (user.exists()) { ... } or if (user.isExisting()) { ... }
not if (user_exists(&user)) .
This is the reason behind coding standards that state bool methods should begin with a verb since they will read like a sentence when the object is in front of them.
Unfortunately lots of old C functions return 0 for success and non-zero for failure so it can be difficult to determine the style being used unless you follow the all bool functions begin with verbs or always compare to true like so if (true == user_exists(&user))
Why not rename the property then?
if (user.isPresent()) {
Purely subjective.
I prefer userExists(...) because then statements like this read better:
if ( userExists( ... ) )
or
while ( userExists( ... ) )
In this particular case, the first example is such horrible English that it makes me wince.
I'd probably go for number three because of how it sounds when reading it in if statements. "If user exists" sounds better than "If does user exists".
This is assuming it's going to be to used in if statement tests of course...
I like any of these:
userExists(...)
isUserNameTaken(...)
User.exists(...)
User.lookup(...) != null
Method names serves for readability, only the ones fit into your whole code would be the best which most of the case it begins with conditions thus subjectPredicate follows natural sentence structure.
Since I follow the convention to put verb before function name, I would do the same here too:
//method name
public boolean doesExists(...)
//this way you can also keep a variable to store the result
bool userExists = user.doesExists()
//and use it like a english phrase
if (userExists) {...}
//or you can use the method name directly also and it will make sense here too
if (user.doesExists()) {...}