Coupling between public functions - oop

Lets say I have a function called do3()
In order for that function to work I need the functions do1() and do2() be executed.
However, do1() and do2() could also be needed for other stuff (maybe for do4())
All these functions are public (and must be public).
Question, how should i implement the code?
Option 1 :
function do3() {
do2()
do whatever is needed for do3
}
function do2() {
do1()
do whatever is needed for do2
}
function do1() {
do whatever is needed for do1
}
So if i call do3(), i am sure that everything will be done, although coupling will appear
Option 2
function do3() {
do whatever is needed for do3
}
function do2() {
do whatever is needed for do2
}
function do2() {
do whatever is needed for do1
}
So when i want to call do3() i have to
do1()
do2()
do3()
I feel that the second option is better as it has less coupling, however I cannot really explain why, it is more like a feeling. I think that if I use option one and one day I change do2() I may have problems.
With option 2 however I must be sure to call do1 and do2 every time i want to use do3.
If someone has a better idea (option 3?) would be great to.
Thanks

Coupling is a concept related to classes not functions.
A function should be able to call any other function of the same class that it lives in.
There is no coupling issue there.
Your first option is fine there is nothing wrong with do3 calling do2 and do2 calling do1 as long as they all are in the same class.
You shouldn't go for option 2 of yours since it would require you to repeat code everywhere.

"Lets say I have a function called do3() In order for that function
to work I need the functions do1() and do2() be executed. "
Juan: As per your description do3() is dependent on do1() and do2().
The dependency Graph is
- ->do2()
do3()
- ->do1()
In this case you should go for the second approach.
If your dependency graph is:
do3()- ->do2() - -> do1()
ie
do3 depends on do2
do2 depends on do1
In this case you should go for first approach.
--> : shows the dependency.

The short answer is that if do3() always must proceed a call to do2/do1 and there are not contexts when a caller may need to perform some action between those calls, then do2 should indeed be included in do3 and so on. I would also assert that unless the doX calls are part of an API or other difficult to change environment, it would be wise to avoid separating the calls "just in case" some case arises in the future that requires their splitting (principle of cautious design).
Longer answer:
One way to test the truth of something is to explore pathological cases. Taking your second option to the extreme would basically entail complete unraveling of functional composition to the point of elimination of functions entirely; after all, some function is calling do1() do2() do3() and is thus "coupled" to those functions.
[soap box]
It is simply not a true proposition that static dependencies (coupling) are necessarily a vice, though this notion is popular right now. Static dependencies may seem inflexible, but they are also easy to comprehend, machine verifiable, and highly optimizable. To illustrate the point, consider this hypothetical code:
person = WebRequest('/GetPerson');
if (person.Phone.AreaCode = '')
person.Phone.AreaCode = GetAreaCodeFromZip(person.Zip);
...
Logic like this can be, and often is decompose for a myriad of reasons into perhaps:
requestService = CreationFactory(IRequest);
requestService.Configure(ConfigurationService.GetConfiguration(requestService));
requestService.SetEntityContext('Person');
response = requestService.Invoke();
entity = EntityService.ProcessEntity(response.Data);
EntityService.RegisterEntityCorrectionService(entity, IAreaCorrectionService);
...
interface IAreaCorrectionService
...
class AreaCorrectionService : IAreaCorrectionService
...
ServiceFactory.Register(AreaCorrectionService...
My point is simply that there is a cost in terms of performance, readability, and even decreased declarativeness to "decoupling". This is rarely explicitly considered when inversion of control, and other frameworks are considered.

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

Doing this on kotlin is a bad practice?

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

Using inline function kotlin

I know there was documented in main kotlin page, but there is no clear explanation about when to use it, why this function need a receiver as a function. What would be the correct way to create a correct definition of inline function.
This is inline function
inline fun String?.toDateString(rawDateFormat: String = MMMM_DD_YYYY, outputDate: String = MM_DD_YYYY, block: (date: String) -> String): String {
return try {
var sdf = SimpleDateFormat(rawDateFormat, Locale.US)
val date = sdf.parse(this.orEmpty())
sdf = SimpleDateFormat(outputDate, Locale.US)
block(sdf.format(date ?: Date()).orEmpty())
} catch (ex: Exception) {
block("")
}
}
The same way we also can do
inline fun String?.toDateString(rawDateFormat: String = MMMM_DD_YYYY, outputDate: String = MM_DD_YYYY): String {
return try {
var sdf = SimpleDateFormat(rawDateFormat, Locale.US)
val date = sdf.parse(this.orEmpty())
sdf = SimpleDateFormat(outputDate, Locale.US)
sdf.format(date ?: Date()).orEmpty()
} catch (ex: Exception) {
""
}
}
If anyone could have a detail explanation about this?
Edit:
I understand that the inline function will insert the code whenever it called by the compiler. But this come to my attention, when I want to use inline function without functional parameter receiver type the warning show as this in which should have a better explain. I also want to understand why this is such recommendation.
There are few things here.
First, you ask about using a function with a receiver.  In both cases here, the receiver is the String? part of String?.toDateString().  It means that you can call the function as if it were a method of String, e.g. "2021-01-15 12:00:00".toDateString(…).
The original String? is accessible as this within the function; you can see it in the sdf.parse(this.orEmpty()) call.  (It's not always as obvious as this; you could simply call sdf.parse(orEmpty()), where the this. is implied.)
Then you ask about inline functions.  All you have to do is to mark the function as inline, and the compiler will automatically insert its code wherever it's called, instead of defining a function in the usual way.  But you don't need to worry about how it's implemented; there are just a few visible effects in the code.  In particular, if a function is inline and accepts a function parameter, then its lambda can do a few things (such as calling return) that it couldn't otherwise do.
Which leads us to what I think is your real question: about the block function parameter.  Your first example has this parameter, with the type (date: String) -> String — i.e. a function taking a single String parameter and returning another String.  (The technical term for this is that toDateString() is a higher-order function.)
The toDateString() function calls this block function before returning, applying it to the date string it has formatted before returning it to the caller.
As to why it does this, it's hard to tell.  That's why we put documentation comments before functions: to explain anything that's not obvious from the code!  Ideally, there would be a comment explaining why you're required to supply a block lamdba (or function reference), when it's not vital to what the function does.
There are times when blocks passed this way are very useful.  For example, the joinToString() function accepts an optional transform parameter, which it applies to each item before joining it to the list.  If it didn't, the effect would be a lot more awkward to obtain.  (You'd probably have to apply a map() to the collection before calling joinToString(), which would be less efficient.)
But this isn't one of those times.  As your second example shows, toDateString() would work perfectly well without the block parameter — and then if you needed to pass the result through another function, you could just call it on toDateString()'s result.
Perhaps if you included a link to the ‘main kotlin page’ where you saw this, it might give some more context?
The edited question also asks about the IDE warning.  This is shown when it thinks inlining a function won't give a significant improvement.
When no lambdas are involved, the only potential benefit from inlining a function is performance, and that's a trade-off.  It might avoid the overhead of a function call wherever it's called — but the Java runtime will often inline small functions anyway, all on its own.  And having the compiler do the inlining comes at the cost of duplicating the function's code everywhere it's called; the increased code size is less likely to fit into memory caches, and less likely to be optimised by the Java runtime — so that can end up reducing the performance overall.  Because this isn't always obvious, the IDE gives a warning.
It's different when lambdas are involved, though.  In that case, inlining affects functionality: for example, it allows non-local returns and reified type parameters.  So in that case there are good reasons for using inline regardless of any performance implications, and the IDE doesn't give the warning.
(In fact, if a function calls a lambda it's passed, inlining can have a more significant performance benefit: not only does the function itself get inlined, but the lambda itself usually does as well, removing two levels of function call — and the lambda is often called repeatedly, so there can be a real saving.)

How to make and use an arraylist of functions

How can i make an arraylist of functions, and call each function easily? I have already tried making an ArrayList<Function<Unit>>, but when i tried to do this:
functionList.forEach { it }
and this:
for(i in 0 until functionList.size) functionList[i]
When i tried doing this: it() and this: functionList[i](), but it wouldn't even compile in intellij. How can i do this in kotlin? Also, does the "Unit" in ArrayList<Function<Unit>> mean return value or parameters?
Just like this:
val funs:List<() -> Unit> = listOf({}, { println("fun")})
funs.forEach { it() }
The compiler can successfully infer the type of funs here which is List<() -> Unit>. Note that () -> Unit is a function type in Kotlin which represents a function that does not take any argument and returns Unit.
I think there are two problems with the use of the Function interface here.
The first problem is that it doesn't mean what you might think. As I understand it, it's a very general interface, implemented by all functions, however many parameters they take (or none). So it doesn't have any invoke() method. That's what the compiler is complaining about.
Function has several sub-interfaces, one for each 'arity' (i.e. one for each number of parameters): Function0 for functions that take no parameters, Function1 for functions taking one parameter, and so on. These have the appropriate invoke() methods. So you could probably fix this by replacing Function by Function0.
But that leads me on to the second problem, which is that the Function interfaces aren't supposed to be used this way. I think they're mainly for Java compatibility and/or for internal use by the compiler.
It's usually much better to use the Kotlin syntax for function types: (P1, P2...) -> R. This is much easier to read, and avoids these sorts of problems.
So the real answer is probably to replace Function<Unit> by () -> Unit.
Also, in case it's not clear, Kotlin doesn't have a void type. Instead, it has a type called Unit, which has exactly one value. This might seem strange, but makes better sense in the type system, as it lets the compiler distinguish functions that return without an explicit value, from those which don't return. (The latter might always throw an exception or exit the process. They can be defined to return Nothing -- a type with no values at all.)