interfaces

package
v0.0.0-...-173ccf6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2018 License: GPL-3.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// Debug enables debugging for some commonly used debug information.
	Debug = false
)
View Source
const (
	// ErrTypeCurrentlyUnknown is returned from the Type() call on Expr if
	// unification didn't run successfully and the type isn't obvious yet.
	ErrTypeCurrentlyUnknown = Error("type is currently unknown")
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Edge

type Edge struct {
	Kind1 string // kind of resource
	Name1 string // name of resource
	Send  string // name of field used for send/recv (optional)

	Kind2 string // kind of resource
	Name2 string // name of resource
	Recv  string // name of field used for send/recv (optional)

	Notify bool // is there a notification being sent?
}

Edge is the data structure representing a compiled edge that is used in the lang to express a dependency between two resources and optionally send/recv.

type Error

type Error string

Error is a constant error type that implements error.

func (Error) Error

func (e Error) Error() string

Error fulfills the error interface of this type.

type Expr

type Expr interface {
	pgraph.Vertex               // must implement this since we store these in our graphs
	Interpolate() (Expr, error) // return expanded form of AST as a new AST
	SetScope(*Scope) error      // set the scope here and propagate it downwards
	SetType(*types.Type) error  // sets the type definitively, errors if incompatible
	Type() (*types.Type, error)
	Unify() ([]Invariant, error) // TODO: is this named correctly?
	Graph() (*pgraph.Graph, error)
	Func() (Func, error) // a function that represents this reactively
	SetValue(types.Value) error
	Value() (types.Value, error)
}

Expr represents an expression in the language. Expr implementations must have their method receivers implemented as pointer receivers so that they can be easily copied and moved around. Expr also implements pgraph.Vertex so that these can be stored as pointers in our graph data structure.

type Func

type Func interface {
	Validate() error // FIXME: this is only needed for PolyFunc. Get it moved and used!
	Info() *Info
	Init(*Init) error
	Stream() error
	Close() error
}

Func is the interface that any valid func must fulfill. It is very simple, but still event driven. Funcs should attempt to only send values when they have changed. TODO: should we support a static version of this interface for funcs that never change to avoid the overhead of the goroutine and channel listener?

type Info

type Info struct {
	Pure bool        // is the function pure? (can it be memoized?)
	Memo bool        // should the function be memoized? (false if too much output)
	Sig  *types.Type // the signature of the function, must be KindFunc
	Err  error       // is this a valid function, or was it created improperly?
}

Info is a static representation of some information about the function. It is used for static analysis and type checking. If you break this contract, you might cause a panic.

type Init

type Init struct {
	Hostname string // uuid for the host
	//Noop bool
	Input  chan types.Value // Engine will close `input` chan
	Output chan types.Value // Stream must close `output` chan
	World  resources.World
	Debug  bool
	Logf   func(format string, v ...interface{})
}

Init is the structure of values and references which is passed into all functions on initialization.

type Invariant

type Invariant interface {
	// TODO: should we add any other methods to this type?
	fmt.Stringer
}

Invariant represents a constraint that is described by the Expr's and Stmt's, and which is passed into the unification solver to describe what is known by the AST.

type Output

type Output struct {
	Resources []resources.Res
	Edges     []*Edge
}

Output is a collection of data returned by a Stmt.

func (*Output) Empty

func (obj *Output) Empty() *Output

Empty returns the zero, empty value for the output, with all the internal lists initialized appropriately.

type PolyFunc

type PolyFunc interface {
	Func // implement everything in Func but add the additional requirements

	// Polymorphisms returns a list of possible function type signatures. It
	// takes as input a list of partial "hints" as to limit the number of
	// possible results it returns. These partial hints take the form of a
	// function type signature (with as many types in it specified and the
	// rest set to nil) and any known static values for the input args. If
	// the partial type is not nil, then the Ord parameter must be of the
	// correct arg length. If any types are specified, then the array must
	// be of that length as well, with the known ones filled in. Some
	// static polymorphic functions require a minimal amount of hinting or
	// they will be unable to return any possible result that is not
	// infinite in length. If you expect to need to return an infinite (or
	// very large) amount of results, then you should return an error
	// instead. The arg names in your returned func type signatures should
	// be in the standardized "a..b..c" format. Use util.NumToAlpha if you
	// want to convert easily.
	Polymorphisms(*types.Type, []types.Value) ([]*types.Type, error)

	// Build takes the known type signature for this function and finalizes
	// this structure so that it is now determined, and ready to function as
	// a normal function would. (The normal methods in the Func interface
	// are all that should be needed or used after this point.)
	Build(*types.Type) error // then, you can get argNames from Info()
}

PolyFunc is an interface for functions which are statically polymorphic. In other words, they are functions which before compile time are polymorphic, but after a successful compilation have a fixed static signature. This makes implementing what would appear to be generic or polymorphic instead something that is actually static and that still has the language safety properties.

type Scope

type Scope struct {
	Variables map[string]Expr
}

Scope represents a mapping between a variables identifier and the corresponding expression it is bound to. Local scopes in this language exist and are formed by nesting within if statements. Child scopes can shadow variables in parent scopes, which is another way of saying they can redefine previously used variables as long as the new binding happens within a child scope. This is useful so that someone in the top scope can't prevent a child module from ever using that variable name again. It might be worth revisiting this point in the future if we find it adds even greater code safety. Please report any bugs you have written that would have been prevented by this.

func (*Scope) Copy

func (obj *Scope) Copy() *Scope

Copy makes a copy of the Scope struct. This ensures that if the internal map is changed, it doesn't affect other copies of the Scope. It does *not* copy or change the Expr pointers contained within, since these are references, and we need those to be consistently pointing to the same things after copying.

func (*Scope) Empty

func (obj *Scope) Empty() *Scope

Empty returns the zero, empty value for the scope, with all the internal lists initialized appropriately.

type Stmt

type Stmt interface {
	Interpolate() (Stmt, error)  // return expanded form of AST as a new AST
	SetScope(*Scope) error       // set the scope here and propagate it downwards
	Unify() ([]Invariant, error) // TODO: is this named correctly?
	Graph() (*pgraph.Graph, error)
	Output() (*Output, error)
}

Stmt represents a statement node in the language. A stmt could be a resource, a `bind` statement, or even an `if` statement. (Different from an `if` expression.)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL