LINUX.ORG.RU
ФорумTalks

Изучение функционального программирования делает ваш код лучше


1

3

Или нет? У меня есть сомнения, так как во всех коллективах принято писать код согласно определенным конвенциям. Человек, который хочет применить ФП в обычных проектах на примитивных императивных языках без особых средств ФП скорее всего имеет в распоряжении

  • Рекурсия (если есть надежда на хвостовую)
  • Выполнение операций на основе предикатов или трансформирущих объектов.
  • Принятие решений на основе конфигурирующих данных. Как бы точнее выразиться? Например построение небольшого интерпретатора, из нескольких команд.
  • Иммутабельность чем больше тем лучше
  • Попытка работать с объектами как с функциями (частичное применение, или создание предикатов как в п. 2)
  • Еще что-то забыл, дополняйте

Но в большинстве коллективов (С, С++, Java) эти приемы будут восприняты как странные, и более того вообще быдлокодом. И на этом языке он и есть быдлокодом в некоторой мере. Тоесть концепции нормальные, но в соединение со средствами которые делают их простыми и краткими. А на вышеперечисленых ЯП лишь гора if-ов и 100500 объектов с нетривиальным состоянием - конвенция.

Вывод: изучение ФП - расширение кругозора, открытие для себя основаных на ФП инструментов. Не повод его пихать везде или гнуть в эту сторону палку в императивном коде как делают некоторые упоротые.

Ваше мнение?

★★★★★

Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от Begemoth

Это ФП или нет?

нет. точно нет. точки с запятыми потому что (причём много).

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

питон окончательно съел твой мозг

Не беспокойся, с моим мозгом всё в порядке. И кстати, Питон - это не ФП (точнее, не язык для ФП), несмотря на наличие list comprehensions и ФВП.

если селёдка это не рыба, то я даже не знаю что назвать рыбой.

В рыбе ты разбираешься лучше, чем в логике.

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

Я предлагаю вам обоим от ваших сарказмов и выражать мысли яснее, спецы по рыбе и метафорам. К примеру, к фразе «list comprehensions - типичное для языков с поддержкой фп средство» труднее придраться, чем к фразе «х - это фп».

Ящитаю, пихать функциональщину в си/++ не нужно, потомв что реализация той же иммутабельности идет вразрез с основными преимуществами си как языка для написания быстрых и нересурсоемких приложений. Поди впихни в микроконтроллер иммутабельный массив, потом попробуй его изменить - все кончится либо полным копированием, либо конвертированию из иммутабельного типа в мутабельный. Например.

cdshines ★★★★★
()

Если ты будешь стараться делать в Си++ как в Haskell, то, очевидно, пользы будет мало. Но если будешь применять некоторые идеи ФП (/= which 'haskell), то польза будет. Эрудированность еще никому не мешала. Мешать может тупое копирование. Впрочем, все это банальности.

Вот, у нас проект на C#. Так я там во всю использую Linq (через комбинаторы; sql-ную форму записи терпеть не могу) и лямбды (которые там являются делегатами). Там, где критична эффективность, пишу старый добрый императивный код. Подход работает замечательно.

С Си и Си++ дело сложнее. У них нет встроенного автоматического управления памятью, а потому многие идеи ФП, пришедшие из лиспа, будут выглядеть чужеродными. Про идеи, развившиеся позже в Haskell, я уже молчу.

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

К примеру, к фразе «list comprehensions - типичное для языков с поддержкой фп средство» труднее придраться,

А к этой фразе никто бы и не придирался (ну, не я, по крайней мере).

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

Ну, смотря что называть «функциональщиной». Делать из Си (и Си++) ФП-язык, конечно, глупо. Но «типичные для языков с поддержкой ФП средства» не повредили бы - например, в Cyclone был рудиментарный pattern matching, который неплохо было бы иметь в Си; в Ivy есть зависимые типы.

Поди впихни в микроконтроллер иммутабельный массив

Микроконтроллер - это всё-таки вырожденный случай. Но вообще-то компиляторы развиваются :)

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)

Еще. Есть такой процесс как конвергенция, когда разные системы сближаются, и уже не поймешь, что ФП, а что нет. Вот и случай с IEnumerable. Впрочем, опять банальности, как и глупые споры вокруг них.

dave ★★★★★
()

Для меня ФП - это ссылочная прозрачность по дефолту. И да, это полезно практически всегда. То есть это должно быть по умолчанию, если нет каких-то аргументов против в каждом конкретном случае.

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

а мне нравиться Scala, очень весело можно по маргинальничать с имплицидными преобразованиями. Зачем загонять себя в рамки подхода?

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

наверное имелось ввиду конструкции типа foreach

BillDver ★★★
()

Есть языки более приспособленные для программирования чем Java.
Например C# где ФП реально помогает.
Но и Java, Oracle вводит элементы ФП, так что никуда вам от него не деться.

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

Но и Java, Oracle вводит элементы ФП, так что никуда вам от него не деться

Зачем мне от него деваться? Но Java программисты в большом числе будут все еще писать циклы и радоваться

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

Но Java программисты в большом числе будут все еще писать циклы и радоваться

Радоваться будут C# программисты как как их код проще, быстрее и понятнее

var between = arr1.Where(x => x >3 && x <= 9);

var join = from a in arr1 
    join b in arr2 on a equals b
     select a;
или нужно распарсить параметры приложения:
private const string ignoreTagParam = "--ignoretag=", ignorecaseParam = "--ignorecase", guiParam = "--GUI", trimParam = "--trim";
// логический свич - есть/нет 
IsCaseSecitive = !args.Contains(ignorecaseParam);
// строковой параметр
var ignoreTag = args.Where(x => x.StartsWith(ignoreTagParam)).FirstOrDefault();
if (!string.IsNullOrEmpty(ignoreTag)) Tag2Ignore = ignoreTag.Substring(ignoreTagParam.Length);
Но самый писец, начинается, козда нужно работать с XML документами. За пол дня была написана программа, которая сравнивала 2 100мб XML документа за 5 минут. XMLSpy был пристрелен после суток так и не произведя результата. Там где Java программер ипётся месяц а программа тормозит и требует часов на малейшее изменение спеков, программа на С# пишется за пол дня и менется быстро и без проблем, так как весь код меньше 200 строк.

Пример из живого кода - выбрать отсутствующие id в 2х XML документах

var tObjects = ((XElement)tanXDoc.FirstNode).Elements().Where(n => n.Name == "Objects").Elements();
var oObjects = ((XElement)ontXDoc.FirstNode).Elements().Where(n => n.Name == "Objects").Elements();

var tIds = from x in tObjects select NormalizeString(x.Attribute("IdString").Value);
var oIds = from x in oObjects select NormalizeString(x.Attribute("IdString").Value);

var tDeltaIds = tIds.Except(oIds);
var oDeltaIds = oIds.Except(tIds);
код не оптиммален, писался быстро и промежуточные объекты используются далее.

И пока C# программисты радуются, Java программисты пишут циклы, объекты, фунции, списки и парсеры

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

Пока C# программисты наслаждаются самым иновационным и современным языком программирования, Scala программисты уже стесняются называть аналогичные фичи в своем ЯП фичами, потому что слишком банально. И консервативная Java в которой просто все работает без мифических ужасов в этом разговоре вообще ни при чем.

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

Scala программисты уже стесняются называть аналогичные фичи в своем ЯП фичами, потому что слишком банально

Тут бы пару примеров кода :)

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

Ссылайся на Александреску всё-время.

Особенно в комментариях к неочевидному коду :) Видал в одном проекте ссылки вплоть до номера страницы. Александреску - жертва поклонения со стороны каргокультистов от крестов.

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

А что делает

Судя по заявлению

vertexua> Scala программисты уже стесняются называть аналогичные фичи в своем ЯП фичами, потому что слишком банально

Я подумал, что ты понял этот фрагмент. Но, видимо, я ошибся.

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

Возможно я понял ошибочно, но оно что, просто выбрало пересечение на основе equals, выбрав инстансы их а?

vertexua ★★★★★
() автор топика

Все зависит от языка и задачи. Метапрограммирование, то что ТС назвал «выполнение операций на основе предикатов или трансформирущих объектов» иногда может быть наикрутейшим багом :) А чтобы оно корректно работало нужно делать кучу проверок, что а) усложняет код б) делает его чаще всего тормозным. Про построение из входных данных интерпретаторов сюда же. В больших проектах такой стиль еще и дебажить сложно, надо на каждый чих писать лог, что пришло и что вышло.

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

gh0stwizard ★★★★★
()
Ответ на: комментарий от tailgunner
def where{
     val arr1 = Array[Int]()
     val arr2 = Array[Int]()

     val between = arr1.filter(x=>x>3 && x<9)

     val res = for (a<-arr1; b<-arr2 if a == b) yield a
   }

  def lists(args:Array[String]){
    val ignoreTagParam = "--ignoretag="
    val isCaseSensetive = !args.contains(ignoreTagParam)
    
    val param = args.filter(_.startsWith(ignoreTagParam)).headOption
    val Tag2Ignore = param match {
      case Some(value)=> value.substring(ignoreTagParam.length)
      case _ => null // or something else here
    }
  }


  def xml{
    val tanXDoc = <someXml/>
    val ontXDoc = <someXml/>

    val tObjects = tanXDoc \\ "Objects" map (_.attribute("IdValue").get.text)
    val oObjects = ontXDoc \\ "Objects" map (_.attribute("IdValue").get.text)

    val tDeltaIds = tObjects.diff(oObjects)
    val oDeltaIds = tObjects.diff(tObjects)

  }

Если что не правильно понял, корректируйте. Не все в точности, просто продемонстрировал что делает в общем то же самое, но не придирался к конкретным переменным. Думаю для иллюстрации достаточно.

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

Но можно без map

    val oObjects = for (obj<-ontXDoc \\ "Objects"; attr<-obj.attribute("IdValue")) yield attr.text

или

    val oObjects = for (attr<-ontXDoc \\ "Objects" \ "@IdValue") yield attr.text
vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от vertexua

Scala программисты уже стесняются называть аналогичные фичи в своем ЯП фичам

Ага.
А в огороде бузина а в Киеве дядька.
Кого волнуют маргинальные ЯП при сравнении популяных ЯП?
Я фофан тоже со скалой побаловался.
И это смешно сравнивать её возможности с C#
у новых скала нет поддержики в базовых библиотеках.
какой-то индус пробовал написать аналог LINQ2Object но обделался а это самая простая часть, хотя и наиболее востребованная. Где linq2Sql и linq2xml?
пс.
Скала изза идиотского синтаксиса несмотря на многие интеrресные идеи никогда не станет популярной.
За 10 лет так никому кроме пары фанатов и не потребовалась.
Даже на Groovy больший спрос
А всё поччему? Потому что целевая аудироия не та(про синтаксис я уже высказаля).
Они нацеливались на Java программистов а не предпочитают писать циклы и радоваться этому.

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

Кстати зачем начинать срач?

Я тоже не понял, зачам писать что ФП никому не нужно, но устоять и не ответить не смог.

Вчера кадр писал что ему за 7 лет программирования алгоритмы не встречались.
Как такую провокацию можно пропустить?

grim ★★☆☆
()

si fueris Romae, Romano vivito more

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

Я тоже не понял, зачам писать что ФП никому не нужно, но устоять и не ответить не смог.

Думаю ты не понял. Я использую ФП и пиарю его везде. Мой point был в том, что Java программисты будут писать без ФП, потому что у них и так все всегда работало. Но хорошего в этом нет ничего.

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

У них нет linq.

пробовали написать(благо язык позволяет) но сдулись, так ка к энтузиастов мало да и передирать фичи из C# в божественную Scala это богохульcтво.

A linq2xml быз которого по нынушним xml-ным временам бывает очень тяжело они даже не рассматрвали, так как он подразумемает создание целой инфраструктуры для лёгких XML объектов.

т.е. scala язык интересный, но бeз капиталовложений он так и останется никому не нужным :(

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

Кого волнуют маргинальные ЯП при сравнении популяных ЯП?

Нашел тут маргинальный

За 10 лет так никому кроме пары фанатов и не потребовалась.

Twitter и т.д. Читай success story. Ее используют в моем старпер-банке, который при этом в десятке самых больших в мире.

Где linq2Sql и linq2xml?

Где «майкрософт фича»? Что за тупой вопрос? В Scala есть отличная иерархия коллекций, которая позволяет делать все что надо. Ну и каждый ORM или библиотека работы с какими угодно данными в том числе XML представляет все в виде эти коллекций. Которые могут быть паралелльными, ленивыми, какими угодно.

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от grim

Ты что слепой? Я тебе короткий код работы с XML привел, в пример твоему ужасному быдлокоду на говноlinq

vertexua ★★★★★
() автор топика
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от vertexua

Нужно чтобы быстро.
DOM не считается. он тормоз.

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

В Scala есть отличная иерархия коллекций, которая позволяет делать все что надо. Ну и каждый ORM или библиотека работы с какими угодно данными в том числе XML представляет все в виде эти коллекций.

DOM это медленно.
нужна лекковесная библиотека, которая бы позволила Scala реализовать возможности.

да, и все вшеперечиленное вами говрит о сравнении Scala по свои возможностям с C# как языка. Но поддержки в базовых библиотеках нет и все приходится писать с нуля и давиться тем что есть.

ps
да в предыдущих сообщения была ошибка. не linq2object а linq2sql пытался реализовать индус.

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

проблем не вижу.

а она есть.
Пока Scala маргинальный ЯП никто не будет вкладыать в развитие библиотек поддерживающих новые возможности и придётся пользоваться тем что досталось от Java.

grim ★★☆☆
()
Последнее исправление: grim (всего исправлений: 1)
Ответ на: комментарий от vertexua

Не все в точности, просто продемонстрировал что делает в общем то же самое, но не придирался к конкретным переменным.

Насколько я понимаю, у тебя в where допустимо только задание диапазона, а в примере на C# там лямбда. Но более интересно как выглядит пример:

var join = from a in arr1 
    join b in arr2 on a equals b
     select a;

насколько я понимаю, это аналог:

join = []
for a in arr1:
   for b in arr2:
      if a == b:
         join.append(a)

но условие в if может быть любым (и в зависимости от него проход по массиву arr2 может оптимизироваться).

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

Но поддержки в базовых библиотеках нет

Остановимся на слове _базовых_. Чего конкретно нет кроме linq в майкрософт виде? Я прошу больше чем один пункт. А вот чего нет в .NET, так это трейтов, миксинов, имплиситов, ad-hoc полиморфизма, вычислителя монад, экстракторов, паттерн матчинга и т.д.

А теперь вспомним что Scala работает на JVM. Что открывает доступ к такому количеству платформ, библиотек и фреймворков, что .NET выглядит вполне маргинальным.

Ну и конечно нельзя не вспомнить что Scala работает на .NET для совсем упоротых, так что можете клепать окошки или что еще там дотнетчики делают

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

а в примере на C# там лямбда

У меня тоже лямбда. Там можно писать в двух стилях. Один - filter, map, flatMap и т.д. Другой - for comprehensions. Второй транслируется компилятором в первый все равно.

но условие в if может быть любым (и в зависимости от него проход по массиву arr2 может оптимизироваться)

Да, я тоже такое же написал. В Scala for - конструкция которая умеет вычислять монады. Потому внутри нее там управление под контролем монады, которая может чудить что хочет. Например скоро в Scala добавят макросы, которые позволяют получить AST и тогда «что угодно» приобретет совсем другой масштаб.

может оптимизироваться

А будет ли? Просто лямбду то можно наворотить любую. Когда оно будет оптимизировать? Есть ли гарантии?

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

Да, я тоже такое же написал.

Ты написал цикл, не сильно отличающийся от моего.

Когда оно будет оптимизировать? Есть ли гарантии?

Думаю, что при первом исполнении, но это неважно. Возможность есть.

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

Чего конкретно нет кроме linq в майкрософт виде

В Java или Scala?
Scala не хуже чем C#. Я имею в виду что у них обоих есть недостатки и достоинства.
Но так как по моему мнению она как и любимая мною Scheme никогда не приблизятся даже к Руби то обсуждать их просто не интересно особенно на не посвящённых им языкам форумах.

В Java не хватает всего, но он зхадумывался как язык для быстрого набора стада отсурснутых программистов с минимальными затратами, так что по моему личному мнению ничего интересного здесь не произойдёт, так как стада за $10 в месц этого не поймут.

то открывает доступ к такому количеству платформ, библиотек и фреймворков, что .NET выглядит вполне маргинальным.

Ага, сказки и сказочники.
Моно и C# к примеру работает на iOS и Android
Как насчёт java для iOS?
Scala для Android?

Scala для дотнета года 2 как умерла.

grim ★★☆☆
()
Последнее исправление: grim (всего исправлений: 1)
Ответ на: комментарий от vertexua

может оптимизироваться

А будет ли?

Будет.
Если есть желание почитайте про expression tree

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

Ты написал цикл, не сильно отличающийся от моего.

for в Scala, не цикл от и до. Я же сказал, это вычислитель монад. Тоесть нагородить с волшебными типами там можно что угодно. Например выполнение кода разграниченного HTTP запросами.

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

Ага, сказки и сказочники.

Нуну. Сходи на Apache, на любую другую опенсорс foundation, там .NET и не пахло. Увы все дружат против Microsoft

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

В Java не хватает всего

В том то и фишка вся что в Java есть Scala. В любой проект где так решат можно на ходу начать писать код на Scala и все будет прекрасно работать. Как только действительно это понадобится. Как в Twitter

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

не совсем верно. При join строится expression tree, которое сохраняется до лучших времен, когда данные реально понядобятся. тогда оно будет проанализированно с дополнительными наложеннми условиями и процедурами

var join = from a in arr1 
    join b in arr2 on a equals b
     select a;

var c = from j in join
     where j>5
     select j;
будет аналогичен
var join = from a in arr1 
    join b in arr2 on a equals b
    where j>5
     select a;
далее работа со списками может оптимизироваться. У меня замена for на linq выражение с join ускорило обработку 2х списков с боле чем 1 часа до нескольких минут(по моему 7 но давно было)

Кроме того можно сложные join разбивать на несколько, зная что linq всё соптимизирует.

grim ★★☆☆
()
Последнее исправление: grim (всего исправлений: 1)
Ответ на: комментарий от vertexua

Сходи на Apache, на любую другую опенсорс foundation, там .NET и не пахло.

А у меня где хоть слово о .Net?

Да, вы так и ответили о том где Scala для Android или хоть Java для iOS.
Так где?

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

не совсем верно. При join строится expression tree, которое сохраняется до лучших времен, когда данные реально понядобятся. тогда оно будет проанализированно с дополнительными наложеннми условиями и процедурами

Что именно? Я знаю про AST, и даже правильно написал, что выражение оптимизируется при первом использовании. Понятно, что приведенный мной алгоритм неоптимизирован.

У меня замена for на linq выражение с join ускорило обработку 2х списков с боле чем 1 часа до нескольких минут

Обычных списков?

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