Re[7]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 15:45
Оценка:
Здравствуйте, deniok, Вы писали:

D>Потому что "гражданские" исходно были ориентированы на максимально "чистое" ООП. Паттерн матчинг хорош, когда внутренняя (алгебраическая) структура типа максимально открыта, тогда по ней тип легко разбирать. А в ООП, наоборот, стремились к унификации всего и вся, в том смысле, что всё есть объект, работа с которым идет через набор методов и свойств, а структурные детали инкапсулированы.


Не думаю, что это проблема. Любой объект имеет публичный интерфейс. Большинство новых языков выражают его в виде свойств. И я не вижу огромной разницы между список публичных свойств и полями алгеброических типов.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 15:45
Оценка:
Здравствуйте, Tonal-, Вы писали:

T>То что нет паттерн-матчинг-а — жалко конечно, но он как бы не является основорологающим.


Для меня, на сегодняЮ, он является определяющим в ыборе языка.

VD>>Ну, а писать в функциональном стиле можно и на C# 2.0. На C# 3.0 это будет делать даже пожалуй удобно. Но вот однажды написав 100 кил с паттерн-матчингом потом уже без него писать не хочется.

T>Давно не интересовался.
T>А там уже есть лямбды, картежи и замыкания?

Лямбды (правдо немного многословные) и замыкания были в 2005-ом в C# 2.0. Сильно ты отстал.
Краткие лямбды и аналог кортежей появились в C# 3.0. В прочем, с кортежами не все однозначно. С одной стороны они лучше, так как у них есть именованные поля, но с другой нельзя описать тип кортежа (он толко может быть выведен), что не дает возвращать кортежи из функций.

T>И можно не писать класс на каждый чих?


Согласен. Только есть языки и с кортежами, и ООП, и с паттерн-мачингом. Они еще к тому же компилируемые и шустные. Внимание вопрос! Нахрена упал Питон?

VD>>Вообще, я никак не могу понять почему гражданские (как их называет Гапертон) языки не рассмотрели этой очень удобной фишки. Как показал опыт Скалы и Немерла она прекрасно интегрируется во вполне себе ООЯ. То есть по сути фича к ФП отношения не имеет. Просто удачное решение родившееся в среде ФП.

T>Надеюсь, что в Python-е оно появиться.

А я почему-то не уверен в этом. Что-то большно сильно мэйнстрим обходит паттерн-мачинг. Как-будтно он заразный.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Немного о функциональном подходе
От: Mamut Швеция http://dmitriid.com
Дата: 14.05.07 16:18
Оценка:
VD>>>Вообще, я никак не могу понять почему гражданские (как их называет Гапертон) языки не рассмотрели этой очень удобной фишки. Как показал опыт Скалы и Немерла она прекрасно интегрируется во вполне себе ООЯ. То есть по сути фича к ФП отношения не имеет. Просто удачное решение родившееся в среде ФП.
T>>Надеюсь, что в Python-е оно появиться.

VD>А я почему-то не уверен в этом. Что-то большно сильно мэйнстрим обходит паттерн-мачинг. Как-будтно он заразный.


Может, он слишком сложен в реализации? (Это не праздный вопрос, действительно интересно)


dmitriid.comGitHubLinkedIn
Re[9]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 14.05.07 22:50
Оценка: 13 (1)
Здравствуйте, Mamut, Вы писали:

M>Может, он слишком сложен в реализации? (Это не праздный вопрос, действительно интересно)


Я не скажу за Скалу (в его компиляторе не разбирался), но судя по Немрлу все не так сложно. Да конечно реализация паттерн-матчинга это не пара ифов, но и сверх сложной задачей ее назвать нельзя. Самый сложный кусок — это построитель дерева решений. Код, конечно, не тривильный (сложная математика), но алгоритмы уже известны и не раз описаны. Есть и готовые реализации. В Немерле его тупо скомуниздили из МЛ-я:
http://nemerle.org/svn/nemerle/trunk/ncc/typing/DecisionTreeBuilder.n
а вот и описание:
http://www.dina.kvl.dk/~sestoft/papers/match.ps.gz (к сожалению, постскрипт).

Вообще, Немерловцы поступили очень прикольно. Они тупо написали первую версию компилятора на ML-е (ОКамле, если не ошибаюсь) и когда получили первую хоть как-то рабочую версию, переписали его на самом себе (благо база общая).

С паттерн-матчингом другая проблема. Он плохо сочетается с ОО-классами. Алгоритм ML рассчитан на работу с алгеброическими типами данных. Все известные мне языки поддерживающие ПМ реализуют и их. В Нмерле это варианты, в Скале кейс-классы, в Эрланге записи (ну, не считаю кортежей) и так дале. Возможно авторы мэйнстримных ООЯ просто боятся вводить в язык еще одну сущность позволяющую хранить данные. Впрочем Васик сто лет имет в своем распоряжении тип данных вариант который очень похож по устройству на алгеброические типы, так что в чем реальная проблема не ясно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: Немного о функциональном подходе
От: deniok Россия  
Дата: 15.05.07 08:29
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, deniok, Вы писали:


D>>Потому что "гражданские" исходно были ориентированы на максимально "чистое" ООП. Паттерн матчинг хорош, когда внутренняя (алгебраическая) структура типа максимально открыта, тогда по ней тип легко разбирать. А в ООП, наоборот, стремились к унификации всего и вся, в том смысле, что всё есть объект, работа с которым идет через набор методов и свойств, а структурные детали инкапсулированы.


VD>Не думаю, что это проблема. Любой объект имеет публичный интерфейс. Большинство новых языков выражают его в виде свойств. И я не вижу огромной разницы между список публичных свойств и полями алгеброических типов.


Алгебраические типы структурно строятся на основе двух операций над типами: "сложения" (disjoint union, перечисление) и "умножения" (cartesian product, кортежи). Плюс (в некоторых языках) — допустима рекурсия в определении типа. То есть типы, в принципе, как строятся, так и матчатся. Список публичных свойств, ИМХО, — более однородная структура — умножение есть, а сложения нету. В каноническом ООП у объекта может быть "и Свойство1, и Свойство2 и Свойство3", но вот "или Свойство4, или Свойство5" — такое только в вариантах или enum'ах. В, Nemerle, насколько я понимаю, это решено через варианты.
Re[8]: Немного о функциональном подходе
От: Трурль  
Дата: 15.05.07 13:07
Оценка: :)
Здравствуйте, VladD2, Вы писали:

VD> И я не вижу огромной разницы между список публичных свойств и полями алгеброических типов.

Разница в точнностиравна разнице между инициальными и финальными алгебрами.
Re[9]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.07 14:14
Оценка:
Здравствуйте, deniok, Вы писали:

D>Алгебраические типы структурно строятся на основе двух операций над типами: "сложения" (disjoint union, перечисление) и "умножения" (cartesian product, кортежи). Плюс (в некоторых языках) — допустима рекурсия в определении типа. То есть типы, в принципе, как строятся, так и матчатся. Список публичных свойств, ИМХО, — более однородная структура — умножение есть, а сложения нету. В каноническом ООП у объекта может быть "и Свойство1, и Свойство2 и Свойство3", но вот "или Свойство4, или Свойство5" — такое только в вариантах или enum'ах. В, Nemerle, насколько я понимаю, это решено через варианты.


Извини, но это все пустые слова. Для паттерн-матчинга нужно всего лишь знать описание интерфейса объекта, чтобы можно было создать паттерн сопоставляемый с объектом. В F# и Scala даже разработали по решению для матчига обычных объектов. Оба основаны на идее запоковки и распаковки. В F# решение более декларативно, в Скале это просто объект с двумя функциями (распаковки и запаковки).

Уверен, что можно сделать паттерн-матчинг и без всех этих ухищьрений.

Например:
class A { public Prop1 : int { get{...} }
class B: A { public Prop2 : A { get{...} }

match (x)
{
  | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
  | A{ Prop1=1; } => ...
}

впроле можно обработать компилятором. Просто алгоритм будет по сложнее.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[10]: Немного о функциональном подходе
От: deniok Россия  
Дата: 15.05.07 15:22
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Например:

VD>
VD>class A { public Prop1 : int { get{...} }
VD>class B: A { public Prop2 : A { get{...} }

VD>match (x)
VD>{
VD>  | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
VD>  | A{ Prop1=1; } => ...
VD>}
VD>


Не вижу тут главной вкусности — рекурсивного разбора по конструкторам рекурсивно определённого типа данных.

Например, Multi-way trees на Хаскелле
type Forest a = [Tree a] 

data Tree a = Node {
                    rootLabel :: a 
                    subForest :: (Forest a) 
                   } 

drawTree :: Tree String -> String
drawTree  = unlines . draw

draw :: Tree String -> [String]
draw (Node x ts0) = x : drawSubTrees ts0
  where -- разбираем по конструкторам списка
        drawSubTrees []     = []
        drawSubTrees [t]    = "|" : shift "`- " "   " (draw t)
        drawSubTrees (t:ts) = "|" : shift "+- " "|  " (draw t) ++ drawSubTrees ts

        shift first other = zipWith (++) (first : repeat other)


При этом
drawTree (Node "r" [(Node "a" []), (Node "b" [])])

нарисует
r
|
+- a
|
`- b
Re[11]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.07 15:48
Оценка:
Здравствуйте, deniok, Вы писали:

VD>>Например:

VD>>
VD>>class A { public Prop1 : int { get{...} }
VD>>class B: A { public Prop2 : A { get{...} }

VD>>match (x)
VD>>{
VD>>  | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
VD>>  | A{ Prop1=1; } => ...
VD>>}
VD>>


D>Не вижу тут главной вкусности — рекурсивного разбора по конструкторам рекурсивно определённого типа данных.


Ну, так попей чайку и еще раз внимательно погляди. Конструкторов конечно ты не увидишь, так как не в нихсуть, но все остальное в наличии.

Матчинг по последовательностям тоже можно сделать.

В общем, надо всего лишь забыть о наукообразии и поглядеть на реальные потребности реальных людей.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[12]: Немного о функциональном подходе
От: deniok Россия  
Дата: 15.05.07 17:33
Оценка:
Здравствуйте, VladD2, Вы писали:

D>>Не вижу тут главной вкусности — рекурсивного разбора по конструкторам рекурсивно определённого типа данных.


VD>Ну, так попей чайку и еще раз внимательно погляди. Конструкторов конечно ты не увидишь, так как не в нихсуть, но все остальное в наличии.


VD>Матчинг по последовательностям тоже можно сделать.


VD>В общем, надо всего лишь забыть о наукообразии и поглядеть на реальные потребности реальных людей.


Мы вообще-то про "гражданские" языки говорим или про Nemerle? В Nemerle, ага, я знаю disjoint union есть, и разбирается всё по вариантам конструкторов (ну может терминология другая) Red, Black:

/// Описывает ветку дерева «красно-черного» дерева.
public variant Node[T] : IEnumerable[T] where T : IComparable[T] 
{
  | Red   { key : T; lchild : Node[T]; rchild : Node[T]; }
  | Black { key : T; lchild : Node[T]; rchild : Node[T]; }
  | Leaf

  /// Подсчет количества элементов.
  public Count : int 
  {
    get
    {
      match (this)
      {
        | Red(_, left, right) | Black(_, left, right) =>
          1 + left.Count + right.Count
        | _ => 0
      }
    }
  }

(c) VladD2
Re[13]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.07 18:58
Оценка:
Здравствуйте, deniok, Вы писали:

D>Мы вообще-то про "гражданские" языки говорим или про Nemerle? В Nemerle, ага, я знаю disjoint union есть, и разбирается всё по вариантам конструкторов (ну может терминология другая) Red, Black:


Пример я вроде привел довольно доходчивый. Что в нем не ясно? Синаксис я использовал Немерловый так как он мне ближе. Но код — это не совсем неперловый. Ты еще раз его погляди...
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[14]: Немного о функциональном подходе
От: deniok Россия  
Дата: 15.05.07 19:44
Оценка:
Здравствуйте, VladD2, Вы писали:


VD>Пример я вроде привел довольно доходчивый. Что в нем не ясно? Синаксис я использовал Немерловый так как он мне ближе. Но код — это не совсем неперловый. Ты еще раз его погляди...


Гляжу ещё раз.

VD>>
VD>>class A { public Prop1 : int { get{...} }
VD>>class B: A { public Prop2 : A { get{...} }

VD>>match (x)
VD>>{
VD>>  | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
VD>>  | A{ Prop1=1; } => ...
VD>>}
VD>>


Разматченное слево от => (образец) как тут связывается для использования в правой?
Re[15]: Немного о функциональном подходе
От: lomeo Россия http://lomeo.livejournal.com/
Дата: 15.05.07 21:05
Оценка:
Здравствуйте, deniok, Вы писали:

VD>>>match (x)

VD>>>{
VD>>> | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
VD>>> | A{ Prop1=1; } => ...
VD>>>}
VD>>>[/c#]

D>Разматченное слево от => (образец) как тут связывается для использования в правой?


Предполагаю, что Prop2=B в первой ветке связывает переменную B со свойством Prop2.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[15]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.07 21:45
Оценка:
Здравствуйте, deniok, Вы писали:

VD>>>
VD>>>class A { public Prop1 : int { get{...} }
VD>>>class B: A { public Prop2 : A { get{...} }

VD>>>match (x)
VD>>>{
VD>>>  | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
VD>>>  | A{ Prop1=1; } => ...
VD>>>}
VD>>>


D>Разматченное слево от => (образец) как тут связывается для использования в правой?


Никак. Этот образец всего лишь находит нужную конструкцию. Он находит экземпляр класса B свойство Prop1 которого равно еденице, а свойство Prop2 ссылается на объект (оптять же) класса B свйосво Prop1 которого равно двум. Если нужна связь, то это будет как-о так:
| B { Prop1=1; Prop2=B { Prop1=2; } as b; } => b.Prop2 *= 2;

или так:
| B { Prop1=1; Prop2=B { Prop1=x; }; } => x

Другими словами мы рассматриваем паттерн как состояние объекта. Уаказываем чему должны быть равны его свойства или используем переменные для связывания со значениями.
Причем обрати внимание, в примере, свойство Prop2 у объекта имеет тип A, что допускает наличие там экземпляра классов наследников A. Соответственно паттерн проверяет, что свойство содержит именно экземпляр класса B и проверяет уже его свойства. Таким образом обходится одно из неприятнешийх свойств ООЯ — необходимость неуклюжих up-cast-ов при работе со списками или иерархиями. Одно это сделало бы язык значительно удобнее.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[16]: Немного о функциональном подходе
От: deniok Россия  
Дата: 15.05.07 22:49
Оценка:
Здравствуйте, VladD2, Вы писали:


D>>Разматченное слево от => (образец) как тут связывается для использования в правой?


VD>Никак. Этот образец всего лишь находит нужную конструкцию. Он находит экземпляр класса B свойство Prop1 которого равно еденице, а свойство Prop2 ссылается на объект (оптять же) класса B свйосво Prop1 которого равно двум. Если нужна связь, то это будет как-о так:

VD>
VD>| B { Prop1=1; Prop2=B { Prop1=2; } as b; } => b.Prop2 *= 2;
VD>

VD>или так:
VD>
VD>| B { Prop1=1; Prop2=B { Prop1=x; }; } => x
VD>

VD>Другими словами мы рассматриваем паттерн как состояние объекта. Уаказываем чему должны быть равны его свойства или используем переменные для связывания со значениями.
VD>Причем обрати внимание, в примере, свойство Prop2 у объекта имеет тип A, что допускает наличие там экземпляра классов наследников A. Соответственно паттерн проверяет, что свойство содержит именно экземпляр класса B и проверяет уже его свойства. Таким образом обходится одно из неприятнешийх свойств ООЯ — необходимость неуклюжих up-cast-ов при работе со списками или иерархиями. Одно это сделало бы язык значительно удобнее.

А чем это в гипотетическом гражданском языке удобнее, чем

if (typeof(x)=B && x.Prop1=1 && typeof(x.Prop2)=B && x.Prop2.Prop1=2)
    {x.(добрались через "." до нужного свойства)*=2;}
else if (typeof(x)=A && x.Prop1=1)
    {...}


Чуть длиннее, но ИМХО требования к x выражены более ясно
Re[17]: Немного о функциональном подходе
От: Cyberax Марс  
Дата: 15.05.07 23:16
Оценка:
deniok wrote:
> Чуть длиннее, но ИМХО требования к x выражены более ясно
Оно удобнее, когда у тебя несколько подобных условий.
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[17]: Немного о функциональном подходе
От: VladD2 Российская Империя www.nemerle.org
Дата: 15.05.07 23:43
Оценка:
Здравствуйте, deniok, Вы писали:

Еще раз намекаю, что оверквотить не стоит.

D>А чем это в гипотетическом гражданском языке удобнее, чем


D>
D>if (typeof(x)=B && x.Prop1=1 && typeof(x.Prop2)=B && x.Prop2.Prop1=2)
D>    {x.(добрались через "." до нужного свойства)*=2;}
D>else if (typeof(x)=A && x.Prop1=1)
D>    {...}
D>


D>Чуть длиннее, но ИМХО требования к x выражены более ясно


Начнем с того, что это уже 4 строки вместо одной. А закочим тем, что они не равнозначны. Полный код будет выглядеть так:
//  | B{ Prop1=1; Prop2=B { Prop1=2; }; } => ...
B b1 = x as B.
if (b1 != null && b1.Prop1 == 1)
{
  B b2 = b1.Prop2 as B;
    if (b2 != null && b2.Prop1 == 2)
    {
      ...
    }
}
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Немного о функциональном подходе
От: Аноним  
Дата: 16.05.07 12:52
Оценка:
А>>По ML:
А>>

К сожалению данное семейство также не является чисто функциональным.

А>>В заключении:
А>>

Поэтому нет смысла сравнивать эти подходы или противопоставлять, гораздо лучше их совместить


U>Просто при беглом обзоре языков, акцентировалось внимание на том является ли язык чисто фунциональным, возможно с целью поиска максимально близкого к эталонному ФЯ, инетерес был вызван чисто академическими соображениями. В конце статьи делаются выводы относительно того, что наиболее рациональным использованием ФП является его совмещение с ИЯ, что и нашло отражение во многих существующих языках. Поэтому никакого противоречия я не вижу.


Читающий такую статью новичок (а если не новчиок — зачем ему введение?) не в курсе истории.
У него основная мысль: что это, чем так хорошо что мне нужно (и нужно ли) учить что-то совсем новое и незнакомое ?

И для него эти куски как раз будут говорить что чистая функциональность это хорошо и к этому нужно стремиться и что чистая функциональность это плохо и нужно стремиться к смеси функциональности с императивностью.
Re[3]: Немного о функциональном подходе, вопрос
От: Аноним  
Дата: 16.05.07 13:01
Оценка:
L>Функциональный подход — это декларативный подход, рассматривающий программу, как одну большую функцию (в математическом смысле). Исполнение программы — вычисление функции.
L>Декларативность подразумевает независимость программы от расположения деклараций (в императивной зависит от расположения инструкций).

Тогда Эрланг не функционален, поскольку не декларативен.
Re[5]: Немного о функциональном подходе
От: Аноним  
Дата: 16.05.07 13:12
Оценка:
U>Редакция 2, исправленная и доработанная

Я бы всё-таки добавил JavaScript

Мне кажется есть мнооого JS-программеров, даже вероятно больше чем питоновцев.
Правда их опыт — 10 функций на 100 страничек.
Но так тем более они новички и аудитория этой статьи.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.