onflow / cadence

Cadence, the resource-oriented smart contract programming language 🏃‍♂️
https://cadence-lang.org
Apache License 2.0
534 stars 138 forks source link

Conditions (assert/pre/post) are eagerly evaluating messages #1838

Open bjartek opened 2 years ago

bjartek commented 2 years ago
assert(true, message: "foo".concat("bar"))

The code above will never trigger, but it will still add computation since we have to evaluate the message.

turbolent commented 2 years ago

Thank you for pointing this out! This is correct behaviour, as, all function arguments are always eagerly evaluated, I see the problem here though.

Other languages solve this in various

Adding support for auto-closures or call-by-name seems like a lot of effort, for mostly this particular use-case.

Maybe we could adopt Kotlin's solution, i.e. change the message parameter to lazyMessage: ((): String), e.g. the example above would be:

assert(true, lazyMessage: fun (): String { return "foo".concat("bar") })

That's quite a lot more boiler-plate code though. We could maybe add sugar for function literals:

assert(true, lazyMessage: () => "foo".concat("bar"))
bluesign commented 2 years ago

On post conditions before has weird behavior too.

false || before(self.getBalance())>=0 calls getBalance, I know the reason but looks little strange

bluesign commented 2 years ago

Oh btw @autoclosure seems to be the elegant way to do this in my opinion. Backwards compatible. Basically rewriting ast to if !assert(expression) { panic(message) }

j1010001 commented 2 years ago

Nice to have, not a stable Cadence blocker