Class: Heist::Runtime::Binding

Inherits:
Object
  • Object
show all
Includes:
Expression
Defined in:
lib/heist/runtime/binding.rb

Overview

A Binding is a simple data object that couples an Expression to a Scope so the expression can be evaluated at some later time. Evaluation is typically memoized, though this is not always the case. Bindings are analogous to the notion of ‘promises’ in Scheme, though in Heist promises are implemented (as suggested in R5RS) using a (delay) macro that produces memoized closures. Bindings are used to implement lazy evaluation, and to maintain lexical scope in hygienic macro expansions by tying variables in the expansion to the lexical scope of the macro.

The Binding class mixes in the Expression module purely as a flag to indicate to the evaluator that it can be evaluated.

Instance Attribute Summary collapse

Attributes included from Expression

#parent

Instance Method Summary collapse

Methods included from Expression

#replace

Constructor Details

#initialize(expression, scope, memoized = true) ⇒ Binding

To initialize a Binding supply an Expression and a Scope in which to evaluate it. An optional third argument states whether the evaluation should be memoized.



25
26
27
28
29
# File 'lib/heist/runtime/binding.rb', line 25

def initialize(expression, scope, memoized = true)
  @expression = expression
  @scope      = scope
  @memoized   = !!memoized
end

Instance Attribute Details

#expressionObject (readonly)

Returns the value of attribute expression.



20
21
22
# File 'lib/heist/runtime/binding.rb', line 20

def expression
  @expression
end

#scopeObject (readonly)

Returns the value of attribute scope.



20
21
22
# File 'lib/heist/runtime/binding.rb', line 20

def scope
  @scope
end

Instance Method Details

#==(identifier) ⇒ Object

We provide an equality method so that a bound Identifier produced by expanding a macro can be matched against literal identifiers in another macro pattern.



48
49
50
# File 'lib/heist/runtime/binding.rb', line 48

def ==(identifier)
  @expression == identifier
end

#eval(scope) ⇒ Object

This method is provided as a convenience so that a Binding may be treated like any other expression during evaluation. All it does is return the result of calling force!.



41
42
43
# File 'lib/heist/runtime/binding.rb', line 41

def eval(scope)
  force!
end

#force!Object

Evaluates the Binding and returns the result. The Expression is only ever evaluated once if the Binding has been memoized.



33
34
35
36
# File 'lib/heist/runtime/binding.rb', line 33

def force!
  return @value if defined?(@value) and @memoized
  @value = Heist.evaluate(@expression, @scope)
end

#innermost_binding(identifier) ⇒ Object



52
53
54
# File 'lib/heist/runtime/binding.rb', line 52

def innermost_binding(identifier)
  @scope
end

#to_rubyObject

Returns a Rubyish representation of the binding’s expression.



57
58
59
# File 'lib/heist/runtime/binding.rb', line 57

def to_ruby
  @expression.respond_to?(:to_ruby) ? @expression.to_ruby : @expression
end

#to_sObject Also known as: inspect

Returns a string representation of the binding’s Expression.



62
63
64
# File 'lib/heist/runtime/binding.rb', line 62

def to_s
  @expression.to_s
end