public static ObjBox Apply(FunctionHolder function, RacketPair list)
        {
            int param_num = function.param_num;
            List<Object> args = new List<Object>();
            ObjBox fun_call;

            if (list.length() != param_num)
                throw new RuntimeException("The expected number of arguments does not match the given number");
            int length = list.length();

            for (int i = 0; i < length; i++)
            {
                args.Add(list.car());
                ObjBox rest = list.cdr();

                if (rest.getType() == typeof(voidObj))
                {
                    break;
                }
                else
                {
                    list = (RacketPair)rest.getObj();
                }
            }
            fun_call = function.invoke(args);

            return fun_call;
        }
        public static ObjBox Apply(FunctionHolder function, RacketPair list)
        {
            int           param_num = function.param_num;
            List <Object> args      = new List <Object>();
            ObjBox        fun_call;

            if (list.length() != param_num)
            {
                throw new RuntimeException("The expected number of arguments does not match the given number");
            }
            int length = list.length();

            for (int i = 0; i < length; i++)
            {
                args.Add(list.car());
                ObjBox rest = list.cdr();

                if (rest.getType() == typeof(voidObj))
                {
                    break;
                }
                else
                {
                    list = (RacketPair)rest.getObj();
                }
            }
            fun_call = function.invoke(args);

            return(fun_call);
        }
        public static ObjBox Reverse(RacketPair list)
        {
            bool restNull = false;

            if (list.isNull())
            {
                return(new ObjBox(list, typeof(RacketPair)));
            }

            RacketPair accu = new RacketPair(list.car(),
                                             new ObjBox(new RacketPair(), typeof(RacketPair)));

            list = (RacketPair)list.cdr().getObj();

            while (!list.isNull())
            {
                accu = new RacketPair(list.car(),
                                      new ObjBox(accu, typeof(RacketPair)));

                list = (RacketPair)list.cdr().getObj();
            }
            return(new ObjBox(accu, typeof(RacketPair)));
        }
        public override bool Equals(object obj)
        {
            if (obj.GetType() == typeof(RacketPair))
            {
                RacketPair other = (RacketPair)obj;
                if (this.isNull() && other.isNull())
                {
                    return(true);
                }
                //one of us is null the other is not
                if (this.isNull() || other.isNull())
                {
                    return(false);
                }
                return(this.value.Equals(other.car()) && this.rest.Equals(other.cdr()));
            }

            return(base.Equals(obj));
        }
        public static ObjBox Reverse(RacketPair list)
        {
            bool restNull = false;
            if (list.isNull())
                return new ObjBox(list, typeof(RacketPair));

            RacketPair accu = new RacketPair(list.car(),
                new ObjBox(new RacketPair(), typeof(RacketPair)));

                list = (RacketPair)list.cdr().getObj();

            while (!list.isNull())
            {
                accu = new RacketPair(list.car(),
                    new ObjBox(accu, typeof(RacketPair)));

                    list = (RacketPair)list.cdr().getObj();
            }
            return new ObjBox(accu, typeof(RacketPair));
        }