erg-lang / erg

A statically typed language compatible with Python
http://erg-lang.org
Apache License 2.0
2.7k stars 55 forks source link

Add `isolate` function #382

Open mtshiba opened 1 year ago

mtshiba commented 1 year ago

Consider a procedure like this.

sum!(arr: [Int; _]): Int =
    s = !0
    for! arr, i =>
        s.inc! i
    s

This procedure has no "external" side effects, aside from being able to be rewritten in the FP side-effect-free style. The side effects are completely localized internally. We want to be able to treat this as a function.

So, I propose the following isolate function.

isolate: |T: Type|(proc!: (() => T) and Localized) -> T

Localized trait means the procedure is completely localized and has no external influence.

sum! can be converted into sum using the isolate function as follows.

sum(arr: [Int; _]): Int =
    sum!() =
        s = !0
        for! arr, i =>
            s.inc! i
        s
    isolate sum!
mtshiba commented 1 year ago

I've added a function perform to the unsound module. This allows you to circumvent Erg effect analysis.

print x =
    unsound.perform do! print! x

print "hello"

This is similar to isolate, but it is more powerful and unsound. It can execute non-localized procedures.