diff --git a/bin/dhallish b/bin/dhallish
index ec2f54dacb64d7dc9d66a287970400c13f9a5fc5..79b947eac1f7fd9d086d2ad223d35e11f3a785a5 100755
--- a/bin/dhallish
+++ b/bin/dhallish
@@ -31,10 +31,6 @@ ARGV.each { |arg|
 	end
 }
 
-dhall = Dhallish::Dhallish.new
-
-time3 = Time.now
-
 if read_from_file.nil?
 	input = $stdin.read
 else
@@ -43,10 +39,10 @@ else
 	file.close
 end
 
-time4 = Time.now
+time3 = Time.now
 
 begin
-	res, type = dhall.evaluate(input)
+	res, type = Dhallish::evaluate(input)
 rescue DhallError => err
 	STDERR.puts err
 	exit! 1
@@ -61,10 +57,9 @@ else
 	end
 end
 
-time5 = Time.now
+time4 = Time.now
 if measure_time
 	puts ""
 	puts "time loading dhallish.rb:        #{time2 - time1}"
-	puts "time creating Dhallish-Instance: #{time3 - time2}"
-	puts "time for typecheck+evaluate:     #{time5 - time4}"
+	puts "time for typecheck+evaluate:     #{time4 - time3}"
 end
diff --git a/lib/DhallishGrammar.treetop b/lib/DhallishGrammar.treetop
index e7fb2c3ca40c8a18e8aaeb51eb17b914a285cb73..15bd77efdd16a4c11331d40764afec793db3dc58 100644
--- a/lib/DhallishGrammar.treetop
+++ b/lib/DhallishGrammar.treetop
@@ -5,13 +5,13 @@ require File.join(File.dirname(__FILE__), 'utils.rb')
 grammar DhallishGrammar
 
 	rule root
-		space? exp:expression space? { def to_node(ctx)  exp.to_node(ctx) end }
+		space? exp:expression space? { def to_node()  exp.to_node() end }
 	end
 
 	rule expression
-		exp:if_then_else_expression 		{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:let_expression 			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:import_alternative_expression 	{ def to_node(ctx) exp.to_node(ctx) end }
+		exp:if_then_else_expression 		{ def to_node() exp.to_node() end } /
+		exp:let_expression 			{ def to_node() exp.to_node() end } /
+		exp:import_alternative_expression 	{ def to_node() exp.to_node() end }
 	end
 
 	rule eol
@@ -41,7 +41,7 @@ grammar DhallishGrammar
 
 	## Number Literals
 	rule integer_literal
-		("+" / "-") [0-9]+ { def to_node(ctx) Dhallish::Ast::Literal_Node.new(text_value.to_i, Dhallish::Types::Integer)  end }
+		("+" / "-") [0-9]+ { def to_node() Dhallish::Ast::Literal_Node.new(text_value.to_i, Dhallish::Types::Integer)  end }
 	end
 
 	rule exponent
@@ -50,27 +50,27 @@ grammar DhallishGrammar
 	end
 
 	rule double_literal
-		("+" / "-")? [0-9]+ (("." [0-9]+ exponent?) / exponent) { def to_node(ctx) Dhallish::Ast::Literal_Node.new(text_value.to_f, Dhallish::Types::Double) end }
+		("+" / "-")? [0-9]+ (("." [0-9]+ exponent?) / exponent) { def to_node() Dhallish::Ast::Literal_Node.new(text_value.to_f, Dhallish::Types::Double) end }
 
 	end
 
 	rule natural_literal
-		[0-9]+ { def to_node(ctx) Dhallish::Ast::Literal_Node.new(text_value.to_i, Dhallish::Types::Natural) end }
+		[0-9]+ { def to_node() Dhallish::Ast::Literal_Node.new(text_value.to_i, Dhallish::Types::Natural) end }
 	end
 
 	## Bools
 	rule bool_literal
-		"True" { def to_node(ctx) Dhallish::Ast::Literal_Node.new(true, Dhallish::Types::Bool) end }
+		"True" { def to_node() Dhallish::Ast::Literal_Node.new(true, Dhallish::Types::Bool) end }
 		/
-		"False" { def to_node(ctx) Dhallish::Ast::Literal_Node.new(false, Dhallish::Types::Bool) end }
+		"False" { def to_node() Dhallish::Ast::Literal_Node.new(false, Dhallish::Types::Bool) end }
 	end
 
 	## Lists
 	rule empty_list_literal
 		"[" space? "]" space? ":" space? "List" space type:expression
 		{
-			def to_node(ctx)
-				Dhallish::Ast::ListNode.new [], type.to_node(ctx)
+			def to_node()
+				Dhallish::Ast::ListNode.new [], type.to_node()
 			end
 		}
 	end
@@ -78,14 +78,14 @@ grammar DhallishGrammar
 	rule non_empty_list_literal
 		"[" space? fst:expression tail:(space? "," space? exp:expression)* space? "]" annot:(space? ":" space? "List" space type:expression)?
 		{
-			def to_node(ctx)
+			def to_node()
 				list = []
-				list.append fst.to_node(ctx)
+				list.append fst.to_node()
 				tail.elements.each { |node|
-					list.append node.exp.to_node(ctx)
+					list.append node.exp.to_node()
 				}
 				if annot.respond_to? :type
-					Dhallish::Ast::ListNode.new list, annot.type.to_node(ctx)
+					Dhallish::Ast::ListNode.new list, annot.type.to_node()
 				else
 					Dhallish::Ast::ListNode.new list, nil
 				end
@@ -94,21 +94,21 @@ grammar DhallishGrammar
 	end
 
 	rule list_literal
-		exp:empty_list_literal		{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:non_empty_list_literal 	{ def to_node(ctx) exp.to_node(ctx) end }
+		exp:empty_list_literal		{ def to_node() exp.to_node() end } /
+		exp:non_empty_list_literal 	{ def to_node() exp.to_node() end }
 	end
 
 	## Records
 	rule record_type_literal
-		"{" space? "}" { def to_node(ctx) Dhallish::Ast::RecordTypeNode.new({}) end } /
+		"{" space? "}" { def to_node() Dhallish::Ast::RecordTypeNode.new({}) end } /
 		"{" space? fstkey:label space? ":" space? fstexp:expression tail:(space? "," space? key:label space? ":" space? exp:expression)* space? "}"
 		{
-			def to_node(ctx)
-				data = { fstkey.text_value => fstexp.to_node(ctx) }
+			def to_node()
+				data = { fstkey.text_value => fstexp.to_node() }
 				tail.elements.each { |node|
 					key = node.key.text_value
 					assert("no key should apeare multiple times in a record: `#{key}`") { !data.key?(key) }
-					data[key] = node.exp.to_node(ctx)
+					data[key] = node.exp.to_node()
 				}
 				Dhallish::Ast::RecordTypeNode.new data
 			end
@@ -116,15 +116,15 @@ grammar DhallishGrammar
 	end
 
 	rule record_literal
-		"{" space? "=" space? "}" { def to_node(ctx) Dhallish::Ast::RecordNode.new({}) end } /
+		"{" space? "=" space? "}" { def to_node() Dhallish::Ast::RecordNode.new({}) end } /
 		"{" space? fstkey:label space? "=" space? fstexp:expression tail:(space? "," space? key:label space? "=" space? exp:expression)* space? "}"
 		{
-			def to_node(ctx)
-				data = { fstkey.text_value => fstexp.to_node(ctx) }
+			def to_node()
+				data = { fstkey.text_value => fstexp.to_node() }
 				tail.elements.each { |node|
 					key = node.key.text_value
 					assert("no key should apeare multiple times in a record: `#{key}`") { !data.key?(key) }
-					data[key] = node.exp.to_node(ctx)
+					data[key] = node.exp.to_node()
 				}
 				Dhallish::Ast::RecordNode.new data
 			end
@@ -135,11 +135,11 @@ grammar DhallishGrammar
 	rule text_literal
 		'"' tail:(exp:('${' space? innerexp:expression space? '}') / esc:('\"') / any:(!'"' .))* '"'
 		{
-			def to_node(ctx)
+			def to_node()
 				parts = []
 				tail.elements.each { |node|
 					if node.respond_to?(:exp)
-						parts.push node.exp.innerexp.to_node(ctx)
+						parts.push node.exp.innerexp.to_node()
 					elsif node.respond_to?(:esc)
 						parts.push "\""
 					else
@@ -153,15 +153,15 @@ grammar DhallishGrammar
 
 	## Optionals
 	rule optional_literal
-		prefix:("Some" / "None") space exp:or_expression { def to_node(ctx) Dhallish::Ast::OptionalNode.new prefix.text_value, exp.to_node(ctx) end }
+		prefix:("Some" / "None") space exp:or_expression { def to_node() Dhallish::Ast::OptionalNode.new prefix.text_value, exp.to_node() end }
 	end
 
 	## Type Literals
 	rule forall_literal
 		("forall" / "∀") space? "(" space? lb:label space? ":" space? type:expression space? ")" space? ("->" / "→") space? res_type:expression
 		{
-			def to_node(ctx)
-				Dhallish::Ast::FunctionType.new(type.to_node(ctx), res_type.to_node(ctx), lb.text_value)
+			def to_node()
+				Dhallish::Ast::FunctionType.new(type.to_node(), res_type.to_node(), lb.text_value)
 			end
 		}
 	end
@@ -170,15 +170,15 @@ grammar DhallishGrammar
 	rule union_literal
 		"<" space? start:(lb:label space? ":" space? type:record_merge_expression space? "|" space?)* lb:label space? "=" space? expr:record_merge_expression tail:(space? "|" space? lb:label space? ":" space? type:record_merge_expression)* space? ">"
 		{
-			def to_node(ctx)
+			def to_node()
 				typed_labels = {}
 				start.elements.each { |node|
-					typed_labels[node.lb.text_value] = node.type.to_node(ctx)
+					typed_labels[node.lb.text_value] = node.type.to_node()
 				}
 				tail.elements.each { |node|
-					typed_labels[node.lb.text_value] = node.type.to_node(ctx)
+					typed_labels[node.lb.text_value] = node.type.to_node()
 				}
-				Dhallish::Ast::UnionLiteral.new(typed_labels, lb.text_value, expr.to_node(ctx))
+				Dhallish::Ast::UnionLiteral.new(typed_labels, lb.text_value, expr.to_node())
 			end
 		}
 	end
@@ -188,13 +188,13 @@ grammar DhallishGrammar
 	end
 
 	rule union_type_literal
-		empty_union_type_literal { def to_node(ctx) Dhallish::Ast::UnionType.new({})  end } /
+		empty_union_type_literal { def to_node() Dhallish::Ast::UnionType.new({})  end } /
 		"<" space? lb:label space? ":" space? type:record_merge_expression tail:(space? "|" space? lb:label space? ":" space? type:record_merge_expression)* space? ">"
 		{
-			def to_node(ctx)
-				type_map = {lb.text_value => type.to_node(ctx)}
+			def to_node()
+				type_map = {lb.text_value => type.to_node()}
 				tail.elements.each { |node|
-					type_map[node.lb.text_value] = node.type.to_node(ctx)
+					type_map[node.lb.text_value] = node.type.to_node()
 				}
 				Dhallish::Ast::UnionType.new(type_map)
 			end
@@ -209,9 +209,9 @@ grammar DhallishGrammar
 	rule import_alternative_expression
 		exp:annotated_expression tail:(space? "?" space? alternative:annotated_expression)*
 		{
-			def to_node(ctx)
-			tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-				Dhallish::Ast::Import_Alternative.new tree, node.alternative.to_node(ctx)
+			def to_node()
+			tail.elements.reduce(exp.to_node()) { |tree, node|
+				Dhallish::Ast::Import_Alternative.new tree, node.alternative.to_node()
 			}
 			end
 		}
@@ -220,9 +220,9 @@ grammar DhallishGrammar
 	rule annotated_expression
 		exp:function_type_expression tail:(space? ":" space? type_expr:function_type_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::TypeAnnotationNode.new tree, node.type_expr.to_node(ctx)
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					Dhallish::Ast::TypeAnnotationNode.new tree, node.type_expr.to_node()
 				}
 			end
 		}
@@ -231,19 +231,19 @@ grammar DhallishGrammar
 	rule function_type_expression
 		arg_type:or_expression tail:(space? ("->" / "→") space? res_type:or_expression)*
 		{
-			def to_node(ctx)
+			def to_node()
 				if tail.elements.size == 0
-					arg_type.to_node(ctx)
+					arg_type.to_node()
 				else
 					tree = nil
 					tail.elements.reverse.each { |node|
 						if tree.nil?
-							tree = node.res_type.to_node(ctx)
+							tree = node.res_type.to_node()
 						else
-							tree = Dhallish::Ast::FunctionType.new node.res_type.to_node(ctx), tree
+							tree = Dhallish::Ast::FunctionType.new node.res_type.to_node(), tree
 						end
 					}
-					Dhallish::Ast::FunctionType.new arg_type.to_node(ctx), tree
+					Dhallish::Ast::FunctionType.new arg_type.to_node(), tree
 				end
 			end
 		}
@@ -252,9 +252,9 @@ grammar DhallishGrammar
 	rule or_expression
 		exp:and_expression tail:(space? "||" space? exp:and_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::BinaryArithOpNode.new([Dhallish::Types::Bool], tree, node.exp.to_node(ctx), "||") { |x, y| x || y }
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					Dhallish::Ast::BinaryArithOpNode.new([Dhallish::Types::Bool], tree, node.exp.to_node(), "||") { |x, y| x || y }
 				}
 			end
 		}
@@ -263,9 +263,9 @@ grammar DhallishGrammar
 	rule and_expression
 		exp:comparison_expression tail:(space? "&&" space? exp:comparison_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::BinaryArithOpNode.new([Dhallish::Types::Bool], tree, node.exp.to_node(ctx), "&&") { |x, y| x && y }
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					Dhallish::Ast::BinaryArithOpNode.new([Dhallish::Types::Bool], tree, node.exp.to_node(), "&&") { |x, y| x && y }
 				}
 			end
 		}
@@ -274,9 +274,9 @@ grammar DhallishGrammar
 	rule comparison_expression
 		exp:add_sub_expression tail:(space? op:("==" / "!=" / "<=" / "<" / ">=" / ">")  space? exp:add_sub_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::ComparisonOpNode.new(tree, node.exp.to_node(ctx), node.op.text_value) { |lhs_val, rhs_val| lhs_val.send(node.op.text_value, rhs_val )}
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					Dhallish::Ast::ComparisonOpNode.new(tree, node.exp.to_node(), node.op.text_value) { |lhs_val, rhs_val| lhs_val.send(node.op.text_value, rhs_val )}
 				}
 			end
 		}
@@ -285,9 +285,9 @@ grammar DhallishGrammar
 	rule add_sub_expression
 		exp:mult_div_expression tail:(space? op:("+"/"-") space? exp:mult_div_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					exp = node.exp.to_node(ctx)
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					exp = node.exp.to_node()
 					if node.op.text_value == "+"
 						Dhallish::Ast::BinaryArithOpNode.new(Dhallish::Types::Numbers, tree, exp, "+") { |x, y| x + y }
 					else
@@ -301,9 +301,9 @@ grammar DhallishGrammar
 	rule mult_div_expression
 		exp:list_concat_expression tail:(space? op:("*"/"/") space? exp:list_concat_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					exp = node.exp.to_node(ctx)
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					exp = node.exp.to_node()
 					if node.op.text_value == "*"
 						Dhallish::Ast::BinaryArithOpNode.new(Dhallish::Types::Numbers, tree, exp, "*") { |x, y| x * y }
 					else
@@ -318,9 +318,9 @@ grammar DhallishGrammar
 	rule list_concat_expression
 		exp:text_append_expression tail:(space? "#" space? exp:text_append_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::ListConcatNode.new(tree, node.exp.to_node(ctx))
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					Dhallish::Ast::ListConcatNode.new(tree, node.exp.to_node())
 				}
 			end
 		}
@@ -329,9 +329,9 @@ grammar DhallishGrammar
 	rule text_append_expression
 		exp:record_merge_expression tail:(space? "++" space? exp:record_merge_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::BinaryArithOpNode.new([Dhallish::Types::Text], tree, node.exp.to_node(ctx), "+") { |x, y| x + y }
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
+					Dhallish::Ast::BinaryArithOpNode.new([Dhallish::Types::Text], tree, node.exp.to_node(), "+") { |x, y| x + y }
 				}
 			end
 		}
@@ -340,14 +340,14 @@ grammar DhallishGrammar
 	rule record_merge_expression
 		exp:application_expression tail:(space? op:("//\\\\" / "⩓" / "/\\" / "∧" / "//" / "⫽") space? exp:application_expression)*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(exp.to_node(ctx)) { |tree, node|
+			def to_node()
+				tail.elements.reduce(exp.to_node()) { |tree, node|
 					if node.op.text_value == "//\\\\" or node.op.text_value == "⩓"
-						Dhallish::Ast::RecordTypeRecursiveMergeNode.new tree, node.exp.to_node(ctx)
+						Dhallish::Ast::RecordTypeRecursiveMergeNode.new tree, node.exp.to_node()
 					elsif node.op.text_value == "/\\" or node.op.text_value == "∧"
-						Dhallish::Ast::RecordRecursiveMergeNode.new tree, node.exp.to_node(ctx)
+						Dhallish::Ast::RecordRecursiveMergeNode.new tree, node.exp.to_node()
 					else
-						Dhallish::Ast::RecordNonRecursiveMergeNode.new tree, node.exp.to_node(ctx)
+						Dhallish::Ast::RecordNonRecursiveMergeNode.new tree, node.exp.to_node()
 					end
 				}
 			end
@@ -357,9 +357,9 @@ grammar DhallishGrammar
 	rule application_expression
 		fn:proj_sel_expression tail:(space? exp:(!reserved arg:proj_sel_expression))*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(fn.to_node(ctx)) { |tree, node|
-					Dhallish::Ast::FunctionCallNode.new(tree, node.exp.arg.to_node(ctx))
+			def to_node()
+				tail.elements.reduce(fn.to_node()) { |tree, node|
+					Dhallish::Ast::FunctionCallNode.new(tree, node.exp.arg.to_node())
 				}
 			end
 		}
@@ -381,8 +381,8 @@ grammar DhallishGrammar
 	rule proj_sel_expression
 		pe:primitive_expression tail:(space? "." space? sel:(a:label / b:key_list))*
 		{
-			def to_node(ctx)
-				tail.elements.reduce(pe.to_node(ctx)) { |tree, node|
+			def to_node()
+				tail.elements.reduce(pe.to_node()) { |tree, node|
 					if node.sel.respond_to? :a
 						Dhallish::Ast::RecordUnionSelector.new tree, node.sel.a.text_value
 					else
@@ -394,23 +394,23 @@ grammar DhallishGrammar
 	end
 
 	rule primitive_expression
-		exp:bool_literal 			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:double_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:natural_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:integer_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:text_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:list_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:function_definition			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:optional_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:forall_literal 			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:import_expression 			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:label 				{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:record_literal                      { def to_node(ctx) exp.to_node(ctx) end } /
-		exp:record_type_literal                 { def to_node(ctx) exp.to_node(ctx) end } /
-		exp:union_literal			{ def to_node(ctx) exp.to_node(ctx) end } /
-		exp:union_type_literal 	                { def to_node(ctx) exp.to_node(ctx) end } /
-		"(" space? exp:expression space? ")"	{ def to_node(ctx) exp.to_node(ctx) end } /
-		"???" { def to_node(ctx) Dhallish::Ast::GetContext.new end }
+		exp:bool_literal 			{ def to_node() exp.to_node() end } /
+		exp:double_literal			{ def to_node() exp.to_node() end } /
+		exp:natural_literal			{ def to_node() exp.to_node() end } /
+		exp:integer_literal			{ def to_node() exp.to_node() end } /
+		exp:text_literal			{ def to_node() exp.to_node() end } /
+		exp:list_literal			{ def to_node() exp.to_node() end } /
+		exp:function_definition			{ def to_node() exp.to_node() end } /
+		exp:optional_literal			{ def to_node() exp.to_node() end } /
+		exp:forall_literal 			{ def to_node() exp.to_node() end } /
+		exp:import_expression 			{ def to_node() exp.to_node() end } /
+		exp:label 				{ def to_node() exp.to_node() end } /
+		exp:record_literal                      { def to_node() exp.to_node() end } /
+		exp:record_type_literal                 { def to_node() exp.to_node() end } /
+		exp:union_literal			{ def to_node() exp.to_node() end } /
+		exp:union_type_literal 	                { def to_node() exp.to_node() end } /
+		"(" space? exp:expression space? ")"	{ def to_node() exp.to_node() end } /
+		"???" { def to_node() Dhallish::Ast::GetContext.new end }
 	end
 
 	## End of operator expressions
@@ -420,30 +420,30 @@ grammar DhallishGrammar
 		"then" space exp_true:expression space
 		"else" space exp_false:expression
 		{
-			def to_node(ctx)
-				Dhallish::Ast::IfThenElseNode.new cond.to_node(ctx), exp_true.to_node(ctx), exp_false.to_node(ctx)
+			def to_node()
+				Dhallish::Ast::IfThenElseNode.new cond.to_node(), exp_true.to_node(), exp_false.to_node()
 			end
 		}
 	end
 
 	rule label
-		("_" / [a-zA-Z]) ("_" / "-" / "/" / [a-zA-Z0-9])* { def to_node(ctx) Dhallish::Ast::VariableNode.new text_value end } /
-		"`" lb:(([a-zA-Z0-9] / "-" / "/" / "_" / ":" / "." / "$")+) "`" { def to_node(ctx) Dhallish::Ast::VariableNode.new lb.text_value end }
+		("_" / [a-zA-Z]) ("_" / "-" / "/" / [a-zA-Z0-9])* { def to_node() Dhallish::Ast::VariableNode.new text_value end } /
+		"`" lb:(([a-zA-Z0-9] / "-" / "/" / "_" / ":" / "." / "$")+) "`" { def to_node() Dhallish::Ast::VariableNode.new lb.text_value end }
 	end
 
 	rule let_expression
 		declarations:("let" space var:label space? annot:(":" space? exp:expression space?)? "=" space? val:expression space)+ "in" space in_expr:expression
 		{
-			def to_node(ctx)
+			def to_node()
 				vars = []
 				declarations.elements.each { |node|
 					typeannot = nil
 					if node.respond_to? :annot and node.annot.respond_to? :exp
-						typeannot = node.annot.exp.to_node(ctx)
+						typeannot = node.annot.exp.to_node()
 					end
-					vars.append [node.var.text_value, typeannot, node.val.to_node(ctx)]
+					vars.append [node.var.text_value, typeannot, node.val.to_node()]
 				}
-				Dhallish::Ast::LetInNode.new vars, in_expr.to_node(ctx)
+				Dhallish::Ast::LetInNode.new vars, in_expr.to_node()
 			end
 		}
 	end
@@ -451,8 +451,8 @@ grammar DhallishGrammar
 	rule function_definition
 		("\\" / "λ") space? "(" space? lb:label space? ":" space? type_exp:expression space? ")" space? ("->" / "→") space? exp:expression
 		{
-			def to_node(ctx)
-				Dhallish::Ast::FunctionDefinitionNode.new lb.text_value, type_exp.to_node(ctx), exp.to_node(ctx)
+			def to_node()
+				Dhallish::Ast::FunctionDefinitionNode.new lb.text_value, type_exp.to_node(), exp.to_node()
 			end
 		}
 	end
@@ -473,7 +473,7 @@ grammar DhallishGrammar
 	rule import_expression
 		prefix:("../" / "./" / "~/" / "env:" / "http:" / "https:") src:import_source as_type:(space "as" space import_type:"Text")?
 		{
-			def to_node(ctx)
+			def to_node()
 				import_as_text = (as_type.respond_to? :import_type and as_type.import_type.text_value == "Text")
 				Dhallish::Ast::Import.new prefix.text_value, src.text_value, import_as_text
 			end
diff --git a/lib/ast.rb b/lib/ast.rb
index 39817011a9e12568504b68fce7ce2cf41623fbfe..66a40061e919863a6c0019ea0c731e5568a287ac 100644
--- a/lib/ast.rb
+++ b/lib/ast.rb
@@ -433,11 +433,11 @@ module Dhallish
 
 			def compute_type(ctx)
 				rectype = @rec.compute_type ctx
-				assert("`.` can only be used on records and unions, the key `#{@key}` must exist") { 
+				assert("`.` can only be used on records and unions, the key `#{@key}` must exist") {
 					((rectype.is_a? Types::Record or rectype.is_a? Types::Union) and !rectype.types[@key].nil?) \
 					or (rectype.is_a? Types::Type and rectype.metadata.is_a? Types::Union)
 				}
-				if rectype.is_a? Types::Union	
+				if rectype.is_a? Types::Union
 					Types::Optional.new rectype.types[@key]
 				elsif rectype.is_a? Types::Record
 					rectype.types[@key]
@@ -630,7 +630,7 @@ module Dhallish
 				else
 					src = @src
 					if prefix == "./" or prefix == "../"
-						basedir = ctx["#DIR#"]
+						basedir = ctx["<#DIR#>"]
 						if basedir.is_a? String
 							src = File.join basedir , (@prefix + src)
 							new_path = File.dirname src
@@ -665,8 +665,7 @@ module Dhallish
 					Types::Text
 				else
 					# treat as dhallish expression
-					d = Dhallish.new new_path
-					@buf, type = d.evaluate text
+					@buf, type = Dhallish::evaluate(text, Dhallish::empty_context(new_path))
 					type
 				end
 			end
@@ -792,7 +791,7 @@ module Dhallish
 				Types::Record.new({})
 			end
 
-			def evaluate(ctx) { "#valctx#" => ctx, "#typectx#" => @typectx } end
+			def evaluate(ctx) { "<#TYPES#>" => @typectx, "<#VALS#>" => ctx } end
 		end
 
 	end
diff --git a/lib/dhallish.rb b/lib/dhallish.rb
index 5c9025b69ea8cba5b957a11636a91db9723d64fb..36638412e8fe461f87b88b5a7b4913c8e7f4d41f 100644
--- a/lib/dhallish.rb
+++ b/lib/dhallish.rb
@@ -15,76 +15,56 @@ end
 
 module Dhallish
 
-	class Dhallish
-		attr_accessor :context
-		attr_accessor :typectx
-		attr_accessor :basedir
+	@@parser = DhallishGrammarParser.new
 
-		def initialize(basedir=nil)
-			if basedir.nil?
-				basedir = Dir.pwd
-			end
-			@parser = DhallishGrammarParser.new
-			@context = Context.new # for values used in `astnode.evaluate`
-			@typectx = Context.new # for type-informations used in `compute_type`
-			@typectx["#DIR#"] = basedir # `#` is not allowed in dhallish-identifiers, so this is should be fine
-			::Dhallish::fill_context(@context, @typectx)
-		end
-
-		def evaluate_file(file, ctx = @context, typectx = @typectx)
-			file = File.open(file)
-			res = evaluate(file.read, ctx, typectx)
-			file.close
-			res
-		end
+	def empty_context(basedir=Dir.pwd)
+		ctx = { "<#TYPES#>" => Context.new, "<#VALS#>" => Context.new }
+		ctx["<#TYPES#>"]["<#DIR#>"] = basedir
+		fill_context(ctx["<#VALS#>"], ctx["<#TYPES#>"])
+		ctx
+	end
+	module_function :empty_context
 
-		def evaluate(dhallcode, ctx = @context, typectx = @typectx)
-			treetopast = @parser.parse dhallcode
-			if treetopast.nil?
-				raise DhallError, "#{@parser.failure_reason} (line/column: #{@parser.failure_line}:#{@parser.failure_column})"
-			end
+	def evaluate(dhallcode, ctx=nil, expected_type=nil)
+		if ctx.nil?; ctx = empty_context() end
 
-			ast = treetopast.to_node nil
-			type = ast.compute_type typectx
+		rawast = @@parser.parse dhallcode
+		ast = rawast.to_node
 
-			return [ast.evaluate(ctx), type]
+		if ast.nil?
+			raise DhallError, "#{@parser.failure_reason} (line/column: #{@parser.failure_line}:#{@parser.failure_column})"
 		end
 
-		def create_ctx_from_file(file)
-			file = File.open(file)
-			res = create_ctx(file.read)
-			file.close
-			res
-		end
+		type = ast.compute_type ctx["<#TYPES#>"]
+		res = ast.evaluate ctx["<#VALS#>"]
 
-		def create_ctx(dhallcode)
-			val, type = evaluate(dhallcode, @context, @typectx)
-			if !type.is_a? Types::Record or val["#valctx#"].nil? or val["#typectx#"].nil?
-				raise DhallError, "Dhallish: create_ctx did not return a context! use `???` as a return expression in dhallish for create_ctx"
+		if !expected_type.nil?
+			if type != expected_type
+				raise DhallError, "expression return type missmatch: expected `#{expected_type}`, got: `#{type}`"
+			else
+				res
 			end
-			val
+		else
+			[res, type]
 		end
+	end
+	module_function :evaluate
 
-		def evaluate_in_ctx_from_file(file, dhallctx, expected_type=nil)
-			file = File.open(file)
-			res = evaluate_in_ctx(file.read, dhallctx, expected_type)
-			file.close
-			res
-		end
-
-		def evaluate_in_ctx(dhallcode, dhallctx, expected_type=nil)
-			if !dhallctx.is_a? Hash or dhallctx["#valctx#"].nil? or dhallctx["#typectx#"].nil?
-				raise DhallError, "Dhallish: evaluate_in_ctx must be called with a context returned by create_ctx"
-			end
-			typectx = dhallctx["#typectx#"]
-			valctx = dhallctx["#valctx#"]
-
-			val, type = evaluate(dhallcode, valctx, typectx)
-			if expected_type != nil
-				assert("return type missmatch of `evaluate_in_ctx`") { type == expected_type }
-			end
-			val
+	def create_ctx(dhallcode, basedir=Dir.pwd)
+		empty_ctx = empty_context(basedir)
+		ctx, type = evaluate(dhallcode, empty_ctx)
+		if type != Types::Record.new({}) or ctx["<#TYPES#>"].nil? or ctx["<#VALS#>"].nil?
+			raise DhallError, "return type of dhallcode supplied to `create_ctx` did not return a context (but something of type `#{type}`). use `???`"
 		end
+		ctx
 	end
+	module_function :create_ctx
 
+	def create_ctx_from_file(dhallfile, basedir=nil)
+		if basedir.nil?; basedir = File.dirname(dhallfile) end
+		file = File.open(dhallfile)
+		res = create_ctx(file.read, basedir)
+		file.close
+		res
+	end
 end
diff --git a/lib/stdlib.rb b/lib/stdlib.rb
index 3371d0fd8da8c95a21d31f60164844d61c2ac38b..cf5b5a72ddb61f12816c303eb76028996df94e91 100644
--- a/lib/stdlib.rb
+++ b/lib/stdlib.rb
@@ -157,7 +157,7 @@ module Dhallish
 		globalctx["List/build"] = BuiltinFunction.new { |a|
 			BuiltinFunction.new { |f|
 				cons = BuiltinFunction.new { |x|
-					BuiltinFunction.new { |list| [x] + list }
+					BuiltinFunction.new { |list| list + [x] }
 				}
 				f.call(Types::List.new(a)).call(cons).call([])
 			}
diff --git a/lib/types.rb b/lib/types.rb
index bd636f1b64ca6174234361e19f45a62c4aaaf1aa..1e6bbee26f4eacf1214c09402f6369345a34d9c5 100644
--- a/lib/types.rb
+++ b/lib/types.rb
@@ -283,6 +283,10 @@ module Dhallish
 		module_function :is_a_type?
 
 		Numbers = [Natural, Integer, Double]
+		TextList = List.new(Text)
+		NaturalList = List.new(Natural)
+		IntegerList = List.new(Integer)
+		DoubleList = List.new(Double)
 	end
 
 	def to_json(dhallval)
diff --git a/tests/test.rb b/tests/test.rb
index 28df652c23f4cb8c223dc79464c4dea4929194ec..bbeb9dc7d215c74dba9131e11a4e69fe59924640 100755
--- a/tests/test.rb
+++ b/tests/test.rb
@@ -41,7 +41,7 @@ positive_tests = {
 negative_tests = {
 	"Undefined Variable": "let x = 1 in x + y",
 	"badly typed list": "[10, +10]",
-	"recursive function definition": "let f = \\(n : Natural) -> f n",
+	"recursive function definition": "let f = \\(n : Natural) -> f n in f 42",
 	"Literal type annotation mismatch": "+42 : Natural",
 	"Let..in type annotation mismatch": "let x : Natural = 10.0 in x",
 	"function call argtype mismatch": "let f = \\(x : Double) -> x * 10e10 in f 5",
@@ -54,8 +54,7 @@ positive_tests.each { |name, arr|
 	code, expected = arr
 
 	begin
-		dhallish = Dhallish::Dhallish.new
-		res = (dhallish.evaluate code)[0]
+		res, type = Dhallish::evaluate(code)
 		assert("Testing Dhallish: `#{code}`") { res == expected }
 	rescue
 		print_msg(name, false)
@@ -69,8 +68,7 @@ negative_tests.each { |name, arr|
 	code = arr
 
 	begin
-		dhallish = Dhallish::Dhallish.new
-		dhallish.evaluate code
+		Dhallish::evaluate(code)
 	rescue
 		print_msg(name, true)
 	else
@@ -89,8 +87,7 @@ dhallfiles.each { |file|
 		expected_file_name = file.sub '.dhall', "_expected.json"
 		expected = JSON.parse(`cat #{expected_file_name}`)
 
-		dhallish = Dhallish::Dhallish.new
-		val = (dhallish.evaluate `cat #{file}`)[0]
+		val, type = (Dhallish::evaluate `cat #{file}`)
 		result = JSON.parse(Dhallish::to_json val)
 		assert("Testing Dhall-Compability for `#{file}`") { expected == result }
 	rescue
@@ -108,8 +105,7 @@ dhallfiles.each { |file|
 		expected_file_name = file.sub '.dhallish', "_expected.json"
 		expected = JSON.parse(`cat #{expected_file_name}`)
 
-		dhallish = Dhallish::Dhallish.new
-		val = (dhallish.evaluate `cat #{file}`)[0]
+		val, type = (Dhallish::evaluate `cat #{file}`)
 		result = JSON.parse(Dhallish::to_json val)
 		assert("Testing Dhall-Compability for `#{file}`") { expected == result }
 	rescue
diff --git a/tests/test_dhallish_ctx.rb b/tests/test_dhallish_ctx.rb
index bff3cd5c35d51a33ca145d5749ca6866f43863b6..fdd0e127bcc6958169d9b560f7a57337322952fb 100644
--- a/tests/test_dhallish_ctx.rb
+++ b/tests/test_dhallish_ctx.rb
@@ -1,13 +1,11 @@
 require_relative '../lib/dhallish.rb'
 
-dhall = Dhallish::Dhallish.new
-
-ctx = dhall.create_ctx("
+ctx = Dhallish::create_ctx("
 let x = 41
 let f = \\(n: Natural) -> n + 1
 in ???
 ")
 
-res = dhall.evaluate_in_ctx("f x", ctx)
+res = Dhallish::evaluate("f x", ctx, Dhallish::Types::Natural)
 
 puts res