LINUX.ORG.RU

Parrot, или Почему мы долго ожидаем Perl 6


0

0

"Как известно, впервые Perl был представлен на суд общественности Ларри Уоллом (Larry Wall) еще в конце 1987 г. В последующие несколько лет язык бурно развивался, одна за другой выходили новые версии, и уже в 1994 г. программисты работали с Perl 5. Однако с тех пор прошло тринадцать лет, и хотя за это время появлялись очередные релизы, номер текущей версии по-прежнему начинается с пятерки. Значит ли это, что Perl идеален? Спору нет, он очень хорош, но и предела совершенствованию, как известно, нет. А одна из причин задержки шестой версии состоит в том, что в ней ожидается поистине революционное новшество - переход на новую систему промежуточного представления кода."

>>> Статья на itc.ua



Проверено: maxcom ()

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

> Теперь нам нечем ответить на "у вас нет многострочных лямбд"... ну как после этого флеймить в форумах? :(

Зато вы руби сможете лошить за медленную скорость работы :)).

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

> Или может признаете?

Эхма, чего не сделаешь ради вьюного фанатика Руби :-)

Так и быть, признаю:

"Насколько я помню, ни Руби ни Питон и близко здесь не стояли..."

(C) впрочем, я уже начинаю повторяться :-)

В общем, Ваш ход, вьюноша! С нетерпением ждем реализации ssalc на Ruby

:-)))

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

>> http://flamber.ru/photos/1164986712/

Блин, откопали ж... Вот поэтому и не люблю фоткаться -- всегда получаюсь неестественно.

> Но ты с таким запалом пишешь, что думал тебе лет 20 :))).

Что поделать, темперамент Наполеона... :-)

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

> В общем, Ваш ход, вьюноша! С нетерпением ждем реализации ssalc на Ruby

ssalc "ClassName" do |c|

  def c.method1
    # method body
  end

  def c.method2
    # method2 body
  end

end



так пойдет? :))))

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

> так пойдет? :))))

Не-а

-:1: undefined method `ssalc' for main:Object (NoMethodError)

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

> так пойдет? :))))

-:1: undefined method `ssalc' for main:Object (NoMethodError)

Кста, предыдущий пример был тоже очень ничего в плане демонстрации того, как важны невидимые символы в некоторых языках :-)))

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

> -:1: undefined method `ssalc' for main:Object (NoMethodError)

Синтаксис корректный, реализацию завтра выложу, сегодня уже неуспеваю.

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

> Синтаксис корректный, реализацию завтра выложу, сегодня уже неуспеваю.

Буду ждать...

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

> Синтаксис корректный, реализацию завтра выложу, сегодня уже неуспеваю.

Кстати, напоминаю: слово class и любые другие примочки использовать запрещено. То есть, задача в том, чтобы ввести в язык ООП средствами самого языка.

И еще хотелось бы, чтобы кроме методов были еще и данные. Если несложно.

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

> При частом использовании у тебя та же структура будет разбросана по всему коду.

Хотелось бы узнать, зачем мне собсна часто использовать такую структуру? Зачем непременно возвращаться в исходный каталог?
Может я как-то не так и что-то не то пишу, но мне пока такой паттерн особо не требовался.

Если уж ОЧЕНЬ приспичит делать врапперы для блоков кода, то:

def wrapper():
    print "wrap start"
    yield True
    print "wrap end"
    
for being in wrapper():
    print "inside"

> Ты мне кстати, еще ссылку на карри не привел.

А посос... всмысле, на гугле забанен?
http://en.wikipedia.org/wiki/Currying

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

> Почему объекты зло? Объекты - суть объединение кода и данных. А для этого уже есть замыкания, посему необходимо использовать их. Логично?

Нелогично. Объекты - более общая концепция. Замыкание - просто шорткат для более быстрого определения объекта. С одной стороны, это может быть удобным; но с другой - вводит излишние сложности во взаимоотношения объектов и функций.

Не надо плодить сущности. Оккам был толковый мужик, слушайте его.

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

> Объекты - более общая концепция. Замыкание - просто шорткат для более быстрого определения объекта. С одной стороны, это может быть удобным; но с другой - вводит излишние сложности во взаимоотношения объектов и функций.

Замыкания - более фундаментальная концепция. Объект - просто контейнер для более компактного описания множества замыканий. С одной стороны, это может быть удобным; но с другой - вводит излишние сложности (в виде лишней сущности -- объекта) во взаимоотношения функций.

> Не надо плодить сущности. Оккам был толковый мужик, слушайте его.

Правильно. Оккам был толковый мужик, слушайте его. Не надо платить новых сущностей в виде объектов, если уже есть замыкания.

Консенсус?

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

> Объект - просто контейнер для более компактного описания множества замыканий.

Нет. Эмулировать произвольный объект при помощи замыканий невозможно.

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

> А посос... всмысле, на гугле забанен?
> http://en.wikipedia.org/wiki/Currying

======== твой ранний пост ============
Кложуры нужны реже, чем это мечтается любителям лиспов и рубей. 

И при необходимости - элементарно эмулируются при помощи классов и карри.
======================================

А посос... тоесть посмотреть в Гугле нужно тебе:

======== из википедии ================
http://en.wikipedia.org/wiki/Currying
Creating closures in python:

def addN(n):
    return lambda x: x + n
======================================

Так вот, кложуры не элементарно эмулируются при помощи карри,
потому что карри реализовывается при помощи замыканий.

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

> Кстати, напоминаю: слово class и любые другие примочки использовать запрещено. То есть, задача в том, чтобы ввести в язык ООП средствами самого языка.

Я написал кошерную реализацию стороннего ООП для Руби. На это ушло несколько часов времени плюс предыдущий флейм занял немало. Хотелось бы получить сухой остаток.

Например ты создашь топик в Толксах с соответ. замечаниями. Ну насколько помню в топике про Лисп было показано, что Лисп зарулил. Теперь хотелось бы чтобы питоновцы написали что DSL в Руби рулит и Гвидо тупит с анонимными замыканиями.

Помоему будет честно? или нет? :)

Да, тогда в след. питоно-рубовских баталиях можно будет давать простую ссылочку на твой топик и не тратить силы программистов на непродуктивный флейм?

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

> Зачем? :) Но всё же - опубликуй ее.

Пришлось изменить первый вариант. Это первая реализация - по-сути кастом-синтаксис для создания классов в Руби: 

===================== 
$current_class = ""

# create namespace
My = Module.new
def My.const_missing(const)
  My.const_set(const, Class.new)
end

def ssalc(const, &block)
  $current_class = const
  yield
  # clear creator
  $current_class = ""
end

def defm(method_name, &block)
  $current_class.send(:define_method, method_name, block)
end


ssalc My::Test do
  defm :method1 do |par1, par2|
    puts "Method1 par1:: #{par1}, part2:: #{par2}"
  end

  defm :method2 do
    puts "Method2 withot parameters"
  end

  defm :what_is_your_name? do
    puts "My name is #{self.class}"
  end
end

obj = My::Test.new
obj.method1 1, 2
obj.method2
obj.what_is_your_name?

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

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

> Ниже сейчас выложу уже реализацию ООП поверх хешовых структур.

======================
$current_class = ""

# create namespace
My = Module.new

# fun part
class SmartHash < Hash
  def self.get_inner_method key, args=[]
    @inner_methods[key]
  end

  def /(key)
    self.class.get_inner_method key
  end

end

class Proc
  def [](*args)
    self.call *args
  end
end
# end fun part

class SmartHash < Hash
  @inner_methods = {}

  def [](key, *args)
    self.class.call_inner_method key, args
  end
  alias :% :[]
  alias :^ :[]
  alias :* :[]

  def self.call_inner_method key, args=[]
    @inner_methods[key].call *args
  end

  def self.add_method(method_name, &block)
    @inner_methods[method_name] = block
  end
end

def My.const_missing(const)
  My.const_set(const, SmartHash)
end

def ssalc(const, &block)
  $current_class = const
  yield
  # clear creator
  $current_class = ""
end

def defm(method_name, &block)
  $current_class.add_method(method_name, &block)
end


ssalc My::Test do
  defm :method1 do |par1, par2|
    puts "Method1 par1:: #{par1}, par2:: #{par2}"
  end

  defm :method2 do
    puts "Method2 withot parameters"
  end

  defm :what_is_your_name? do
    puts "My name is #{self.class}"
  end
end

obj = My::Test.new
obj[:method1, 1, 2]
# in Ruby 1.9 you can do it in this way: obj[:method1](1,2)
obj[:method2]
obj[:what_is_your_name?]
# fun part
(obj/:method1)[3,4]
obj^:method2
obj*:method2
obj%:what_is_your_name?

===============================

Пока что текущая ветка Руби 1.8, поэтому один из нормальных вариантов -
с помощью хешей obj[:method1, 1, 2] - первый аргумент метод, дальше аргументы.
В Руби 1.9 можно сделать даже так: obj[:method1](1,2), но оно выйдет
только в конце этого года.

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

=======================================
def curry(_curried_func, *args, **kwargs):
    def _curried(*moreargs, **morekwargs):
        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
    return _curried
=======================================

Функция внутри функции, захватывающая переменные из верхней области.
И снова замыкания?

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

> потому что карри реализовывается при помощи замыканий.

Карри - это одно из типичных применений замыканий.
Питонской поддержки замыканий вполне достаточно для его реализации.
Второе применение (аккумуляторы) - следует реализовывать через объекты.


Пример в википедии написан неправильный - это сильно частный случай.
Правильная реализация curry есть, например, в Django:

def curry(_curried_func, *args, **kwargs):
    def _curried(*moreargs, **morekwargs):
        return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
    return _curried

Кстати, в Ruby есть keyword arguments?

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

> Карри - это одно из типичных применений замыканий.

Тоесть ты уже понял, что карри без замыканий сделать нельзя, поэтому надеюсь, что ты понял абсурдность фразы о возможности реализовать замыкания через классы и каррри?

Ответ на твой код написал выше.

> Кстати, в Ruby есть keyword arguments?

Есть.

news = News :first, :conditions => "hide=0", :join => [:athours, :comments]

Ruby 1.9
news = News :first, conditions: "hide=0", join: [:athours, :comments]

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

Что значит произвольный объект? :/ 

sub mkcounter { 
    my $count = shift; 
    my $start = $count; 
    my $bundle = {
       "next"  => sub { return ++$count }, 
       "prev"  => sub { return --$count },
       "get"   => sub { return $count   }, 
       "set"   => sub { $count = shift  },
       "reset" => sub { $count = $start }, 
    };
    return $bundle; 
} 
$counter = mkcounter(20); 

И далее вызываем методы: 
$counter->{next}->(); 
$counter->{get}->(); 
$counter->{set}->(25); 

Чем не объект? Инкапсуляция в наличие, переопределять и добавлять методы очень просто.
С наследованием конечно облом, ну дык об объектах говорим, а не о классах.

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

> Чем не объект? Инкапсуляция в наличие, переопределять и добавлять методы очень просто. > С наследованием конечно облом, ну дык об объектах говорим, а не о классах.

+100

Прикольная реализация.

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

Фундаментов не знаете. Смотри Python, Lua.

Класс есть совокупность неймспейса, предка(ов) и имени. Экземпляр есть совокупность неймспейса и класса.

Практически в любом языке, где есть ассоцмассивы и first-class functions, возможно реализовать ООП своими средствами.

Вот только непонятно зачем. Питонское ООП пытается избежать магии, и доступ к неймспейсу объекта делает явным. А замыкания - они для пальцезагибания хороши, а ясности и удобства коду не прибавляют. Поэтому их использование следует сводить к минимуму.

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

> Класс есть совокупность неймспейса, предка(ов) и имени. Экземпляр есть совокупность неймспейса и класса.

Мудрёно как то излагаете. Тем не менее, локальный контекст функции-конструктора в примере с замыканиями - это по сути и есть неймспейс класса. Я даже представляю как можно добавить простенький механизм наследования к такой ОО модели. Функция может вызывать "родительский конструктор", который будет возвращать хеш с замыканиями. А внутри "дочернего конструктора" можно просто добавлять в этот хеш нужные функции. Может я чего то и упускаю, надо будет попробовать. Информацию об имени "класса" можно получать через тот же хеш.

> Практически в любом языке, где есть ассоцмассивы и first-class functions, возможно реализовать ООП своими средствами. > Вот только непонятно зачем.

Я с этим и не спорю. Действительно, зачем реализовывать ООП, если оно уже реализовано. Я оспариваю ваши слова о том, что с помощью замыканий полноценный объект вообще никак не получить. Пока что вы убедительных контраргументов не привели.

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

Может насчёт неймспейса я и не правильно выразился. Получается примерно так: интерфейс класса определяется возвращаемым хешем, а данные экземпляра - это сохраняемый в замыканиях локальный контекст функции-конструктора. Для обычного класса всё немного по-другому.

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

> Я оспариваю ваши слова о том, что с помощью замыканий полноценный объект вообще никак не получить.

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

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

Да, автомобилька не умеет вставать на дыбы и круто поворачивать, как мацацыкл. И тёлка с жопой на заднем сиденье менее эффектно смотрицо. Но это ж не значит, что автомобильки бесполезны и всем надо срочно прыгать на мацацыклы!

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

> Фундаментов не знаете. Смотри Python, Lua.

В луа очень убогий ооп. Он там вообще лишь бы считался.

Если хома неверующий еще не понял силу замыканий на отличном примере Hjorn'a, посмотри на библиотеку Prototype. Из прототайп-based к JavaScriptу прикрутили классические механизмы ооп: приватные переменные, наследование и т.п. Реализовано с помощью замыканий.

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

> Наследования нету, синтаксис коряв, прямого обращения к атрибутам, как понимаю, не позволяет...

У меня уже был мини холи-вор с ero-sennin'ым - твоим коллегой по цеху, насчет прямого доступа к атрибутам в питоне. Вобщем-то это не считается хорошим тоном лезть в кишки объекта напрямую. Для этого существует интерфейс.

В хороших языках это закрыто by design. Например в Руби. Доступ к объекту аля Смалтолк - посылаешь сообщение(вызываешь метод) - получаешь ответ - например значение атрибута.

Ты ограничен моделью ООП в питоне и думаешь что она единственно правильная. Проснись, правильной нет.

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

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

Опять такую фигню пишешь, аж плакать хочется. Есть такие языки Хаскелл и Окамль, только недобитый пионер вроде тебя будет кричать что Питон лучше их(или ты с этим согласишься? :))) ). Так вот в Хаскелле ООП нет... Представь себе нет. А замыкания - это __главный__ механизм языка.

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

У Окамля ООП есть. Но вот странно, когда читал описание этого языка, от человека использующего его в реальных проектах, он сказал, что ООП не нужен в Окамле и система типов (Хиндли-Миллера, как и в Хаскелле) отлично справляется со своей задачей.

Можешь глянуть на досуге http://ru.wikipedia.org/wiki/Модель_типизации_Хиндли_&#8212;_Милнера и выйти из маленького змеинно-лунного мирка, в котором ты живешь.

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

eugine_kosenko: Ну, вроде бы неглупый человек, а этим постом ты резко упал в моих глазах, просто можно сказать провалился. :) Повторяешь те же бессмысленные аргументы среднего питоновца, не знающего других языков, совершенно не понимая в чём претензии к питоновскому синтаксису. Да ещё и врёшь, не краснея. Возьми любой код, например:

if something:
print 1
print 2

Знаю, индентацию порезало, но, что делать, если в этом форуме у сообщений есть лишь опция "User line break", и нет "User indentation". Но я уверен, ты способен востановить исконный смысл данного кода, тем более, что у тебя есть такие прекрасные текстовые редакторы на такой прекрасной OS (ты упомянал, что на работе программируешь под Windows), и это разрешимая, как ты выше утверждаешь, задача.

А также нагло врёшь, что удаление/добавление уровня индентации в коде Питона, например в вышеприведённых строках, эквивалению удалению/добавлению фигурной скобки в perl. А я всё же продолжаю настаиваивать, что в первом случае получаем синтаксически верный (но по смыслу неверный) код, а во втором случае - синтаксическую ощибку.

Или ты хотел сказать, что пустая строка в Питоне - это такой конец блока. Вот уж не знал, я-то по наивности думал, что пустые строки можно и в середине блока использовать. А Гвидо в курсе?

И Лисп на защиту питона зря привёл. Лисп ничем от нормальных языков не отличается в смысле насильственной индентации и разделения на строки вместо символов начала и конца блока, и лишний TAB никогда не поменяет логику программы. Я всегда в Лиспе использовал индентацию один-таб-на-один-уровень, как и во всех других языках, и ничего. Другое дело, что в Лиспе слишком много этих уровней и простым введением приоритетов операций можно снизить число этих уровней в несколько раз. Но мы тут не недостатки Лиспа обсуждаем, а неюзабильность синтаксиса Питона.

Если с языком нельзя нормально работать в любом редакторе, в том числе в редакторе коммандной строки, то это недо-язык. Впрочем, Питону никакой редактор не поможет, когда уровни надо подправит.ь Синтаксис остаётся верным, а смысл - нет. Один из самых неудобных синтаксисов, встреченных мною.

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

Да, претензия по копи-пасту обоснованная. Как то я сам не допёр... Просто не приходилось ещё копи-пастить на Питоне. :) Пожалуй, отсутствие явных разделителей блоков это всё же больше недостаток, чем достоинство. В общем, если блоки (со скобачками) из Perl6 прикрутить к Питону, будет весьма недурно. Если не ошибаюсь, в Perl6 любой блок - это замыкание.

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

> if something:
> print 1
> print 2

> А также нагло врёшь, что удаление/добавление уровня индентации в коде Питона, например в вышеприведённых строках, эквивалению удалению/добавлению фигурной скобки в perl. А я всё же продолжаю настаиваивать, что в первом случае получаем синтаксически верный (но по смыслу неверный) код, а во втором случае - синтаксическую ощибку.

Ты нагло врёшь. Приведённый тобой код на питоне генерирует синтаксическую ошибку. Или ты "ой, не знааал"?

А что у форума есть режим Preformatted text, и всё более-менее вменяемые люди приводят исходники в нём - тоже не знаешь?

А что это за "редактор командной строки", простите? И кому надо использовать язык программирования в командной строке? Криворуким админам, изобретателям велосипедов, которые не знают стандартных утилит?

А C ты использовал в "редакторе командной строки"? Или это тоже "недо-язык"?

> Один из самых неудобных синтаксисов, встреченных мною.

А ты много на питоне написал/отдебажил кода, чтобы быть уверенным в его неудобстве? Или, что более похоже на правду, тебе "Рабинович по телефону напел"?

Если у тебя какие-то тараканы в башке суетятся или предрассудки буйствуют, держи их лучше при себе, не смеши человеков.

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

> Если с языком нельзя нормально работать в любом редакторе

Я нормально работал с Питоном в mcedit

> в том числе в редакторе коммандной строки

А в Си, ты, наверное, пользуешься триграфами.

> то это недо-язык.

Более веских аргументов нет?

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

> Есть такие языки Хаскелл и Окамль, только недобитый пионер вроде тебя будет кричать что Питон лучше их

Что значит "лучше"? По набору библиотек? По количеству программистов на рынке? По лёгкости изучения? По лёгкости написания и поддержки кода? По портабельности? По стабильности?

Замыкания, тайп инференс, ленивые вычисления - всё это бесконечно круто. Но вот надо ли оно на самом деле?

Хороший язык - это который решает задачу. Если я не смогу найти/обучить Хаскелл-разработчиков - для меня это плохой язык. Несмотря на его заоблачную крутизну.

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

> Ты нагло врёшь. Приведённый тобой код на питоне генерирует синтаксическую ошибку. Или ты "ой, не знааал"?

Хм.. Вообще то mihalych имел ввиду, что по этому куску кода невозможно восстановить исходную семантику, потому что нельзя точно определить где заканчивается блок if. В Питоне же нет ограничения: "блок должен заканчиваться пустой строкой". То есть теоретически проблемы при копи-пасте возможны. Являются ли они настолько серьёзными, чтобы вообще отказаться от Питона? Очевидно, нет.

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

> Замыкания, тайп инференс, ленивые вычисления - всё это бесконечно круто. Но вот надо ли оно на самом деле?

type inference - нужен, замыкания - полезны. Ленивые вычисления я ниасилил.

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

> Мне не трудно признать, что Лисп и Тикль в плане DSL на голову выше Руби. Собственно я сам натыкался на его ограничения.

Лисп и Тикль - каждый в своём роде хорошие языки, но в плане практических возможностей Perl даст им хороший бой. Хотя многое от задачи зависит. Сам программировал на всех вышеперечисленных языках.

> коих нет в Питоне из-за отсутствия лямбды(как вариант добавить хаскельную стрелочку и скобочки для аргументов \ (x,y) -> ).

Это Питону не поможет. Ну, будет очередной костыль, способность определять одну нормальную ламбду в конце выражения. А если мне надо две и не в конце? Я постоянно использую такие вещи:

@components = search_db("condition", filter => sub { ... }, sort => { ... });

А может и так:

@components = $use_db ? search_db(..., sub ..., sub ...) : something_else;

Или так (если мы уж заговорили о DSL):

show use_db ? search { ... } filtered { ... } sorted { ... } templated { ... } : default_content + warning_content;

И это ещё не используя perl source code filters (http://search.cpan.org/dist/Filter/perlfilter.pod).

Кстати, к синтаксису блоков в Ruby у меня свои претензии есть, синтаксис того же Perl 6 (да и 5 тоже) логичней и более функциональней будет. Но рубисты сами понимают, что их синтаксис покрывает некоторые задачи лишь на 80%. Поболее, чем Python, но всё равно мало. :)

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

> Ты нагло врёшь. Приведённый тобой код на питоне генерирует синтаксическую ошибку. Или ты "ой, не знааал"?

Я же сказал, индентация потерялась в связи со спецификой данного форума. Причём, если индентацию второй строки можно востановить, зная свойство питона не кушать пустые блоки (что я считаю очередным недостатком синтаксиса), то со следующей строкой додуматься уже никак не выйдет. Хотя кто-то с жаром утверждал обратное, да и редакторы умные предлагал. Так что врёт всё же кто-то другой.

> А что у форума есть режим Preformatted text, и всё более-менее вменяемые люди приводят исходники в нём - тоже не знаешь?

Знаю, конечно же, но глядя на наши с тобой сообщения с длинными обзацами, нас бы справедливо обматюкали за использование такого режима. :)

> А что это за "редактор командной строки", простите?

Да любой имеющийся в наличии, можно даже без поддержки libreadline, но желательно с поддержкой Backspace и bindable forward-char и backward-char.

> А C ты использовал в "редакторе командной строки"? Или это тоже "недо-язык"?

C не претендует на звание динамического/скриптового языка. Хотя в своё время внимательно следил за IOCCC (Obfuscated C Contest), попадаются просто шедевры. Синтаксис у этого языка - то что надо. :)

> А ты много на питоне написал/отдебажил кода, чтобы быть уверенным в его неудобстве?

Да я-то как раз с питоном справлюсь, мало ли неудобных языков, на которых писать приходилось. Например Smalltalk, но его неудобство совсем другого типа, и там хотя бы не надо программы распечатывать на бумаге в клеточку, да и можно обойтись одной строкой для любой программы, насколько помню. То есть неудобно, но языком с недо-синтаксисом назвать нельзя. :)

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

> Знаю, конечно же, но глядя на наши с тобой сообщения с длинными обзацами, нас бы справедливо обматюкали за использование такого режима. :)

Гм. Пользуюсь и что-то никто не матюкает. Быстрее обматюкают если я исходники на ЛЮБОМ языке запощу без отступов и превращу в нечитабельную кашу.

> Хотя в своё время внимательно следил за IOCCC (Obfuscated C Contest), попадаются просто шедевры. Синтаксис у этого языка - то что надо. :)

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

> Да я-то как раз с питоном справлюсь,

Ага. То есть ничего не писал и просто фантазируешь. Как я и думал.

> и там хотя бы не надо программы распечатывать на бумаге в клеточку

А зачем питонские программы распечатывать на бумаге в клеточку? Нужно обладать сильной близорукостью, чтобы не различать отступы блоков.

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

> Кстати, к синтаксису блоков в Ruby у меня свои претензии есть, синтаксис того же Perl 6 (да и 5 тоже) логичней и более функциональней будет. Но рубисты сами понимают, что их синтаксис покрывает некоторые задачи лишь на 80%. Поболее, чем Python, но всё равно мало. :)

А можно синтаксис блоков в 5 и 6 перле? =) Только с аргументами, потому что sub без названия уже видел :).

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

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

Мне хочется иметь возможность делать с языком всё, беру максимум от языка. Покаместь для меня очевидно, что языки с синтаксисом блока {} - самое эффективное и беспроблемное решение. В Питоне же вообще неудобоваримый бардак в синтаксисе, решили одну несуществующую проблему в виде символа "}" умышленнным ослаблением синтаксиса и добавлением большого числа реальных проблем. Смотри мои сообшения в начале топика для обоснования этой позиции.

> Ага. То есть ничего не писал и просто фантазируешь. Как я и думал.

Неправильно думал. Частенько приходится читать и править средней длины скрипты и библиотеки. К сожалению, дистростроители используют этот язык и пишут на них некоторые критичные системные программы, которые часто падают с backtrace, и которых надо уметь чинить. Да и некоторые програмы стали использовать scons (вот где можно было удобный DSL сделать, ан нет, auto-tools имеют более приятный и интуитивный синтаксис конфигурации, по крайней мере для меня). Но с увеличением сложности программы и длины кода работать с таким синтаксисом становится всё невыносимей (включая перечисленные мной проблемы), и для своих больших проектов я использую более гибкие и читабельные языки.

> А зачем питонские программы распечатывать на бумаге в клеточку? Нужно обладать сильной близорукостью, чтобы не различать отступы блоков.

Ну, если только мелкие програмки на пол странички распечатываешь с максимум одним-двумя уровнями в глубину, тогда не нужна в клетку бумага, а если покрупней и поглубже програмка, то никак тут без линейки не обойтись. Тут, понимаешь, принципиальный спор, что даёт больше практической пользы/вреда, синтаксис, где конец блока указывается ровно одним символом, или где конец блока определяется по массе обязательной невидимой индентации. И неумышленная потеря информации без возможности востановления - очень весомый в этом споре аргумент.

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

> Ну, если только мелкие програмки на пол странички распечатываешь с максимум одним-двумя уровнями в глубину, тогда не нужна в клетку бумага, а если покрупней и поглубже програмка, то никак тут без линейки не обойтись.

The answer to that is that if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program. (c)

http://pantransit.reptiles.org/prog/CodingStyle.html, читайте классиков! :)

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

Не надо путать максимум в 3 уровня отступов на C (особенно для "тупого" описания в ядре логики работы оборудования) и на Perl/Python/Lisp...

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

> А можно синтаксис блоков в 5 и 6 перле? =) Только с аргументами, потому что sub без названия уже видел :).

Ну, раз попросил, расскажу немного. О родных конструкциях языка рассказывать не буду (if, for, while и подобное, в том числе и хвостовые конструкции), очень удобны, но их нельзя изменить.

Если в Ruby можно удобно подать один блок на функцию в конце, то в Perl 5 такой блок подаётся в начале, то есть как первый аргумент. У функции могут быть 2 синтаксиса:

func arg1, arg2, arg3
func(arg1, arg2, arg3)

и:

func block arg2, arg3
func(block arg2, arg3)

Желающие узнать все тонкости, могут изучить документацию, или поекспериментировать с perl -e.

Посему можно использовать pipe-подобные цепочки из вызовов таких функций и порядок выполнения таких pipes будет справа налево. В самом perl немало таких встроенных функций, дающих, например, удобный способ любых преобразований листа/массива. Уже приводил пример выше:

@final_values = sort { $b <=> $a } map { $_ + 1 } grep { defined } @values;

Можно и покороче, но по-моему будет намного менее читабельно, так как всё сбилось в кучу:

@final_values = reverse sort map $_ + 1, grep defined, @values;

Для тех, кто любит детали, замечу, что для создания таких пользовательских функций им надо задать сигнатуру, например если бы в языке не было функций map и grep, их можно было бы определить примерно так:

sub map (&@) { my $func = shift; my @results; push @results, $func->($_) foreach @_; @results }

sub grep (&@) { my $func = shift; map { $func->($_) ? ($_) : () } @_ }

У встроенной функции sort свои исторические причуды, самому полностью эмулировать её сложнее.

Если нужен синтаксис с приоритетом слева направо, то это решается тем, что функции возвращают другие функции (closures). Например так сделан новый синтаксис:

try { code } catch Exception::Class with { code } excepts { code } otherwise { code } finally { code };

Естественно функция может принимать много других функций (замыканий), но синтактический сахар получим, лишь когда они идут первым аргументом, в других случаях нужно добавлять sub {}. Связано это с тем, что {} уже зарезервировано в Perl (да и в других нами обсуждаемых языках) под хэш. Так имеем прагматичный компромис, первый блок (без запятой) берётся именно как блок, в остальных случаях - как хэш.

В Perl 6, насколько я понял апокалипсисы Ларри, различие между блоком и хэшем почти сотрётся (то есть практически никогда не будет конфликта в распознавание что есть что) и можно будет полностью эмулировать TCL без вышеназванных ограничений Perl 5. Если я ошибаюсь, пусть меня поправят. Кроме того в Perl 6 всё есть объект. Как и в Ruby, только ешё интересней, например в Ruby есть явные и неявные преобразования в стринг, число, массив, хэш, а в Perl 6 понятие контекста вынесено на новый уровень, можно возвращать объект, который себя ведёт тем или иным образом в разных контекстах (per-object, не per-class), и число контекстов больше, чем в Perl 5 и Ruby. Опять же, пусть меня подправят, если что-то изменилось с тех пор как я последний раз читал спеки. Ну и соответственно в добавок к существующим синтаксисам, в Perl 6 появились новые, как объектно-ориентированные типа 0.join(1, 2, 3), так и нет.

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

>Быстрее обматюкают если я исходники на ЛЮБОМ языке запощу без отступов и превращу в нечитабельную кашу.

Можешь матюгатся, если не слышал/не умеешь пользоваться утилитами a la indent:)

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

Perl6:

@new_list = @list.map: -> $item { 
    ... 
}

for @list -> $item { 
    ... 
}

$code = -> $param1, $param2 { 
   ... 
}

Для анонимной функции без аргументов можно просто:
$code = { ... }

Соответственно определение блока - это тоже анонимная функция.
Для ясности можно писать так:
$hash = hash { ... }
$code = sub { ... }

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