На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (495) « Первая ... 405 406 [407] 408 409 ...  494 495  ( Перейти к последнему сообщению )  
> Delphi vs C++ vs C# , ну и Java немножко, где-то ближе к старшему байту номеров страниц
    Ну в C++ можно сделать специальный scope-объект, возвращающий переменную в исходное состояние при выходе из scope. Завтра покажу, если интересно.
      Цитата D_KEY @
      Ну в C++ можно сделать специальный scope-объект, возвращающий переменную в исходное состояние при выходе из scope. Завтра покажу, если интересно.

      Ну покажи, если не сложно, только не забывай, что в разных потоках должны быть разные биндинги, т.е.
      ExpandedWrap disabled
        #include <iostream>
         
        int CONTEXT;
         
        void p () {
          CONTEXT++;
        }
         
        void out () {
          std::cout << CONTEXT << std::endl;
        }
         
        void a () {
          with (CONTEXT = 0) {
            for (i <- 1..1000) {
              p();
            }
            out();
          }
        }
         
        void b () {
          with (CONTEXT = 0) {
            for (i <- 1..100) {
              p();
            }
            out();
          }
        }
         
        int main () {
          thread a();
          thread a();
          thread b();
          wait;
          return 0;
        }

      Что у тебя выведет на печать? Должно
      ExpandedWrap disabled
        100
        1000
        1000

      Не обязательно именно в таком порядке, но именно эти числа.
      Сообщение отредактировано: korvin -
        Что-то вроде такого
        ExpandedWrap disabled
          template<typename T>
          struct StateSaver
          {
            StateSaver(T &data)
              : m_value(data),
                m_data_ref(data)
            {
            }
           
            ~StateSaver()
            {
              m_data_ref = m_value;
            }
           
            T m_value;
            T &m_data_ref;
          };


        Ну и соответственно:
        ExpandedWrap disabled
          void p_Test () {
              StateSaver<int> ss(CONTEXT);
              CONTEXT = 0;
              p();
              std::cout << CONTEXT << std::endl;
          }


        Только никакого практического применения не вижу :)

        Добавлено
        Вот с разными потоками придется повозиться...
        Кстати, а разве в CL локальные биндинги глобальных переменных нормально разруливаются между нитками?
          Цитата D_KEY @
          Вот с разными потоками придется повозиться...
          Кстати, а разве в CL локальные биндинги глобальных переменных нормально разруливаются между нитками?

          Да, потому что это новые биндинги, а не просто установка/восстановление значения.

          Добавлено
          Цитата D_KEY @
          Что-то вроде такого ...

          ИМХО, лучше
          ExpandedWrap disabled
            template<typename T>
            struct StateSaver
            {
              StateSaver(T &data, T new_value)
                : m_value(data),
                  m_data_ref(new_value)
              {
              }
             
              ~StateSaver()
              {
                m_data_ref = m_value;
              }
             
              T m_value;
              T &m_data_ref;
            };

          ExpandedWrap disabled
            void p_Test () {
                StateSaver<int> ss(CONTEXT, 0);
                p();
                std::cout << CONTEXT << std::endl;
            }

          не?
          Сообщение отредактировано: korvin -
            Цитата korvin @
            Цитата D_KEY @
            Вот с разными потоками придется повозиться...
            Кстати, а разве в CL локальные биндинги глобальных переменных нормально разруливаются между нитками?

            Да, потому что это новые биндинги, а не просто установка/восстановление значения.

            Совсем как там не выйдет. В смысле с обычными глобальными переменными. Нужно писать свою приблуду для создания глобальных переменных и биндингов к ним. Если бы придумалось практическое применение, стоило бы подумать над этим ;)

            Добавлено
            Цитата korvin @
            не?

            Можно и так. Суть ты понял - происходит восстановление значение при выходе из текущего scope. Можно еще смарт-поинтер написать для этого :)
            Все-равно с нитками это не поможет. И все потому, что скомпилированная версия p уже будет ссылаться на ту самую переменную CONTEXT, что будет видеть при компиляции.
              Цитата D_KEY @
              Если бы придумалось практическое применение, стоило бы подумать над этим ;)

              Любая передача разного рода контекста с возможностью локальной настройки. Не, ну можно конечно все передавать параметрами функций, но это не удобно. Я использовал, когда писал принтер для Паскаля, передавал уровень индентации, т.е. типа
              ExpandedWrap disabled
                int INDENT_LEVEL  = 0
                int INDENT_LENGTH = 2
                 
                String indentation () {
                  return makeString( ' ', INDENT_LEVEL * INDENT_LENGTH )
                }
                 
                macro indent (expr) {
                  with (INDENT_LEVEL += INDENT_LENGTH) expr
                }
                 
                Block::print () {
                  printBegin()
                  indent {
                    for (expr : body) {
                      expr.print()
                    }
                  }
                  printEnd()
                }

              Тут конечно нет многопоточности, хотя можно несколько файлов "параллельно" печатать.

              Так же можно создавать окружения для функций с сайд эффектами, чтоб потестить их.

              Добавлено
              Цитата D_KEY @
              Совсем как там не выйдет. В смысле с обычными глобальными переменными. Нужно писать свою приблуду для создания глобальных переменных и биндингов к ним. Если бы придумалось практическое применение, стоило бы подумать над этим ;)

              Все-равно с нитками это не поможет. И все потому, что скомпилированная версия p уже будет ссылаться на ту самую переменную CONTEXT, что будет видеть при компиляции.

              Не, это-то мне понятно
                Цитата D_KEY @
                Ну в C++ можно сделать специальный scope-объект, возвращающий переменную в исходное состояние при выходе из scope.
                korvin, а чем ограничивается скоп такой вот "глобальной" копии глобальной переменной?
                  Цитата Qraizer @
                  Цитата D_KEY @
                  Ну в C++ можно сделать специальный scope-объект, возвращающий переменную в исходное состояние при выходе из scope.
                  korvin, а чем ограничивается скоп такой вот "глобальной" копии глобальной переменной?

                  scope и ограничивается. То есть даже если мы вернем из scope лямбду, которая по ссылке захватит новый биндинг, то вызов этой лямбды из другого scope приведет к работе с тем биндингом, что будет актуален для scope вызова. По крайней мере так в CL, а задачка, видимо, как раз идет оттуда. В общем в CL все несколько иначе в плане работы с глобальными переменными. Доступ к переменным, видимо, сделан по "именам", а поиск осуществляется в текущем контексте.
                  ExpandedWrap disabled
                    (defvar *my-global* 10)
                     
                    (defun f ()
                        (format t "~a~%" *my-global*))
                     
                    (defun g ()
                        (f)
                        (let ((*my-global* 20))
                            (f))

                  ExpandedWrap disabled
                    > (g)
                    10
                    20
                    NIL


                  При этом, если определим
                  ExpandedWrap disabled
                    (defun foo ()
                        (let ((*my-global* 20))
                            #'(lambda () (format t "~a~%" *my-global*))))


                  То результат (funcall (foo)) будет зависеть от значения *my-global* в вызывающем контексте, а привязка к 20 будет "забыта".

                  Добавлено
                  Причем это работает только с глобальными переменными. С обычными let логика примерно такая же, как и в других языках.

                  На всякий случай поясню. format - форматированный вывод, t в данном случае означает стандартный поток вывода, ~a - вывод значения ~% - переход на новую строку(\n в общем).
                  Сообщение отредактировано: D_KEY -
                    Цитата korvin @
                    Еще вопрос знатокам C#: я тут понатыкался на инфу, что обычный цикл for в большинстве случаев (массивы, числовые диапазоны) показывает заметно лучшую производительность, нежели foreach, так ли это и если да, то почему?


                    Конкретно для массивов - гон.
                    Для пользовательских типов - да, такое возможно, foreach будет неявно вызывать GetEnumerator/IEnumerable.Current/MoveNext, есть доп накладные расходы.
                      Цитата Qraizer @
                      korvin, а чем ограничивается скоп такой вот "глобальной" копии глобальной переменной?

                      Эм, не знаю как сказать, блоком выполнения, хотя конечно никто не мешает в блоке сохранить ссылку на значение, заданное в новом биндинге, в какую-то еще переменную.

                      Добавлено
                      Цитата D_KEY @
                      Причем это работает только с глобальными переменными. С обычными let логика примерно такая же, как и в других языках.

                      Глобальность тут не при чем =)
                      ExpandedWrap disabled
                        (defun test ()
                          (let ((local 0))
                            (declare (special local))
                            (flet ((foo () (format t "~s~%" local)))
                              (foo)
                              (let ((local 1))
                                (declare (special local))
                                (foo)))))
                         
                        (test)

                      ExpandedWrap disabled
                        0
                        1
                        korvin, я говорил об обычном let.
                        Что такое (declare (special local)) :blush: ? Ибо без него все будет так, как говорил я.

                        Добавлено
                        А понял, я использовал не верный термин. Имена с таким поведением называются "специальными", просто глобальные привязки являются такими автоматически.
                        Так?
                          Цитата D_KEY @
                          korvin, я говорил об обычном let.
                          Что такое (declare (special local)) :blush: ? Ибо без него все будет так, как говорил я.

                          Добавлено
                          А понял, я использовал не верный термин. Имена с таким поведением называются "специальными", просто глобальные привязки являются такими автоматически.
                          Так?

                          Да, специальные переменные. defvar и defparameter объявляют специальные переменные.

                          Qraizer, вспомнил, их скоп ограничевается Динамической областью видимости

                          D_KEY, кстати, в Emacs Lisp нет статического (лексического) скопа, только динамический =)
                            Вот-вот. Спопы - они такие разные... Сформулируйте сначала для себя, потом для нас.
                            И всё-таки. Как мне, скажем, синтаксисом C++ ограничить скоп вашего биндинга? Вот где он начинается и где заканчиватся. Чтоб чётко и однозначно: глянул в программу, а там "вот тут один биндинг, а вот тут уже другой; а вон там продолжается первый".
                              Цитата korvin @
                              D_KEY, кстати, в Emacs Lisp нет статического (лексического) скопа, только динамический =)

                              Там это как-то пофигу. Правда я и делал-то очень простые вещи.

                              Добавлено
                              Цитата Qraizer @
                              Вот-вот. Спопы - они такие разные... Сформулируйте сначала для себя, потом для нас.
                              И всё-таки. Как мне, скажем, синтаксисом C++ ограничить скоп вашего биндинга? Вот где он начинается и где заканчиватся. Чтоб чётко и однозначно: глянул в программу, а там "вот тут один биндинг, а вот тут уже другой; а вон там продолжается первый".

                              А из примеров не понятно? Могу перевести их на псевдо-плюсы.

                              Добавлено
                              Если коротко - значение береться из ближайшего по "стэку" scope при вычислении выражения с именем.

                              Добавлено
                              Что-то в таком духе:
                              ExpandedWrap disabled
                                /*defvar*/ my_global = 10;
                                 
                                void f()
                                {
                                    std::cout << my_global << std::endl;
                                }
                                 
                                void g()
                                {
                                    f();
                                    {
                                        my_global = 20;
                                        f();
                                    }
                                }
                                 
                                /*...*/ foo()
                                {
                                    my_global = 30;
                                    return [&]() {std::cout << my_global << std::endl;};
                                }
                                 
                                int main()
                                {
                                    g();
                                    auto a = foo();
                                    a();
                                    {
                                        my_global = 40;
                                        a();
                                    }
                                    a();
                                }


                              ExpandedWrap disabled
                                10
                                20
                                10
                                40
                                10


                              При этом в случае разных ниток установка локальных биндингов не влияет на другие нитки.
                              Сообщение отредактировано: D_KEY -
                                Цитата D_KEY @
                                А из примеров не понятно? Могу перевести их на псевдо-плюсы.

                                Добавлено Сегодня, 13:11
                                Если коротко - значение береться из ближайшего по "стэку" scope при вычислении выражения с именем.

                                Добавлено Сегодня, 13:19
                                Что-то в таком духе:
                                Нет, не понятно. Не надо переводить на C++, я просил представить в синтаксисе C++ границы этих скопов:
                                ExpandedWrap disabled
                                  int x;
                                   
                                  void f()
                                  {
                                    int y = ++x;
                                    {
                                     int z = ++x;
                                     {
                                      int t = ++x;
                                     }
                                    }
                                  }
                                И? Где? И почему?
                                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (495) « Первая ... 405 406 [407] 408 409 ...  494 495


                                Рейтинг@Mail.ru
                                [ Script execution time: 0.5281 ]   [ 14 queries used ]   [ Generated: 30.07.26, 03:20 GMT ]