apply env (VarExpr n) args =
    case M.lookup n builtins of
        -- if it is a unary function handle it right away
        Just (Builtin 1 f) -> do
            --args <- (eval env args)
            f [args]
        -- n-ary function must harvest additional n-1 parameters
        Just b -> do
            --args <- (eval env args)
            return $ FuncCtx b [args]
        Nothing -> do
            --args <- (eval env args) 
            applyFromEnv env n args
apply env (VarExpr n) args =
    case M.lookup n builtins of
        -- if it is a unary function handle it right away
        Just (Builtin 1 f) -> do
            --args <- (eval env args)
            f [args]
        -- n-ary function must harvest additional n-1 parameters
        Just b -> do
            --args <- (eval env args)
            return $ FuncCtx b [args]
        Nothing -> do
            --args <- (eval env args) 
            applyFromEnv env n args
apply env (VarExpr n) args =
    case M.lookup n builtins of
        -- if it is a unary function handle it right away
        Just (Builtin 1 f) -> do
            --args <- (eval env args)
            f [args]
        -- n-ary function must harvest additional n-1 parameters
        Just b -> do
            --args <- (eval env args)
            return $ FuncCtx b [args]
        Nothing -> do
            --args <- (eval env args) 
            applyFromEnv env n args