I'm trying to transition my code to use kotlinx.datetime instead of the java.time library as I'd like to make use of the serialization benefits of the kotlinx library (it can serialize instant using the #Serialize annotation).
However, i have tests that are using the java.time.Clock and while there is a kotlinx.datetime.Clock class, it appears much more limited than the java one.
Is there a way I can achieve the same thing as this (which uses java.time.Clock and java.time.Instant):
val clockFixed = Clock.fixed(Instant.now().minusMillis(1000), ZONE_ID_UTC)
using the kotlinx library? It doesn't have to be exactly like for like but I would like a clock that always returns the same instant so I can use it for tests and for production code.
kotlinx.datetime.Clock is a very simple interface that (as of version 0.4.0) only includes a single function declaration.
/**
* A source of [Instant] values.
*
* See [Clock.System][Clock.System] for the clock instance that queries the operating system.
*/
public interface Clock {
/**
* Returns the [Instant] corresponding to the current time, according to this clock.
*/
public fun now(): Instant
...
}
As of 0.4.0 there is no implementation of a Fixed clock provided by the library itself. However, you can easily provide your own implementation of a Fixed clock and make it available on the companion object of the Clock interface.
public class FixedClock(private val fixedInstant: Instant): Clock {
override fun now(): Instant = fixedInstant
}
private fun Clock.Companion.Fixed(fixedInstant: Instant): Clock = FixedClock(fixedInstant)
Then, you can use it like the official System clock provided by the library.
val systemClock: Clock = Clock.System
val fixedClock: Clock = Clock.Fixed(...)
Related
Some programming languages have the inline or other keyword to manual specify a function call site to be replaced with the body of the called function.
C# for example does not have this, because the compiler automatically decides which code gets inlined, avoiding, in my opinion, polluting the developer experience (developers shouldn't be worrying about optimizations).
Some languages implemented a syntax to inline classes like Kotlin and now Dart, which wrap an existing type into a new static type, reducing the overhead of a tradicional class.
Dart declaration example (specificated, not yet implemented):
inline class Foo {
// A single instance variable, defining the representation type.
final Bar bar;
// The desired set of other members.
void function1() {
bar.baz;
}
...
}
My question is, could a compiler make this optimization automatically in classes? If not, what challenges make this difficult/impossible?
It is not only about optimisation. Some inlining could make the resultant code less performant and/or larger, so Kotlin gives you control. (IntelliJ warnings against inlining in some cases - warning you that it won't improve performance.)
More than that, you should read about Reified Type Parameters - this allows for certain coding techniques that are only possible when the function is inlined as well as the type information.
Here is some code that is impossible in Java:
Suppose you have a series of enums, representing states of an Object, e.g.
enum class Color {RED,BLUE,GREEN}
enum class Size {SMALL,MEDIUM,LARGE}
data class MyObject(val color: Color, val size:Size)
and you had a test data generator that uses an Random number generator to pick a random enum for the Object.
In Kotlin you can write:
val rnd = Random(1)
val x = MyObject(
color = getRandomEnum(rnd),
size = getRandomEnum(rnd),
)
Using this
private inline fun <reified T : Enum<T>> getRandomEnum(rnd: Random): T {
val values: Array<T> = enumValues()
return values.get(rnd.nextInt(values.size))
}
I have some data transfer class which I want to share between platforms. There is only one difference. The implementations have different annotations on different platforms. What is the best way to do it? I know the only one way.
In the commonsMain:
expect class ErrorMessage (message: String = "") : DataTransferObject {
var message: String
}
In jvmMain:
#SomeJvmAnnotation
actual class ErrorMessage actual constructor (actual var message: String) : DataTransferObject
But if I implement every class this way than there is no profit from KMM. This way I need to implement every class n + 1 times where n is a number of platforms. Is there a simpler way to apply different annotations?
May be there is a way not to put expect on class.
Not the greatest solution, but you can use actual and expect to define your platform-specific annotations.
I used it to ignore unit tests only on the JS runtime.
commonMain
/**
* Ignore a test when running the test on a JavaScript test runtime.
*/
#Target( AnnotationTarget.CLASS, AnnotationTarget.FUNCTION )
expect annotation class JsIgnore()
jsMain
actual typealias JsIgnore = kotlin.test.Ignore
jvmMain
// Nothing to do. This should only ignore tests on the JavaScript test runtime.
actual annotation class JsIgnore
I guess whether or not this is appropriate for you will really depend on the specific annotations you need for each platform, and to which degree they semantically overlap.
Intro
I've been diving into functional programming in the last few months, and since I'm really intrigued by the Kotlin language, I've been using the Arrow library to toy around with a few things.
A few weeks ago, I've been researching for a guest lecture at university on Clean Architecture and while doing so, I stumbled upon this great blog Post by Mark Seemann, describing how using functional programming automatically leads to Clean Architecture (or with a language like Haskell may the compiler may even enforce Clean Architecture).
That inspired me to come up with a draft (checkout and build of the repo should be a breeze, if you're interested) of a restaurant reservation Software (staying true to Mark Seemann's domain ;) ). However, I'm not entirely sure if the use case layer in this draft can be called pure, and I wanted some feedback from people with more experience and knowledge with FP than myself.
Entity layer
A basic use case is trying to create a new reservation for a certain number of seats in our restaurant. I've modelled the entity layer for that the following way:
fun reservationPossible(
requestedSeats: Int,
reservedSeats: Int,
capacity: Int
): Either<RequestedTooManySeats, ReservationPossible> =
if (reservedSeats + requestedSeats <= capacity) {
ReservationPossible(requestedSeats + reservedSeats).right()
} else {
RequestedTooManySeats.left()
}
const val CAPACITY = 10
object RequestedTooManySeats : Error()
sealed class Error
data class ReservationPossible(val newNumberOfReservedSeats: Int)
Nothing too fancy going on here, just a function checking if a reservation with a certain number of requested seats would be possible or not. Some Error and Result classes are also down below as well as a (for the sake of simplicity) const val to model the capacity of our restaurant.
Frameworks/Adapters #1
To make sense in a real world application, some data would also need to be stored in and loaded from some sort of persistence layer. So, in the outermost layer of our onion architecture, there would be a Database which I mocked for this example:
suspend fun getCurrentlyReservedSeats(): Either<ReadError, Int> {
delay(1) // ... get stuff from db
return 4.right()
}
suspend fun saveReservation(value: String, reservationPossible: ReservationPossible): Either<WriteError, Long> {
delay(1) // ... writing something to db
return 42L.right() // newRecordId
}
abstract class DbError : Error()
object ReadError : DbError()
object WriteError : DbError()
Again, not too much going on here... Just stubs for Database read/write ops. Note however, that (by convention proposed by Arrow) these functions are marked with the suspend modifier as impure functions.
Use Case
So now for the use case, which basically describes our application flow:
get number of currently reserved seats from DB
check if the requested number of seats is still available
if so, persist the new reservation
and return the newly created reservation id
which is translated to code in the reservationUseCase function:
data class UseCaseData(
val requestedSeats: Int,
val reservationName: String,
val getCurrentlyReservedSeats: suspend () -> Either<ReadError, Int>,
val writeVal: suspend (String, ReservationPossible) -> Either<WriteError, Long>,
)
fun reservationUseCase(data: UseCaseData): suspend () -> Either<Error, UseCaseResultData> = {
data.getCurrentlyReservedSeats()
.flatMap { reservationPossible(data.requestedSeats, it, CAPACITY) }
.flatMap { data.writeVal(data.reservationName, it) }
.flatMap { UseCaseResultData(it).right() }
}
data class UseCaseResultData(val newRecordId: Long)
Here is the point, where it gets interesting: This function takes some UseCaseData as input and returns a suspend function to be executed at the program entry like this:
suspend fun main() {
reservationUseCase(
UseCaseData(
requestedSeats = 5,
reservationName = "John Dorian",
::getCurrentlyReservedSeats,
::saveReservation,
)
).invoke().fold(
ifLeft = { throw Exception(it.toString()) },
ifRight = { println(it.newRecordId) },
)
}
So now my questions are:
Can the reservationUseCase function itself be considered pure? I've read some blog post (taking F# as example language, however) suggesting that pure functions which receive impure functions as parameters could be pure, but cannot be guaranteed to be pure. reservationUseCase in this example clearly does receive impure functions with the UseCaseData.
If it can't be considered pure, how could one write a pure use case like the one described above in Kotlin and Arrow?
As you already assume, strictly speaking, reservationUseCase is not a pure function.
The only way I see how you could make it a pure function is to pass all the needed data directly instead of a function which provides access to that data but I doubt that this makes your code finally more clean or nicer to read.
This would lead to the conclusion that use case functions which orchestrate "workflows" can rarely be pure as almost always some interaction with some kind of repository is needed.
If you want some core logic to be pure you would have to extract those into functions which again only accept and return pure data.
I'm looking for documentation on how Jackson works with private constructors on immutable types. Using Jackson 2.9.6 and the default object mapper provided by spring boot two running with jdk-10.0.1
Given JSON:
{"a":"test"}
and given a class like:
public class ExampleValue {
private final String a;
private ExampleValue() {
this.a = null;
}
public String getA() {
return this.a;
}
}
Deserialisation (surprisingly, at least to me) seems to work.
Whereas this does not:
public class ExampleValue {
private final String a;
private ExampleValue(final String a) {
this.a = a;
}
public String getA() {
return this.a;
}
}
And this does:
public class ExampleValue {
private final String a;
#java.beans.ConstructorProperties({"a"})
private ExampleValue(final String a) {
this.a = a;
}
public String getA() {
return this.a;
}
}
My assumption is that the only way the first example can work is by using reflection to set the value of the final field (which I presume it does by java.lang.reflect.AccessibleObject.setAccessible(true).
Question 1: am I right that this is how Jackson works in this case? I presume this would have the potential to fail under a security manager which does not allow this operation?
My personal preference, therefore, would be the last code example above, since it involves less "magic" and works under a security manager. However, I have been slightly confused by various threads I've found about Lombok and constructor generation which used to generate by default #java.beans.ConstructorProperties(...) but then changed default to no longer do this and now allows one to configure it optionally using lombok.anyConstructor.addConstructorProperties=true
Some people (including in the lombok release notes for v1.16.20) suggest that:
Oracle more or less broke this annotation with the release of JDK9, necessitating this breaking change.
but I'm not precisely clear on what is meant by this, what did Oracle break? For me using JDK 10 with jackson 2.9.6 it seems to work ok.
Question 2: Is any one able to shed any light on how this annotation was broken in JDK 9 and why lombok now considers it undesirable to generate this annotation by default anymore.
Answer 1: This is exactly how it works (also to my surprise). According to the Jackson documentation on Mapper Features, the properties INFER_PROPERTY_MUTATORS, ALLOW_FINAL_FIELDS_AS_MUTATORS, and CAN_OVERRIDE_ACCESS_MODIFIERS all default to true. Therefore, in your first example, Jackson
creates an instance using the private constructor with the help of AccessibleObject#setAccessible (CAN_OVERRIDE_ACCESS_MODIFIERS),
detects a fully-accessable getter method for a (private) field, and considers the field as mutable property (INFER_PROPERTY_MUTATORS),
ignores the final on the field due to ALLOW_FINAL_FIELDS_AS_MUTATORS, and
gains access to that field using AccessibleObject#setAccessible (CAN_OVERRIDE_ACCESS_MODIFIERS).
However, I agree that one should not rely on that, because as you said a security manager could prohibit it, or Jackson's defaults may change. Furthermore, it feels "not right" to me, as I would expect that class to be immutable and the field to be unsettable.
Example 2 does not work because Jackson does not find a usable constructor (because it cannot map the field names to the parameter names of the only existing constructor, as these names are not present at runtime). #java.beans.ConstructorProperties in your third example bypasses this problem, as Jackson explicitly looks for that annotation at runtime.
Answer 2:
My interpretation is that #java.beans.ConstructorProperties is not really broken, but just cannot be assumed to be present any more with Java 9+. This is due to its membership in the java.desktop module (see, e.g., this thread for a discussion on this topic). As modularized Java applications may have a module path without this module, lombok would break such applications if it would generate this annotation by default. (Furthermore, this annotation is not available in general on the Android SDK.)
So if you have a non-modularized application or a modularized application with java.desktop on the module path, it's perfectly fine to let lombok generate the annotation by setting lombok.anyConstructor.addConstructorProperties=true, or to add the annotation manually if you are not using lombok.
In Java, we can create an utilities class like this:
final class Utils {
public static boolean foo() {
return false;
}
}
But how to do this in Kotlin?
I try using functions inside object:
object Utils {
fun foo(): Boolean {
return false
}
}
But when call this method from Java code it need to add INSTANCE. Ex: Utils.INSTANCE.foo().
Then I change to declare it as top-level function (without class or object):
#file:JvmName("Utils")
#file:JvmMultifileClass
fun foo(): Boolean {
return true
}
Then I can call Utils.foo() from Java code. But from Kotlin code I got Unresolved reference compiler error. It only allow be to use foo() function directly (without Utils prefix).
So what is the best approach for declaring utils class in Kotlin?
The last solution you've proposed is actually quite idiomatic in Kotlin - there's no need to scope your function inside anything, top level functions are just fine to use for utilities, in fact, that's what most of the standard library consists of.
You've used the #JvmName annotation the right way too, that's exactly how you're supposed to make these top level functions easily callable for Java users.
Note that you only need #JvmMultifileClass if you are putting your top level functions in different files but still want them to end up grouped in the same class file (again, only for Java users). If you only have one file, or you're giving different names per file, you don't need this annotation.
If for some reason you want the same Utils.foo() syntax in both Java and Kotlin, the solution with an object and then #JvmStatic per method is the way to do that, as already shown by #marianosimone in this answer.
You'd need to use #JvmStatic for that:
In Kotlin:
object Utils {
#JvmStatic
fun foo(): Boolean = true
}
val test = Utils.foo()
In Java:
final boolean test = Utils.foo()
Note that the util class you used in Java was the only way to supply additional functions there, for anything that did not belong to a particular type or object. Using object for that in Kotlin does not make any sense. It isn't a singleton, right?
The second approach you mentioned is rather the way to go for utility functions. Internally such functions get translated to static ones and as you can see they become the static util classes in Java you are searching for, as you can't have standalone functions in Java without a class or enum. In Kotlin itself however they are just functions.
Some even count utility classes to the anti-patterns. Functions on the other hand make totally sense without a class or object whose name hasn't so much meaning anyway.