Difference between private top-level extension function and private extension function inside class - kotlin

We are currently switching our project to Kotlin, and ran across following question:
We need a certain extension function only inside a given class. Thus, we have two possibilities: (1) Declaring the extension function private on the file top-level or (2) declaring the extension function private inside the class.
Following a MCVE:
Top-level example (file C1.kt):
private fun String.double() = this.repeat(2)
class C1 {
init {
println("init".double())
}
}
Inside class example (file C2.kt):
class C2 {
private fun String.double() = this.repeat(2)
init {
println("init".double())
}
}
Questions:
Is there any difference to those two approaches, except that in C1.kt the extension function String.double() would also be visible to other possible file members (such as further classes in the same file)?
Since we want to achieve code "as kotlinic as possible", we would like to know which of the two approaches is the suggested one. Is there an official suggestion / style guide on the example above? I think it is considered good practice to declare extension functions as close as possible to its intended use, thus in the above example the structure of C2 would be suggested?

Is there any difference to those two approaches, except that in C1.kt the extension function String.double() would also be visible to other possible file members (such as further classes in the same file)?
There is one difference: When specifying an extension function inside the class (in your example C2), then you additionally have access to the instance of this class with the qualified this syntax (in your example this#C2).
Since we want to achieve code "as kotlinic as possible", we would like to know which of the two approaches is the suggested one. Is there an official suggestion / style guide on the example above? I think it is considered good practice to declare extension functions as close as possible to its intended use, thus in the above example the structure of C2 would be suggested?
That's a good question. Personally, I would put the extension functions outside the class, since they (normally) specify behavior that is related to the extended type and not to the type of the class where they are used. However, if you do need class-related information within the extension function, I would then specify them inside the class.

Related

Differenence between ways to declare functions in Kotlin

I have seen some code declaring functions as seen below. What is the difference between fun1 and fun2?
interface Test {
fun fun1() : Boolean = false
}
fun Test.fun2() : Boolean = true
fun1 defined inside the interface describes an open function that any implementer of the interface can override. Since it also defines a default implementation by returning something, it is not abstract and implementing classes can choose not to override it.
fun2 is an extension function. When these are used with interfaces, often the reason is to discourage overriding. An extension function cannot be overridden, but it can be hidden by another extension function with the same signature, but only in a specific scope. Therefore, some implementer of Test in another module that passes its instance back to this module cannot change the functionality of fun2 as used in this module.
The second version is an extension function.
The difference is that extension functions can be applied to any type (even outside of your code), but they do not have access to private members of that type. They are pretty much the same as calling function with this type as a first parameter, just nicer syntax

Where should the code processing the state of the object be?

I have a class as follows:
data class ProductState(
val id: Int,
val products: MutableMap<Int, MutableSet<Int>> = mutableMapOf(),
val customerTopics: Topic = Topic()
)
It is basically a data class.
Now I have a function that among other things, processes the products and customerTopics and creates some output based on the processing.
But it seems to me that it is not a good idea to have the logic in the function.
My question is:
Do we create methods inside the data class for the processing of the object'state? If so would it be some companion object? Or is there some other design pattern that deals with this better?
In kotlin you have several options:
Additional method on the data class (if it should be called in multiple other places);
Public extension method in the same file as the data class (if it should be called in multiple other places but you want to keep your data class simple and have the handling methods separated);
Private extension method in the same file as the only place where it is called (this only applies if this processing is to be called in a single place in your code);
Private method in the only place where this processing is needed.
The best place really depends on what the processing is (is it very specific to ProductState or does it need additional data? If it is very specific then it may make sense to keep it as a ProductState method or an extension function) and in how many places it will be triggered (if in a single very specific place, then maybe keeping it along-side that piece of code as a private extension function or private method might be the best option).

Kotlin extension functions vs member functions?

I am aware that extension functions are used in Kotlin to extend the functionality of a class (for example, one from a library or API).
However, is there any advantage, in terms of code readability/structure, by using extension functions:
class Foo { ... }
fun Foo.bar() {
// Some stuff
}
As opposed to member functions:
class Foo {
...
fun bar() {
// Some stuff
}
}
?
Is there a recommended practice?
When to use member functions
You should use member functions if all of the following apply:
The code is written originally in Kotlin
You can modify the code
The method makes sense to be able to use from any other code
When to use extension functions
You should use extension functions if any of the following apply:
The code was originally written in Java and you want to add methods written in Kotlin
You cannot change the original code
You want a special function that only makes sense for a particular part of the code
Why?
Generally, member functions are easier to find than extension functions, as they are guaranteed to be in the class they are a member of (or a super class/interface).
They also do not need to be imported into all of the code that uses them.
From my point of view, there are two compelling reasons to use extension functions:
To "extend" the behaviour of a class you're not the author of / can't change (and where inheritance doesn't make sense or isn't possible).
To provide a scope for particular functionality. For example, an extension function may be declared as a freestanding function, in which case it's usable everywhere. Or you may choose to declare it as a (private) member function of another class, in which case it's only usable from inside that class.
It sounds like #1 isn't a concern in your case, so it's really more down to #2.
Extension functions are similar to those you create as a utility functions.
A basic example would be something like this:
// Strings.kt
fun String.isEmail() : Boolean {
// check for email pattern and return true/false
}
This code can be written as a utility function in Java like this:
class StringUtils {
public static boolean isEmail(String email) {
// check for email pattern and return true/false
}
}
So what it essentially does is, calling the same function with the object you call on will be passed as the first parameter to the argument. Like the same function I have given example of in Java.
If you want to call the extension function created in kotlin from java, you need to pass the caller as the first argument. Like,
StringsKt.isEmail("example#example.com")
As per the documentation,
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
They are simply static functions with the caller as the first argument and other parameters followed by it. It just extends the ability for us to write it that way.
When to create extension functions?
When you don't have access to that class. When that class belongs to some library you have not created.
For primitive types. Int, Float, String, etc.
The another reason for using extension function is, you don't have to extend that class in order to use the methods, as if they belong to that class (but not actually part of that class).
Hope it makes a bit clear for you..
As mentioned in other answers, extension functions are primarily used in code that you can't change - maybe you want to change complex expression around some library object into easier and more readable expression.
My take would be to use extension functions for data classes. My reasoning is purely philosophical, data classes should be used only as data carriers, they shouldn't carry state and by themselves shouldn't do anything. That's why I think you should use extension function in case you need to write a function around data class.

Is there a way to have a private file constant in Kotlin

Suppose I have some Utils.kt file which will contain only some utility functions, no classes, no objects. And suppose that those functions use some common set of constant values.
So I do something like this:
package myapp
private val CONST1 = 1
private val CONST2 = 2
public fun function1() {}
public fun function2() {}
Unfortunately Kotlin treats private as "available to the whole package".
So CONST1 and CONST2 are available to all files which are in the same package.
The only way to isolate them is to move this file to a separate package.
But what if I have several utility files like this, each with its own set of private constants. Then i have only two options: move each of them to a unique package or give up and have consts from all of them accessible everywhere.
Either way seems to create clutter.
Any options or advice?
(upd: actually, I must say this is one of those rare things that bother me in Kotlin - no way to make some entity be file-local (without using some syntax hacks): it's either available to whole package or to everyone at all)
UPD: This question is now obsolete (see the accepted answer)
Top-level declarations with private visibility are visible only in the file where they are declared.
(original answer, valid when the question was asked: Kotlin does not have any concept of file-local scope, and to the best of my knowledge there are no plans to introduce it. If you don't like package scope (why?), you can create an object encapsulating the functions and the private constants that they use.

Is there a way to declare public and private methods for S4 Reference Classes?

Up-front: I am aware that R is a functional language, so please don't bite ;-)
I've had great experiences with using an OOP approach for a lot of my programs.
Now, I'm wondering if there's a way to make a distinction between public and private methods when using S4 Reference Classes in R?
Example
Class Definitions
setRefClass("B",
field=list(
b.1="numeric",
b.2="logical"
),
methods=list(
thisIsPublic=function(...) {
thisIsPublic_ref(.self=.self, ...)
},
thisIsPrivate=function(...) {
thisIsPrivate_ref(.self=.self, ...)
}
)
)
setRefClass("A",
field=list(
a.1="B"
)
)
NOTE
I usually do not place the actual method definition within the class def but separate it to a S4 method (i.e. thisIsPublic_ref) for the following reasons:
That way the class def stays clearly arranged and is easier to read in cases when the individual method defs grow quite large.
It allows you to switch to a functional execution of methods at any time. Be x an instance of a certain class, you are able to call foo_ref(.self=x) instead of x$foo().
It allows you to byte-compile the methods via compiler::cmpfun() which I think is not possible if you have "plain" Reference Class methods.
It sure does not really make sense to make it that complicated for this specific example, but I thought I'd nevertheless illustrate that approach.
Method Definitions
setGeneric(
name="thisIsPublic_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPublic_ref")
}
)
setGeneric(
name="thisIsPrivate_ref",
signature=c(".self"),
def=function(
.self,
...
) {
standardGeneric("thisIsPrivate_ref")
}
)
require(compiler)
setMethod(
f="thisIsPublic_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.1 * 1000
})
)
setMethod(
f="thisIsPrivate_ref",
signature=signature(.self="B"),
definition=cmpfun(function(
.self,
...
){
.self$b.2
})
)
Instances
x.b <- new("B", b.1=10, b.2=TRUE)
x.a <- new("A", a.1=x.b, a.2="hello world")
Public vs. private
Instances of class A (i.e. x.a) should be allowed to use class B's public methods:
> x.a$a.1$thisIsPublic()
[1] 10000
Instances of class A (i.e. x.a) should not be allowed to use class B's private methods. So I would want this not to work, i.e. result in an error:
> x.a$a.1$thisIsPrivate()
[1] TRUE
Any idea how one could specify this?
The only thing I came up with so far:
Adding a sender argument to each method, explicitly specify it for each method call and check if class(.self) == class(sender). But that seems a bit “explicit“.
As functions are first-class objects in R, you can embed one inside the other, as follows:
hello <- function() {
print_ <- function() {
return ('hello world')
}
print_()
}
Yes, it's cheeky, probably not the cleanest way, but it does work... Invoke using 'hello()'.
The short answer is to make a package. R's object systems and it's means of partitioning code (namespaces) are more separate than their equivalents in Java-like languages.
When you make a package, you specify what gets exported in a file called NAMESPACE using directives export and exportMethods. You can choose not to export methods and other R objects that you wish to be package private (to use Java terminology). See the Namespaces with S4 classes and methods section of the Writing R Extensions manual
Making a package is tricky the first time you do it, but there's lot's of help. See the docs for package.skeleton and the Writing R Extensions manual linked above.
Make sure Reference classes are really what you want. Regular S4 classes are usually the more R-ish way, for whatever that's worth. A great source of information about R's many OO constructs (and about packaging, too) is on Hadley Wickham's devtools wiki.