Ky Leggiero
11/08/2019, 6:06 PMPablichjenkov
11/08/2019, 7:24 PMHullaballoonatic
11/09/2019, 8:03 PMvar next = stack.last
get() {
field = stack.pop()
field
}
var next = stack.last
get() = field := stack.pop()
Hullaballoonatic
11/09/2019, 8:46 PMval i = 2
-i // -2
~i // 0.5
val M = Matrix.ofRows(vectorOf(4, 7), vectorOf(2, 6))
// [ 4 7
// 2 6 ]
-M
// [ -4 -7
// -2 -6 ]
~M
// [ 0.6 -0.7
// -0.2 0.4 ]
jimn
11/21/2019, 10:09 AMhttps://files.slack.com/files-pri/T09229ZC6-FP3NH4PCJ/image.png▾
Burkhard
11/24/2019, 9:36 AM<?>
). Than you could do something like this
data class Test<?>(
val foo: Foo<?>, // nullable depending on class parameter
val bar: Bar, // never null
val baz: Baz:? // allways nullable
)
val test1 = Test<?>(getFooOrNull(), Bar(), null)
val test2 = Test<!>(Foo(), Bar(), null)
test1.foo?.doSomething()
test2.foo.doSomething()
This could be used to easily create Builder classes for data classes with immutable values.Samuel Michael
11/26/2019, 12:16 AMKy Leggiero
12/01/2019, 3:52 AMHullaballoonatic
12/01/2019, 3:56 AMnapperley
12/02/2019, 10:00 PMinline class ColourPair(val id, val backgroundColour: Int, val foregroundColour: Int) {
fun generatePairValue(): Int {
// ...
}
}
stantronic
12/04/2019, 12:48 PMjimn
12/05/2019, 7:06 AMby
should be considered something like extremelyvisibleaggregatememberVtable
because you basically can only send a call through a one-way wormhole to the instance named unless you manually (and without intellij's help) "replace delegation by overrides" at the container level.
there should be by
, which does what is documented now, and a v2 by
by some other clever infix name which does delegation through the declarator's vtable of that interface.Leon K
12/05/2019, 4:17 PMHullaballoonatic
12/21/2019, 6:01 PMval nums = listOf(1, 2, 3, 4, 5, 6)
val firstThree = nums[..2]
val lastThree = nums[-3..]
val trimEndsByTwo = nums[2..-3]
And the issue that I remember (note: not the only issue, perhaps) is that indexOf
returns -1
on an unfound element. so
val elementsToSeven = nums[..indexOf(7)]
would return the entirety of nums
, an unexpected value
C# 8.0 skirts around this issue by using ^
instead of -
as the end-orientation operator, and throws out of range for negative indices.
val lastThree = nums[^3..]
Would kotlin benefit from the same approach? I believe so. Especially given ^
is not currently used at allHullaballoonatic
12/31/2019, 10:01 PMHullaballoonatic
01/01/2020, 7:24 PMopen class Line(open var from: Point, open var to: Point) {
val reversed = Reversed
inner class Reversed : Line(to, from) {
override var from: Point
get() = <mailto:this@Line.to|this@Line.to>
set(v) {
<mailto:this@Line.to|this@Line.to> = v
}
override var to: Point ...
}
}
Where every instance of Line has its own singular instance of Reversed, which only borrows its state from Line, and is otherwise stateless
It is here that the idea of inner object
comes to mind
interface Line {
var from: Point
var to: Point
inner object Reversed : Line {
override var from: Point
get() = <mailto:this@Line.to|this@Line.to>
set(v) {
<mailto:this@Line.to|this@Line.to> = v
}
override var to: Point ...
}
}
I'm not sure if this is the best nomenclature for this structure, though. Maybe satellite
?
Could this be considered stateless in the same way that any getters/setters are? And thus usable in interfaces?stantronic
01/10/2020, 10:14 AMmax.cruz
01/20/2020, 6:16 PMpublic inline fun <R, T> Result<T>.fold(
onSuccess: (value: T) -> R,
onFailure: (exception: Throwable) -> R
): R
Leon K
01/24/2020, 4:46 PMautoDSL
, a library based on annotation processing that can automatically generate a dsl-style builder for your classes, which is simmilar to what i want, but is rather inelegant, and a library needing kapt - hurting compile-times
What would you think about some kind of language-feature that allows for easier building of immutable (data)-classes, like some kind of buildable
class modifier?
I could imagine it being a way to specify that a data-class has some buildable
fields, that are, as long as the class has not been built, mutable (and also might include building
-functions, that are only present whilst the object hasn't been built.
the modifier could then introduce a new method create
which turns the buildable class-instance into the normal, immutable data-class instance that you would then use everywhere.
this would, in a way, be a way of combining a builder class together with it's fully built, immutable version. for simple data-container-classes, this could be really practical
any thoughts?Derek Peirce
02/10/2020, 2:25 AMequals
or hashCode
or toString
implementation that uses fields based on their annotations or types, and to write easily understood serialization and deserialization formats.
Another example. If properties are more aggressively inlined, it would also simplify existing code that uses properties.
Consider this use of map delegation:
class MapExample(
map: Map<String, String>
) {
val x by map
}
When the by
is inlined, it becomes (effectively):
val x: String get() = map.getOrImplicitDefault(MapExample::x.name)
The decompiled class contains an entire KPropertyObject
that is used only for its name. Suppose that this name access were inlined, because the compiler knows that the name of x
is “x”:
val x: String get() = map.getOrImplicitDefault("x")
Now the overhead of involving properties is entirely eliminated.
As I work on mobile code where reductions in bytecode size and execution time are top priorities, I would like to have property-inlining features like these to be able to use reflection-like features without their large overhead (We’ve eliminated many uses of by
because of the unnecessary KProperty
fields). Would these be feasible for the language, and how useful would they be to you?Leon K
02/23/2020, 1:01 PMGilberto Diaz
03/18/2020, 3:06 PMrrader
03/21/2020, 9:57 PMdata class EmployeeDetailedDTO(val firstName: String)
class EmployeesRepository {
inline fun <reified T> findPage(isDeleted: Boolean = false): List<T> {
return when(T::class) {
EmployeeDetailedDTO::class -> listOf(EmployeeDetailedDTO("John")) as List<T>
else -> TODO()
}
}
}
so, it will not be needed to add as List<T>
Derek Peirce
04/05/2020, 4:16 AMlist.forEach { println(it) }
The Kotlin extension methods have an advantage in that, because they’re effectively static methods, they can be inlined, which makes this equivalent to:
for (value in list) { println(value) }
Meanwhile, the Java default methods have an advantage in that because it’s a default method, it can be specialized to the collection. For example, if list
is an ArrayList
, here’s how its forEach
is implemented:
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int size = this.size;
for (int i=0; modCount == expectedModCount && i < size; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
This is significantly more efficient than using its iterator, which requires creation and use of an iterator object as well as more frequent modCount
checks. The cost is that action is no longer inlined, so a lambda object is created instead (either once or per forEach
call, depending on what is in its scope), and there’s another level of indirection in executing it.
Of course, this doesn’t consider additional performance improvements from JIT optimizations, but I would expect that inlining the lambda is much simpler than inlining the logic of an iterator object, and the resulting code would still be more efficient due to the modCount
checks.
However, we haven’t covered another advantage of specialized methods: they can operate significantly more efficiently on their collections. Take, for example, Kotlin’s getOrPut
method versus Java 8’s computeIfAbsent.
They are effectively the same in what they do. However, getOrPut
requires a get
call that may be followed by a put
call. On a HashMap
, this means hashing the object twice and finding the proper location in the proper hash bucket twice. On a TreeMap
, this means traversing the tree twice. However, `HashMap`’s computeIfAbsent
is specialized so that as soon as it’s determined that there’s no prior value at the correct hash bucket, the new value can be put in the correct place immediately, without rehashing or renavigating. (Strangely, TreeMap
doesn’t have a similar specialized computeIfAbsent
implementation, and I can’t tell why.)
There’s also the issue that extension methods, being implementation-agnostic, can’t guarantee that a ConcurrentHashMap
is operated on safely, while its specialized computeIfAbsent
can.
So where does that leave Kotlin? Are there plans to ever find some way that a more advanced or JIT compiler can benefit from both inlining and specialization, or are we doomed to create iterators over `ArrayList`s forever?Kroppeb
05/10/2020, 1:18 PMwhen
conditions
https://github.com/Kotlin/KEEP/pull/213wasyl
06/04/2020, 2:55 PMpublic
visibility modifier is required. So now all declarations will require either public
modifier or private/internal
. Is making internal
visibility default in this mode on the table?CraftSpider
06/25/2020, 5:40 PMCraftSpider
06/25/2020, 7:40 PMSlackbot
07/05/2020, 5:53 PMandrzej
07/08/2020, 1:44 PMalso
scope function: https://github.com/JetBrains/kotlin-web-site/pull/1676/commits/c9d8e8fdb32ccf54da5b11459231e555a33eb597. It was already challenging to use scope functions properly (i.e. to not over- or mis-use them), this change made it harder...
From previous clear usage advice of when to use also
, now it is smth. like: "use also
for a specific reason ("Use also
for actions that need a reference rather to the object than to its properties and functions") unless there is this
shadowing, all the usage guidance do not count, use it as apply
.
While reading code I need to analyse if also
is put there because it was shadowing this
or if it followed intended usage.
Not to mention that all code bases that applied previous rule for years become messy after starting to apply new version of the rule...
If really this change was needed, why not simplify it and just say: use it as apply, whenever it
is more proper than this
.andrzej
07/08/2020, 1:44 PMalso
scope function: https://github.com/JetBrains/kotlin-web-site/pull/1676/commits/c9d8e8fdb32ccf54da5b11459231e555a33eb597. It was already challenging to use scope functions properly (i.e. to not over- or mis-use them), this change made it harder...
From previous clear usage advice of when to use also
, now it is smth. like: "use also
for a specific reason ("Use also
for actions that need a reference rather to the object than to its properties and functions") unless there is this
shadowing, all the usage guidance do not count, use it as apply
.
While reading code I need to analyse if also
is put there because it was shadowing this
or if it followed intended usage.
Not to mention that all code bases that applied previous rule for years become messy after starting to apply new version of the rule...
If really this change was needed, why not simplify it and just say: use it as apply, whenever it
is more proper than this
.ilya.gorbunov
07/08/2020, 5:40 PMit
is more proper than `this`" describes the essence of what we have tried to convey with this new wording, but then the request to clarify "when it
is more proper" would inevitably come.
So we expanded it with the situations when it is.andrzej
07/08/2020, 9:48 PMalso
on this page are about logging, it would be good to change that (I understand now there are many other valid cases, yet no single example of them)
2. Update section "Here is a short guide for choosing scope functions depending on the intended purpose:" and namely statements: "Object configuration: apply
" and "Additional effects: also
", now it should probably be a mix of both.
3. Still for me the following sentence: "Use also
for actions that need a reference rather to the object than to its properties and functions" is a hint that using also
in similar scenario as apply
is discouraged and I if I understood you correctly, it is actually completely fine. Example: a mapping function as extension method - you would normally use apply
but to avoid this
shadowing you can use also
(about which I have now some doubts because the docs say: "object rather than its properties")