Languages like Haskell have the concept of pure functions and will not compile if a function that is supposed to be pure is in fact not pure.
e.g. if I have
processFoo :: (() -> Foo) -> Boolean
and pass in
getFooFromServer :: () -> IO Foo
as the first argument, then the code does not compile and I get an error. This is useful because I easily get to see which parts of my code are pure (and so easily testable, don't do any mutation, etc etc), and which parts form the boundary to external systems.
As far as I know there are no languages that offer something similar where a function can be marked as pure and if it
does an IO operation
relies on or mutates global state, or
calls a function that is not also pure
then the compiler/interpreter throws an error, e.g.
Foo getFooFromServer () {
// ... do some IO
}
void pure processFoo() {
getFooFromServer()
// ^ compile error - not a pure function
}
Question: Is there such a language?
Related
panic! allows the setting of a custom (albeit global) hook. Is there anything comparable for early returns with the ? operator? I have a function that needs to close some resources in a special way before exiting. I could write a function ok_or_close() that closes the resources before returning the error:
fn opens_resources() -> Result<(), MyError> {
//Opens some stuff.
//Now a bunch of functions that might raise errors.
ok_or_close(foo(), local variables)?;
ok_or_close(bar(), local variables)?;
ok_or_close(baz(), local variables)?;
ok_or_close(Ok(()), local variables)
}
But that seems verbose. What I'd really like to do is this:
fn opens_resources() -> Result<(), MyError> {
//Opens some stuff.
//Now a bunch of functions that might raise errors.
foo()?;
bar()?;
baz()?;
on_err:
//Closes some stuff. Would prefer not to make
// this a function, uses many local variables.
Ok(())
}
Is there a way to do this or a pattern of programming that gets around this?
The closest thing to this would be the Try trait which allows you to implement how ? affect a specific type, but sadly it is still a nightly experiment as stated here
If you're interested in this features I'd recommend you give a +1 at this issue
This is a general question about callback functions, defined in Kotlin Native, called by C functions.
For argument's sake, let's say I'm trying to walk a directory in a filesystem recursively, using https://linux.die.net/man/3/nftw in Kotlin Native.
(I know there are other ways to do this, using other C functions, but that is not the core of this question.)
nftw() takes a function as a callback:
val directory = "//some/directory"
val callback = kotlinx.cinterop.staticCFunction {
file: CPointer<ByteVar>?,
stat: CPointer<stat>?,
typeFlag: Int,
b: CPointer<FTW>? ->
val fileName = file?.toKString()
println(fileName)
val result = 0
result
}
val depth = 10
val flags = 0
platform.posix.nftw(directory, callback, depth, flags)
This works for listing files via "println()", but as as soon as the lambda contains any captured value, I get the following compiler error:
"kotlinx.cinterop.staticCFunction must take an unbound, non-capturing function or lambda".
My question is: is there any recommended approach on how to
access any non-global state from such a callback?
I did come up with a nasty workaround using a global variable, so that's not what I'm looking for primarily. If there is a commonly accepted solution using #ThreadLocal or something else, please discuss.
For native callbacks in general (not specific to nftw). The C function should accept a void* userData parameter and pass it to the callback when it is called. This allows you to pass local data to the callback, instead of global data.
This is the case even in C/C++.
For this particular case (regardless of language) there isn't really a way to do this without some global data (or JIT but let's not think about it). So any workaround would have to be nasty.
Using #ThreadLocal is a "reasonable nasty" solution.
nftw is just not a well designed C interface.
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.)
I have a list of Job instances which I want to cancel at some point after launch. This looks as follows:
val jobs = arrayListOf<Job>()
//launch and add jobs...
jobs.forEach { it.cancelAndJoin() } // cancels the jobs and waits for completion
Unfortunately, it's not possible to use a method reference here. The reason: cancelAndJoin is a suspend function, as the compiler complains:
jobs.forEach (Job::cancelAndJoin)
"Error:(30, 24) Kotlin: Unsupported [Callable references to suspend functions]"
Why doesn't this work?
UPD: This has already been implemented in Kotlin 1.3.x. Taking a callable reference to a suspending function gives you an instance of KSuspendFunctionN (N = 0, 1, ...). This type has its invoke operator defined as a suspending function, so that you can invoke such a callable reference suspending a coroutine in the same way as a direct invocation would.
Basically, supporting this requires an additional portion of language design and does not simply come bundled with coroutines.
Why is it non-trivial? Because when you take a callable reference of an ordinary function e.g. String::reversed, you get something like a KFunction1<String, String>. If you could do the same with a suspend function, what would you expect to get?
If it's the same KFunctionN<...>, then there's an obvious problem that you can pass it around where an ordinary function is expected and call it, violating the rule that suspend functions can only be called inside coroutines (where the compiler transforms their call sites).
So, it should be something more specific. (I'm currently only speculating, without any idea of actual design attempts) It could be, for example, a SuspendKFunctionN<...>, with its invoke(...) being a suspending function, or it could (less likely) be a special notation only for passing a function reference where a suspend (T) -> R is expected, but anyway, a feature like this requires thorough design to be future-proof.
These helpers currently lack in Kotlin Standard library, but you can implement your own.
For example:
suspend fun <T> Iterable<T>.forEachAsync(action: suspend (T) -> Unit): Unit {
val list = this.map { e ->
async(...) {
action(e)
}
}
list.forEach { it.await() }
}
However, what context to pass to async now depends on the threading model your service is using (i.e. do you want to do multi-threading or want to keep everything in a single thread).
Java CompletableFuture<T> has a lot of async methods, static or instance, in this format
public <U> CompletableFuture<U> XXXasync(SomeFunctionalInterface<T> something, Executor executor)
If you have enough experience with FP in kotlin, you will immediately realize these function are extremely awkward to use in kotlin, because the SAM interface is not the last parameter.
aCompletableFutrue.thenComposeAsync(Function<SomeType, CompletableFuture<SomeOtherType>> {
// ^ WHAT A LONG TYPE NAME THAT NEED TO BE HAND WRITTEN
// do something that has to be written in multiple lines.
// for that sake of simplicity I use convert() to represent this process
convert(it)
}, executor)
That Function has a very very long generic signature that I don't know how to let IDE generate. It will be a plain in the butt if the type name become even longer or contains a ParameterizedType or has type variance annotations.
It also looks nasty because of the trailing , executor) on line 5.
Is there some missing functionality in kotlin or IDE that can help with the situation? At least I don't want to write that long SAM constructor all by myself.
Rejected solutions:
Using named parameter doesn't seem to work because this feature only works on a kotlin function.
Abandon async methods sounds bad from the very beginning.
Kotlin corountine is rejected because we are working with some silly Java libraries that accept CompletionStage only.
IF you calling the api from java that takes a functional interface parameter at last, you can just using lambda in kotlin.
val composed: CompletableFuture<String> = aCompletableFutrue.thenComposeAsync {
CompletableFuture.supplyAsync { it.toString() }
};
Secondly, if you don't like the java api method signature. you can write your own extension methods, for example:
fun <T, U> CompletableFuture<T>.thenComposeAsync(executor: Executor
, mapping: Function1<in T, out CompletionStage<U>>): CompletableFuture<U> {
return thenComposeAsync(Function<T,CompletionStage<U>>{mapping(it)}, executor)
}
THEN you can makes the lambda along the method.
aCompletableFutrue.thenComposeAsync(executor){
// do working
}