karelpeeters
09/26/2018, 10:39 AMEugenio
09/26/2018, 1:06 PMinterface Parent1 {
var state1: String
fun manipulateState1() {
state1 += "!"
}
}
interface Parent2 {
var state2: Int
fun manipulateState2() {
state2 += 1
}
}
class Child : Parent1, Parent2 {
override var state1 = "hello"
override var state2 = 0
fun manipulateState() {
manipulateState1()
manipulateState2()
}
}
karelpeeters
09/26/2018, 1:09 PMChild
to access both states, there's no encapsulation.Eugenio
09/26/2018, 1:19 PMinterface Parent1_ {
var state1: String
fun manipulateState1() {
state1 += "!"
}
}
interface Parent2_ {
var state2: Int
fun manipulateState2() {
state2 += 1
}
}
interface Parent1 : Parent1_ {
@Deprecated("", level = HIDDEN)
override var state1: String
}
interface Parent2 : Parent2_ {
@Deprecated("", level = HIDDEN)
override var state2: Int
}
class Child : Parent1, Parent2 {
override var state1 = "hello"
override var state2 = 0
fun manipulateState() {
manipulateState1()
manipulateState2()
}
}
karelpeeters
09/26/2018, 1:20 PMChild
not interact with state1
and state2
then? That's evil 😒imple_smile:Eugenio
09/26/2018, 1:28 PM(this as Parent1_).state1
otherwise it's as if it doesn't exist, not even in the autocompleteinterface Parent1 {
fun manipulateState1()
}
interface Parent2 {
fun manipulateState2()
}
interface Parent1State : Parent1 {
var state1: String
override fun manipulateState1() {
state1 += "!"
}
}
interface Parent2State : Parent2 {
var state2: Int
override fun manipulateState2() {
state2 += 1
}
}
class Child :
Parent1 by object : Parent1State { override var state1 = "" },
Parent2 by object : Parent2State { override var state2 = 0 }
{
fun manipulateState() {
manipulateState1()
manipulateState2()
}
}
karelpeeters
09/26/2018, 1:29 PMEugenio
09/26/2018, 1:29 PMkarelpeeters
09/26/2018, 1:29 PMEugenio
09/26/2018, 1:31 PMfun Parent1(state1: String): Parent1 = object : Parent1State { override var state1 = state1 }
fun Parent2(state2: Int): Parent2 = object : Parent2State { override var state2 = state2 }
class Child :
Parent1 by Parent1(""),
Parent2 by Parent2(0)
{
fun manipulateState() {
manipulateState1()
manipulateState2()
}
}
karelpeeters
09/26/2018, 1:31 PMEugenio
09/26/2018, 2:54 PMkarelpeeters
09/29/2018, 1:56 PMprotected
visibility? interface User {
fun foo()
}
class ConstUser(size: Int) : User {
private val values = Array(size) { "$it" }
override fun foo() = print(values)
fun get(index: Int) = values[index]
}
class MyUser: User by ConstUser(2) {
//I want ConstUser.get(index) to be protected-level visible here
}
Eugenio
09/29/2018, 2:25 PMinterface User {
fun foo()
}
class ConstUser(size: Int) : User {
private val values = Array(size) { "$it" }
override fun foo() = print(values)
operator fun get(index: Int) = values[index]
}
open class MyUser
private constructor (
private val user: ConstUser
): User by user {
constructor() : this(ConstUser(2))
protected operator fun get(index: Int) = user[index]
}
karelpeeters
09/29/2018, 2:30 PMMyUser
-type classes). I wonder if there's a way to get access to the delegate object instance, that might simplify things a bit.Eugenio
09/29/2018, 2:39 PMkarelpeeters
09/29/2018, 2:49 PMEugenio
09/29/2018, 2:55 PMkarelpeeters
09/29/2018, 3:35 PMValue
. Instructions themselves are also values, representing the result of their computation (this works and is elegant because of SSA, don't worry about it).
Current code, commented with things I'm not happy about: https://gist.github.com/flaghacker/bfc6c09e50bacdbb236e79b8729ffe24Eugenio
09/29/2018, 3:52 PMkarelpeeters
09/29/2018, 3:58 PMAdd(Constant(1), Constant(2))
as an operand, that operand can be replaced with Constant(3)
everywhere in the IR. In practice this would be a replaceWith(Constant(3))
call on the add instruction I mentioned above, that then loops over the users and replaces itself with the new value.
• I specifically don't want Value to be a User, see the comment above Value. That is just my current crappy solution to the fundamental multiple inheritance problem: things can be Values and Users at the same time.
• Because the optimizations mutate stuff all over the place, eg. in the above example replacing 1 + 2
with 3
requires mutating of everything that uses 1 + 2
. Creating so many new objects is both bad for performance and difficult to do polymorphically (see Java's Clonable
disaster).Eugenio
09/29/2018, 4:00 PMkarelpeeters
09/29/2018, 4:01 PMEugenio
09/29/2018, 4:02 PMkarelpeeters
09/29/2018, 4:14 PMEugenio
09/29/2018, 5:22 PMkarelpeeters
09/29/2018, 5:41 PMoperator
outside of Add
, right? I guess it's not that bad.Eugenio
09/29/2018, 5:43 PMOperandDelegate
, BUT that by itself is stateless!provideDelegate
is invoked, which can only be invoked on the right kind of object, and can access internals of ConstUser
because it's enclosed in it (but it's not an inner class!)OperandDelegate
(for a certain Value
) across different properties and even different instructionskarelpeeters
09/29/2018, 5:59 PMprovideDelegate
thing, thanks! I used to cache the delegate instances but I cut out that part to have simpler code. I'll toy around a bit with this.val zero = Constant(0)
val x = Add(zero, zero)
with(x) { x.operand(zero) }
but that's pretty unlikely.Eugenio
09/30/2018, 6:04 PMby
karelpeeters
09/30/2018, 6:45 PM