1. Куча / Говнокод #11978

    +132

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    main = do
            print [1 .. 9]
            print [1, 3 .. 9]
            print [1, 3 .. 10]
            print [26.0, 26.2 .. 27.0]
            print [25.5..30.0]
            print [25, 25 .. 25]

    В хаскеле сломан генератор списков. :(
    http://ideone.com/AvBSuz

    Запостил: HaskellGovno, 22 Октября 2012

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

    • Сломано - не пользуйся.
      Ответить
    • насчет [25, 25 .. 25] еще можно понять, а вот с [25.5..30.0] уже интересно...
      Ответить
      • >[25, 25 .. 25]
        main = do
                print [25 .. 25]
                let t = (-1/0, 0/0)
                print t
                print $ uncurry compare t
                print [4, 1 .. 10]
                print [100, 1 .. 10]
                print [1/0, 1 .. 10]
                print [-1/0, 1 .. 10]
                print [0/0, 1 .. 10]
                print [-1/0, -1/0 .. -1/0]

        http://ideone.com/9HQgCW
        Забавный факт, но Хаски считает, что -1/0 > 0/0
        Ответить

        • Суть:
          import Data.List
          main = do
                  print $ sort [1, 0/0, 3, 2, 1, 0/0]

          http://ideone.com/92PHF2
          Ответить
          • Кстати, когда я попросил кресты справится - они справились:
            http://liveworkspace.org/code/bb5d5a7fb37f6fc7555a03d49a1c517e
            #include <algorithm>
            #include <iostream>
            #include <limits>
            #include <list>
            #include <vector>
            using namespace std;
            
            bool compare_nan( double a, double b )
            {
               if( a != a ) return false;
               if( b != b ) return true;
            
               return a < b;
            }
            
            void sort_nan( const initializer_list<double>& in )
            {
               list<double> data( in );
               data.sort( compare_nan );
            
               for( double v : data ) cout << v << ' ';
               cout << endl;  
            }
            
            int main()
            {
               double nan = numeric_limits<double>::quiet_NaN();
            
               sort_nan( { 2, nan, nan, nan, 1, nan, 3, nan, nan, 6, nan, nan, 5, nan, 0 } );
            }
            Ответить
          • Лоол. Это ж надо было додуматься - сортировать NaNы - надо будет запомнить.
            Ответить
      • Имхо как-то так:
        [a .. b] => for (i=a; i<=b; i++);
        [a, b .. c] => for (i=a; i<=c; i+=(b-a))

        [25, 25 .. 25] отлично вписывается в схему. А вот про 30.5 действительно непонятно.
        Ответить
        • Кстати [1%2 .. 5] тоже выдает [1%2,3%2,5%2,7%2,9%2,11%2].
          Ответить
          • А. Ну так если не задавать второй параметр, то Хацкил считает шагом инкремента - 1.
            Всё правильно.
            Человеческое мышление оно ведь инерционно и сразу думает в случае: print [25.5..30.0] что шаг 0.5.
            Это код-подъебка. Особенно когда уже усталый смотришь.
            http://ideone.com/yl5LWQ
            Правильно так:
            main = do
            print [25.5,26.0..30.0]
            А у гумна аналогично такому:
            main = do
            print [25.5,26.5..30.0]
            Ответить
            • Баг в том, что последнее число вылезает за пределы диапазона:

              25.5 26.5 27.5 28.5 29.5 30.5

              Хотя надо курить доку, вдруг так и задумано.
              Ответить
        • > А вот про 30.5 действительно непонятно.
          Наверное округляет в инты неправильно. Строгая типизация и явные задания типов тут рулят.
          http://ideone.com/HZoCdY
          Ответить
          • > округляет в инты
            Хммм... а это мысль.

            Походу да: http://ideone.com/nKJ7er

            Возможно, что он делит длину диапазона на размер шага, и считает сколько нужно сделать шагов. Вот в этот момент и происходит то самое округление не в ту сторону.

            P.S. По идее тут надо делать floor а не round... Но судя по результатам там таки round.
            Ответить
            • http://ideone.com/KXHjHF
              Хацкил - очевидный язык.
              Ответить
              • Ну собственно подтверждает мою теорию: http://ideone.com/esqRE7.

                Непонятно только какого хрена там round.
                Ответить
                • Так с интами ж нормально.
                  >какого хрена там round.
                  говно. хотя может они так перестраховаться от плавающей точки решили.
                  Ответить
                  • Ну у интов видимо шаг не вычисляют, а тупо крутят цикл. Надо бы взглянуть, как это реализовано в ghc.

                    P.S. Кажется начинаю понимать - в нормальных условиях (а не в таких, которые подобрал для нас Гумно) первый и последний аргумент выбраны не хуй-пойми как, а в качестве них взяты действительно первая и последняя точки перечисляемого нами отрезка. Если бы они делали floor, то тот перескок, который мы видим сейчас происходил бы на корректных ситуациях в духе [1.0,3.0 .. 5.0]. Такой вот трейд-офф.
                    Ответить
                    • В этом примере мы видим баг в действии:
                      http://ideone.com/5g9w3w

                      Благодаря round на вменяемых примерах его нет. Хотя из-за этого и страдают примеры, приведенные Гумном.
                      Ответить
                      • И что снова, но завуалировано возвращает нас к проблеме неточной плавающей запятой.
                        Ответить
                      • Ведь метод с эпсилоном - это тоже трейдофф.
                        Да и здание оного в списке испортило бы всю красоту запейси:
                        [25,27 .. 32.0, eps=0.001]
                        А по другому проблему 4.9999 итераций никак не разрулить.
                        Разве что помнить, что циклы (списки) с плавающей точкой на наших процессорах - источник опастности в любом языке.

                        Вот в питоне range ясно дает понять что к чему:
                        TypeError: range() integer end argument expected, got float.
                        И в аде тоже
                        for f in Float range 25.0 .. 28.0 loop
                        prog.adb:7:14: expected a discrete type
                        Ответить
                    • Вообщем вывод топика осталось сделать: Никогда не используй генераторы списков с плавающими числами. А если сделал, то потом не плач, что ноги отстрелило.
                      Ответить
                      • Ну почему - используй, но правильно. Указывая по краям не хер-знает-что, а именно концы отрезка.
                        Ответить
                      • > Никогда не используй генераторы списков с плавающими числами

                        Об этом, кстати, в самом начале RWH говорят
                        http://book.realworldhaskell.org/read/getting-started.html
                        "Beware enumerating floating point numbers"
                        Ответить
                        • Мудаки. Они ведь приблизились ближе всех к решению этой проблемы.
                          Могли ведь просто запретить float и оставить дроби - было крайне кошерно. А хацкель был бы единственным языком который корректно работает с рациональными числами.

                          Нет, хотим говнячить Float и Double и делать хаки с округлением.

                          PS. Мне так и не удалось сломать Ratio Integer.
                          Ответить
                          • Сломать Ratio Integer можно только по переполнению памяти :P

                            Совсем от флоата и дабла избавляться не стоит. Есть много задач где их точности вполне достаточно, и при этом важна скорость вычислений. А вот из класса Enum их вполне можно было выкинуть. Ну какие они к черту перечисляемые?
                            Ответить
                            • >Совсем от флоата и дабла избавляться не стоит.
                              Так никто об этом не говорит. Надо просто поубирать их из чисто дискретных аспектов и функций.
                              Ответить
                          • что-то мне подсказывает, что иногда могут быть полезны бесконечные списки http://ideone.com/i8t9RA, но я не уверен (ошибка копится, да)
                            Ответить
                            • Если есть желание такой список пилится в 2-3 строчки. И там явно пишется погрешность - если надо.
                              Но только теперь язык не виноват в том что ты берешь пистолет и стреляешь себе в ногу.

                              Ада же не дает range по флоатам, как тут сказал Тарас -
                              >Выбирая такое неточное говно, как Float, ты уже подписываешься на то, что тебе пофиг точность.
                              http://govnokod.ru/11979
                              Сам написал говноцикл - сам и разруливай.
                              Ответить
                            • http://ideone.com/NSxQ7V
                              Ответить
    • Лень постить на эту тему ГК. Исправлюсь.
      http://habrahabr.ru/post/153659/
      Ответить
      • Ну да, то что hClose закрывает файл, обламывая чтение с одной стороны неудобно. А с другой - а что ему еще делать? Откладывать до конца чтения смысла нет, т.к. тогда файл сам закроется и без hClose.

        А если читать файл надо не "для поиграться", а по-настоящему - есть модуль ByteString, в котором все работает побыстрее Prelude'ского hGetContents (читает чанками), кушает меньше памяти, и есть версии с ленью и без нее.
        Ответить
      • Эту их беду можно устранить одним seq.
        Ответить
    • Теперь. По поводу print [26.0, 26.2 .. 27.0]
      Рекомендую запустить в коносли:
      for (var i=26.0;i<27.0;i+=0.2) console.log(i);

      Это из-за FPU, его баг если хотите.

      Это давно известная херня и так ведут себя все языки:
      http://ideone.com/hU0BGx
      http://ideone.com/hVR0Qw


      Другое дело что хацкель гордовитый своей сверхвысокоуровневостью мог бы и обойти такое поведение.
      Ответить
      • А зачем обходить? Лучше уж знать, что работаешь с числами на компьютере, а не на бумажке.
        Ответить
        • Тогда нужно знать о регистрах, стеке, ассемблере.
          Но хацкил хочет быть выше этого.
          Ответить
      • (loop for i from 26.0 upto 27.0 by 0.2
              do (format t "i = ~f~&" i))
        ;; i = 26.0
        ;; i = 26.2
        ;; i = 26.400002
        ;; i = 26.600002
        ;; i = 26.800003
        :/
        Ответить
      • (loop for i from 26.0d0 upto 27.0d0 by 0.2d0
              do (format t "i = ~f~&" i))
        ;; i = 26.0
        ;; i = 26.2
        ;; i = 26.4
        ;; i = 26.599999999999998
        ;; i = 26.799999999999997
        ;; i = 26.999999999999996
        
        (loop for i from 26.0s0 upto 27.0s0 by 0.2s0
              do (format t "i = ~f~&" i))
        ;; i = 26.0
        ;; i = 26.2
        ;; i = 26.400002
        ;; i = 26.600002
        ;; i = 26.800003
        
        (loop for i from 26.0f0 upto 27.0f0 by 0.2f0
              do (format t "i = ~f~&" i))
        ;; i = 26.0
        ;; i = 26.2
        ;; i = 26.400002
        ;; i = 26.600002
        ;; i = 26.800003
        
        (loop for i from 26.0l0 upto 27.0l0 by 0.2l0
              do (format t "i = ~f~&" i))
        ;; i = 26.0
        ;; i = 26.2
        ;; i = 26.4
        ;; i = 26.599999999999998
        ;; i = 26.799999999999997
        ;; i = 26.999999999999996
        
        (loop for i from 26/1 upto 27/1 by 1/5
              do (format t "i = ~f~&" i))
        ;; i = 26.0
        ;; i = 26.2
        ;; i = 26.4
        ;; i = 26.6
        ;; i = 26.8
        ;; i = 27.0

        Более подробная информация :)
        Ответить
    • Низкоуровневые плюсы и ада таки работают, но как-то хуёво:
      ideone.com/pXIhvY
      Ответить
    • Функциональные языки по своей природе говно. Нельзя впихнуть парадигму, основанную на функциях в архитектуру, основанную на состоянии и не получить при этом пиздец ядерный.
      Ответить
      • Достаточно просто изменить нашу вселенную убрав из нее состояние... И тогда функциональные языки станут удобными.
        Ответить
      • - Движенья нет, - сказал мудрец брадатый.
        Другой смолчал и стал пред ним ходить.
        Сильнее не мог он возразить.
        Ответить
      • > Функциональные языки по своей природе говно
        > Достаточно просто изменить нашу вселенную убрав из нее состояние

        Ох уж мне эта трёхмерная крестоимперативщина.
        Бесконечноразрядный компьютер вселенной тик за тиком раскрывает бесконечный ленивый персистентный вектор иммутабельных состояний пространства-времени.
        Иначе как, по вашему, работает машина времени?
        Ответить
        • > Иначе как, по вашему, работает машина времени?
          Если не заныкать ссылочку на предыдущее состояние - никак. GC ведь уберет все ненужное, и возвращаться будет некуда.
          Ответить
          • > GC ведь уберет все ненужное
            У бесконечноразрядного компьютера вселенной бесконечное количество оперативной памяти, GC там не нужён.
            Память освободит вселенская операционная система при завершении программы...
            Ответить
            • У меня только 2 вопроса что вы принимаете и где это достать ?
              Ответить
            • >при завершении программы...
              GC - это Большое сжатие.
              Ответить
          • Так вот кто такие лангольеры!
            Ответить
        • Уж не думал что пространство-время дискретно, детерминировано, а в придачу ко всему - иммутабельно.
          >Иначе как, по вашему, работает машина времени?
          Она порождает новый вектор? Ведь старые состояния нельзя изменить.
          Ответить
          • > дискретно, детерминировано, а в придачу ко всему - иммутабельно
            Я тут на стороне Эйнштейна. Хаос не потому хаос, что он не определяется детерминированными законами, а потому, что законы эти чрезвычайно чувствительны к входным данным (правда, это должно означать, что наша судьба, поступки и мысли полностью определены заранее :[).

            > Она порождает новый вектор?
            Именно, рождается новая ветвь бытия
            Ответить
            • Понятно из детерминизма следует что хаос псевдослучаен.
              >правда, это означать, что наша судьба полностью определена заранее
              Да. Я бы тоже был полным сторонником такого .
              Если бы не одно НО! - принцип неопределенности гейзенберга.
              Ответить
              • > принцип неопределенности гейзенберга
                Но ведь каждую из сопряжённых величин мы можем измерять с достаточной точностью, проблемы возникают лишь при наблюдениях за несколькими величинами одновременно
                лол, упираемся в дискретное время вселенского процессора
                Ответить
                • Уточню на всякий: измерив одну величину, запорем значения другой. Измерить по очереди не выйдет.
                  Ответить
    • Объясните мне глупому, почему крестомудаки чуть ли не на уровне коммитета стандартизации подменяют суть терминов и используют их не по назначению?
      Например:
      *Функтор. Крестобляди считаю, что это функциональный объект. Почему? Функтор из теории категорий: отображение одного множества на другое.
      *Каррирование. Крестобляди считают, что это bind. В то время как на самом деле bind - это частичное применение/биндинг. В то время как каррирование/декаррирование - это преобразование функции принимающую несколько параметров в функцию принимающую кортеж и обратно.
      И таких моментов много. Почему так?
      Ответить
      • Нубы, сэр
        Ответить
      • эка тебя
        functor - 0 вхождений в документ стандарта
        function object - 59

        curry/сurrying - 0 вхождений
        binding - 46
        Ответить
      • Ты так говоришь, как будто это что-то плохое. Каждый человек может вводить новые значения для терминов в своей области исследований. Это могло быть просто случайное совпадение.
        Ответить
    • Короче из приведенного кода гумну достаточно было запостить такое:
      main = do
      	print [25,27..32.0]
      	print [25,27.. 32 ]

      Самая суть говнистости хацкила.

      Хотя с NaNами мне тоже понравилось.
      Ответить
      • Посоны, это ведь суть Хаски!
        http://ideone.com/KjeLmf
        Смачно вбросил. Уважуха.
        Ответить
        • Тут я вообще понять не могу, что происходит.
          Ответить
          • В посте http://govnokod.ru/11978#comment157134 и постом выше я попытался уяснить, почему оно так работает, и почему авторы выбрали именно round а не floor.

            Почитай, может найдется, что покритиковать или дополнить.
            Ответить
        • Если решишь забросить этот пример любителям маминого борща на сосач или еще куда - не стесняйся, кинь сюда сцылку.
          Ответить
      • С другой стороны, это упоминается в первой же главе Real World Haskell.


        ghci> [1.0,1.25..2.0]
        [1.0,1.25,1.5,1.75,2.0]
        ghci> [1,4..15]
        [1,4,7,10,13]
        ghci> [10,9..1]
        [10,9,8,7,6,5,4,3,2,1]


        In the latter case above [тут он соснул, не в последнем примере, а во втором], the list is quite sensibly missing the end point of the enumeration, because it isn't an element of the series we defined.

        We can omit the end point of an enumeration. If a type doesn't have a natural “upper bound”, this will produce values indefinitely. For example, if you type [1..] at the ghci prompt, you'll have to interrupt or kill ghci to stop it from printing an infinite succession of ever-larger numbers. If you are tempted to do this, type C to halt the enumeration. We will find later on that infinite lists are often useful in Haskell.

        [Warning] Beware enumerating floating point numbers

        Here's a non-intuitive bit of behaviour.

        ghci> [1.0..1.8]
        [1.0,2.0]

        Behind the scenes, to avoid floating point roundoff problems, the Haskell implementation enumerates from 1.0 to 1.8+0.5.

        Using enumeration notation over floating point numbers can pack more than a few surprises, so if you use it at all, be careful. Floating point behavior is quirky in all programming languages; there is nothing unique to Haskell here.

        http://book.realworldhaskell.org/read/getting-started.html#starting.list
        Ответить
        • Задокументированный баг становится фичей?
          Ну я уже неоднократно предлагал рациональное лекарство.

          >is quirky in all programming languages
          Съезд. В пыхе ведь всё гораздо лучше.
          Ситуацию усугубляет то, что они самые рьяные борцуны за чистоту и простоту кода, высокоуровневость и читаемость языка.
          Ответить
    • Нашел кстати истинное лицо хаскелевых диапазонов:
      enumFrom :: a -> [a]
      Used in Haskell's translation of [n..]
      
      enumFromThen :: a -> a -> [a]
      Used in Haskell's translation of [n,n'..].
      
      enumFromTo :: a -> a -> [a]Source
      Used in Haskell's translation of [n..m].
      
      enumFromThenTo :: a -> a -> a -> [a]
      Used in Haskell's translation of [n,n'..m].
      Ответить
      • А вот и виновники торжества (вызываются из enumFrom* для Float, Double, Ratio):
        numericEnumFrom         :: (Fractional a) => a -> [a]
        numericEnumFrom n   =  n `seq` (n : numericEnumFrom (n + 1))
        
        numericEnumFromThen     :: (Fractional a) => a -> a -> [a]
        numericEnumFromThen n m = n `seq` m `seq` (n : numericEnumFromThen m (m+m-n))
        
        numericEnumFromTo       :: (Ord a, Fractional a) => a -> a -> [a]
        numericEnumFromTo n m   = takeWhile (<= m + 1/2) (numericEnumFrom n)
        
        numericEnumFromThenTo   :: (Ord a, Fractional a) => a -> a -> a -> [a]
        numericEnumFromThenTo e1 e2 e3
            = takeWhile predicate (numericEnumFromThen e1 e2)
                                        where
                                         mid = (e2 - e1) / 2
                                         predicate | e2 >= e1  = (<= e3 + mid)
                                                   | otherwise = (>= e3 + mid)
        Внимательный читатель заметит +1/2 в numericEnumFromTo и +mid в numericEnumFromThenTo.
        Ответить
        • Смотрится как вседа на Хаскеле красиво, жаль что работает не так же красиво.
          Ответить
          • Повторюсь, на корректных входных данных, когда e1 и e3 являются концами перечисляемого отрезка, этот код работает получше, чем без +1/2 и +mid. Так что работа кода по-своему красива.
            Ответить
            • >Так что работа кода по-своему красива.
              По-своему некрасива.

              У нас есть выбор
              а) по сути UB, когда мы сравниваем прямо:
              http://ideone.com/hU0BGx
              http://ideone.com/pXIhvY

              Это если мы не округляем.
              б) проблемы связанные с округлением.
              Но тут тоже не все так просто
              > m + 1/2
              Ведь можно окрулять вверх не от половины, а от 0.99, например.
              Тогда проблемный диапазон становится меньше.
              И конечно основную проблему так мы не решаем - какое-то гумно может взять большие числа и интервалы.
              Ответить
            • Из этого следует простой вывод - если в языке разрешено юзать встроенные циклы по диапазонам из плавающих чисел - он говно.

              Но! Есть еще один вариант. Мне вот нравится то что пишет Ада:
              expected a discrete type. А конкретно слово дискретный.

              в) Можно превращать это в дроби. Тогда коды гумна выше можно интерпретировать так:
              [51/2..60/1],[26/1,131/5 .. 27/1]
              И все проблемы решаются т.к. дроби дискретные и можно точно узнать количество итераций.
              Такие циклы [0,1/3..10/3] будут работать безупречно, несмотря на бесконечную дробь
              Единственное что надо запрещать - ставить переменные-floatы, а константы всегда можно выразить в виде дроби.
              Ответить
              • 2 раза бы пюсанул...
                Ответить
              • Хаскелю рациональные числа не помогли, т.к. с ними, несмотря на их точность, зачем-то работает тот же самый код с +1/2.

                Грустно.
                Ответить
                • А может Ratio - это простая обертка и считается оно равно как Float, Double в регистрах fpu.

                  Ну кстати можно попробовать взять их код, убрать округление и посмотреть как ведут себя дроби при расчете количества итераций. Дабы понять - это сахарок или полноценные инты.
                  Повторюсь Float, Double там вовсе не нужны.
                  Ответить
                  • > А может Ratio - это простая обертка и считается оно равно как Float, Double в регистрах fpu.

                    Нет-нет. Дроби это полноценные рациональные числа. Там же не зря пишется не просто Ratio, а Ratio a, где вместо a обычно подставляют Int (если уверен что не зашкалит) или Integer (труъ рационалки, ограниченные только памятью).
                    Ответить
                    • Тогда надо повторить эксперимент http://ideone.com/5g9w3w на Ratio.
                      Ответить
                      • Ну собственно что долго думать, скопипастил код из настоящей реализации, убрал +mid: http://ideone.com/8NwsDm
                        Ответить
                        • Об том и речь:
                          1. убрать Float, Double
                          2. убрать говнохак +1/2.
                          ...
                          Хацкель снова рулит.
                          Ответить
                        • Вот только стандартные генераторы списков [..] сразу пошли лесом... :(
                          Ответить
                          • Зато ты будешь хацкель-илитой, зная что стадартные генераторы для быдла.
                            Ответить
                            • То есть из-за того, что в каком-то никому не нужном хаскиле есть баги - ты и он стал илитой?
                              Ответить
                          • К тому же ты постоянно лез из кожи вон, пытаясь найти изъян и доказать что хацкель это говно.
                            И вот свершилось! Сбылась мечта идиота!
                            http://25.media.tumblr.com/tumblr_m4vdb7JBM61qcbdv2o1_500.jpg
                            Ответить
                            • Я же для популяризации Хацкеля лез из кожи вон, а не чтобы в нем ошибку найти. Похоже я допустил ошибку, найдя в нем ошибку.
                              Ответить
                              • Зато сколько говна я раскопал по ходу!
                                И всё илитные функцианальные языки соснулей у пхп. Какой позор.
                                Ответить
                          • Можно запилить свой Ratio с нормальной реализацией. И генераторы будут работать с ним красиво и точно. А флоаты и ратио с говнореализацией numericEnumFrom пускай идут лесом.
                            Ответить
                            • Шок! Сенсация!
                              htttp://ideone.com/BZ6lr5
                              В убогом пхп всё отлично работает по дефолту.

                              Решил проверить еще парочку языков, так, чисто для галочки.
                              И выяснилось страшное - быдлопыха работает правильней, чем илитные лисп и хацкель. Ха-ха-ха!
                              Ответить
                              • Он использует строковое представление чисел при вычислениях.
                                Ответить
                                • Насрать как. Главное - правильно. Причем проходит-то идеально все тесты.
                                  Главное факт: хацкель, а вместе с ним лисп соснули у пхп.
                                  PHP выбор разработчиков-профессионалов для разработки высоконадежных систем, а haskell и lisp удел псевдоматематического безработного быдла.
                                  Ответить
                                • Ты не расстраивайся. Я нашел язык который еще хуже чем лисп и хацкель. Это вообще полное говно. Сначала я думал наоборот - неплохо, но подробные тесты диагностировали обратное.
                                  Хотите знать что это?
                                  Следите за анонсами в новостях.
                                  Ответить
                                • Короче это мерзкое поделие из говна - Скала.
                                  А еще она дико тормознутая - пример ideone компилился больше минуты.
                                  println    (13.0 to (14.0, 0.1));
                                      println    (13.0 to 14.0 by 0.1);
                                      println    (1.3 to  1.4 by 0.01);
                                      println    (25.5 to 30.0 by 1);
                                      println    (26.0 to 27.0 by 0.2);
                                      println    (7.0 to 8.2 by 0.3);

                                  Так мало того оно на ideone работает по-другому чем у меня.

                                  http://ideone.com/IoYR62
                                  Ответить
                                • У меня безобидный пример
                                  println (7.0 to 8.2 by 0.3);
                                  выдает ArithmeticException.
                                  Это пиздец, да.
                                  NumericRange(13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14.0)
                                  NumericRange(13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 13.7, 13.8, 13.9, 14.0)
                                  NumericRange(1.3, 1.31, 1.32, 1.33, 1.34, 1.35, 1.36, 1.37, 1.38, 1.39)
                                  NumericRange(25.5, 26.5, 27.5, 28.5, 29.5)
                                  NumericRange(26.0, 26.2, 26.4, 26.6, 26.8, 27.0)
                                  java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
                                  	at java.math.BigDecimal.divide(BigDecimal.java:1616)
                                  	at java.math.BigDecimal.divide(BigDecimal.java:1650)
                                  	at scala.math.BigDecimal.$div(BigDecimal.scala:228)
                                  	at scala.math.Numeric$DoubleAsIfIntegral$class.quot(Numeric.scala:136)
                                  	at scala.math.Numeric$DoubleAsIfIntegral$.quot(Numeric.scala:166)
                                  	at scala.math.Numeric$DoubleAsIfIntegral$.quot(Numeric.scala:166)
                                  	at scala.math.Integral$IntegralOps.$div$percent(Integral.scala:23)
                                  	at scala.collection.immutable.NumericRange.genericLength(NumericRange.scala:104)
                                  	at scala.collection.immutable.NumericRange.(NumericRange.scala:63)
                                  	at scala.collection.immutable.NumericRange$$anon$1.(NumericRange.scala:163)
                                  	at scala.collecti...

                                  PS. Тут есть ScalaGovno?
                                  Ответить
                                  • У тебя, наверное, старая версия скалы, в которой NumericRange был ленивым. В 2.8 это выпилили, т.к. многие конфьюзились.
                                    Компилится да, охренеть как долго.
                                    Ответить
                              • В пхп покурил сырцы. Они применили вот такой фикс для проблемы:
                                #define DOUBLE_DRIFT_FIX        0.000000000000001
                                for (value = low; value <= (high + DOUBLE_DRIFT_FIX); value = low + (++i * step)) {
                                ...
                                }
                                Ответить
                                • А. Ну #define DOUBLE_DRIFT_FIX 0.000000000000001 молодцы, чё.
                                  Как и предполагалось выше:
                                  >Ведь можно окрулять вверх не от половины, а от 0.99, например.
                                  Тогда проблемный диапазон становится меньше.


                                  Я не курил сырцы но нашел пример иллюстрирующий. И в руби наверное тоже так.

                                  Вот кстати баш и руби
                                  http://ideone.com/5tjYy6
                                  http://ideone.com/ZZSbj1
                                  Ответить
                              • PHP сопротивлялось до последнего, но было повержено:
                                http://ideone.com/2Yb8Fw
                                Ответить
                                • Вот читер.
                                  .999999 - нечестно ведь.
                                  Ответить
                                  • > Как быть с башем пока не знаю - работает безупречно.
                                    Вот у него то уж точно децималы в виде строк...
                                    Ответить
                                    • Нихера. Баш повержен:
                                      http://ideone.com/5tjYy6
                                      Правда девяток многовато, но это наверное из-за того что в пыхе флоат, а баше дабл или вовсе 80-битный.
                                      Ответить
                                      • В пыхе дабл.
                                        Ответить
                                        • А вот вам еще говнеца на лопате.
                                          Хацкельные дроби c Int соснули:
                                          http://ideone.com/PVn4Ug
                                          Правда c Integer - нормал.
                                          Ответить
                                        • Fix:
                                          Int соснул - ничего не вывел.
                                          Integer соснул - вывел элемент за пределами диапазона.
                                          PHP wins again!
                                          Ответить
                                          • А можно пример с Ratio Integer?
                                            Ответить
                                            • А я код в ссылке выше обновил.
                                              Но он на удивление банален
                                              print $ (myEnumFromThenTo 1.5 1.8 2.99  :: [Ratio Integer])
                                              [3%2,9%5,21%10,12%5,27%10]
                                              Ответить
                                              • > print $ (myEnumFromThenTo 1.5 1.8 2.99 :: [Ratio Integer])
                                                [3%2,9%5,21%10,12%5,27%10]

                                                Эм, а что тут не так? [1.5, 1.8, 2.1, 2.4, 2.7] 3.0 же уже не нужно.
                                                Ответить
                                                • А, блин, точно. Проглядел.
                                                  Меня сбил с толку предыдущий Int который вывел ошибочный и странный результат:
                                                  [3%2,9%5,21%10,12%5]
                                                  Ответить
                                                • Продолжая наш праздник:

                                                  Пёрлу - похуй.
                                                  http://ideone.com/pOQFnA
                                                  Луа соснула, равно как и все жабоскриптовые:
                                                  Lua: http://ideone.com/pgPiqW
                                                  Rhino: http://ideone.com/Vn71Mz
                                                  spidorMonkey: http://ideone.com/r3IlGM

                                                  А груви кстати оказался на удивление хорош, но с .9999999 он сфейлил.
                                                  http://ideone.com/ZOlfyv

                                                  PS. Проверьте кто-нибудь в крестах бустовский range.
                                                  Ответить
                                                  • > бустовский range
                                                    да он походу целочисленный
                                                    если кому хочется плавающей точки - предлагается написать самому
                                                    только вот мне никогда и целочисленной не доводилось захотеть
                                                    Ответить
    • Кто все эти люди и что я тут делаю?
      Ответить
    • Ну и незаслуженно забыты еще 2 функциональных язычка.
      Шарпоблядский OCAML F# и cуровый Erlang.
      C F# всё уныло и собственно никакого интереса не представляет. Ну говно как говно, и что?
      http://ideone.com/7P6YAup

      Забавно другое в шарпе поступили мудро там нельзя! писать иначе как Enumerable.Range(int a,int b)
      Неудивительно что в скором времени нашлись забавные поциенты которые взялись и "решили" эту "проблему":
      http://www.c-sharpcorner.com/uploadfile/b942f9/dealing-with-ranges-of-numbers-in-C-Sharp
      Ответить
      • А Ерланг тот падает в рантайме - отличный выбор для надежных распределенных систем:
        "Вы узнаете об ошибке во время выполнения программы."

        http://ideone.com/BG9EXu
        Ответить
        • /me пошёл за попкорном
          Ответить
          • ИСЧХ в этом треде обосрались строго функциональные - F#, Haskell, Lisp.
            Репутацию Лиспа и Хацкеля подправили красивые дроби
            А вот Scala и Erlang зашкварены особо .
            Ответить
        • Erlang предполагает, что все аргументы функции list:seq являются целыми числами
          http://www.erlang.org/doc/man/lists.html#seq-3
          Интересно, чего вы ожидали от языка с динамической типизацией...
          Ответить
          • Это я понял. А как ошибки компиляции?
            А ладно. Я теперь понял суть названия ErrLang.
            Ответить
            • Он разве не интерпретируемый?
              Ответить
              • Компиляется в байт-код, выполняемый на виртуальной машине beam.
                Ответить
              • Просто меня смутили типы в описаниях функций. Зачем они?
                Ответить
            • Какие ошибки компиляции? аннотации типа в документации приводятся для программиста, а не для компилятора, в сорцах (видимых компилятору) они не фигурируют. Для проверки типов по аннотациям в erldoc (также не обязательных) есть отдельный инструмент - Dialyzer.
              Ответить
              • ясно. спасибо.

                В итоге незашкваренными оказалась: Ада, С#
                Более-менее нормально генераторы работают в Руби, Груви, Баше и PHP
                Ирланг, Пёрл и Путхон - динамика, но флоаты не разрешают.
                Остальные - зашкварены в той или иной мере.
                Ответить
            • Валить процесс при первой неприятности - это часть идеологии. Это вам не php, который поделит на 0 и, быть может, напишет по этому поводу ворнинг. Программы на эрланге под otp, как правило, организуются с участием дерева супервизоров - иерархии пастухов, следящих за жизнеспособностью рабочих процессов. Если кто-то свалится с ошибкой, её бережно запишут в журнал и поднимут новый рабочий процесс (или вырежут всё "стадо", породив вслед новое).
              Ответить
              • Хм. Интересно, причем вдвойне, потому что я на жабе недавно писал такую многопоточную шнягу fail-fast-and-retry.
                Спишем это на мои крайне низкие познания.
                При таком подходе - это хорошо что оно падает. Недетерминированый float-код не сможет выполнится.
                Ответить
                • Если бы мне пришлось писать многопоточный распределённый сервер, я бы выбрал эрланг не задумываясь, там для этого уже давно созданы весьма удобные фрэймворки, большая часть работы осуществляется конфигурацией и определением коллбэков.
                  С другой стороны, для какой-либо другой задачи я бы брать erlang не стал.
                  по сценарию должен придти @wvxvw и обосрать изделие шведских телекомовцев
                  Ответить
                  • >или вырежут всё "стадо"
                    У меня возникли проблемы с этим. В жабе concurent фреймворк написан замечательно (в сравнении с другими частями стандартной либы он превосходен).
                    Но лажа в том что никак нельзя остановить треды, которые сами не хотят останавливаться.
                    http://ideone.com/v9K21C
                    Да и в Thread Api всё задепрекейтили.

                    И еще неочедидный и часто заёбывающий InterruptedException приправленый spurious wakeupами на линукс-системах.

                    Какое нормальное решение этого вопроса, как правильно останавливать треды, на примере того же эрланга?
                    Ответить
                    • >приправленый spurious wakeupами
                      Что означает?
                      Ответить
                      • О. Это чудесная трабла с которой ты столкнешься используя java-треды только в диких условиях. Ты знаешь что тред должен выйти по InterruptedException, тестишь код на винде или соляре - всё заебись.
                        Но вот только иногда (из-за специфичности потоков на некоторых ос) оно возникает случайно.
                        Зачем так сделано - хуй знает. Может перестраховка от дедлоков, но твой тред отваливается с прерыванием по непонятной причине - хоть его никто не прерывал.
                        О проблеме кстати в документации написана только 1 строка.
                        Ответить
                    • Может, я чего-то не понял, но можно хранить флажок running в самих callable и организовать некий интерфейс передачи им сообщения "закругляйтесь, ребята". Другого выходя я пока не вижу.

                      В эрланге другая модель - легковесные процессы (шедулящиеся в юзерспейсе), не имеющие общего состояния, и асинхронная передача сообщений. Функционал супервизоров там из коробки. Уронить процесс безусловно там можно всегда функцией exit(Pid, Reason). Но вызывается она в основном из системного кода.
                      Ответить
                      • > но можно хранить флажок running в самих callable и организовать некий интерфейс передачи им сообщения "закругляйтесь, ребята"
                        Ну так можно поступить - если ты это контроллируешь .
                        Трабла в том что код который в Callable небезопастный - его пишут другие люди. Или он может юзать Blocking IO, например
                        Ответить
                        • К сожалению, у этой проблемы нет простого решения. Во всяком случае, я его не вижу. Нужно приучать всех писать в задачах код, время от времени проверяющий, стоит ли вообще что-то делать.
                          Замахиваешься на асинхронность - жертвуй. В том же Node.js получаются трёхэтажные конструкции с коллбэками к коллбэкам именно из-за того, что нельзя зависать в блокирующих операциях.
                          Ответить
                        • Запускай не надежный код в отдельном домене\процессе
                          Ответить
                  • Так а кто ж говорит, что не будет работать? Работать будет замечательно, просто опеределение работы будет другим. Активное ничего не делание - тоже, по-своему, работа.
                    Все равно никто никогда не запустит ничего серьезного на Эрланге, а на полсотню-сотню пользователей, и не на таком говне слепить можно. Даже сами разработчики этого никогда не делали, и большая часть ихней инфраструктуры написана на сях, Эрланг - для не принципальных моментов.
                    Ответить
      • А че он сразу шарпоблядский-то? На самом деле этот ваш шарп окамлоблядский. Учите историю.
        Ответить
      • поржал с этого:
        Print(Range.Double(2.5, 6.5, 0.4)); // fails to give final value!
        Print(Range.Double(2.5, 6.51, 0.4)); // adjusted to do so

        таких изобретателей надо высылать на урановые рудники
        Ответить
        • Ну да, даже в PHP подгонку делают внутри Range, а не заставляют заниматься этим пользователей.
          Ответить

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