LINUX.ORG.RU

[история успеха] Я не осилил Perl :(

 


0

2

Я давно понял, что для автоматизации выполнения повседневных задач мне необходим какой-нибудь простой интерпретируемый язык с большой базой подпрограмм на все случаи жизни. В котором мне не придётся волноваться о выделении и освобождении памяти, указателях, грамотном ООП, синтаксических заморочках. Где не нужно продираться через многочисленные уровни абстракций, дабы понять в чём скрывается ошибка, насилуя трасcировщик и многократно перекомпилируя исходники.

В качестве такого языка я решил выбрать Perl. Благо, он позволяет большие вольности в оформлении программ, а книги по нему написаны простым и доступным языком. И поначалу всё было хорошо, пока я решал простенькие задачки и учебные примеры. Впрочем, никаких практических навыков подобное обучение не давало и все полученные знания быстро вылетали из головы. Тогда я решил начать делать то, ради чего и взялся за изучение Перла - решать повседневные задачи. Мне показалось, что это лучший путь для освоения нового языка.

Беда пришла оттуда, откуда я её совсем не ждал. Я решил, по старой привычке, создать несколько структур данных, исключительно в целях организации кода. Но никакой отдельной главы, им посвященной, я в книгах не нашёл. Копнув глубже, я обнаружил, что в качестве структур данных в Перле используются хеши, причём их синтаксис, применительно к сложным структурам, меня абсолютно не обрадовал. Поначалу, я решил плюнуть на структуры данных и попробовать местные объекты, благо им, таки, была посвящена отдельная глава. Но, как я и предполагал, объектами оказались те же хеши, оформленные особым образом. Возвращаясь к ним, я с ужасом, обнаружил местные ссылки и оператор разыменования. Так же я понял, что без хорошей зубрёжки и многочасового вдумчивого чтения мне никогда не понять в каких случаях этот оператор работает; когда в коде стоит употреблять фигурные, когда круглые, когда квадратные скобки, а когда ещё ставить перед ними волшебные слова; в какой ситуации вместо двойной кавычки стоит употреблять одинарную; когда перед именем хеша стоит ставить %, а когда $ и в каком случае эти два одинаковых имени будут относится к двум совершенно между собой не связанным структурам данных. В принципе - всё это в книгах описано и через недельку я, наверное, в этом бы разобрался, а через пару лет практики даже перестал бы совершать связанные с этим ошибки, но, нет уж спасибо...

Так что я решил забить на Perl т.к. перестал понимать в какой ситуации его использование будет предпочтительнее чем применение связки C+Lua, тем более, что сложность их освоения, похоже, сопоставима. Большие надежды я возлагаю на Лисп, в особенности, если научусь вызывать из него программы с аргументами и парсить их вывод. И, возможно, стоит таки попробовать Питон. Я не ругаю Perl. Просто жалко, что его изучение, поначалу напоминавшее добрую сказку, под конец превратилось в какое-то жёсткое порно.

Ответ на: комментарий от geekless

Проблема не в циклах, а в общих правилах видимости.

Ну да, проблема в правилах видимости _цикла_.

(define lst (let ([n 10])
              (let loop ([lst '()])
                (if (= 0 n)
                    lst
                    (begin (set! n (- n 1)) 
                           (loop (cons (λ () (display n)) lst)))))))

(define lst2 (let ([n 10])
               (let loop ([lst '()])
                 (let ([x n])
                   (if (= 0 n)
                       lst
                       (begin (set! n (- n 1)) 
                              (loop (cons (λ () (display x)) lst))))))))

->

> (for ([f lst]) (f))
0000000000
> (for ([f lst2]) (f))
12345678910
> 
Если в реализации цикла для итератора вводится промежуточная переменная, то будет как во втором случае, если не вводится - как в первом. Если язык поддерживает итерации по коллекциям, то _должно_ быть как во втором случае. Но иногда язык делают идиоты, которые этого не понимают.

anonymous
()
Ответ на: комментарий от anonymous

Да, дыра в дизайне. В оправдание можно лишь сказать, что в руби циклы для итерации по коллекциям использовать не принято. Такой вариант работает как ожидается:

blocks = []
(1..10).each { |x|
	blocks.push proc { puts x }
}
blocks.each(&:call)

geekless ★★
()
Ответ на: комментарий от anonymous

А пример без циклов работает как, как он и должен везде работать.

Ты действительно считаешь, что

x = 0
b[0] = lambda : x
x = 1
b[1] = lambda : x

должно отличаться от

for i in 0, 1:
  x = i
  b[i] = lambda : x

?

anonymous
()
Ответ на: комментарий от anonymous

Должен признать, что товарищ geekless здесь прав. Дыра в дизайне. Самая натуральная. Но к счастью есть [функциональные] языки, где такой дыры нет. Для этого иммутабельность должна быть умолчательной, а мутабельность прописываться всегда явно.

Следующий код на Scala

val closures = for {
  x <- 0 to 10
} yield (() => print(x))

for (c <- closures) c()

вернет правильные и ожидаемые

012345678910
dave ★★★★★
()
Ответ на: комментарий от dave

Речь про перл, питон и руби, а ты притащил скалу сюда. Ну она совсем не к месту. Или ты решил удивить тем, что не во всех ЯП так сделано?

anonymous
()
Ответ на: комментарий от dave

Должен признать, что товарищ geekless здесь прав. Дыра в дизайне. Самая натуральная

Ну, не такая уж и натуральная:

>>> l = []
>>> for i in range(0, 2): 
>>>   l.append(lambda x = i: x)
>>> i = 2
>>> l[0]()
0
>>> l[1]()
1
>>> print i
2
tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Это зависит от семантики цикла в конкретном ЯП. Либо цикл производит присваивание для уже существующей переменной во внешнем скопе, либо вводит новую переменную во внутреннем. Причем для итерации, например, по списку, естественен именно второй вариант.

anonymous
()
Ответ на: комментарий от tailgunner

Создаем временную переменную (не силен в питоне)? Ну да, это сработает. Только выглядит такое все же ненатурально :)

dave ★★★★★
()
Ответ на: комментарий от dave

> Только выглядит такое все же ненатурально :)

Зато решает задачу, и выглядит кратко.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

Это никак не скажется на двух приведенных кусках кода, потому что замыкается там переменная x, а не i.

anonymous
()
Ответ на: комментарий от anonymous

Да, невнимательно посмотрел. Во втором варианте x = i следует убрать, либо надо поменять в первом варианте x на i а потом добавить иксы с локальным скопом.

anonymous
()
Ответ на: комментарий от anonymous

То есть вместо ответа на поставленный вопрос ты предлагаешь корректировать сам вопрос? Я не согласен.

anonymous
()
Ответ на: комментарий от Bad_ptr

все эти ваши функция2(функция1(переменная))

вместо переменнёая.функция1.функция2

qwerty013
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

Ну, при таком ответе на вопрос ты либо не знаешь, что такое цикл, либо предлагаешь сделать явную дыру в дизайне ЯП, пытаясь закрыть неявную дыру, которая собственно и не дыра в реальности.

P.S. Но ведь на ЛОР'е-то распоследний аноним может почувствовать себя крутым дизайнером языков программирования.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.