1. C++ / Говнокод #12316

    +10

    1. 1
    virtual ~T() {}

    нахуя?
    у всех наследников то же самое и наличие чего-либо внутри не предполагается
    Первая ссылка по гуглозапросу "c++ mersenne twister" выдаёт склад оопиозного говнокода:
    http://www.bedaux.net/mtrand/

    Запостил: TarasB, 19 Декабря 2012

    Комментарии (109) RSS

    • Почему с вихрем Мерсенна такой пиздец?
      В разных местах разная реализация.
      1.
      #define UMASK 0x80000000UL /* most significant w-r bits */
      #define LMASK 0x7fffffffUL /* least significant r bits */
      #define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
      #define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
      static void next_state(void)
      {
          unsigned long *p=state;
          int j;
      
          /* if init_genrand() has not been called, */
          /* a default initial seed is used         */
          if (initf==0) init_genrand(5489UL);
      
          left = N;
          next = state;
          
          for (j=N-M+1; --j; p++) 
              *p = p[M] ^ TWIST(p[0], p[1]);
      
          for (j=M; --j; p++) 
              *p = p[M-N] ^ TWIST(p[0], p[1]);
      
          *p = p[M-N] ^ TWIST(p[0], state[0]);
      }

      http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/MTARCOK/mt19937ar-cok.c

      2.
      void MersenneTwister::generateNumbers()
      {
      	unsigned int y;
      
      	unsigned short int i;
      	for (i=0; i<VEC_L; i++)
      	{
      		y = (state[i]>>31)+((state[(i+1)%VEC_L]<<1)>>1);
      		state[i] = state[(i+SHF_C)%VEC_L]^(y >> 1);
      		if ((y % 2) != 0)
      		{
      			state[i] ^= ODG_C;
      		}
      	}
      }

      http://www.cplusplus.com/forum/beginner/79754/

      Блядь, это разные вещи, какую же выбрать-то?

      Походу на крестосайте забыли написать
      (state[i]>>31)<<31
      Ответить
      • > (state[i]>>31)<<31
        state[i] & TARAS_B_CONSTANT

        > (state[(i+1)%VEC_L]<<1)>>1
        state[(i+1) % VEC_L] & ~TARAS_B_CONSTANT
        Ответить
        • Правильно, лишние биты надо не обнулять, а спихивать.
          Ответить
    • > virtual ~T() {}
      > Нахуя?

      Чтобы у класса был виртуальный деструктор. Если у базового класса не будет виртуального деструктора, ты получишь много приятных ощущений при удалении потомка через указатель на тот самый базовый класс...
      // Как-то так
      struct A {
          ~A() {} // невиртуальный деструктор, компилер по дефолту сделает подобный
          virtual void test() {}
      };
      struct B {
          virtual ~B() {} // а тут его сделали виртуальным, но уже поздно...
          virtual void test() {}
      };
      A *a = new B();
      delete a; // ... поэтому тут вызовется A::~A(), вместо  предполагаемого B::~B()
      Ответить
      • Кэп, я в курсе, зачем вообще нужны виртуальные деструкторы.
        Нахуй вообще хоть в одном месте иерархии в данном случае усрался хоть какой-то деструктор?
        Ответить
        • Виртуальный деструктор нужен чтобы делать что-нибудь в таком духе. Ведь всегда найдется тот, кто поюзает его именно так (раз уж сделана иерархия):
          MTRand_int32 *mt = create_some_twister();
          delete mt;

          А вот нахуя тут иерархия и наследования - я не знаю. По хорошему тут аггрегация нужна, а не наследование, т.к. имеем отношение "реализован через MTRand_int32" а не "является MTRand_int32".
          Ответить
          • > MTRand_int32 *mt = create_some_twister();
            > delete mt;

            Ну поюзает и что? Деструкторы-то блядь пустые и никогда, уверен, в них не появится ни-че-го!
            Ответить
            • А, там и у класов ниже по иерархии есть деструкторы, не приметил их... ну да, вот те точно не нужны, пока они пустые.

              А первый можно убрать только в том случае, если в документации явно написать - "тот кто будет юзать эту недоиерархию как иерархию - тот пидор".

              Еще раз повторюсь. Отношение "A реализован через B" это совсем не повод для публичного наследования B от A. А если уж поюзал паблик наследование - будь добр, напиши виртуальный деструктор, не расставляй грабли другим.

              P.S. Не написав виртуальный деструктор в иерархии ты нарушаешь принцип подстановки Лисков (один из принципов SOLID), т.к. в результате нельзя подставить объект вместо его предка.
              Ответить
            • P.P.S Тарас, отъебись от деструкторов уже, в этом говне ООПшника есть проблемы и похуже - состояние хранится в статик переменных. Если я запилю два таких генератора - они просто распидорасят друг другу состояния...
              Ответить
            • > Деструкторы-то блядь пустые

              Сравни:
              http://ideone.com/2Ea8d4
              http://ideone.com/5lB2cR

              Не замечаешь кое-какой проблемы?
              Ответить
              • У тебя деструкторы на самом деле не пустые.
                Тут же даже неподов в данных нет.
                Ответить
            • >Деструкторы-то блядь пустые и никогда, уверен, в них не появится ни-че-го!
              Даже если деструкторы пустые и использовалась перегрузка операторов new\delete, то если забыть виртуальные деструкторы в базовом, то delete может вызоватся не торт.
              Ответить
            • > Деструкторы-то блядь пустые и никогда, уверен, в них не появится ни-че-го!
              От этой иерархии могут отнаследоваться и всё пойдет псу под хвост, если там деструкторы не пустые будут
              Ответить
              • Да, спасибо, что открыл глаза, теперь я обязательно в классы Fixed и Point добавлю виртуальный деструктор, чтобы когда я от них отнаследуюсь, то у меня не было проблем.
                Ответить
                • Тарас, не перегибай пожалуйста палку. Fixed и Point это классы, которые не предполагают никакого наследования (как впрочем и класс который в топике, просто автор какого-то хуя засунул его в бессмысленную иерархию). В них, конечно же, виртуальный деструктор не нужен. Была бы это жаба - я бы написал в их описании final, чтобы показать, что от них наследоваться не стоит.

                  P.S. По хорошему - из кода, который ты кидал в топике, нужно выкинуть всю эту ебучую иерархию к хуям, и собрать все это в один простой и понятный класс... (При этом не забыв написать в доке, что наследоваться от него нельзя). Тогда и деструктор не нужен.
                  Ответить
                  • > как впрочем и класс который в топике
                    Ну дык а я о чём.
                    Вот открыл я код, увидел МТ в виде иерархии, и какой вопрос сразу же возник у меня? Правильно, "нахуя".
                    Ну и статические члены, да, но я типа честный рекламщик, выдаю интригующие вещи, а самые вкусные оставляю только для тех, кто всё-таки посмотрит, а то некоторые все фишки в рекламе показывают и потом смотреть нечего, некруто нифига.
                    Ответить
                    • Все правильно сделал. Интересно, там самого MT то правильно запилили?

                      P.S. Код в твоем первом комменте под номером 1 это я так понимаю код японца-автора МТ? Тогда он и корректен.
                      Ответить
                      • Под номером 1 оригинальный код от самого автора? Не знал.
                        Ответить
                        • Ну не знаю сколько там осталось авторского кода. Все-таки столько лет прошло, всяко там что-то допиливали...

                          Но насколько я понимаю http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html это официальный сайт МТшки и попутно хоумпага Makoto Matsumoto, который является одним из авторов.
                          Ответить
                        • А вот работа Мацумото и Нишимуры: http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/ARTICLES/mt.pdf. Там на 21й странице есть код на сишечке. Вот видимо он и был самой первой реализацией мистера-твистера.
                          Ответить
                  • А что тут мешает так писать? В С++ же есть final.
                    Ответить
                    • > В С++ же есть final.
                      C++ разные бывают. В каких-то есть, в каких-то нет :P
                      Ответить
                      • Где нет и где есть?
                        Ответить
                        • В С++11 compliant compilers есть, а в других нет
                          Ответить
                          • Но помоему этого нет даже в MS VS 2012. Только в норм компиляторе GCC
                            Ответить
                            • А ещё есть С++ под разные микроконтроллеры... Кстати, надо на предмет ГК покопать СДК Ардуино. Судя потому, что максимальная частота ШИМ на мегагерцовом контроллере получается в 1 килогерц - там явно индусятины хватает.
                              Ответить
                              • Эм, ну разве что им хардварных шимов не хватает, и они начинают эмулировать их софтовым подергиванием ножек...

                                А вообще с++ под такие контроллеры - это жесть какая-то. Места практически нет, стек маленький и рискует наползти на память... Чисто ради Си с шаблонами?
                                Ответить
                              • Есть реальные примеры индусятины?
                                Ответить
                          • Так можно ведь поиграться с виртуальным наследованием, приватным конструктором/деструктором и друзьями для достижения аналогии final
                            Ответить
                            • > можно ведь поиграться с виртуальным наследованием

                              Я бы такого умника уволил, чтобы не игрался на работе. Прикинь потом код с этим блядством комуто придется поддерживать?
                              Ответить
            • Всегда найдётся мудак, не поймёт общую задумку и сделает как привык - то есть, через жопу (встречал результат их деятельности - ентерпрайз, да). Так что лучше пусть будет.
              Ответить
    • Сделай над собой усилие, наконец
      #include <boost/random.hpp>
      ну или <boost/random/mersenne_twister.hpp>
      там 0 виртуальных методов
      Ответить
      • Собирать говяшки по тырнетам гораздо веселее, чем настраивать проект под буст. Не стоит прогибаться под изменчивый буст...
        Ответить
        • Поглядел я тут Скаллачку. Понял, что я раньше Немерле зря недооценивал. 16+. Это как небо и хуйня.
          Ответить
          • Истину молвишь. Я уже давно говорю, что Немерле рулит. Правда Mono тормознутей JVM - это раз, а скала один из самых шустрых функцанальных языков. За это ей можно простить многое.
            Ответить
          • "Обоснуй" (c)
            Хотелось бы услышать аргументированную критику. Не то чтобы я сильно сох по скале (меня больше интересуют решения, чем средства), просто ты нам недавно (http://govnokod.ru/12041) явно продемонстрировал, как прост, элегантен и краток код на Nemerle.
            Ответить
            • Паттерн-матчинг в скале примитивно слаб. Да и вообще скала по сравнению с Haskell\F#\Nemerle самая не выразительная, много кода приходится писать. Вывод типов не лучше, чем у C#. DSL и прочие метапрограммисткие приемы - на нуле. Правильные языки, типа Лиспа и Немерле выращивали язык и стандартную библиотеку на некотором базисе. Компилятор\интерпретатор у обоих очень прост. Мясо наращивали за счет макросов. А в скале пошли наоборот через задницу: сначала написали весь язык, а потом из под левой пятки попытались впихнуть в язык макросы, а воз и ныне там. Что в лиспе, что в немерле - макросы показали свою истинную силу хотябы просто созданием языка и его стандартной библиотеки. А в скале, если когда-нибудь и получится добавить макросы, то с языком это сочитаться не будет, тк изначально язык не проектировался для их добавления, вызывая кучу скаллапроблем (пример можно увидеть в крестах, хотя скала очевидно учтет многие ошибки времен крестопрепроцессора).
              Ну и уже сейчас видна куча ненужного синтаксического сахара, ухудшаещего читабильность из-за ерунды, увеличивающего число способов записи программы и разрушая единый стиль написания кода, без нужды усложняющего компилятор.
              Например:
              (4 -> "ko") синоним для (4, "ko")
              или
              obj.method(5) синоним obj method 5 со всеми проблемами: с приоритетами, читабильностью и частичным применением.
              или эта любовь все заворачивать в объекты, даже локальные функции, притом не автоматом, а руками, расписывая поэмы
              или
              это частичное применение аля хаскель:
              func (1) ("arg2") (ko) и не лень же кому-то расставлять скобки...

              В целом ничего научного, эволюционного, инновационного или революционного, но как замена жабы, побеждающая большинство её жабапроблем - сойдет...
              Ответить
              • > это частичное применение аля хаскель:
                > func (1) ("arg2") (ko)
                Правильнее это назвать результатом каррирования, конечно
                Ответить
              • Ты, как всегда, остался на уровне сравнения мелких фишечек и не понял идеи. Почитай Scalable Component Abstractions Одерски, может поймёшь, зачем создавался язык, и что в нём является ключевым.

                Макросы там не особо нужны, и это основная причина того, что их там ещё нет. Продвигают их фанатики типа тебя.

                > DSL и прочие метапрограммисткие приемы - на нуле
                DSL, к твоему сведению, имеет весьма косвенное отношение к метапрограммированию, можешь почитать Фаулера и DSL in Action по этому поводу.
                Очень многого можно добиться одними лишь имплиситами, сохраняя типобезопасность. К примеру, покажи, как реализовать в Nemerle такой код:
                val duration = 5 seconds


                > куча ненужного синтаксического сахара
                Тот пример, что ты привёл - это не синтаксический сахар, это неявное преобразование, объявленное в Predef - довольно простой и универсальный механизм. Нет специального правила в компиляторе трактовать стрелочку как запятую.

                > любовь все заворачивать в объекты, даже локальные функции
                Это ограничение жабо-машины - классы и объекты - основные кирпичики. Нужно сказать спасибо скале, что позволяет смотреть на функции как на функции: на значения типа (TI => TO).

                > Паттерн-матчинг в скале примитивно слаб
                А вот тут можно поподробнее? По-моему, экстракторы рвут классический ПМ, т.к. позволяют сохранить инкапсуляцию, предоставлять View для структур.
                Ответить
                • >DSL, к твоему сведению, имеет весьма косвенное отношение к метапрограммированию, можешь почитать Фаулера и DSL in Action по этому поводу

                  Один из немногих способов организации EDSL и DSL: создание кода среды программирования на основе кода *DSL, но конечно не единственный.

                  >Scalable Component Abstractions

                  Ковариация и контравариация и обобщённое программирование есть даже C#, не говоря уж о Nemerle. То что в jvm этого нет и поэтому ты принял скалу за божественное проведение - тут ничего не поделать.

                  >Это ограничение жабо-машины

                  Вот только с некоторыми из них справляется скала, а так больше ничего нового.
                  Ответить
                  • > Ковариация и контравариация и обобщённое программирование есть даже C#
                    Ты не читал, а уже делаешь выводы. Это не то, что лежит в основе языка.

                    > ты принял скалу за божественное проведение
                    Лол. Это всего лишь очередной язык, со своими преимуществами и недостатками. Как и Nemerle. Он мне нравится потому, что в основе лежит неплохая оригинальная идея, а не просто желание напихать побольше фишечек (по этому пути, с моей точки зрения, сейчас идёт c#).
                    Ответить
                    • >Ты не читал, а уже делаешь выводы.
                      Я видел там красивые иерархии наследования между всеми типами, по аналогии как с тайпклассами в хаскел. Понятно что это один из способов организации обобщенного программирования, впрочем более медлительный, чем тот, что принят в хаскеле или С++.
                      Ответить
                      • Там просто приводится иерархия типов при кратком введении в язык. Смотрел картинки, не читал.
                        Ответить
                      • Кратко объясню для тех, кто не любит читать.
                        Идея в том, чтобы предоставлять софт в виде настраиваемых компонентов. При этом компонент - это не какая-то новая сущность. Интерфейс модуля выражается как класс или трэйт. Сам модуль - объект. Модуль может содержать другие модули для своей работы, и т.п.
                        Конфигурация задаётся не тупыми xml, а наследованием и переопределением ссылок на модули - зависимости (DI с компайл-тайм проверкой наличия всех зависимостей).
                        Это одна из ключевых (но не единственная) идей, лежащих в основе языка.
                        Ответить
                • >Макросы там не особо нужны, и это основная причина того, что их там ещё нет. Продвигают их фанатики типа тебя.

                  Основная причина, почему их там нет - то что в язык уже поздно добавлять макросы, тк изначально язык не разрабатывался, как совместимый с добавлением макросов.

                  >Очень многого можно добиться одними лишь имплиситами

                  Метапрограммировать через костыли? В крестах тоже можно метапрограммировать на шаблонах, но каков результат? И то на крестах это делать удобнее.
                  Ответить
                • > К примеру, покажи, как реализовать в Nemerle такой код:
                  val duration = 5 seconds

                  Ну это можно реализовать поразному и с разными целями. Начни с себя и покажи код реализации этого.
                  Ответить
                  • > покажи код реализации этого
                    http://ideone.com/IiUxmq
                    держи
                    Ответить
                    • import java.util.concurrent._
                       
                      class Duration(amount: Int, unit: TimeUnit) {
                          override def toString = "Duration(" + amount + ", " + unit + ")"
                      }
                       
                      object Duration {
                          class DurationConv(amount: Int) {
                              def seconds = Duration(amount, TimeUnit.SECONDS)
                              def second = seconds
                              def minutes = Duration(amount, TimeUnit.MINUTES)
                              def minute = minutes
                          }
                          implicit def amountToConv(amount: Int) = new DurationConv(amount)
                          def apply(amount: Int, unit: TimeUnit) = new Duration(amount, unit)
                      }
                       
                      object Main extends App {
                          import Duration._
                          
                          val duration = 5 seconds
                          val another = 5 minutes
                          
                          println(duration)
                          println(another)
                          
                          println(1 minute)
                          println(101 second)
                          //Суть Б:
                          println(amountToConv(101).seconds)
                          println(amountToConv(101) seconds)
                      }
                      Ответить
                    • >101 second
                      требует окончания s на конце по правилам английского языка
                      101 seconds
                      Ответить
                      • > требует окончания s на конце по правилам английского языка
                        да, я знаю, ступил

                        > можно реализовать поразному и с разными целями
                        давай, порази нас элегантностью и мощью Nemerle, я весь день жду
                        Ответить
                        • >да, я знаю, ступил
                          Scala должна была за тебя проверить правильность окончания. Так делают настоящие EDSL и DSL.
                          Ответить
                          • В общем, унылые нападки и троллинг - это всё, на что ты способен. Как я и думал.
                            Ответить
                            • #include <chrono>
                              #include <iostream>
                              using namespace std;
                              using namespace chrono;
                              
                              inline constexpr seconds operator"" _seconds ( unsigned long long v ){ 
                                 return seconds(v);
                              }
                              
                              inline constexpr minutes operator "" _minutes ( unsigned long long v ){ 
                                 return minutes(v);
                              }
                              
                              inline constexpr seconds operator"" _second ( unsigned long long v ){ 
                                 return seconds(v);
                              }
                              
                              inline constexpr minutes operator "" _minute ( unsigned long long v ){ 
                                 return minutes(v);
                              }
                              
                              int main() {
                                 auto duration = 5_seconds;
                                 auto another = 5_minutes;
                                 
                                 cout
                                    <<duration<<endl
                                    <<another<<endl
                                    
                                    <<1_minute<<endl
                                    <<1_second<<endl;
                                 
                                 return 0;
                              }
                              PS: Вижу тролля.
                              Ответить
                            • Версия на Nemerle:
                              http://rsdn.ru/forum/src/1823225.all
                              Чуть позже дам на F#.
                              Ответить
                      • (format t "~{~&~d second~:@P~^,~}" '(1 2 3 4 5 6 7 8 9 0))

                        Нет, вы не подумайте...
                        Ответить
                  • > это можно реализовать поразному и с разными целями
                    Цель - предоставить удобный интерфейс для задания временных интервалов, такие вещи часто реализуются через monkey patching. Твоя очередь.
                    Ответить
                • >> Паттерн-матчинг в скале примитивно слаб
                  > А вот тут можно поподробнее? По-моему, экстракторы рвут классический ПМ
                  Мм. Экстракторы? Пример? Пока я видел только многословный детский сильноограниченный сад в ПМ скалы.
                  Ответить
                  • > Пока я видел только многословный детский сильноограниченный сад
                    Поведай об ограничениях, которые ты нашёл, по сравнению с остальными языками, поддерживающими функциональную парадигму.
                    Ответить
                    • О. Только заметил тред.
                      Я еще тогда хотел упомянуть что возможно Гумно не осилило скалу.
                      Сам краем глаза поглядываю. Не понравились всякие антиинтуитивные значки, ну ладно там стрелочки - это понятно. Но когда я увидел такое: :: ::: то сразу вспомнил о крестах.

                      А в немерле мне дико нравится концепция "всё - выражение", и простой язык на макросах.
                      return try{ "Hi Taras!" } catch {null}
                      Что может быть удобней?

                      В целом не скажу что скала сильно в чем-то сливает, и на ней невозможно писать.
                      По сути срач должен состоять JVM vs CLR. Тут JVM выигрывает по скорости, распространнёности.
                      Ответить
                      • > val v = try{ "Hi Taras!" } catch {null}
                        В скала тоже многое выражени, в том числе и это.
                        Ответить
                      • Scala:
                        for (x <- expr1; if expr2; y <- expr3) ...

                        Это, конечно, эквивалентно следующему:
                        for (x <- expr1) {
                          if (expr2) {
                            for (y <- expr3) ...
                          }
                        }
                        Ответить
                        • Scala:
                          Естественно, возникает вопрос: как же так, язык объектно-ориентированный; есть методы у объектов — как это всё сочетается с наличием обычных функций, не методов? Ну вот взять, например,
                          class A(i:Integer) {
                            def f1(j: Integer, k: Integer) = i+j+k
                            val f2 = (j:Integer, k: Integer) => i+j+k
                          }


                          Здесь очевидно, что f1 — метод, а f2 — функция. Какая разница между f1 и f2? Можно ли написать val f3 = f1? Нет, нельзя. Чтобы превратить метод класса в полноправную функцию (т. е., экземпляр типа Function), нужно, формально говоря, добавить подчёркивание после пробела:
                          val f3 = f1 _
                          Ответить
                          • Но нужно признать, что Nemerle такую запись, насколько я знаю, не осилила:
                            {_ % s.head != 0}

                            Максимум осилила:
                            _ % s.head
                            Ответить
                        • Нифига,
                          for (x <- expr1; if expr2; y <- expr3)
                          эквивалентно
                          expr1 withFilter(x => expr2) foreach (x => expr3 foreach (y => ...))
                          http://ideone.com/kHZhDY
                          Ответить
                          • Понял. А почему ты Box сам написал? Он же вроде уже засветился на говнокоде и есть в стандартной библиотеке.
                            Ответить
                            • Туплюс с утра.
                              abstract class Box[+T] {
                                  def withFilter[A](p: T => Boolean) = if (isDefined && p(value)) {
                                      println("Box.withFilter")
                                      Full(value)
                                  } else Empty
                                  
                                  def foreach(act: T => Unit) = if (isDefined) {
                                      println("Box.foreach")
                                      act(value)
                                  }
                               
                                  val isDefined: Boolean
                                  def value: T
                              }
                              case object Empty extends Box[Nothing] {
                                  override val isDefined = false
                                  override def value = throw new RuntimeException("Empty box")
                              }
                              case class Full[T](item: T) extends Box[T] {
                                  override val isDefined = true
                                  override val value = item
                              }
                               
                              object Main extends App {
                                  val empty = Empty
                                  val full  = Full("Surprise")
                                  
                                  for (x <- empty) println("Empty :[")
                                  
                                  for {
                                      x <- full
                                      if x startsWith "Sur"
                                      y <- Full(x.reverse)
                                  } println(y)
                              }

                              Хороший годный пример унификации интерфейсов. Желаю такого же всем языкам.
                              Ответить
                  • Кстати, часть функционала твоих экстракторов:
                    Nemerle:
                    regexp match (str) {
                      | "a+.*" => printf ("a\n");
                      | @"(?<num : int>\d+)-\w+" => printf ("%d\n", num + 3);
                      | "(?<name>(Ala|Kasia))? ma kota" =>
                         match (name) {
                           | Some (n) => printf ("%s\n", n)
                           | None => printf ("noname?\n")
                         }
                      | _ => printf ("default\n");
                    }
                    Ответить
                    • Scala, Встроенный XML

                      пример:
                      class Person(val id: Int,
                                   val firstName: String,
                                   val lastName: String,
                                   val title: String) {
                      
                          def toXML = {
                              <person>
                                  <id>{id}</id>
                                  <firstName>{firstName}</firstName>
                                  <lastName>{lastName}</lastName>
                                  <title>{title}</title>
                              </person>
                          }
                      }

                      Что регекспы (хоть и слабее Немерловых), что XML встроен в язык Scala. Ну и наркоманство разращивать и переусложнять компилятор Scala, хотя вполне можно было не добавлять такую ерунду в язык, а сделать на уровне библиотеки, как это сделано а Nemerle. И это притом, что регекспы в скале не такие красивые и краткие, как в немерле, хотя XML в обоих языках по синтаксису и удобству абсолютно одинаковые.
                      Ответить
                      • xml встроен и это довольно удобно.
                        Сахар регекспов реализован через экстракторы, т.е. к усложнению компилятора никак не относится.
                        Ответить
                        • Ты не поверишь, но в Немерле XML не встроен и это довольно удобно. Зато он есть в стандартной библиотеке на макросах без лишнего усложнения компилятора:
                          Nemerle:
                          def html = xml <# 
                                  <html>
                                    <head>
                                      <title>$title</title>
                                      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> 
                                      <link rel="stylesheet" href="http://rsdn.ru/css/article.css" type="text/css" />
                                    </head>
                                    <body marginwidth="20" marginheight="20">
                                      <H1>$title</H1>
                                      
                                      <H2 $unless (props.IsEmpty())>Properties</H2>
                                      <ol $unless (props.IsEmpty())>
                                        <li $foreach (p in props)>$(p.Name) : $(p.PropertyType)</li>
                                      </ol>
                                      
                                      <H2 $unless (events.IsEmpty())>Events</H2>
                                      <ol $unless (events.IsEmpty())>
                                        <li $foreach (e in events)>$(e.Name) : $(e.EventHandlerType)</li>
                                      </ol>
                                    </body>
                                  </html>
                             #>;
                          Ответить
                  • И это... Твои экстракторы, тролль, есть почти в любом функциональном языке, так что скала не более чем копипастер очередной технологии.
                    Ответить
                    • В каком ещё языке есть экстракторы? Haskell? Lisp? Erlang?
                      Ответить
                      • F#, Nemerle и тд. Обычное извлечение на основе конструктора данных из объекта. Если ты с чем то не согласен, то приведи пример.
                        Ответить
                        • Ты опять ничего не понял. я устал кормить тебя примерами. найди книжку и почитай.
                          Гугл ТАМ ==>
                          Ответить
                          • Окей, тролль, тогда это 2 функции - прямая и обратная. Ты снова мне не поверишь, но это есть в любом языке.
                            Ответить
            • >явно продемонстрировал, как прост, элегантен и краток код на Nemerle.

              Код, как код. Что тебе там не понравилось? Рекурсивная стейт-машина. Ты просто не осилил паттерн.
              Ответить
        • > Собирать говяшки по тырнетам гораздо веселее

          Собирать говяшки по сортирам ещё веселее!

          P.S. Роман тут чаще всех употреблял слово «говяшки».
          Ответить
      • Да буста дохуя надо ради трёх процедур этого мистера твистера
        Ответить
        • могу дать сишкоблядский код твистера
          но ты реально задумайся над бустом для ndk
          Ответить
          • > но ты реально задумайся над бустом для ndk
            тонко
            Ответить
            • я серьезно
              буст неизбежен, как победа коммунизма
              там могут быть косяки только с исключениями в ndk (в ndk нет исключений, да?)
              Ответить
              • > в ndk нет исключений, да?
                Да, нет, кажется.
                И это единственное что в нём хорошо.
                Ответить
                • Возрадуйся, о не поддавшийся крестоблядским порокам Тарас:
                  The NDK toolchain supports C++ exceptions, since NDK r5, however all C++ sources are compiled with -fno-exceptions support by default, for compatibility reasons with previous releases.

                  To enable it, use the '-fexceptions' C++ compiler flag
                  Ответить
        • In new C++11 standard mersenne twister is available.
          Ответить
    • http://liveworkspace.org/code/3g7M9U$10
      Посоны, почему вызывается operator=? У меня пол уходит из под ног.
      Ответить
      • Тут кресты показывают очень похожую ситуацию:
        http://liveworkspace.org/code/3g7M9U$16

        А это эпо гей крестоповедения:
        http://liveworkspace.org/code/3g7M9U$15
        Легким движением руки, если забыл вызвать конструктор копирования базового класса в конструкторе копирования потомка, то вызывается конструктор поумолчанию базового класса и все члены базового класса вместо копирования - конструируются поумолчанию. Олололо

        [ color=blue][ u][/ u][/ color]

        Ответить
        • http://liveworkspace.org/code/3g7M9U$20
          Что и требовалось доказать. Tracer a из базового класса B не скопировался, а дефаултсконструировался (sic!). Как мои программы до этого вообще работали? Это - крестопиздец (неожиданный, но пора уж привыкнуть и ждать), а я - нубьё!
          Ответить
          • Посоны, посоветуйте чем снять стресс?
            Ответить
          • > Tracer a из базового класса B не скопировался, а дефаултсконструировался
            ясен хер, потому что в копирующем конструкторе в списке инициализации ты не указал копирующий конструктор базового класса, т.е. базовый класс конструируется по умолчанию
            http://liveworkspace.org/code/3g7M9U$25

            > Посоны, почему вызывается operator=?
            *this = other; в конструкторе копирования (sic!)
            Ответить
            • > *this = other; в конструкторе копирования (sic!)
              Е*ать! Какой петух этот snipet сделал?
              Обычно operator= по правилам принято делать через конструктор копирования, а не наоборот.
              Ответить
            • >Tracer( const std::string & name = "(none)" )
              Это можно считать синонимом того, что есть конструктор поумолчанию Tracer(void) и конструктор из строки Tracer(const std::string & name) одновременно или хоть где-нибудь в варианте с конструкторе с опциональным параметром будет различие в поведение с 2хконструкторным вариантом?
              Ответить
              • ты таким образом объявляешь и конструктор по умолчанию, и конструктор из строки
                одной записью
                два конструктора () и (string = "default") будут конфликтовать при попытке компиляции Tracer t;
                Ответить
                • Я говорю не
                  >() и (string = "default")
                  а:
                  () и (string) - такая 2хконструкторная запись полностью эквивалентна по семантике и поведению с одноконструкторным вариантом (string = "default") или есть тонкие различия, которые обязательно вылезут когда-нибудь?
                  Ответить
                  • эквивалентна
                    причем зачастую T(another const & = another(...)) делают explicit, если это нужно, что не влияет на семантику "дефолтный конструктор"
                    Ответить
                    • Хохо! То есть если сделать дефолтный конструктор T() и потом одновременно explicit T(another const & = another(...)) , то амбигити никогда не будет?
                      Ответить
                      • Блин, вот чем больше смотрю, тем больше люблю адское РАИИ, и похуй, что там в операторе копирования о ужас ресурс уничтожается и заново создаётся, нормальные люди такие объекты всё равно просто так не копируют.
                        Ответить
                      • ошибка будет, если два конструктора подойдут по сигнатуре
                        я говорил именно что
                        explicit T(another const & = another(...)) убивает сразу несколько зайцев
                        1) работает как конструктор от another,
                        2) работает как дефолтный конструктор, фактически ведя себя как конструктор от another с определенным аргументом,
                        3) благодаря explicit не позволит сделать
                        another a;
                        T b = a; (типа std::vector<int> v = 2;)
                        но позволит T b(a);
                        Ответить

    Добавить комментарий