Артемий Трегубенко: «…Вот, собственно говоря, недостатки цикла for: он объединяет в себе по меньшей мере три разновидности операций, и фокусирует внимание на второстепенной детали — прохождении последовательности (индексов) значений. Но на самом деле, свёртывание, преобразование и фильтрация — это три различных способа обработки списка и они должны восприниматься по-разному…»
Сегодня Эллиотт Расти Харольд (Elliotte Rusty Harold) опубликовал свои сомнения по поводу возможных изменений. Один из главных заданных им вопросов: “Почему вы ненавидите цикл for”(«Why Hate the for Loop?»)?
Я не знаю, что заставляет людей так страстно мечтать об избавлении от циклов for. Это не первый и даже не второй раз, когда теоретики от мира computer science восстают против них.
Листинг 1. Простейшее замыкание.
3.times {puts "Inside the times method."}
Результаты:
Inside the times method.
Inside the times method.
Inside the times method.Здесь times — метод объекта 3, он исполняет код замыкания три раза.
и есть замыкание. Это анонимная функция, которая, будучи переданной методу times, выводит строку “Inside the times method.” на печать. Данный код является куда более ясным и простым, нежели его альтернатива с применением цикла for:{puts "Inside the times method."}
Листинг 2. Цикл без замыканий.
for i in 1..3 puts "Inside the times method." end
Я не стану обсуждать претензии Эллиота к коду, написанному на языке Ruby — эта тема не стоит выеденного яйца. Я также обойду стороной как споры о синтаксисе, предложенном для замыканий в Java, так и вопрос о том, вписываются ли они в этот язык на текущей стадии его развития. Я не интересуюсь этим вопросом, и, честно говоря, мне не важно, когда и как эти проблемы будут разрешены, и будут ли они разрешены вообще.
Тем не менее, Эллиотт поднимает действительно важный вопрос: “Почему вы ненавидите цикл for”?
Вот вам распространенный пример:
double sum = 0;
for (int i = 0; i < array.length; i++) {
sum += array[i];
}
Желаете доказательств? Пожалуйста, привожу вам следующий же пример из статьи Эллиотта:
String s = "";
for (int i = 0; i < args.length; i++) {
s += array[i];
}
Если бы у вас была возможность написать простой цикл for в одну строчку, с меньшим количеством символов, его было бы гораздо легче прочесть. Потому что более краткая форма записи ведет к куда как меньшей вероятности возникновения ошибок в коде, и, когда они все-таки появляются, их (в основном) гораздо проще отловить.
Как в этой ситуации могли бы помочь замыкания? Вот вам первый пример на Haskell:
total = sum array
total = foldl (+) 0 array
s = concat array
s = foldr (++) [] array
Два приведенных выше примера показывают, как можно взять список и свернуть его в один элемент. В мире функционального программирования подобные операции называются свертками. Для своей работы свертка принимает функцию (замыкание), начальное значение (прим. переводчика: далее по тексту — “аккумулятор”) и посещает первый элемент списка. Замыкание применяется к аккумулятору и первому элементу списка, результат кладется в аккумулятор. Затем свертка применяет замыкание к обновленному значению аккумулятора и второму элементу списка. Этот процесс продолжается вплоть до конца списка, когда последнее значение аккумулятора и становится результатом применения свертки.
Вот наглядное объяснение:
s = foldl (+) 0 [1, 2, 3]
= foldl (+) (0 + 1) [2, 3]
= foldl (+) 1 [2, 3]
= foldl (+) (1 + 2) [3]
= foldl (+) 3 [3]
= foldl (+) (3 + 3) []
= foldl (+) 6 []
= 6
Разумеется, свертки являют собой очень примитивные операции, и было бы весьма неразумно выбросить за борт циклы for и заменить их различными fold-образными “заклинаниями”. Вместо этого, более высокоуровневые операции, такие как sum, prod и concat, определены в терминах сверток. Вы, в свою очередь, программируете уже в терминах данных высокоуровневых операций, получая более сжатый код, код, который гораздо проще прочесть, написать и понять.
Однако не каждый цикл представляет собой сворачивание списка в один элемент. Рассмотрим следующий пример:
for (int i = 0; i < array.length; i++) {
array[i] *= 2;
}
new_array = map (*2) array
Третья разновидность циклов for — фильтрующие циклы. Рассмотрим пример:
int tmp[] = new int [nums.length];
int j = 0;
for (int i = 0; i < nums.length; i++) {
if ((nums[i] % 2) == 1) {
tmp[j] = nums[i];
j++;
}
}
odds = filter (\i -> (i `mod` 2) == 1) nums
odds = filter odd nums -- более верно
Если замыкания не являются эзотерическим инструментом, но глубоко встроены в язык и его стандартную библиотеку, нам не нужно возиться с этими низкоуровневыми операциями (прим. переводчика: здесь имеются в виду map, fold и filter). Вместо этого, мы можем создать высокоуровневые операции, с говорящими названиями, например sum или product.
Кроме того, работа с подобными терминами помогает гораздо легче понимать более сложные операции, такие как преобразование дерева (mapping a tree), фильтрация вектора (filtering a vector) или свертывание списка в хэш (прим. переводчика: не совсем понятно, что имел в виду автор под словами “folding a list into a hash” — сворачивание списка в одно-единственное значение, или функцию получения хэш-таблицы из списка кортежей, имеющуюся в стандартной библиотеке).
В конце концов Эллиотт поразводил руками на тему параллельного исполнения кода на нескольких ядрах, и посетовал на то, что код
3.times {...}
почти наверняка будет параллелиться хуже, чем аналогичный цикл for. Мне кажется, что он упускает из виду одно обстоятельство. Да, есть вычисления, которые должны выполняться последовательно, есть и такие, которые могут выполняться параллельно. Но отделение одних от других является для компилятора сложной задачей, если единственный используемый вами инструмент — цикл for. Если же вы можете разделить последовательные вычисления (то бишь foldl и foldr) и (возможно) параллельные (map и filter), то, тем самым, вы серьезно упрощаете задачу компилятора. Более того, вы даже можете явно запросить последовательную или параллельную версию map, если вы знаете природу обрабатываемых вами данных лучше, чем компилятор.
Артемий Трегубенко: «в спорах покусанных с собаководами нередко поднимается тема обязательного экзамена на умение обращаться с собакой, и вот это начинает становиться реальностью»
Dog owners in Germany are bracing themselves for the introduction of a license which would require passing written and practical tests and could cost hundreds of euros.
Authorities in Lower Saxony passed a law last year requiring owners to prove their basic knowledge about dogs and for the pets to pass a behaviour test. Berlin may follow suit. The Lower Saxony measure takes effect in 2013, although people who can prove they have owned a dog for at least two years since 2003 will be exempt. Owners will be tested on their knowledge of dog owner rules and of dogs' needs in general. A practical test of the animal, which can be completed by a veterinarian, will also be required to show that the pet is socialized and not dangerous. The rule also requires dog owners to have liability insurance for their pets and that dogs have an identification chip inserted under their skin. Lower Saxony's agricultural ministry expects dog owners will have to pay around €350 to €550, depending on how much the vet charges, ministry spokesperson Natascha Manski told The Local.
Now Berlin’s authorities, having recorded significant increases in dog bites over the past few years, are working out how to introduce similar licensing rules. The number of dog bites reported to authorities rose by 44 to 704 last year, compared to 2010 – a six percent increase. That follows a 30 percent rise in 2010 over 2009. "That is clearly an alarm signal," Claudia Hämmerling, the animal rights spokeswoman for Berlin's Green party, told the Tagessppiegel newspaper. She noted that of the 704 bites reported, just 32 were attributable to ‘attack’ dog breeds. Hämmerling, herself the owner of a Staffordshire Bull Terrier, is working to get a licensing rule similar to that in Lower Saxony through the Berlin state government.
Under the bill being discussed dogs would be divided into three categories based on size and breed. Attack, hunting and herding dogs would be required to pass additional tests based on the breed's character. There has been much discussion about the costs, the paper noted. Prices for the written exam would be around €25 and between €50 and €75 for the practical test.
Hämmerling, who met dog owners on Tuesday evening, said cooperation among the interested parties had been "superb." She did say that many were worried their beloved pet might be taken away if they fail to pass the test. The Green party politician said she assured owners that the aim of the law was not to separate dog owners from their pets but to make sure people who own canines are responsible. Asked whether someone would fail if their dog did not come on command, Hämmerling giggled and said: "Whose dog comes on command?" The idea is to show that the dogs are socialized and not a danger to people.
Артемий Трегубенко: «простенькая антиутопия с любопытной задумкой: деньги не так важны, как время, поэтому давайте использовать его в качестве валюты. Фантастическое допущение, что время собственной жизни отмерено до секунды, и его можно получать или передавать, кажется натянутым, но в целом вышло умеренно интересно.»
Артемий Трегубенко: «хороший закон в Индии»
Germany’s pharmaceutical giant Bayer has made history by being the first firm ordered to give up control of a patented drug after an Indian court said its cancer drug Nexavar was too expensive. The drug, used to treat liver and kidney cancers, is currently sold at more than €4,000 (284,428 Rupees) for a month’s supply of 120 tablets – well beyond the financial reach of most Indian patients. Generic drugs company Natco took Bayer through the Indian courts to win a license to produce cut-price copies of the drug. It said in a statement it would sell the drug at less than €134 (8880 Rupees) a month.
The Indian Patents Act rules that drugs unavailable at affordable prices must be compulsorily licensed after three years of patent approval, the Times of India newspaper reported on Tuesday. Under the agreement, Natco will pay Bayer six percent royalties on sales, but Bayer is determined to continue fighting the decision if possible. This was decided on Monday, a spokeswoman for Bayer confirmed to The Local. “We are very disappointed and will be checking out legal options,” she said.
Indian Patent Controller PH Kurian said Bayer had priced the drug “exorbitantly,” making it “out of reach” of most Indian patents. The case will be watched carefully by other pharmaceutical firms keen to protect their patented drugs and the high prices they can demand for them. Under the World Trade Organization's TRIPS Agreement, which governs trade and intellectual property rules, compulsory licences are a legally recognised means to overcome barriers in accessing affordable medicines.
The decision was welcomed by Medecins Sans Frontieres (Doctors Without Borders), whose policy director Michelle Childs said it, “serves as a warning that when drug companies are price gouging and limiting availability, there is a consequence.”
недавно я впечатлился интересным развитием идеи двоичных наручных часов вроде вот этих. Такие часы не показывают привычные арабские цифры. Тут используется вариант двоичной записи чисел: набор точек, некоторые из которых светятся. У каждого числа свой набор светящихся точек. Думаю, после месяца использования значение считываешь уже автоматически.
но что, если такой подход применить и для букв? Каждой букве можно назначить свой набор точек. Поскольку буквы практически не используются поодиночке, а преимущественно в группах-словах, тут получается интересный результат. Каждое слово превращается в маленькую пиксельную картинку. Этакий пиксельный иероглиф. Но, в отличие от настоящих иероглифов, тут каждая буква — по-прежнему буква, и незнакомую картинку всегда можно прочитать по частям.
про иероглифы давно известно, что они воспринимаются мозгом как целостные картинки. Позже выяснили, что у взрослых людей то же самое происходит и со словами, записанными буквами. Благодаря этому текст можно довольно легко читать даже тогда, когда соседние буквы переставлены местами, о чём год-два назад по интернету широко гулял текстик. Ну а двоичные буквы ещё больше упрощают эти картинки.
было бы интересно почитать результаты исследования на скорость и качество восприятия таких текстов по сравнению с другими письменностями. Хотя очень маловероятно, что эта идея приживётся, всё-таки писать такие буквы вручную довольно неудобно.
а ещё я бы посмотрел, что с таким алфавитом сделали бы дизайнеры шрифтов : )
Артемий Трегубенко: «местами нарочитый, но хороший мультик для кошколюбов»
Артемий Трегубенко: «люблю комедии со Стивом Мартином, они вроде незатейливые, но хорошие»