Why has Kotlins SortedMap no .forEachIndexed() function? - dictionary

Kotlins SortedMap is "a map that further provides a total ordering on its keys."
As a result, it should be indexable. However, this extension doesn't exist
`sortedMap.forEachIndexed()`
Why not? Am i overlooking something? Is it performance reasons? Didn't anyone bother?
(Yes, i know, i could use a List<Pair<Key, Value>>, but that's doesn't feel like the "intuitive" structure for my usecase, a map fits much better)

Most of the things that have a forEachIndexed get it either from Iterable or have it as an extension function. Map does not, but one of its properties, the entries is actually a Set, which does have forEachIndexed because it inherits from Collection (which inherits from Iterable).
That means that you can do something like this:
map.entries.forEachIndexed { index, (key, value) ->
//do stuff
}
The reason I've added this to the already existing asIterable().forEachIndex answer, is because asIterable() creates a new object.

forEachIndexed is an extension function on all sorts of Arrays and also Iterable. SortedMap is unrelated to those types, so you can't call forEachIndexed on it.
However, SortedMap does have asIterable (inherited from Map), which converts it to an Iterable. After that, you can access forEachIndexed:
someSortedMap.asIterable().forEachIndex { index, entry ->
// ...
}
However, the newer extension function onEachIndexed are declared on Maps. Unlike forEachIndexed, this also returns the map itself.

Related

Treating single and multiple elements the same way ("transparent" map operator)

I'm working on a programming language that is supposed to be easy, intuitive, and succinct (yeah, I know, I'm the first person to ever come up with that goal ;-) ).
One of the features that I am considering for simplifying the use of container types is to make the methods of the container's element type available on the container type itself, basically as a shortcut for invoking a map(...) method. The idea is that working with many elements should not be different from working with a single element: I can apply add(5) to a single number or to a whole list of numbers, and I shouldn't have to write slightly different code for the "one" versus the "many" scenario.
For example (Java pseudo-code):
import static java.math.BigInteger.*; // ZERO, ONE, ...
...
// NOTE: BigInteger has an add(BigInteger) method
Stream<BigInteger> numbers = Stream.of(ZERO, ONE, TWO, TEN);
Stream<BigInteger> one2Three11 = numbers.add(ONE); // = 1, 2, 3, 11
// this would be equivalent to: numbers.map(ONE::add)
As far as I can tell, the concept would not only apply to "container" types (streams, lists, sets...), but more generally to all functor-like types that have a map method (e.g., optionals, state monads, etc.).
The implementation approach would probably be more along the lines of syntactic sugar offered by the compiler rather than by manipulating the actual types (Stream<BigInteger> obviously does not extend BigInteger, and even if it did the "map-add" method would have to return a Stream<BigInteger> instead of an Integer, which would be incompatible with most languages' inheritance rules).
I have two questions regarding such a proposed feature:
(1) What are the known caveats with offering such a feature? Method name collisions between the container type and the element type are one problem that comes to mind (e.g., when I call add on a List<BigInteger> do I want to add an element to the list or do I want to add a number to all elements of the list? The argument type should clarify this, but it's something that could get tricky)
(2) Are there any existing languages that offer such a feature, and if so, how is this implemented under the hood? I did some research, and while pretty much every modern language has something like a map operator, I could not find any languages where the one-versus-many distinction would be completely transparent (which leads me to believe that there is some technical difficulty that I'm overlooking here)
NOTE: I am looking at this in a purely functional context that does not support mutable data (not sure if that matters for answering these questions)
Do you come from an object-oriented background? That's my guess because you're thinking of map as a method belonging to each different "type" as opposed to thinking about various things that are of the type functor.
Compare how TypeScript would handle this if map were a property of each individual functor:
declare someOption: Option<number>
someOption.map(val => val * 2) // Option<number>
declare someEither: Either<string, number>
someEither.map(val => val * 2) // Either<string,number>
someEither.mapLeft(string => 'ERROR') // Either<'ERROR', number>
You could also create a constant representing each individual functor instance (option, array, identity, either, async/Promise/Task, etc.), where these constants have map as a method. Then have a standalone map method that takes one of those "functor constant"s, the mapping function, and the starting value, and returns the new wrapped value:
const option: Functor = {
map: <A, B>(f: (a:A) => B) => (o:Option<A>) => Option<B>
}
declare const someOption: Option<number>
map(option)(val => val * 2)(someOption) // Option<number>
declare const either: Functor = {
map: <E, A, B>(f: (a:A) => B) => (e:Either<E, A>) => Either<E, B>
}
declare const either: Either<string,number>
map(either)(val => val * 2)(someEither)
Essentially, you have a functor "map" that uses the first parameter to identify which type you're going to be mapping, and then you pass in the data and the mapping function.
However, with proper functional languages like Haskell, you don't have to pass in that "functor constant" because the language will apply it for you. Haskell does this. I'm not fluent enough in Haskell to write you the examples, unfortunately. But that's a really nice benefit that means even less boilerplate. It also allows you to write a lot of your code in what is "point free" style, so refactoring becomes much easier if you make your language so you don't have to manually specify the type being used in order to take advantage of map/chain/bind/etc.
Consider you initially write your code that makes a bunch of API calls over HTTP. So you use a hypothetical async monad. If your language is smart enough to know which type is being used, you could have some code like
import { map as asyncMap }
declare const apiCall: Async<number>
asyncMap(n => n*2)(apiCall) // Async<number>
Now you change your API so it's reading a file and you make it synchronous instead:
import { map as syncMap }
declare const apiCall: Sync<number>
syncMap(n => n*2)(apiCall)
Look how you have to change multiple pieces of the code. Now imagine you have hundreds of files and tens of thousands of lines of code.
With a point-free style, you could do
import { map } from 'functor'
declare const apiCall: Async<number>
map(n => n*2)(apiCall)
and refactor to
import { map } from 'functor'
declare const apiCall: Sync<number>
map(n => n*2)(apiCall)
If you had a centralized location of your API calls, that would be the only place you're changing anything. Everything else is smart enough to recognize which functor you're using and apply map correctly.
As far as your concerns about name collisions, that's a concern that will exist no matter your language or design. But in functional programming, add would be a combinator that is your mapping function passed into your fmap (Haskell term) / map(lots of imperative/OO languages' term). The function you use to add a new element to the tail end of an array/list might be called snoc ("cons" from "construct" spelled backwards, where cons prepends an element to your array; snoc appends). You could also call it push or append.
As far as your one-vs-many issue, these are not the same type. One is a list/array type, and the other is an identity type. The underlying code treating them would be different as they are different functors (one contains a single element, while one contains multiple elements.
I suppose you could create a language that disallows single elements by automatically wrapping them as a single-element lists and then just uses the list map. But this seems like a lot of work to make two things that are very different look the same.
Instead, the approach where you wrap single elements to be identity and multiple elements to be a list/array, and then array and identity have their own under-the-hood handlers for the functor method map probably would be better.

What is the difference between find and firstOrNull?

Given the following code extracted from Kotlin Koans:
fun Shop.findAnyCustomerFrom(city: City): Customer? {
// Return a customer who lives in the given city, or null if there is none
return customers.firstOrNull { it.isFrom(city) }
}
My own solution used customers.find. Both work in the koan scenario.
The documentation for firstOrNull and find seem to be very similar.
What is the difference between these two functions?
In this thread from 2014, Kotlin community members and JetBrains staff discuss the merits of the different methods find and firstOrNull:
https://youtrack.jetbrains.com/issue/KT-5185
While not an official statement, JetBrains' employee Ilya Ryzhenkov describes it as:
I think we can undeprecate find and make it an alias to firstOrNull. Much like indexOf has well-known semantics, find is also widely recognised as "find first item matching predicate or return null if nothing is found". People who like precise meaning can use firstOrNull, singleOrNull to express the intent.
In other words:
find(predicate) and firstOrNull(predicate) are identical in behaviour and find can be considered alias of firstOrNull
find is kept around as an alias because it's more intuitive and discoverable for programmers not already familiar with these Linq-style - or functional - methods.
In actuality the definition of Array<out T>.find is not defined as an alias, but as a wrapper (though the optimizing compiler will inline it, effectively making it an alias):
https://github.com/JetBrains/kotlin/blob/1.1.3/libraries/stdlib/src/generated/_Arrays.kt#L657
#kotlin.internal.InlineOnly
public inline fun <T> Array<out T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}
Ditto for Sequence<T>.find:
https://github.com/JetBrains/kotlin/blob/1.1.3/libraries/stdlib/src/generated/_Sequences.kt#L74
#kotlin.internal.InlineOnly
public inline fun <T> Sequence<T>.find(predicate: (T) -> Boolean): T? {
return firstOrNull(predicate)
}
(I'm not a Kotlin user myself, but I'm surprised that these methods are implemented as compile-time generated code manually defined for each collection type instead of as a single JVM generic method - is there some reason for this?)

Is it possible to declare a tuple struct whose members are private, except for initialization?

Is it possible to declare a tuple struct where the members are hidden for all intents and purposes, except for declaring?
// usize isn't public since I don't want users to manipulate it directly
struct MyStruct(usize);
// But now I can't initialize the struct using an argument to it.
let my_var = MyStruct(0xff)
// ^^^^
// How to make this work?
Is there a way to keep the member private but still allow new structs to be initialized with an argument as shown above?
As an alternative, a method such as MyStruct::new can be implemented, but I'm still interested to know if its possible to avoid having to use a method on the type since it's shorter, and nice for types that wrap a single variable.
Background
Without going into too many details, the only purpose of this type is to wrap a single type (a helper which hides some details, adds some functionality and is optimized away completely when compiled), in this context it's not exactly exposing hidden internals to use the Struct(value) style initializing.
Further, since the wrapper is zero overhead, its a little misleading to use the new method which is often associated with allocation/creation instead of casting.
Just as it's convenient type (int)v or int(v), instead of int::new(v), I'd like to do this for my own type.
It's used often, so the ability to use short expression is very convenient. Currently I'm using a macro which calls a new method, its OK but a little awkward/indirect, hence this question.
Strictly speaking this isn't possible in Rust.
However the desired outcome can be achieved using a normal struct with a like-named function (yes, this works!)
pub struct MyStruct {
value: usize,
}
#[allow(non_snake_case)]
pub fn MyStruct(value: usize) -> MyStruct {
MyStruct { value }
}
Now, you can write MyStruct(5) but not access the internals of MyStruct.
I'm afraid that such a concept is not possible, but for a good reason. Each member of a struct, unless marked with pub, is admitted as an implementation detail that should not raise to the surface of the public API, regardless of when and how the object is currently being used. Under this point of view, the question's goal reaches a conundrum: wishing to keep members private while letting the API user define them arbitrarily is not only uncommon but also not very sensible.
As you mentioned, having a method named new is the recommended approach of doing that. It's not like you're compromising code readability with the extra characters you have to type. Alternatively, for the case where the struct is known to wrap around an item, making the member public can be a possible solution. That, on the other hand, would allow any kind of mutations through a mutable borrow (thus possibly breaking the struct's invariants, as mentioned by #MatthieuM). This decision depends on the intended API.

Kotlin: Modifying (immutable) List through cast, is it legitimate?

As we know the List in Kotlin is immutable i.e. you can't do add and remove as below.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
But if we cast it to ArrayList as below, the add and remove works.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
I just thought this is odd, as myList is really a List, which is suppose to be immutable. And casting it, allow it to be altered.
Is what done above (casting to Array and modify the content) legitimate, or the language need to improve to disallow that?
There are a few different types of immutability:
One is mentioned from a separate SO answer here.
Readonly - you are NOT supposed to change it (Kotlin's List) but something may (cast to Mutable, or change from Java).
List is just an interface that does not have mutating methods, but you can change the instance if you cast it to MutableList.
Someone then goes on to comment that Kotlin chose to be readonly in order to use Java collections directly, so there is no overhead or conversion in using Java collections.
Kotlin List is readonly, not immutable. Other callers (Java for example) may change the list. Kotlin callers might cast the list and change it. There is no immutable protection.
Original Source: Kotlin and Immutable Collections?
Is it legitimate? Well, yes. There are uses cases in which that would make sense.
Is it a good idea? I think not, especially if you're talking about casting a list that was returned by some external library. The cast will fail if someone actually hands you some List implementations that really is immutable and does not implement MutableList. The fact that at the moment (Kotlin 1.0.2), all of Kotlin's Lists are also MutableLists doesn't mean that every List you'll ever see in your code is also an MutableList.
Right now if you use listOf() you'll get a List with all methods, which mutate the list, throwing java.lang.UnsupportedOperationException:
val list = listOf(1, 2)
val mlist = list as MutableList
mlist.add(3)
This throws:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)

How do I pass an enumerated function argument in Julia?

I'm a C and Matlab programmer moving to Julia, and I'm trying to understand how function options should look when passed in.
Sometimes, a function provides different functionality based on an argument passed in with a limited number of different options. In C, it could look something like this:
enum Options{
OPTION_1,
OPTION_2
};
// Other arguments omitted
void foo(..., enum Options option){
switch(option){
case OPTION_1:
// Do something
break;
case OPTION_2:
// Do something else
break;
}
}
In Julia, I am not sure how to structure this. My first attempt used a hierarchy of abstract types, and then a function that accepts a singleton type to make the decision. See the following code:
abstract Options
abstract Option_1 <: Options
abstract Option_2 <: Options
function foo{T<:Options}(..., ::Type{T})
if isa(Option_1, Type{T}
//Do something
elseif isa(Option_2, Type{T})
//Do something else
end
end
However, this seems like a very strange way to approach the problem; creating types just to control function input feels awfully strange.
Also, to clarify, I don't think that this is a solution solvable by general parametric methods in Julia. I am looking for the user to be able to specify a flag (such as run version 1 or version 2), not have different functionality based on input type.
Thanks for the help!
I think parametric methods are actually exactly what you are looking for.
abstract Option_1
abstract Option_2
foo{T<:Options_1}(...) = do_something()
foo{T<:Options_2}(...) = do_something_else()
if there is common code between the two implementations then factor it out into another function and use it in both. Julia doesn't have enums but it does have ways to accomplish the same thing and parametric methods are a perfectly valid way to do so.
If you analyse your question, what you are doing is choosing one of two different functionalities via an argument. Thus you actually have two different functions mixed up inside a single function, and you can (and should) split the two different functionalities out into two different functions.
Once you have done this, it's a short step to realise that the way you decide which function to call is probably (or, at least, often) related to the type of an object. But maybe if you give some more details of your actual use case, we can suggest other alternatives. For example, it might just be a boolean variable that turns on or off a certain type of behaviour.
Note that in Julia v0.4 (the current stable version), you can also use #enum to create enums similar to those available in C: see the NEWS.md file.

Resources