diff --git a/.gitignore b/.gitignore
index f992c97bea706f79570d7d27526f3e34f73f39ef..ef9be3c4785d2f9b4d1e4362889263bd1d54d792 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
 .bundle/
 *.swp
-
-
-
+*.gem
+lib/DhallishGrammar.rb
diff --git a/Dhallish.gemspec b/Dhallish.gemspec
index ae4bd72233190f39f10ea5e7ccb595c3f35dfb86..5d1a1d561afb6ac4aa184a4b4662d15bbf052076 100644
--- a/Dhallish.gemspec
+++ b/Dhallish.gemspec
@@ -5,9 +5,9 @@ Gem::Specification.new do |s|
 	s.summary	= "A Ruby Implementation of a Dhall-like Language"
 	s.description	= s.summary
 	s.authors	= ["Lou Knauer <lou.knauer@fau.de>", "Philipp Panzer <philipp.panzer@fau.de>"]
-	s.files		= ["./bin", "./lib"]
+	s.files		= Dir["./bin/*"] + Dir["./lib/*"]
 	s.executables	= ["dhallish"]
 	s.homepage	= "https://gitlab.cs.fau.de/basst/ruby-dhallish"
-	s.required_ruby_version = '>= 2.5'
+	s.required_ruby_version = '>= 2.4'
 	s.add_runtime_dependency 'treetop', '~> 1.6.10'
 end
diff --git a/benchmark.dhall b/benchmark.dhall
new file mode 100644
index 0000000000000000000000000000000000000000..b856f459cbb38606e1ea6eba69fd90e6ab95de62
--- /dev/null
+++ b/benchmark.dhall
@@ -0,0 +1,11 @@
+let len = 10000
+let list =
+	Natural/fold len (List Natural)
+	(\(list: List Natural) ->
+		list # [Optional/fold Natural
+			(List/last Natural list) Natural (\(x: Natural) -> x + 1) 1])
+	([]: List Natural)
+let sum = \(list: List Natural) ->
+	List/fold Natural list Natural (\(x: Natural) -> \(y: Natural) -> x + y) 0
+in
+	sum list
diff --git a/bin/dhallish b/bin/dhallish
index 8f0fc718653ffca4f92c638f318aa0fd0d92d5ec..ec2f54dacb64d7dc9d66a287970400c13f9a5fc5 100755
--- a/bin/dhallish
+++ b/bin/dhallish
@@ -1,12 +1,17 @@
 #!/usr/bin/env ruby
 
-this_file = File.readlink(__FILE__)
+time1 = Time.now
+
+this_file = File.realpath(__FILE__)
 require File.expand_path("../lib/dhallish.rb", File.dirname(this_file))
 require 'json'
 
+time2 = Time.now
+
 pretty_json = false
 show_type = false
 read_from_file = nil
+measure_time = false
 
 ARGV.each { |arg|
 	case arg
@@ -14,6 +19,8 @@ ARGV.each { |arg|
 		pretty_json = true
 	when "--type"
 		show_type = true
+	when "--time"
+		measure_time = true
 	else
 		if File.file?(arg)
 			read_from_file = arg
@@ -26,6 +33,8 @@ ARGV.each { |arg|
 
 dhall = Dhallish::Dhallish.new
 
+time3 = Time.now
+
 if read_from_file.nil?
 	input = $stdin.read
 else
@@ -34,6 +43,8 @@ else
 	file.close
 end
 
+time4 = Time.now
+
 begin
 	res, type = dhall.evaluate(input)
 rescue DhallError => err
@@ -49,3 +60,11 @@ else
 		puts Dhallish::to_json res
 	end
 end
+
+time5 = 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}"
+end
diff --git a/lib/dhallish.rb b/lib/dhallish.rb
index 5af922ba8f85e87b887a4fd61f21f1b25735a7ac..5c9025b69ea8cba5b957a11636a91db9723d64fb 100644
--- a/lib/dhallish.rb
+++ b/lib/dhallish.rb
@@ -4,7 +4,14 @@ require_relative 'utils.rb'
 require_relative 'types.rb'
 require_relative 'stdlib.rb'
 
-Treetop.load File.join(File.dirname(__FILE__), 'DhallishGrammar.treetop')
+DIR = File.dirname(__FILE__)
+if File.exists?(DIR + '/DhallishGrammar.rb') and File.mtime(DIR + '/DhallishGrammar.rb') >= File.mtime(DIR + '/DhallishGrammar.treetop')
+	require_relative 'DhallishGrammar.rb'
+elsif File.writable?(DIR) and does_cmd_exist?('tt') and system("tt '#{DIR + '/DhallishGrammar.treetop'}'")
+	require_relative 'DhallishGrammar.rb'
+else
+	Treetop.load File.join(DIR, 'DhallishGrammar.treetop')
+end
 
 module Dhallish
 
@@ -58,14 +65,14 @@ module Dhallish
 			val
 		end
 
-		def evaluate_in_ctx_from_file(file, dhallctx)
+		def evaluate_in_ctx_from_file(file, dhallctx, expected_type=nil)
 			file = File.open(file)
-			res = evaluate_in_ctx(file.read, dhallctx)
+			res = evaluate_in_ctx(file.read, dhallctx, expected_type)
 			file.close
 			res
 		end
 
-		def evaluate_in_ctx(dhallcode, dhallctx)
+		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
@@ -73,6 +80,9 @@ module Dhallish
 			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
 		end
 	end
diff --git a/lib/stdlib.rb b/lib/stdlib.rb
index 351c6b4faac851d0fb3069798c09fd366ddbaebf..3371d0fd8da8c95a21d31f60164844d61c2ac38b 100644
--- a/lib/stdlib.rb
+++ b/lib/stdlib.rb
@@ -1,8 +1,6 @@
 require_relative './types.rb'
 require_relative './utils.rb'
 
-require "pry"
-
 module Dhallish
 
 	def make_fn_type(*args, rettype)
diff --git a/lib/types.rb b/lib/types.rb
index 2b2a86a371d16f78a33124cde9874dd40ca3428c..d99d256cf4c98ed61521de8bf357065426384a0f 100644
--- a/lib/types.rb
+++ b/lib/types.rb
@@ -22,7 +22,13 @@ module Dhallish
 					true
 				end
 			end
-			def to_s() "Type(#{@metadata.to_s})" end
+			def to_s()
+				if @metadata.nil? or @metadata.is_a? Unresolved
+					"Type"
+				else
+					"Type(#{@metadata.to_s})"
+				end
+			end
 		end
 		class Optional
 			# Type of Optional
@@ -103,11 +109,11 @@ module Dhallish
 
 			def to_s()
 				if !@restype.nil? and !@unres.nil?
-					"∀(#{@unres}: #{@argtype.to_s} -> #{@restype.to_s})"
+					"∀(#{@unres}: #{@argtype.to_s}) -> #{@restype.to_s}"
 				elsif !@restype.nil?
-					"∀(#{@argtype.to_s} -> #{@restype.to_s})"
+					"∀(#{@argtype.to_s}) -> #{@restype.to_s}"
 				else
-					"∀(#{@argtype.to_s} -> ?)"
+					"∀(#{@argtype.to_s}) -> ?"
 				end
 			end
 		end
@@ -117,7 +123,7 @@ module Dhallish
 				@name = name.to_sym
 			end
 			def ==(otype) otype.is_a? Unresolved and otype.name == @name end
-			def to_s() "Unresolved(#{@name})" end
+			def to_s() "#{@name}" end
 		end
 		class Union
 			# types: label -> Type
@@ -126,7 +132,7 @@ module Dhallish
 				@types = types
 			end
 
-			def ==(otype) 
+			def ==(otype)
 				if !otype.is_a? Union
 					return false
 				end
@@ -136,7 +142,7 @@ module Dhallish
 				}
 			end
 
-			def to_s() 
+			def to_s()
 				"< #{@types.keys.map { |key|
 					"#{key}: #{@types[key].to_s}"
 				}.join(" | ")} >"
@@ -301,7 +307,7 @@ module Dhallish
 			if Types::is_a_type? dhallval
 				"\"#{dhallval.to_s}\""
 			else
-				"\"Dhallish-Internal: #{escape_str(dhallval.inspect)}\""
+				"\"<#{escape_str(dhallval.class.to_s)}##{dhallval.hash.abs.to_s(16)}>\""
 			end
 		end
 	end
diff --git a/lib/utils.rb b/lib/utils.rb
index bb05b08144b354d54485e0a64e421344bb4bfaf4..4e806d7d7ab2bae610f8562d323db7933663ed5d 100644
--- a/lib/utils.rb
+++ b/lib/utils.rb
@@ -22,3 +22,13 @@ end
 def escape_str(str)
 	str.gsub("\n", "\\n").gsub("\"", "\\\"")
 end
+
+def does_cmd_exist?(cmd)
+	ENV['PATH'].split(File::PATH_SEPARATOR).each { |path|
+		exe = File.join(path, cmd)
+		if File.executable?(exe) && !File.directory?(exe)
+			return true
+		end
+	}
+	return false
+end