- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
>>> r=range(16);print '\n'.join(' '*y+' '.join('# '[x&y>0] for x in r) for y in r)
# # # # # # # # # # # # # # # #
# # # # # # # #
# # # # # # # #
# # # #
# # # # # # # #
# # # #
# # # #
# #
# # # # # # # #
# # # #
# # # #
# #
# # # #
# #
# #
#
1. Почему f(x, y) = 1-sign(x&y) даёт в результате треугольник Серпинского?
2. Олимпиада: на вашем любимом языке написать программу, которая выводит аналогичный фрактал(см. код). Победит тот язык, программа на котором займёт наименьшее число символов. Нулевое приближение на Python - 78 символов.
71 символ. Я уверен, что на каком-нибудь J это заняло бы 10 символов.
Первый вопрос более актуален.
И за это всего 8 плюсов. А ху еть.
Кокой багор )))
Scala, 82 символа. Если бы было неявное приведение Int => Boolean, можно было бы без if..else. Скобки в выражении тоже вынужденная мера
Немного короче, но все-таки multiple-value-bind уж очень длинное название :)
Вот, как надо было!
Относительно сабжа, скорее, возможность несложно создавать "комбинаторные" edsl.
Сорт оф прув: http://projects.haskell.org/diagrams/gallery/Sierpinski.html
Имхо хаскеле-вариант смотрится читабельнее, чем что-нибудь вроде:
На языке s===(s|||s) могут читать только японские дети дошкольного возраста, но они поймут ету записть как "мой покемон сильнее твоих двух покемонов". Как инструкцию начертить треугольник Серпинского - ни один человек никогда это не воспримет, даже на секунду сомнение такое не возникнет.
Претензия понятна, но в рамках конкретной библиотеки часто используемые бинарные ф-ии задать в виде операторов - вполне приемлемо
(+ в данном случае акцент на равноправность аргументов).
Да и глазу проще цепляться при наличии операторов (перебор, конечно, нежелателен).
если вы заподозрили иронию, вы не ошиблись
Тем не менее, у каждого лиспа, дожившего до наших дней, очень много недостатков. Scheme мне нравится, но отсутсвие макросов и системы модулей делает её малопригодной для серьёзных проектов. Common Lisp очень мощный, но меня отталкивает семейство lisp-2, они гораздо менее элегантные, чем lisp-1; отсутствие элементарного функционала в стандарте, а взамен куча бесполезного хлама, запутанная система пакетов. Удручает, что бинарные версии программ тянут тяжеленный рантайм.
Clojure - глоток свежего воздуха, но он, на мой взгляд, ещё слишком медлителен и жрёт слишком много памяти, + ограничения, наложенные жаба-машиной.
Haskell тоже далеко не идеален, но на фоне современных лиспов он выглядит как свинченная болтами металлическая конструкция на фоне шаткого строения, скреплённого изолентой и степлером.
Если по лиспам ещё были какие-то аргументы, то про Хаксекель вы просто расчувствовались. В программировании в частности и в точных науках в целом - нет места чувствам. Лучше бы аргументы привели.
Ну, недостатки я уже приводил, да и достоинства тоже не раз. Достаточно высокая производительность и относительно низкое потребление памяти, наличие большого количества библиотек (структуры данных, парсеры, обработка текста, коннекторы базы данных, STM, etc.), высокая степень повторного использования кода, лаконичный и мощный синтаксис, мощная система типов, ленивые вычисления.
C++
>> наличие большого количества библиотек
C++ (Boost, Qt, OpenMP)
>> высокая степень повторного использования кода
С++ (крестошаблоны)
>> лаконичный и мощный синтаксис, мощная система типов, ленивые вычисления
Блин, так и знал, что кресты говно. Куда же без мощной системы типов и лаконичного синтаксиса.
ускоряет и разработку, и доработку, и конечный машинный код
Но у них цель немного другая:
1) Бинарная совместимость - даже если добавили/убрали поля в приватной части, но не поменяли публичный интерфейс - dll/so все равно остается бинарно совместимой. Без pimpl - однозначная пересборка всех, кто юзает dll'ку.
2) Скрытие в приватную часть засирающих всё что можно инклудов (типа windows.h).
Ради этого pimpl и юзают тролльтехи в том же Qt.
однако (не могу сказать за всех, конечно), в нашей конторе так сложилось, что самообновляющийся проект в поле у заказчика практически всегда реинсталлит себя (удаляет предыдущую установку, ставит новые бинарники), сохраняя лишь настройки - в т.ч. и потому, что положено по тз ставить версии в обратную сторону
а раз так, то бинарная совместимость - слабое требование, если её не будет, никто не опечалится, и дллки все сплошь крестоблядские с трехэтажными шаблонами, где надо
Имхо он имеет право на жизнь только в либах, которые юзают во многих-многих проектах, типа того же Qt. Было бы довольно неприятно обновлять все KDE'шные и Qt'шные проги только из-за изменения минорной циферки в Qt/KDE либах.
P.S. А в винде почти всегда проще поставить нужные версии либ в папку с самой прогой, все равно 99%, что их у юзера нет.
А можно тут поподробнее.
Туда же старый баттхёрт от того, что в стандартной библиотеке не отражены связи между сущностями, отчего легко найти группы по пять функций делающих одно и то же.
Из-за высоких абстракций и мощной типизации порой возникают проблемы, столкнуться с которыми в старой доброй императивщине просто не придётся.
Тем не менее, haskell - очень интересный и мощный язык, который во многом приятнее и компактнее той же scala.
Если кратко - принудительная чистота кода и полный отказ от императивщины таки сильно мешают людям.
Всё та же старая песня. Ну это ж намеренно так сделали.
Я-то надеялся услышать какие-то фундаментальные проблемы всплывшие после детального ознакомления, или непродуманности в дизайне.
Ну, будь какие-то очень серьёзные и нерешаемые проблемы, его бы так не любили.
На данный момент есть определённые проблемы с инфраструктурой, но в целом писать практичный, надёжный, переносимый и поддерживаемый код на Haskell на данный момент вполне можно.
Про проблемы от высоких абстракций тоже не очень понятно, что имелось в виду. Кроме проблем с вкуриванием, конечно :)
По остальным пунктам критика справедлива, да.
"symbolic operators take less visual real estate than alphabetic ones. That’s important for a parser because it lets you concentrate on the grammar at hand, instead of the combinators themselves...
(if we use alphabetic names) somebody new to combinator parsing could probably figure out better what the code is supposed to do."
Т.е. для людей, знакомых с dsl, код читается легче, для незнакомых - сложнее. Всё зависит от целевой аудитории. Лично я в основном за операторы: "лучше день потерять, а потом за 5 минут долететь" (с)
Улучшенная клавиатура для набора программ на Хаскелле
Особенно хорошо подходит тем, кому не терпится написать встраиваемый язык, а символов непечатных - не хватает.
Распространение таких клавиатур в среде любителей Хаскелла позволит исправить так же некоторые вопиющие недостатки в языке. Например, реализовать числа не цифрами (что за плебейство вообще?), а наборами из костяшек домино, или пермутациями кубика Рубика.
> пермутациями кубика Рубика.
Омг, сколько же там клавиш с ними.
Проблема в том, как запомнить какой как набирается ;)
Да можно и одной кнопкой набрать любой символ юникода. Морзе подтверждает.
Это я про Alt+ молчу.
official_brainfuck_keyboard.jpg
Например, хорошие игровые клавиатуры поэтому пишут, что можно нажать сколько угодно кнопок одновременно.
Обычные драйвера для Винды, например, не поддерживают корды больше четырех, или пяти кнопок, кажется. Но если пользоваться, например, ностромо с его драйверами, или какой-нибудь клавиатурой Стилсерис / Абисус и т.п. То можно и больше нажать. А то, что вы можете одной кнопкой набрать что угодн было еще очень давно проиллюстрировано Морзе.
Ясно. Пермутации - это очень правильное слово.
Но на стандартной 101-клавишной клавиатуре всего-лишь двумя зажатыми клавишами можно сделать 101*100=101000 комбинаций. Что уже больше означенных 6000.
И буфер клавиатуры IBM PS/2 32 байта кажись. Туда влезает вроде 16 символов. Так что хватит на всех.
А на символ выделяется 2 байта, что уже даёт 65K вариантов.
+ Я ошибся, когда инфу копировал, не 6 тысяч, а 60, но это роли не играет.
ЗЫ. Не, на всех не хватит, тот же ностромо может посылать одновременно все нажатые клавиши. Кроме того, он помнит, в каком порядке они были нажаты, итого получаем 15^15 примерно 2^58.
>очень давно проиллюстрировано Морзе.
морзянка не является префиксным деревом и поэтому в ней возможны неоднозначности и, соотвественно, набрать что угодно не получится
[/зануда-mode]
Невозможны. Там помимо - и . есть еще паузы между символами.
Крайне неоптимально, да. Тогда Шенон еще не родился. Кодинг Хаффмана и арифметический не изобрели.
Чего-чего?
Как можно вообще дать имена всем числам?
Можно всё сказать. Запросто.
Вот например. Четные числа, подмножество натуральных.
Можно поставить в соотвествие любому натуральному четное.
2-1, 4-2, 6-3, 8-4, 10-5, 12-6 итд.
Следовательно при помощи четных чисел можно пересчитать все натуральные.
Мощность множества. Есть такое понятие.
>но мы бы запарились давать имена до того, как заметили, что слов не хватает
Надо думать, прежде чем начинать что-то делать. Особенно когда трудоемкость равна бесконечности.
Пример:
1 - один.
2 - два.
3 - три.
(attention on deck, chief officer's on deck!)
Смысл вообще в чем: множество комплексных чисел - это множество первого порядка, а sparse алфавиты - это множество нулевого порядка, т.е. они не эквивалентны.
Теорема Кантора, блин :)
PS А. Еще знак забыл. Принцип тот же.
И значит эквивалентно это такому вот коду:
01
011
0111
01111
итд.
Где 0 - это пауза. А 1 - это наш унарный символ.
Завожу кодовую таблицу.
01 - 1
011 - 2
0111 - 3
01111 - 4
..
0111111111 - 9
01111111111 - .
011111111111 - "-"
0111111111111- i
Но они забывают о таком важнейшем элементе как пауза.
Так вот.
Хоть бы на вики штоле сходили.
Или как по-вашему люди этим пользовались?
Так вот кстати с этим была трабла при трансатлантической передаче.
Всё из-за интерференции сигнала и того, что разные волны имеют разную скорость распространения и коеф. поглощения средой - некоторые сигналы приходили раньше других. И на другой конец приходила всякая херня, из-за перекрытия пауз. Rase condition во всей красе.
Race. selffix
> только даже единиц достаточно
Без пробелов (нулей), недостаточно.
Энтропия тогда нулевая.
А то будет:
Ехал Морзе через Морзе
видит Морзе: Морзе, Морзе
Сунул Морзе Морзе в Морзе
Морзе Морзе Морзе Морзе
В скалке можно вводить операторы? А что там с ассоциативностью вновь введенных операторов и приоритетами?
[|, |]
{-, -}
Элсо по делу:
Идея хорошая. Жаль что в скалле не так. Я не уверен, но что-то мне кажется, что из-за перегрузок, приведения типов и наследования в совокупе это не сработает.
Элсо, как они делают это для операторов с одним аргументом? Ассоциативность влияет на такие операторы как-нибудь?
1)a.operator1(b); эквивалентно
a operator1 b;
2)a.operator2(); эквивалентно
operator1 a;
3)function1(a); эквивалентно a.function1();
Почему бы не сделать как-то так? Создатели Scala (Мартин Одесский и пр.) хоть в чем нибудь со мной согласны?
потрясающая пустотой своей фраза.
"На языке s===(s|||s) могут читать только японские дети дошкольного возраста, но они поймут ету записть как "мой покемон сильнее твоих двух покемонов". Как инструкцию начертить треугольник Серпинского - ни один человек никогда это не воспримет, даже на секунду сомнение такое не возникнет."
Да ладно? А название функции ни на какую мысль не натолкнет? К тому же что могут понять и дети, нормальному человеку тоже должно быть понятно.
Да, потому, что я сптопицот раз до этого написал, что монотонный код читается АХУЕННО! - именно на этом самом основании вы сделали такой вывод - вы должны собой гордится!
Операторы выглядят прекрасно при должном форматировании. К тому же, у них наверняка есть алиасы с читаемыми именами, что-то вроде
Представил как Линк вырезает мечом алгоритм решения на шкуре камнееда :)
Головоломка решена, дверца уровня открывается... :)
Толи просто я нуб, толи язык действительно заборитсый >_<. Но хоть чуток короче, чем пример с сайта на Haskell(291) и без монад - чисто функцильнально :)
https://ideone.com/HpK0kW
Оператор and не определён просто для чисел, но он определён для типов Unsigned_8, Unsigned_16, Unsigned_32 etc из модуля Interfaces.
Переменную y объявлять не надо: она создаётся в цикле. Её тип тоже указывать не надо, он выводится из диапазона. Диапазон (0..16) записан как одно выражение. Чтобы пройти его задом наперёд, есть слово «reverse».
(cond | a | b) это короткая запись для IF cond THEN a ELSE b FI.
Так это из «Algol-68» разработчики «Bash» взяли пары «if-fi», «case-esac» и тому подобные?
Вижу тернарник (cond | a | b).
Вижу объявления переменных, почти как в сишке, но всё же удобнее: скобочки у массива прилеплены к типу (почти как в «Паскале»), а не к переменной. Не нравится мне, как в сишке объявляются массивы, указатели на данные и указатели на функции.
Вижу довольно странную конструкцию «new line».
А BIN –— это такая же, как в языке «Ада», необходимость, чтобы получить доступ к битовому представлению?
Пробелы в идентификаторах игнорируются, а чтобы отличать операторы они пишутся КАПСОМ, или в типографике выделяются жырным.
> чтобы получить доступ к битовому представлению
Да, над INT побитовых операций нет, только над BITS, BIN как раз в них кастит.
https://github.com/aemkei/jsfuck
В языке «Ада» так не получится, потому что нужно явно вызывать функции преобразования типов.
https://ideone.com/F51LUj
А у перечислимых типов есть атрибут Pos, возвращающий порядковый номер значения. Например, Boolean'Pos(x > 5) вернёт 1, если x > 5, и ноль в противном случае (да, тут непарный апостроф).
Но кококококонкретно в данной задаче проще сразу объявить массив с индексом типа Boolean.
На мой взгляд «Оберон» получился игрушечным. Постоянное ощущение, что чего-то не хватает. А вот язык «Ада» получился слишком сложным, перегруженным. С другой стороны, язык «Ада» получился более логичным, последовательным, чем кресты и языки с крестоблядским синтаксисом.
Если тайпдефом сделаешь два производных типа от Integer, то переменной одного типа просто так не сможешь присвоить значение другого, пока явно не укажешь, что нужно кастовать:
А ещё она вербозная, но зато читается довольно легко.
Кстати, на «ГК» нет раздела «Ада», потому что на языке «Ада» говнокод не пишут!
Не в обиду будь сказано, я кажется снёс яичко...
Вот эти вот скобочки –— это так называемые «S-expressions» (для краткости их называют «sexp»):
https://en.wikipedia.org/wiki/S-expression
Был альтернативный вариант синтаксиса –— «M-expressions», однако, он не прижился:
https://en.wikipedia.org/wiki/M-expression
Мало того, что тупой синтаксис, так ещё и не компилируецца. Ради компилируемости я даже готов смириться с синтаксисом, так было с паскалью.
А в языке «Ада» средства предотвращения ошибок из коробки.