- 1
- 2
- 3
- 4
- 5
- 6
- 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]
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+132
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
http://ideone.com/9HQgCW
Забавный факт, но Хаски считает, что -1/0 > 0/0
Суть:
http://ideone.com/92PHF2
http://liveworkspace.org/code/bb5d5a7fb37f6fc7555a03d49a1c517e
[a .. b] => for (i=a; i<=b; i++);
[a, b .. c] => for (i=a; i<=c; i+=(b-a))
[25, 25 .. 25] отлично вписывается в схему. А вот про 30.5 действительно непонятно.
Всё правильно.
Человеческое мышление оно ведь инерционно и сразу думает в случае: 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
Хотя надо курить доку, вдруг так и задумано.
http://ideone.com/TAY8A0
Наверное округляет в инты неправильно. Строгая типизация и явные задания типов тут рулят.
http://ideone.com/HZoCdY
Хммм... а это мысль.
Походу да: http://ideone.com/nKJ7er
Возможно, что он делит длину диапазона на размер шага, и считает сколько нужно сделать шагов. Вот в этот момент и происходит то самое округление не в ту сторону.
P.S. По идее тут надо делать floor а не round... Но судя по результатам там таки round.
Хацкил - очевидный язык.
Непонятно только какого хрена там round.
>какого хрена там round.
говно. хотя может они так перестраховаться от плавающей точки решили.
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 говорят "Beware enumerating floating point numbers"
Могли ведь просто запретить float и оставить дроби - было крайне кошерно. А хацкель был бы единственным языком который корректно работает с рациональными числами.
Нет, хотим говнячить Float и Double и делать хаки с округлением.
PS. Мне так и не удалось сломать Ratio Integer.
Совсем от флоата и дабла избавляться не стоит. Есть много задач где их точности вполне достаточно, и при этом важна скорость вычислений. А вот из класса Enum их вполне можно было выкинуть. Ну какие они к черту перечисляемые?
Так никто об этом не говорит. Надо просто поубирать их из чисто дискретных аспектов и функций.
Но только теперь язык не виноват в том что ты берешь пистолет и стреляешь себе в ногу.
Ада же не дает range по флоатам, как тут сказал Тарас -
>Выбирая такое неточное говно, как Float, ты уже подписываешься на то, что тебе пофиг точность.
http://govnokod.ru/11979
Сам написал говноцикл - сам и разруливай.
http://habrahabr.ru/post/153659/
А если читать файл надо не "для поиграться", а по-настоящему - есть модуль ByteString, в котором все работает побыстрее Prelude'ского hGetContents (читает чанками), кушает меньше памяти, и есть версии с ленью и без нее.
Рекомендую запустить в коносли:
Это из-за FPU, его баг если хотите.
Это давно известная херня и так ведут себя все языки:
http://ideone.com/hU0BGx
http://ideone.com/hVR0Qw
Другое дело что хацкель гордовитый своей сверхвысокоуровневостью мог бы и обойти такое поведение.
Но хацкил хочет быть выше этого.
Более подробная информация :)
М-м. Божественно.
ideone.com/pXIhvY
> Достаточно просто изменить нашу вселенную убрав из нее состояние
Ох уж мне эта трёхмерная крестоимперативщина.
Бесконечноразрядный компьютер вселенной тик за тиком раскрывает бесконечный ленивый персистентный вектор иммутабельных состояний пространства-времени.
Иначе как, по вашему, работает машина времени?
Если не заныкать ссылочку на предыдущее состояние - никак. GC ведь уберет все ненужное, и возвращаться будет некуда.
У бесконечноразрядного компьютера вселенной бесконечное количество оперативной памяти, GC там не нужён.
Память освободит вселенская операционная система при завершении программы...
GC - это Большое сжатие.
>Иначе как, по вашему, работает машина времени?
Она порождает новый вектор? Ведь старые состояния нельзя изменить.
Я тут на стороне Эйнштейна. Хаос не потому хаос, что он не определяется детерминированными законами, а потому, что законы эти чрезвычайно чувствительны к входным данным (правда, это должно означать, что наша судьба, поступки и мысли полностью определены заранее :[).
> Она порождает новый вектор?
Именно, рождается новая ветвь бытия
>правда, это означать, что наша судьба полностью определена заранее
Да. Я бы тоже был полным сторонником такого .
Если бы не одно НО! - принцип неопределенности гейзенберга.
Но ведь каждую из сопряжённых величин мы можем измерять с достаточной точностью, проблемы возникают лишь при наблюдениях за несколькими величинами одновременно
лол, упираемся в дискретное время вселенского процессора
Например:
*Функтор. Крестобляди считаю, что это функциональный объект. Почему? Функтор из теории категорий: отображение одного множества на другое.
*Каррирование. Крестобляди считают, что это bind. В то время как на самом деле bind - это частичное применение/биндинг. В то время как каррирование/декаррирование - это преобразование функции принимающую несколько параметров в функцию принимающую кортеж и обратно.
И таких моментов много. Почему так?
functor - 0 вхождений в документ стандарта
function object - 59
curry/сurrying - 0 вхождений
binding - 46
Самая суть говнистости хацкила.
Хотя с NaNами мне тоже понравилось.
http://ideone.com/KjeLmf
Смачно вбросил. Уважуха.
Почитай, может найдется, что покритиковать или дополнить.
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
Съезд. В пыхе ведь всё гораздо лучше.
Ситуацию усугубляет то, что они самые рьяные борцуны за чистоту и простоту кода, высокоуровневость и читаемость языка.
Шикарно
По-своему некрасива.
У нас есть выбор
а) по сути 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ы, а константы всегда можно выразить в виде дроби.
Грустно.
Ну кстати можно попробовать взять их код, убрать округление и посмотреть как ведут себя дроби при расчете количества итераций. Дабы понять - это сахарок или полноценные инты.
Повторюсь Float, Double там вовсе не нужны.
Нет-нет. Дроби это полноценные рациональные числа. Там же не зря пишется не просто Ratio, а Ratio a, где вместо a обычно подставляют Int (если уверен что не зашкалит) или Integer (труъ рационалки, ограниченные только памятью).
1. убрать Float, Double
2. убрать говнохак +1/2.
...
Хацкель снова рулит.
И вот свершилось! Сбылась мечта идиота!
http://25.media.tumblr.com/tumblr_m4vdb7JBM61qcbdv2o1_500.jpg
И всё илитные функцианальные языки соснулей у пхп. Какой позор.
htttp://ideone.com/BZ6lr5
В убогом пхп всё отлично работает по дефолту.
Решил проверить еще парочку языков, так, чисто для галочки.
И выяснилось страшное - быдлопыха работает правильней, чем илитные лисп и хацкель. Ха-ха-ха!
Главное факт: хацкель, а вместе с ним лисп соснули у пхп.
PHP выбор разработчиков-профессионалов для разработки высоконадежных систем, а haskell и lisp удел псевдоматематического безработного быдла.
Хотите знать что это?
Следите за анонсами в новостях.
А еще она дико тормознутая - пример ideone компилился больше минуты.
Так мало того оно на ideone работает по-другому чем у меня.
http://ideone.com/IoYR62
println (7.0 to 8.2 by 0.3);
выдает ArithmeticException.
Это пиздец, да.
PS. Тут есть ScalaGovno?
Компилится да, охренеть как долго.
Как и предполагалось выше:
>Ведь можно окрулять вверх не от половины, а от 0.99, например.
Тогда проблемный диапазон становится меньше.
Я не курил сырцы но нашел пример иллюстрирующий. И в руби наверное тоже так.
Вот кстати баш и руби
http://ideone.com/5tjYy6
http://ideone.com/ZZSbj1
http://ideone.com/2Yb8Fw
.999999 - нечестно ведь.
Вот у него то уж точно децималы в виде строк...
http://ideone.com/5tjYy6
Правда девяток многовато, но это наверное из-за того что в пыхе флоат, а баше дабл или вовсе 80-битный.
Хацкельные дроби c Int соснули:
http://ideone.com/PVn4Ug
Правда c Integer - нормал.
Int соснул - ничего не вывел.
Integer соснул - вывел элемент за пределами диапазона.
PHP wins again!
Но он на удивление банален
[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.
да он походу целочисленный
если кому хочется плавающей точки - предлагается написать самому
только вот мне никогда и целочисленной не доводилось захотеть
Шарпоблядский 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
Репутацию Лиспа и Хацкеля подправили красивые дроби
А вот Scala и Erlang зашкварены особо .
А ладно. Я теперь понял суть названия ErrLang.
В итоге незашкваренными оказалась: Ада, С#
Более-менее нормально генераторы работают в Руби, Груви, Баше и PHP
Ирланг, Пёрл и Путхон - динамика, но флоаты не разрешают.
Остальные - зашкварены в той или иной мере.
Спишем это на мои крайне низкие познания.
При таком подходе - это хорошо что оно падает. Недетерминированый float-код не сможет выполнится.
С другой стороны, для какой-либо другой задачи я бы брать erlang не стал.
по сценарию должен придти @wvxvw и обосрать изделие шведских телекомовцев
У меня возникли проблемы с этим. В жабе concurent фреймворк написан замечательно (в сравнении с другими частями стандартной либы он превосходен).
Но лажа в том что никак нельзя остановить треды, которые сами не хотят останавливаться.
http://ideone.com/v9K21C
Да и в Thread Api всё задепрекейтили.
И еще неочедидный и часто заёбывающий InterruptedException приправленый spurious wakeupами на линукс-системах.
Какое нормальное решение этого вопроса, как правильно останавливать треды, на примере того же эрланга?
Что означает?
Но вот только иногда (из-за специфичности потоков на некоторых ос) оно возникает случайно.
Зачем так сделано - хуй знает. Может перестраховка от дедлоков, но твой тред отваливается с прерыванием по непонятной причине - хоть его никто не прерывал.
О проблеме кстати в документации написана только 1 строка.
В эрланге другая модель - легковесные процессы (шедулящиеся в юзерспейсе), не имеющие общего состояния, и асинхронная передача сообщений. Функционал супервизоров там из коробки. Уронить процесс безусловно там можно всегда функцией exit(Pid, Reason). Но вызывается она в основном из системного кода.
Ну так можно поступить - если ты это контроллируешь .
Трабла в том что код который в Callable небезопастный - его пишут другие люди. Или он может юзать Blocking IO, например
Замахиваешься на асинхронность - жертвуй. В том же Node.js получаются трёхэтажные конструкции с коллбэками к коллбэкам именно из-за того, что нельзя зависать в блокирующих операциях.
Все равно никто никогда не запустит ничего серьезного на Эрланге, а на полсотню-сотню пользователей, и не на таком говне слепить можно. Даже сами разработчики этого никогда не делали, и большая часть ихней инфраструктуры написана на сях, Эрланг - для не принципальных моментов.
таких изобретателей надо высылать на урановые рудники