Context Receivers
От: kov_serg Россия  
Дата: 09.05.22 18:10
Оценка: 80 (1) +1
Good news, everyone:
https://www.youtube.com/watch?v=GISPalIVdQY&t=1588s
И почему этого раньше не было.
Re: Context Receivers
От: kov_serg Россия  
Дата: 11.05.22 09:35
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>И почему этого раньше не было.

Теперь можно писать так:
class ModuleArithmetic(val module:Int) { }
class SaturationArithmetic(val low:Int,val high:Int) { }
class Num(val v:Int) {}

context(ModuleArithmetic) operator fun Num.plus(rv:Num):Num {
    var r=(v+rv.v)%module
    if (r<0) r+=module
    return Num(r)
}
context(SaturationArithmetic) operator fun Num.plus(rv:Num):Num {
    var r=v+rv.v
    if (r<low) r=low
    if (r>high) r=high
    return Num(r)
}

fun main() {
    val a=Num(8)
    val b=Num(7)
    with( ModuleArithmetic(13) ) {
        var z=a+b
        println("z=${z.v}")
    }
    with( SaturationArithmetic(0,10) ) {
        var z=a+b
        println("z=${z.v}")
    }    
}

z=2
z=10
Re[2]: Context Receivers
От: · Великобритания  
Дата: 11.05.22 12:12
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>Теперь можно писать так:

_>    with( ModuleArithmetic(13) ) {
_>        var z=a+b
_>        println("z=${z.v}")
_>    }
_>    with( SaturationArithmetic(0,10) ) {
_>        var z=a+b
_>        println("z=${z.v}")
_>    }    
_>}

Т.е. по сути синтаксический сахар для
{
  var ctx = new ModuleArithmetic(13);
  var z = ctx.plus(a, b);
  println("z=${z.v}")
}
{
  var ctx = new SaturationArithmetic(0,10);
  var z = ctx.plus(a, b);
  println("z=${z.v}")
}

И всё? Ну нафиг такое счастье. Даже по строчкам ровно столько же.

Видео не смортел. Вопрос возник — как это будет работать в случае вызовов методов внутри with? Контекст неявно передаётся? А если вызовы асинхронные, в других тредах?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 11.05.2022 12:14 · . Предыдущая версия .
Re[3]: Context Receivers
От: kov_serg Россия  
Дата: 11.05.22 13:18
Оценка:
Здравствуйте, ·, Вы писали:

·>Видео не смортел. Вопрос возник — как это будет работать в случае вызовов методов внутри with? Контекст неявно передаётся? А если вызовы асинхронные, в других тредах?

Передаётся если функции получают эти контексты.
Может передаваться не один контекст, а пачка. Помимо этого можно передвать например стратегию обработки ошибок (как в VB: On Error Resume Next )
Помимо всего прочего их можно использовать для построения графа вычислений по выражению.
Re[4]: Context Receivers
От: · Великобритания  
Дата: 11.05.22 19:17
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>·>Видео не смортел. Вопрос возник — как это будет работать в случае вызовов методов внутри with? Контекст неявно передаётся? А если вызовы асинхронные, в других тредах?

_>Передаётся если функции получают эти контексты.
А если забыли передать контексты? a+b внезапно окажется в глобальном контексте?

_>Может передаваться не один контекст, а пачка. Помимо этого можно передвать например стратегию обработки ошибок (как в VB: On Error Resume Next )

sсala implicits, короче. Жуть жуткая, write-once код, поддержке и рефакторингу не подлежит.

_>Помимо всего прочего их можно использовать для построения графа вычислений по выражению.

Не очень ясно как. Для этого надо захватывать аргументы, а не их значения. Или я не понял что ты имеешь в виду.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 11.05.2022 19:17 · . Предыдущая версия .
Re: Context Receivers
От: vsb Казахстан  
Дата: 11.05.22 19:25
Оценка: +1 -1
Считаю все эти контексты, миллион неявных this-ов большой ошибкой создателей языка. Без IDE уже невозможно разобраться, кто кого вызывает. Конечно для компании, у которой IDE это их дойная корова, это вряд ли ощущается как проблема, но моё твёрдое мнение — код должен в уме интерпретироваться в блокноте без подглядывания в другие файлы. Должно быть однозначно понятно, какой метод вызывается. Лично я вернулся на java в том числе из-за этого. И Scala не стал учить тоже в немалой степени из-за её implicit-ов.
Re[5]: Context Receivers
От: kov_serg Россия  
Дата: 11.05.22 20:10
Оценка:
Здравствуйте, ·, Вы писали:

_>>Помимо всего прочего их можно использовать для построения графа вычислений по выражению.

·>Не очень ясно как. Для этого надо захватывать аргументы, а не их значения. Или я не понял что ты имеешь в виду.
class Vars {
    var last_id:Int=0
    fun newID() = last_id++
    fun input(name:String):Var {
        var v=Var()
        println("R${v.id}=$name")
        return v
    }
    fun output(name:String,v:Var) {
        println("$name=R${v.id}")
    }
    fun emit_add(res:Var,a:Var,b:Var):Var {
        println("R${res.id}=R${a.id}+R${b.id}")
        return res
    }
    fun emit_mul(res:Var,a:Var,b:Var):Var {
        println("R${res.id}=R${a.id}*R${b.id}")
        return res
    }
}

context(Vars) class Var { val id:Int=newID() }
context(Vars) operator fun Var.plus(rv:Var):Var { return emit_add(Var(),this,rv) }
context(Vars) operator fun Var.times(rv:Var):Var { return emit_mul(Var(),this,rv) }

fun main() {
    with( Vars() ) {
        val a=input("a")
        val b=input("b")
        val c=input("c")

        val d=(a+b*c)*(a+b)

        output("result",d)
    }
}

R0=a
R1=b
R2=c
R3=R1*R2
R4=R0+R3
R5=R0+R1
R6=R4*R5
result=R6
Re[6]: Context Receivers
От: · Великобритания  
Дата: 30.08.22 14:01
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>>>Помимо всего прочего их можно использовать для построения графа вычислений по выражению.

_>·>Не очень ясно как. Для этого надо захватывать аргументы, а не их значения. Или я не понял что ты имеешь в виду.
_>    with( Vars() ) {
_>        val a=input("a")
_>        val b=input("b")
_>        val c=input("c")

_>        val d=(a+b*c)*(a+b)

_>        output("result",d)
_>    }
_>}

Тут, как я понял, эффект лишь от того, что есть перегрузка операторов и удалось обойтись бинарными операторами. "По старинке" это выглядело бы как-то так:
    val ctx = Vars()
    val a=ctx.input("a")
    val b=ctx.input("b")
    val c=ctx.input("c")

    val d=ctx.mul(ctx.plus(a, ctx.mul(b, c)), ctx.plus(a, b))

    output("result",d)
}


В итоге, если оно и полезно, то только в каком-то очень специфичном коде, где, например, много математики и хочется чтобы математические выражения выглядели более естественно.
А в целом, выглядит как очередной удобный дробовик для стрельбы в ногу, как и scala implicits.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Отредактировано 30.08.2022 14:02 · . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.