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;
 }
 public final SubLObject mapcar(
     final SubLFunction functionTyped,
     final SubLObject[] moreLists,
     final boolean returnConsedResults) {
   if (this == SubLNil.NIL) {
     return SubLNil.NIL;
   }
   for (int i = 0, size = moreLists.length; i < size; i++) {
     if (moreLists[i] == SubLNil.NIL) {
       return SubLNil.NIL;
     }
   }
   final int mapArity = 1 + moreLists.length;
   if (mapArity == 1) {
     UnaryFunction func = UnaryFunction.makeInstance(functionTyped);
     return mapResult(func, returnConsedResults);
   } else if (mapArity == 2) {
     BinaryFunction func = BinaryFunction.makeInstance(functionTyped);
     SubLList listTyped2 = moreLists[0].toList();
     return mapResult(func, listTyped2, returnConsedResults);
   } else {
     return mapResult(functionTyped, moreLists, returnConsedResults);
   }
 }