mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-07 23:07:14 +02:00
Express at-most-once evaluation (thunk caching) in types
This commit is contained in:
parent
94797696a9
commit
0ec5f40a58
18
thunks.go
18
thunks.go
@ -38,9 +38,19 @@ func (rv *readyValue) bindToObject(sb selfBinding, origBinding bindingFrame, fie
|
||||
return rv
|
||||
}
|
||||
|
||||
func (rv *readyValue) aPotentialValue() {}
|
||||
|
||||
// potentialValues
|
||||
// -------------------------------------
|
||||
|
||||
// evaluable is something that can be evaluated and the result is always the same
|
||||
// It may require computation every time evaluation is requested (in contrast with
|
||||
// potentialValue which guarantees that computation happens at most once).
|
||||
type evaluable interface {
|
||||
// fromWhere keeps the information from where the evaluation was requested.
|
||||
getValue(i *interpreter, fromWhere *TraceElement) (value, error)
|
||||
}
|
||||
|
||||
// thunk holds code and environment in which the code is supposed to be evaluated
|
||||
type thunk struct {
|
||||
env environment
|
||||
@ -94,10 +104,10 @@ func (th *callThunk) getValue(i *interpreter, trace *TraceElement) (value, error
|
||||
// TODO(sbarzowski) force use cached/ready everywhere? perhaps an interface tag?
|
||||
// TODO(sbarzowski) investigate efficiency of various representations
|
||||
type cachedThunk struct {
|
||||
pv potentialValue
|
||||
pv evaluable
|
||||
}
|
||||
|
||||
func makeCachedThunk(pv potentialValue) *cachedThunk {
|
||||
func makeCachedThunk(pv evaluable) *cachedThunk {
|
||||
return &cachedThunk{pv}
|
||||
}
|
||||
|
||||
@ -112,6 +122,8 @@ func (t *cachedThunk) getValue(i *interpreter, trace *TraceElement) (value, erro
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (t *cachedThunk) aPotentialValue() {}
|
||||
|
||||
// errorThunk can be used when potentialValue is expected, but we already
|
||||
// know that something went wrong
|
||||
type errorThunk struct {
|
||||
@ -126,6 +138,8 @@ func makeErrorThunk(err error) *errorThunk {
|
||||
return &errorThunk{err}
|
||||
}
|
||||
|
||||
func (th *errorThunk) aPotentialValue() {}
|
||||
|
||||
// unboundFields
|
||||
// -------------------------------------
|
||||
|
||||
|
7
value.go
7
value.go
@ -40,14 +40,15 @@ type value interface {
|
||||
// are not calculated before they are used). It is also a useful abstraction
|
||||
// in other cases like error handling.
|
||||
//
|
||||
// It may or may not require computation.
|
||||
//
|
||||
// Getting the value a second time may or may not result in additional evaluation.
|
||||
// It may or may not require arbitrary computation when getValue is called the
|
||||
// first time, but any subsequent calls will immediately return.
|
||||
//
|
||||
// TODO(sbarzowski) perhaps call it just "Thunk"?
|
||||
type potentialValue interface {
|
||||
// fromWhere keeps the information from where the evaluation was requested.
|
||||
getValue(i *interpreter, fromWhere *TraceElement) (value, error)
|
||||
|
||||
aPotentialValue()
|
||||
}
|
||||
|
||||
// A set of variables with associated potentialValues.
|
||||
|
Loading…
Reference in New Issue
Block a user