Is there a Kotlin std lib function to copy a list, removing all elements equal to ONE single element? A function taking only one non-collection arg? - kotlin

Given a list of arbitrary objects
input = listOf(a, b, c, a)
... is there a function (with one non-collection argument) in the Kotlin standard library that I can use to make a copy of this list, removing all instances of ONE object?
Something like:
val filtered = input.removeAllInstancesOf(a)
To clarify, I'm aware of other (potential) solutions to this task:
Using the filter function to do this. → val output = input.filterNot { it == a }
Using the minus function with a collection → val output = input.minus(listOf(a))
Using the minus function with a non-collection argument → val output = input.minus(a) ← Only removes the first instance of a!
Removing all instances from a mutable list.
Writing such a function. → Wrap any of the above.
... but I'm wondering why I can't find a function which takes just ONE, non-collection value.

but I'm wondering why I can't find a function which takes just ONE, non-collection value.
Because that's a hyper-specific use-case of the already existing filter function. As you yourself showed it can be done in one line, and is probably the first thing a Kotlin dev would try to do (at least I would). So adding new function to the standard library probably doesn't add much value.

Related

Why does `EffectScope.shift` need the type parameter `B`?

The move to the new continuations API in Arrow brought with it a handy new function: shift, in theory letting me get rid of ensure(false) { NewError() } or NewError().left().bind() constructs.
But I'm not sure how to properly use it. The documentation states that it is intended to short-circuit the continuation, and there are no conditionals, so it should always take the parameter, and (in either parlance) "make it a left value", and exit the scope.
So what is the type parameter B intended to be used for? It determines the return type of shift, but shift will not return. Given no more context, B can not be inferred, leading to this kind of code:
val res = either {
val intermediate = mayReturnNull()
if (intermediate == null) {
shift<Nothing>(IntermediateWasNull())
}
process(intermediate)
}
Note the <Nothing> (and ignore the contrived example, the main point is that shifts return type can not be inferred – the actual type parameter does not even matter).
I could wrap shift like this:
suspend fun <L> EffectScope<L>.fail(left: L): Nothing = shift(left)
But I feel like that is missing the point. Any explanations/hints would be greatly appreciated.
That is a great question!
This is more a matter of style, ideally we'd have both but they conflict so we cannot have both APIs available.
So shift always returns Nothing in its implementation, and so the B parameter is completely artificial.
This is something that is true for a lot of other things in Kotlin, such as object EmptyList : List<Nothing>. The Kotlin Std however exposes it as fun <A> emptyList(): List<A> = EmptyList.
For Arrow to stay consistent with APIs found in Kotlin Std, and to remain as Kotlin idiomatic as possible we also require a type argument just like emptyList. This has been up for discussion multiple times, and the Kotlin languages authors have stated that it was decided too explicitly require A for emptyList since that results in the best and most consistent ergonomics in Kotlin.
In the example you shared I would however recommend using ensureNotNull which will also smart-cast intermediate to non-null.
Arrow attempts to build the DSL so that you don't need to rely on shift in most cases, and you should prefer ensure and ensureNotNull when possible.
val res = either {
val intermediate = mayReturnNull()
ensureNotNull(intermediate) { IntermediateWasNull() }
process(intermediate) // <-- smart casted to non-null
}

Terraform module as "custom function"

It is possible to use some i.e. local module to return let' say same calculated output. But how can you pass some parameters? So each time you will ask for the output value you will get different value according to the parameter(ie different prefix)
Is it possible to pass resource to module and enhance it with tags?
I can imagine that both cases are more likely to be case for providers, but for some simple case it should work maybe. The best would be if they implemented some custom function that you will be able to call at will.
It is possible in principle to write a Terraform module that only contains "named values", which is the broad term for the three module features Input Variables (analogous to function arguments), Local Values (analogous to local declarations inside your function), and Output Values (analogous to return values).
Such a module would not contain any resource or data blocks at all and would therefore be a "computation-only" module, which therefore has all of the same capabilities as a function in a functional programming language.
variable "a" {
type = number
}
variable "b" {
type = number
}
locals {
sum = var.a + var.b
}
output "sum" {
value = local.sum
}
The above example is contrived just to show the principle. A "function" this simple doesn't really need the local value local.sum, because its expression could just be written inline in the value of output "sum", but I wanted to show examples of all three of the relevant constructs here.
You would "call the function" by declaring a module call referring to the directory containing the file with the above source code in it:
module "example" {
source = "./modules/sum"
a = 1
b = 2
}
output "result" {
value = module.example.sum
}
I included the output "result" block here to show how you can refer to the result of the "function" elsewhere in your module, as module.example.sum.
Of course, this syntax is much more "chunky" than a typical function call, so in practice Terraform module authors will use this approach only when the factored out logic is significant enough to justify it. Verbosity aside though, you can include as many module blocks referring to that same module as you like if you need to call the "function" with different sets of arguments. Each call to the module can take a different set of input variable values and therefore produce a different result.

How resolving Kotlin functions/properties with the same name work?

The following statement compiles and prints "fun: called":
fun main(vararg args: String) {
fun toCall(arg: String) = println("fun: $arg")
val toCall = fun(arg: String) = println("val: $arg")
toCall("called")
}
Note: the same problem would arise if they were top level declarations or inside a class, this is just the simplest repro with local function/variable.
Looking for clarification on why this compiles in the first place?
What rule comes into play that picks the function over the property?
Note: it's possible to call the val one through:
(toCall)("called")
toCall.invoke("called")
This document regarding name resolution contains details about it.
I will just quote some passages out of it specifically dealing with your problem. It contains several other interesting things as well, but I think I would end up copying everything here then ;-) If you are interested, I can only recommend you to read it completely.
Summarizing, the compiler divides the functions (member/extension/member extension)/properties into groups and decides which one to call first... The properties are put in the group of the invoke-functions and in the following passage you already see why the function was taken before your val:
The property is considered together with the invoke function. Groups of properties with invoke functions are mixed with groups of regular functions, in a sense that a group of properties can have higher priority than a group of functions and vice versa. However, functions and properties can’t go in one group: the function always surpasses the property of the same category. Both the property and the invoke function determine the priority of the group: we compare the priority of the property and of the invoke function and the "lowest" one becomes the group priority.
That's why the function was considered first here and the property later. As soon as you specified invoke it was clear that it can only be the property as the function itself has no visible invoke (lets not go down the byte code now ;-)). Now (toCall) behaves similarly. Here it is clear, that toCall can only be the property. It isn't possible to call (toCall) with the function (compile errors: function invocation expected / the function invoke is not found).
The linked document also contains a sample with a member property function followed by this statement, which basically also confirms the previous regarding local functions:
Note that there is no member function named foo, but if it was present, it would be put into a separate group with the highest priority.

Non-destructively iterating over a Rust collection, but not by reference

I can write the following two ways, the second is inspired by What is the idiomatic way to create a collection of references to methods that take self?:
channels.iter().flat_map(|c|c.to_uppercase()).collect(),
channels.clone().into_iter().flat_map(char::to_uppercase).collect(),
The second line has to clone the collection because char::to_uppercase doesn't accept a reference as it's argument and .iter() provides references and .into_iter() moves the collection.
Is there a way to do this that doesn't need to clone the collection or create a closure? I don't hate closures, I promise, and I know they're just turned into (usually inline) function calls in LLVM anyway, but I like the cleanness of referring to a function like in the second line and would prefer to use it if it can be done without the clone.
Iterator has a cloned method which is equivalent to .map(|x| x.clone()) which, in case of Copy types is equivalent to .map(|&x| x). This way you can write
channels.iter().cloned().flat_map(char::to_uppercase).collect()
You can define a function that takes a reference. You can even put it inside another function, if you want to keep it close to its usage.
fn foobar() {
fn to_uppercase(c: &char) -> ::std::char::ToUppercase {
c.to_uppercase()
}
// [...]
let channels_upper = channels.iter().flat_map(to_uppercase).collect();
}

Erlang Looping through a list (or set) to process files

I want to create 16 directories in Erlang.
for ( create_dir("work/p" ++ A, where A is an element in a list [0, 1, ... f]) (sixteen number in hex notation).
I could of course write sixteen lines like: mkdir ("work/p0"), mkdir("work/p1") etc.
I have looked at lists:foreach. In the examples fun is used, is possible to define a function outside the loop and call it?
I am new to Erlang and used to C++ etc.
Yes, it's possible to define a (named) function outside the call to lists:foreach/2. Why would you, though? This is a case when an anonymous function is incredibly handy:
lists:foreach(fun(N) ->
file:make_dir(
filename:join("work", "p"++integer_to_list(N, 16)))
end, lists:seq(0, 15)).
The filename:join/2 call will use the appropriate directory separator to construct the string work/pN, where N is an integer in hex representation constructed using integer_to_list/2, which converts an integer to a string (list) in a given base (16).
lists:seq/2 is a friendly little function that returns the list [A,A+1,A+2,...,B-1,B] given A and B.
Note that you could just as well have used the list comprehension syntax here, but since we're applying functions to a list for the side-effects alone, I chose to stick with a foreach.
If you really want to define a separate function -- let's call it foo and assume it takes 42 arguments -- you can refer to it as fun foo/42 in your code. This expression evaluates to a function object that, like an anonymous function defined inline, can be passed to lists:foreach/2.