public SubLObject eval(final SubLEnvironment env) {
   Values.resetMultipleValues();
   SubLObject operatorSymbol = first();
   if (operatorSymbol.isSymbol()) {
     SubLOperator operator = operatorSymbol.toSymbol().getFunction();
     if (operator.isFunction()) {
       return operator.getFunc().evalViaApply(this.toCons(), env);
     }
     if (operator.isSpecial()) {
       final SubLFunction func = operator.toSpecialOperator().getEvaluationFunction();
       final BinaryFunction binFunc = func.getBinaryFunction();
       if (binFunc != null) {
         return binFunc.processItem(toCons(), env);
       }
       return func.apply(this.toCons(), env);
     }
     if (operator.isMacroOperator()) {
       return operator
           .toMacro()
           .getMacroExpander()
           .apply(this.asConsList().toCons(), env)
           .eval(env); // @hack asConsList() call
     }
     Errors.error(operatorSymbol + " does not have a function value.");
   } else if (SubLInterpretedFunction.isPossiblyLambdaExpression(operatorSymbol, true)) {
     final SubLInterpretedFunction lambda =
         SubLOperatorFactory.makeInterpretedFunction(operatorSymbol.toCons(), env);
     return lambda.evalViaApply(this.toCons(), env);
   }
   throw new InvalidSubLExpressionException(operatorSymbol + " is not an operator.");
 }
 private final SubLList mapResult(
     BinaryFunction function, SubLList list2, boolean returnConsedResults) {
   SubLList result = SubLNil.NIL;
   for (SubLObject cur = this, cur2 = list2;
       (cur != SubLNil.NIL) && (cur2 != SubLNil.NIL);
       cur = cur.rest(), cur2 = cur2.rest()) {
     final SubLObject curResult = function.processItem(cur.first(), cur2.first());
     if (returnConsedResults) {
       result = SubLObjectFactory.makeCons(curResult, result);
     }
   }
   if (returnConsedResults) {
     return result.asConsList().reverse(true).toList();
   }
   return result;
 }
 public SubLList assoc(SubLObject item, BinaryFunction test, UnaryFunction key) {
   SubLObject currentItem = null;
   SubLList result = SubLNil.NIL;
   SubLListListIterator iter = null;
   Resourcer resourcer = Resourcer.getInstance();
   SubLList curAssoc;
   try {
     iter = resourcer.acquireSubLListListIterator(this);
     while (iter.hasNext()) {
       curAssoc = iter.nextSubLObject().toList();
       if (SubLNil.NIL != test.processItem(item, key.processItem(curAssoc.first()))) {
         result = curAssoc;
         break;
       }
     }
   } finally {
     resourcer.releaseSubLListListIterator(iter);
   }
   return result;
 }