gabrielfv
08/11/2020, 10:23 PMController<S>
and a View<S>
and I want this to work as a cyclic dependence where the controller depends on the view indirectly. For that I was thinking on defining a Provider
that takes a concrete controller and creates an instance of view with that injected.
Currently it looks like this:
fun interface ViewProvider<C : Controller<S>, S : State> {
fun get(controller: C): View<S>
}
It feels redundant that I have to locally specify S
, since Controller<S>
already does that job. For example:
class AController : Controller<A>
class Provider : ViewProvider<AController, A>
S
here can only be A
, since Controller<S>
is invariant in S
, and here S
is A
. Specifying A
looks somewhat redundant.
Could the type parameter here be inferred so the client code becomes less redundant?Nir
08/19/2020, 4:48 PMdata class foo(val i: Int, val s: String)
val (s, i) = foo(5, "hello") // Reverse order you might expect, s is an int, i is a string
One could imagine doing it by name of the field instead. Imagine we use =, to piggy back off of the analogy between positional and named arguments
val (=s, =i) = foo(5, "hello") // okay, now it matches by name instead, so we create a variable s that's a string, i that's an int
It would require that there was a property with the name of the variable. if not, compiler error. behind the scenes it just gets translated to:
val unusable = foo(5, "hello")
val s = unusable.s
val i = unusable.i
Advantages would be that it would allow destructuring "safely", without worrying about getting the order right. It's a relatively minor/simple thing to implement, easy to understand at first glance, and has a similar benefit for correctness as named arguments over positional arguments.Fleshgrinder
08/20/2020, 5:07 AM<=>
would be nice together with a corresponding Ordering
Enum.
when (a <=> b) {
Ordering.Less -> {}
Ordering.Equal -> {}
Ordering.Greater -> {}
}
edrd
08/20/2020, 3:20 PMpackage com.fasterxml.jackson.module.kotlin
import com.fasterxml.jackson.databind.ObjectMapper
companion object ObjectMapper.Kotlin {
fun forKotlin(): ObjectMapper = ...
}
// Would then also work
fun ObjectMapper.Kotlin.withAlphabeticallySortedProperties(): ObjectMapper = ...
// Usage from another file
import com.fasterxml.jackson.module.kotlin.ObjectMapper.Kotlin
fun main() = ObjectMapper.forKotlin()
This eliminates the need to add empty companion object
declarations in classes solely for the purpose of allowing extension functions and allows defining extensions for Java types.
The difference between internally and externally defined companion objects would be the ability to access private and protected members.
For more information on use cases and problems of the current alternatives, see my previous proposal (linked above).Nir
08/31/2020, 1:37 PMinline
functions with loops? Since return
is allowed inside lambdas in that situation, it seems surprising that break/continue do not work. It also limits the language's ability slightly to "extend" the built in loops.janvladimirmostert
09/02/2020, 8:28 PMclass postgresql(function: postgresql.() -> Unit) {
....
infix fun postgresql.DESC(value: Unit): postgresql {
return this
}
}
fun main() {
postgresql {
SELECT (
ListingTable::section, ListingTable::id,
ListingImageTable::name, ListingImageTable::listingId
) FROM (
ListingTable::class
) LEFT JOIN (
ListingImageTable::class
) ON (
ListingTable::id == ListingImageTable::id
) WHERE (
true
) ORDER BY(ListingTable::modified) DESC Unit
}
Nir
09/06/2020, 2:47 AMnatpryce
09/10/2020, 12:22 PMList.of(…)
and List.copyOf(…)
create immutable lists. The Kotlin equivalents, listOf(…)
and anIterable.toList()
actually create mutable lists but return the List interface that doesn’t allow mutation. In Kotlin, that’s not a problem — lists are processed by being transformed with map/flatMap/filter/etc. and so nothing holds on to a reference to mutable lists and aliasing errors do not occur. However… when you pass the Kotlin List across the Java interop boundary, Java sees it as a mutable java.util.List and, because the Kotlin list is actually mutable, Java can mutate a list through an interface that the Kotlin type system considers to be unmodifiable. Worse, the Kotlin code is now more error prone than the Java code, because the Java code would fail immediately if you tried to mutate the immutable list, but the Kotlin code allows that list to be mutated.
Suggestions:
• when the kotlin compiler is targeting JVM version 11 and above, translate Kotlin’s listOf and toList to the JDK List.of and List.copyOf functions.
• on 1.8 and below, wrap Kolin Lists with Collections.unmodifiableList (or some equivalent in the Kotlin runtime) when being passed across the interop boundary.Eduardo Guerra
09/11/2020, 1:47 PMfunc returnMultipleValues() -> (String, Int, Double) {
return ("Swift Tuple", 12, 3.14)
}
PS. I know how to use lists hahaha, I just think that it would be a lot easier this wayNir
09/16/2020, 7:08 PMreified
is. I think that would be super useful. That could allow simple tuples, and non-neutered implementations of things like zip, for example.eduardog3000
09/17/2020, 6:32 PM@class:Controller
@GetMapping("/test")
fun singleFunController() = "viewname"
At the moment all top level functions in a file compile to the same class, so any with a class annotation would have to compile to its own class, presumably with a name based on the function name, SingleFunControllerKt
or something. Probably a little limited in use, but it would be neat.blackstardlb
09/21/2020, 1:43 PMclass Test1 {
private val _subject: Subject<String> = BehaviorSubject.createDefault("Test")
val subject: Observable<String> = _subject
fun onEvent(event: String) = _subject.onNext(event)
}
class Test2 {
val subject: Observable<String> = BehaviorSubject.createDefault("Test")
fun onEvent(event: String) = (subject as BehaviorSubject<String>).onNext(event)
}
class Proposal {
exposed:Observable<String> val subject: BehaviorSubject<String> = BehaviorSubject.createDefault("Test")
protected exposed:Observable<String> val subject2: BehaviorSubject<String> = BehaviorSubject.createDefault("Test")
fun onEvent(event: String) = subject.onNext(event)
}
fun main() {
// should all be of type Observable<String>
val test = Test().subject
val test2 = Test2().subject
val proposal = Proposal().subject
}
Test1 shows the private backing property method. Test2 shows using the val as the interface / parent class and casting everywhere with as. Proposal show an example syntax of how this could be made less verbose and more readable.Sebastian Brunner
09/23/2020, 6:46 PMif (1 <= x <= 10) // do something
This would greatly improve readability and would reduce bugs since it's easier to understand that x is within the boundaries of 1 and 10.
Way better than the current equivalent: if (1 <= x && x <= 10)
. The "&& x" is just boilerplate code here...
Assignments:
For assignments I'd like to have the possibility of assigning an assignment to another variable.
E.g. myObject.apply { inputFee = outputFee = 1.0 }
In this case both inputFee and outputFee would be set to 1.0 (or more like inputFee would be set to outputFee).
This is useful for mapping code so it makes most sense for properties.
I could also imagine like saving a property to a variable before it is modified in someway. Maybe like this:
val before = myObject.counter = someArg
myObject.count() // modifies counter
val difference = myObject.counter - before
What do you guys think?Fleshgrinder
09/26/2020, 11:58 AMnatpryce
10/02/2020, 8:32 PMnatpryce
10/02/2020, 8:32 PMSlackbot
10/03/2020, 3:28 PMDaniele Segato
10/06/2020, 5:07 PMSomething.Builder()
.apply {
foo("mandatory argument*)
val barArg = grabBarArg()
if (barArg != null) {
bar(barArg)
} else {
// do nothing, leave the default
}
}
.build()
With the default parameters we don't have the option of leaving the default like that;
Something (
foo = "mandatory argument",
bar = grabBarArg() ?: _
)
I think it would be helpful to have a way of explicitly saying "use default" like passing a Nothing
? Or in some other similar way?
When I'm this situation if i have control on the class i create a secondary constructor, but it could be helpful, i think, to have a way to provide the default from the caller.
It might also improve kotlin / java interoperability.holgerbrandl
10/10/2020, 10:20 AMNumber
interface extending Comparable
? Being a number always superimposes an ordering imho.raulraja
10/13/2020, 10:01 PMaarjav
10/14/2020, 2:56 PMabstract class Foo(val id: String, val f1: String, val f2: String)
class Bar(id: String, f1: String, f2: String, val other: String): Foo(id, f1, f2)
I want to avoid having to specify the same props (id
,f1
, f2
), and better yet would like to reuse the documentation across all the subclassesMarc Knaup
10/16/2020, 9:52 PMfinally
block.
I often log timing, exceptions and cancelations for a block of code. With the current approach I’d have to duplicate logging code in catch
clause(s) and at the end of the try block in the success case. I’d also have to use .also { … }
in the try block to not change the return value.
It would be much easier if I could something like
val start = TimeSource.Monotonic.markNow()
val x = try {
lotsOfLogic()
}
finally { e -> // Throwable?
// complicated logging with or without exception
}
Without:
val start = TimeSource.Monotonic.markNow()
val x = try {
lotsOfLogic().also {
// complicated logging without exception
}
}
// multiple catch clauses would duplicate logging
catch(e: Throwable) {
// complicated logging with exception
throw e // rethrow needed
}
aleksey.tomin
10/22/2020, 5:57 AMelect
10/22/2020, 11:04 AMwhen
and the possibility to declare some val
quite limiting:
val platform = when(val os = DefaultNativePlatform.getCurrentOperatingSystem()) {
os.isWindows -> 0
}
if I declare something like that, when
expect exclusively matches against os
Type
I'd like something more broadMarc Knaup
10/25/2020, 12:55 PMNir
10/26/2020, 1:49 PMinterface Result<out T> : Serializable
inline class Outcome<out T, out E: Throwable> : Result<T>
If you do something like this, then you can use Outcome
as local error handling wherever you want to keep the type. And, if you need to collect errors from multiple sources, you just let Outcome up-convert to a Result.
Things like runCatching
could construct an Outcome<T, Throwable>
(i.e. the most general case of Outcome) which could then be allowed to up-convert to Result instantly (leaving their API identical to now)natario1
10/27/2020, 12:14 PMfun getMarkerLocation(): Pair<Double, Double> { ... }
fun addMarker(name: String, lat: Double, lng: Double, color: Int) { ... }
addMarker(
name = "marker",
color = Color.RED,
(lat, lng) = getMarkerLocation()
)
I wonder if this has ever been discussed.Animesh Sahu
10/31/2020, 2:55 PM@inheritDoc
. Something even more extensible and familiar, more like:
/**
* @copyFrom SuperClassOrInterfaceManualSelection.someFunctionName
* // extended docs with other info
*/
• It could be used by IDE to jump into correct definition.
• It could be beneficial to follow strict code styles where a KDoc is required on public/internal/protected functions.
• It can and also give the user a clue from where the doc is being inherited from, such as if a class has multiple Interface inheritence (and no superclass) with same function defined with different KDoc one can assure the overridden KDoc follows the particular interface.
• Same goes (on rare cases) if one wants to inherit KDoc from the interface instead of super class (if class both extend a class and implement interface(s)).
Edit:
Another idea came in my mind extending the above feature-request/proposal, if there can be pythonic style line selector in @copyFrom
:
@copyFrom Interface.method[1:5] // copy/inherit line 1 to 5 (exclusive or maybe inclusive)
@copyFrom Interface.method[2:] // copy/inherit line 2 to the last line
@copyFrom Interface.method[:6] // copy/inherit from first line to line 6
// Below are not important part of this proposal, but maybe easier to select from bottom if the KDoc of Interface.method was long enough
@copyFrom Interface.method[:-2] // copy/inherit from first line to second last line
Apologies for any grammatical errors and/or improper formatting.elect
11/27/2020, 11:23 AM*
operator, so that this:
val s = "pos (%8.2f,%8.2f), uv (%.6f,%.6f)\n".format(v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col)
may become
val s = "pos (%8.2f,%8.2f), uv (%.6f,%.6f)\n".format(*v.pos, *v.uv)
Marc Knaup
11/28/2020, 11:24 PMinterface SomeType
@RequiresAtLeastOneOptionalArgument
fun SomeType.with(key: String? = null, ref: Ref<*>? = null, block: () -> Unit): Unit = TODO()
fun foo(some: SomeType) {
some.with {
// useless with
}
some.with(key = "key") {
// good
}
}
Another example:
@RequiresAtLeastOneOptionalArgument
fun makeBorder(width: BorderWidth? = null, style: BorderStyle? = null, color: Color? = null): Border =
if (width != null || style != null || color != null) Border(width, style, color)
else error("At least one property must be specified.")
makeBorder()
is then statically known to be invalid.
It won’t catch makeBorder(null)
but that’s another issue.Marc Knaup
11/28/2020, 11:24 PMinterface SomeType
@RequiresAtLeastOneOptionalArgument
fun SomeType.with(key: String? = null, ref: Ref<*>? = null, block: () -> Unit): Unit = TODO()
fun foo(some: SomeType) {
some.with {
// useless with
}
some.with(key = "key") {
// good
}
}
Another example:
@RequiresAtLeastOneOptionalArgument
fun makeBorder(width: BorderWidth? = null, style: BorderStyle? = null, color: Color? = null): Border =
if (width != null || style != null || color != null) Border(width, style, color)
else error("At least one property must be specified.")
makeBorder()
is then statically known to be invalid.
It won’t catch makeBorder(null)
but that’s another issue.ephemient
11/28/2020, 11:44 PMprivate fun makeBorderImpl(width: BorderWidth?, style: BorderStyle?, color: Color?): Border = ...
fun makeBorder(width: BorderWidth, style: BorderStyle? = null, color: Color? = null) =
makeBorderImpl(width = width, style = style, color = color)
fun makeBorder(style: BorderStyle, color: Color? = null) =
makeBorderImpl(width = null, style = style, color = color)
fun makeBorder(color: Color) =
makeBorderImpl(width = null, style = null, color = color)
Marc Knaup
11/28/2020, 11:50 PMn
overloads but n * m
(times amount of functions). That’s a looot.
(You also wouldn’t be able to call that with three nullable variables in your example)louiscad
11/29/2020, 9:26 AM