Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Implement Concurrency Primitives #3

Open
spy16 opened this issue Oct 14, 2020 · 0 comments
Open

Implement Concurrency Primitives #3

spy16 opened this issue Oct 14, 2020 · 0 comments
Milestone

Comments

@spy16
Copy link
Owner

spy16 commented Oct 14, 2020

Concurrency primitives need to be decided.

Consider:

type GoExpr struct {
	Value value.Any
}

// Eval forks the given context to get a child context and launches goroutine
// with the child context to evaluate the Value.
func (ge GoExpr) Eval(ctx *Context) (value.Any, error) {
	child := ctx.fork()

        p := Promise{
                val: make(chan value.Any, 1)
                err: make(chan error, 1)
        }

	go func() {
                // N.B.:  we don't need to close any of the channels (see note below).
		if val, err := child.Eval(ge.Value); err != nil {
                    p.err <- err  // non-blocking due to buffer
                } else {
                    p.val <- val
                }
	}()
	return nil, nil
}

type Promise struct{
    // both channels are buffered (len=1)
    val chan value.Any
    err chan error
}

(p Promise) Eval(ctx *Context) (value.Any, err) {    return p, nil    }

(p Promise) Invoke(ctx *Context, args ...value.Any) (val value.Any, err error) {
    select {
    case val = <-p.val
    case err = <-p.err
    }
    return
}
@spy16 spy16 added this to the v1.0 milestone Oct 14, 2020
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant