def specializeFreeVariablesAndEvaluate(
            self,
            foraExpression,
            renamedVariableMapping
            ):
        allAreIVC = True
        for _, v in renamedVariableMapping.iteritems():
            if not isinstance(v, ForaNative.ImplValContainer):
                allAreIVC = False

        if allAreIVC:
            missingVariableDefinitions = [
                x for x in foraExpression.freeVariables if x not in renamedVariableMapping
                ]

            if missingVariableDefinitions:
                raise pyfora.PythonToForaConversionError(
                    ("An internal error occurred: we didn't provide a " +
                     "definition for the following variables: %s" % missingVariableDefinitions +
                     ". Most likely, there is a mismatch between our analysis of the "
                     "python code and the generated FORA code underneath. Please file a bug report."
                    ))

            #we need to determine whether we should bind the free variables in this expression as constants
            #inline in the code, or as class members. Binding them as constants speeds up the compiler,
            #but if we have the same function bound repeatedly with many constants, we'll end up
            #producing far too much code. This algorithm binds as constants the _First_ time we bind
            #a given expression with given arguments, and as members any future set of times. This
            #should cause it to bind modules and classes that don't have any data flowing through them
            #as constants, and closures and functions we're calling repeatedly using class members.
            shouldMapArgsAsConstants = True

            boundValues = tuple(renamedVariableMapping[k].hash for k in sorted(renamedVariableMapping))
            if foraExpression.hash() not in self.boundExpressions:
                self.boundExpressions[foraExpression.hash()] = boundValues
            else:
                bound = self.boundExpressions[foraExpression.hash()]
                if boundValues != bound:
                    shouldMapArgsAsConstants = False

            return ForaNative.evaluateRootLevelCreateObjectExpression(
                foraExpression,
                renamedVariableMapping,
                shouldMapArgsAsConstants
                )
        else:
            #function that evaluates the CreateObject.
            #Args are the free variables, in lexical order
            expressionAsIVC = foraExpression.toFunctionImplval(False)

            args = []
            for f in foraExpression.freeVariables:
                args.append(renamedVariableMapping[f])

            res = ComputedValue.ComputedValue(
                args=(expressionAsIVC, Symbol_Call) + tuple(args)
                )

            return res
dataset/ETHPy150Open ufora/ufora/ufora/FORA/python/PurePython/Converter.py/Converter.specializeFreeVariablesAndEvaluate/original