 skipWS = (inStream) ->
   while inStream.peek() in WHITESPACE then inStream.next()
 
-invisibleProperty = (obj, name, value) ->
-  Object.defineProperty obj, name,
-    value: value
-    configurable: false
-    enumerable: false
-    writable: false
-  obj
-
-lineInfo = (obj, line, column) ->
-  invisibleProperty obj, '__position', {line: line, column: column}
-
 # (type, value, line, column) -> (node {type, value, line, column)}
-makeObj = (value, type, line, column) ->
-  lineInfo (invisibleProperty value, '__type', type), line, column
+makeObj = (type, value, line, column) ->
+  list(type, value, line, column)
 
 # msg -> (IO -> Node => Error)
 handleError = (message) ->
-  (line, column) -> lineInfo (cons "error", message), line, column
+  (line, column) -> makeObj('error', message, line, column)
 
 # IO -> Node => Comment
 readComment = (inStream) ->

    [line1, column1] = inStream.position()
    obj = read inStream, true, null, true
    return obj if (car obj) == 'error'
    cons (makeObj (new String type), 'symbol', line1, column1), obj

# I really wanted to make anything more complex than a list (like an
# object or a vector) something handled by a read macro.  Maybe in a


readMacros =
  '"': readString
  '(': makeReadPair ')', 'list'
  ')': handleError "Closing paren encountered"
  '[': makeReadPair ']', 'vector'
  ']': handleError "Closing bracket encountered"
  '{': makeReadPair('}', 'record', (res) ->
    res.length % 2 == 0 and true or mkerr "record key without value")
  '}': handleError "Closing curly without corresponding opening."
  "`": prefixReader 'back-quote'
  "'": prefixReader 'quote'
