Считаю все эти контексты, миллион неявных this-ов большой ошибкой создателей языка. Без IDE уже невозможно разобраться, кто кого вызывает. Конечно для компании, у которой IDE это их дойная корова, это вряд ли ощущается как проблема, но моё твёрдое мнение — код должен в уме интерпретироваться в блокноте без подглядывания в другие файлы. Должно быть однозначно понятно, какой метод вызывается. Лично я вернулся на java в том числе из-за этого. И Scala не стал учить тоже в немалой степени из-за её implicit-ов.
Здравствуйте, 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}")
}
}
{
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? Контекст неявно передаётся? А если вызовы асинхронные, в других тредах?
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
·>Видео не смортел. Вопрос возник — как это будет работать в случае вызовов методов внутри with? Контекст неявно передаётся? А если вызовы асинхронные, в других тредах?
Передаётся если функции получают эти контексты.
Может передаваться не один контекст, а пачка. Помимо этого можно передвать например стратегию обработки ошибок (как в VB: On Error Resume Next )
Помимо всего прочего их можно использовать для построения графа вычислений по выражению.
Здравствуйте, kov_serg, Вы писали:
_>·>Видео не смортел. Вопрос возник — как это будет работать в случае вызовов методов внутри with? Контекст неявно передаётся? А если вызовы асинхронные, в других тредах? _>Передаётся если функции получают эти контексты.
А если забыли передать контексты? a+b внезапно окажется в глобальном контексте?
_>Может передаваться не один контекст, а пачка. Помимо этого можно передвать например стратегию обработки ошибок (как в VB: On Error Resume Next )
sсala implicits, короче. Жуть жуткая, write-once код, поддержке и рефакторингу не подлежит.
_>Помимо всего прочего их можно использовать для построения графа вычислений по выражению.
Не очень ясно как. Для этого надо захватывать аргументы, а не их значения. Или я не понял что ты имеешь в виду.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Здравствуйте, ·, Вы писали:
_>>Помимо всего прочего их можно использовать для построения графа вычислений по выражению. ·>Не очень ясно как. Для этого надо захватывать аргументы, а не их значения. Или я не понял что ты имеешь в виду.
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)
}
}
Здравствуйте, 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.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай