что круче pyhton или ruby?

Dasar

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

Maurog

стоит задача внедрить какой-нибудь приличный скрипт в программу
мне кажется, вы справились со своей задачей :grin:
зы: попробуйте сформулировать вопрос более конкретно, оба языка вполне "приличные" =)

Dasar

попробуйте сформулировать вопрос более конкретно, оба языка вполне "приличные" =)
дык, ткнулся реальную мини-задачку по обработке коллекций решить на питоне, но код получается "грязнее", чем C#-ный, хотя должно быть наоборот. скрипт должен быть чище, чем типизированный язык.

psihodog

дык, ткнулся реальную мини-задачку по обработке коллекций решить на питоне, но код получается "грязнее", чем C#-ный, хотя должно быть наоборот. скрипт должен быть чище, чем типизированный язык.
не верю! код в студию

Maurog

код получается "грязнее"
можно в этом направлении двигаться
например:
посоветуйте pythonic-way для обработки коллекции
мой код такой:
bla-bla
как сделать послаще?
когда вы наберете кучку таких вопрос-ответ, то сможете уже взвешивать, подходит ли вам питон или нет
серебряных пуль нет и не будет, надо находить компромисс

Dasar

не верю! код в студию
почти все на конвейерную обработку
допустим искусственная задачка:
из последовательности от 0 до 99 включительно выбрать числа, в которых есть 3 и 8,
сгруппировать по десяткам (т.е. чтобы в одну группу попали числа из одного десятка)
отсортировать по кол-ву чисел в группу
и вывести список сум чисел в каждой группе
на шарпе это:

Enumerable.Range(0, 99)
.Where(i => i.ToString.Contains('3','8'
.GroupBy(i => i/10)
.OrderBy(group => group.Count
.ForEach(group => Console.WriteLine(group.Sum;

при этом конвейер ленивый, и поэтому оверхед минимальный.

psihodog

допустим искусственная задачка:
искусственные задачи не интересно.
их всегда можно подогнать, чтоб они решались лучше всего на заданном языке.
эта задача:
из последовательности от 0 до 99 включительно выбрать числа, в которых есть 3 и 8,
сгруппировать по десяткам (т.е. чтобы в одну группу попали числа из одного десятка)
отсортировать по кол-ву чисел в группу
и вывести список сум чисел в каждой группе

типичный SQL.
в C# встроен SQL, поэтому понятно, что она на нём будет решаться лучше всего.
ах, да... на SQLе будет ещё красивей

Dasar

в C# встроен SQL, поэтому понятно, что она на нём будет решаться лучше всего.
в решении, которое я привел нет никакого sql, а есть лишь конвейер.

psihodog

в решении, которое я привел нет никакого sql, а есть лишь конвеер.
.Where...
.GroupBy...
.OrderBy...

:confused:
в питоне нет таких встроенных команд как GroupBy.
делается лист-компрехеншенами, отчего код получится более громоздким, чем у тебя.
кроме того, у тебя сама задача поставлена императивно, значит
в более императивном языке она будет реализована более дословно.

Dasar

в питоне нет таких встроенных команд как GroupBy.
так это библиотечная функция, а не встроенная команда.
в этом-то и прелесть C#, что конвейер легко нарастить своими методами.

Dasar

sum $ sortBy
доллар что такое?

alfadred

доллар что такое?
f $ x = f x
просто чтобы скобок не ставить:
g $ f x = g (f x)

Dasar

let result = map sum $ sortBy (comparing length) $ groupBy
так конечно лучше, но конвейер в обратную сторону сбивает с толку....

alfadred

так конечно лучше, но конвеер в обратную сторону сбивает с толку....
Ну я уже привык, а вообще никто не мешает сделать (|>) = flip ($) и писать x |> f |> g
Или import Control.Category и (f >>> g) x

vall

похоже руби надо уже с перлом сравнивать =)

Dasar

похоже руби надо уже с перлом сравнивать =)
это руби был?

alfadred

это руби был?
Это был Haskell

vall

:censored:

Dasar

Это был Haskell
предлагаешь haskell интегрировать в приложение? :)

alfadred

Виноват, забыл оффтоп поставить.
В руби, кстати, у списков есть map, select, group_by и sort, будет похоже на C#.

Dasar

В руби, кстати, у списков есть map, select, group_by и sort, будет похоже на C#.
они конвейерные? или это просто функции?

alfadred

они конвеерные? или это просто функции?
методы Enumerable.

psihodog

так это библиотечная функция, а не встроенная команда.
не встроенная куда?
это какая-то нестандартная библиотека?
в этом-то и прелесть C#, что конвеер легко нарастить своими методами.
аа... так вот откуда это пошло в юниксовый шелл и c++, из c# оказывается! :grin:

Dasar

методы Enumerable.
в контексте ruby мне это, к сожалению, ни о чем не говорит.

alfadred

в контексте ruby мне это, к сожалению, ни о чем не говорит.
(0..99).to_a.select{|x| have38(x)}.group_by{|x| x/10}.sort{|k, v| v.length}.map{|k, v| sum(v)}

july


в питоне нет таких встроенных команд как GroupBy.
groupby есть в itertools. собственно, на итертулзах приведенная искуственная задача не так плохо выглядит

Dasar

(0..99).to_a.select{|x| have38(x)}.
ruby - конечно, получше выглядит
лямбды опять же красиво записываются

Maurog

почти все на конвеерную обработку
придется указать на ошибку, ато в этом обсуждении она размножается
конвейер
при этом конвеер ленивый, и поэтому оверхед минимальный.
во-первых, ленивость в данном решении на языке C# только во вред, как мне кажется, ибо все выражения вычисляются, а накладные расходы на ленивость остаются
во-вторых, неужели ленивость - это ваша цель? а функциональная парадигма - тоже ваша цель? скорость работы тоже должна опережать C# ? или всё же ваша цель удешевить разработку, переместив часть логики в более высокоуровневый язык? с последним замечательно справляется питон
использовать C#-style в программах на питоне мне кажется неправильным. либо вы при приеме на работу спрашиваете у претендента знание питона, либо знание C#-style inside python, тем самым увеличивая порог вхождения
функциональный подход в моем понимании означает оперирование функциями. в вашем решении я не нашел этого.
основными кирпичиками, позволяющими делать из одних функций другие, являются карринг и композиция,. именно поэтому решение, предложенное он будет тормозить, ибо это не его стихия. нужна именно функциональщина - берите GHС\Haskell\FFI и вперед. питон как был так и останется преимущественно императивным языком.
резюме: питонисты замечательно владеют питоном, даже если не знают C#

Dasar

во-первых, ленивость в данном решении на языке C# только во вред, как мне кажется, ибо все выражения вычисляются, а накладные расходы на ленивость остаются
где именно накладные расходы, и что надо сделать, чтобы их не было?
во-вторых, неужели ленивость - это ваша цель? а функциональная парадигма - тоже ваша цель? скорость работы тоже должна опережать C# ? или всё же ваша цель удешевить разработку, переместив часть логики в более высокоуровневый язык? с последним замечательно справляется питон
цель: иметь наглядный скрипт для быстрой обработки больших массивов
соотвественно ленивость, функциональность и конвейер - приближает к достижению этой цели.
использовать C#-style в программах на питоне мне кажется неправильным. либо вы при приеме на работу спрашиваете у претендента знание питона, либо знание C#-style inside python, тем самым увеличивая порог вхождения
могу еще раз повторить: что меня больше интересует возможность описать конвейерную обработку в явном виде, чем наличие синтаксиса совпадающего с C#.
именно поэтому решение, предложенное , является в моем понимании "самым функциональным" и "в обратную сторону" ничего не сбивает (ну а что же вы ожидали от одного из самых функциональных языков?).
нелогичное утверждение и нарушает как минимум два принципа программирования:
наименьшего удивления
и разное делай разным, одиннакое - одиннаковым.
и соответственно, я не вижу пользы от того, что прямую последовательность выполнения команд надо записывать как обратную.
ваше решение достаточно декларативно и содержит лямбды, но до функционального еще далеко
если вот так поменять, то уже достаточно функционально(по крайней мере, карринг уже используется)?

var digits = new[]{'3', '8'};

Enumerable.Range(0, 99)
.Where(i => i.ToString.Where(ch=>digits.Contains(ch
.GroupBy(i => i/10)
.OrderBy(group => group.Count
.ForEach(group => Console.WriteLine(group.Sum;

Dasar

или всё же ваша цель удешевить разработку, переместив часть логики в более высокоуровневый язык?
c# - у нас довольно дешевый. и от внедрения Python-а мы скорее ожидаем удорожание разработки, т.к. отсутствие статической типизации плохо ложится на командную разработку, и на динамичную разработку.
python расматривается лишь как возможность на уровне пользователя заскриптовать программу.

Maurog

если вот так поменять, то уже достаточно функционально(по крайней мере, карринг уже используется)?
var digits = new[]{'3', '8'};
<skip>
.Where(i => i.ToString.Where(ch=>digits.Contains(ch
<skip>
изменений совсем немного оказалось. я правильно понял, что в этих двух строчках вы увидели карринг?
я его тут не вижу. под каррингом в данном случае я понимаю построение функции одного переменного из функции двух переменных путем фиксации значения первого аргумента. здесь же у вас нет функции двух переменных, а есть лишь одна лямбда-функция одного переменного. вы пытаетесь проинтерпретировать ООП код по-функциональному, хотя с функциями напрямую не работаете. у вас ни одной функции, но есть методы у объектов. можно на методы смотреть как на функции, принимающие первым аргументом сам объект, однако после ООП-рассахаривания у вас получится то, что вам ужасно не понравится =)

Maurog

python расматривается лишь как возможность на уровне пользователя заскриптовать программу
цель: иметь наглядный скрипт для быстрой обработки больших массивов
ваши цели мне непонятны :confused:

Dasar

изменений совсем немного оказалось. я правильно понял, что в этих двух строчках вы увидели карринг?
я его тут не вижу. под каррингом в данном случае я понимаю построение функции одного переменного из функции двух переменных путем фиксации значения первого аргумента
вот это: i.ToString.Where(ch=>digits.Contains(ch - формально функция двух переменных: i и digits
при этом из нее делается функция одной переменной i
> проинтерпретировать ООП код по-функциональному
можешь показать где там ООП?

Maurog

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

Dasar

ваши цели мне непонятны
на уровне пользователя необходима возможность написать код для обработки массивов
так понятнее?

Dasar

так где в моем коде ООП? там даже ни одного метода нет, сплошные функции

Marinavo_0507

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

okis

думаю, пользователи — сами программисты, просто для гибкости системы требуется скриптинг (:

Marinavo_0507

ну если у них уже стоят средства разработки, то, наверное, не очень сложно сделать скриптинг на C#, раз он так удобен?

Dasar

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

Dasar

для тех кто не знаком с C#
вот этот код


var digits = new[]{'3', '8'};

Enumerable.Range(0, 99)
.Where(i => i.ToString.Any(ch=>digits.Contains(ch
.SplitWhile(i => i/10)
.OrderBy(group => group.Count
.ForEach(group => Console.WriteLine(group.Sum;


в итоге, при выполнении превращается вот в такой императивный код:

List<List<int>> groups = new List<List<int>>
List<int> group = new List<int>
int groupKey = -1;
for (int i = 0; i <= 99; ++i)
{
var s = i.ToString;
foreach (var ch in s)
{
foreach (var digit in digits)
if (ch == digit)
goto L1;
goto L2;
}
L1:
var key = i /10;
if (groupKey != key)
{
group = new List<int>
groups.Add(group);
groupKey = key;
}
group.Add(i);
L2:
}
groups.QuickSort(group => group.Length);
foreach (var group in groups)
{
int sum = 0;
foreach (int i in group)
sum += i;
Console.WriteLine(sum);
}

если переписать вот так:


var digits = new[]{'3', '8'};

Enumerable.Range(0, 99)
.Where(i => i.ToString.Any(ch=>digits.Contains(ch
.SplitWhile(i => i/10)
.Select(group => new {Count=group.Count Sum=group.Sum})
.OrderBy(pair => pair.Count)
.ForEach(pair => Console.WriteLine(pair.Sum;


то при выполнении получится вот такой код:

List<Pair> groups = new List<Pair>
Pair pair = new Pair
int groupKey = -1;
for (int i = 0; i <= 99; ++i)
{
var s = i.ToString;
foreach (var ch in s)
{
foreach (var digit in digits)
if (ch == digit)
goto L1;
goto L2;
}
L1:
var key = i /10;
if (groupKey != key)
{
pair = new Pair;
groups.Add(pair);
groupKey=key;
}
pair.Count+=1;
pair.Sum+=i;
L2:
}
groups.QuickSort(pair => pair.Count);
foreach (var group in groups)
{
Console.WriteLine(group.Sum);
}


Dasar

на уровне компилятора
вот такой сахар(код)

Enumerable.Range(0, 99)
.Where(i => i.ToString.Any(ch=>digits.Contains(ch
.SplitWhile(i => i/10)
.OrderBy(group => group.Count
.ForEach(group => Console.WriteLine(group.Sum;

превращается в

ForEach(
OrderBy(
SplitWhile(
Where(
Range(0, 99
i => Any(i.ToString ch=>Contains(digits, ch

i => i/10

group => Count(group)

group => Console.WriteLine(Sum(group
)

кто-то до сих пор утверждает:
1. что здесь есть ООП
2. вторая запись более удобная, чем первая
?
вторая запись плоха тем, что название функции и ее параметры очень сильно разнесены.

Papazyan

Конечно она будет плохой, если язык для нее не предназначен. В языке специально рассчитанном на работу с массивами, все проще (: - присваивание, each = map):

sum each a g key asc count each g:group div[;10] a:a where (max "38" in) each a:til 100

Dasar

В языке специально рассчитанном на работу с массивами, все проще (: - присваивание, each = map):
 
в данном случае, как всегда, хочется взаимоисключающего: достаточно-распространенный язык, но чтобы на нем удобно записывались операции над коллекциями

Marinavo_0507

как вообще это читать?
что-то вроде форта что ли

Marinavo_0507

но чтобы на нем удобно записывались операции над коллекциями
в твоём примере коллекции-то не нужны

Dasar

в твоём примере коллекции-то не нужны
там Enumerable.Range выполняет роль исходной коллекции.

Marinavo_0507

там поток, а не коллекция
и обработка однопроходная

Dasar

там поток, а не коллекция
и обработка однопроходная
вот так обработка коллекции есть?

var items = Enumerable.Range(0, 99).ToArray;

items
.Where(i => i.ToString.Any(ch=>digits.Contains(ch
.SplitWhile(i => i/10)
.OrderBy(group => group.Count
.ForEach(group => Console.WriteLine(group.Sum;


ps
да, и сортировка без коллекций не бывает

Marinavo_0507

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

Papazyan

как вообще это читать?
Справа налево.

durka82

python расматривается лишь как возможность на уровне пользователя заскриптовать программу.

Может проще тогда выбрать JavaScript/VBscript?
Так как необходимость знания парадигм явно не пойдёт в прок рядовым пользователям, которые захотят что-то заскриптовать.

Dasar

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

timefim

Ruby всяко по веселее будет, более вменяемые лямбды(нет громадного кейворда и мультистейтменость) плюс скобки можно опускать и писать менее страшный dsl. Там сейчас все еще линковские экстеншен методы не работают? Можно попробовать манки патчингом их добавить, тогда для работы с коллекциями разницы практически не будет.

Marinavo_0507

скриптинг из статик-типизированных языков плохо получается:
неудобное требование, чтобы программа была полностью корректной при запуске
требование явного приведения и согласования типов
фактическая невозможность работы в режиме командной строки
полностью корректной программа быть не обязана, иначе нельзя было бы подгружать код в динамике
но а если не подгрузится юзерский скрипт из-за ошибок - это же хорошо, можно их вовремя исправить
явное приведение типов? в твоём примере его нет
зачем оно?
командная строка? ты вообще о чём? сейчас же XXI век на дворе, в моде мультитач, им и набрасывай
вообще, всякие *ML и хаскели вроде тоже как-то осиливают командную строку, то есть принципиальной невозможности нет

Dasar

но а если не подгрузится юзерский скрипт из-за ошибок - это же хорошо, можно их вовремя исправить
новичка это пугает.
О! у меня тысяча одна ошибка, да мне их за всю жизнь не разобрать! пошли все на фиг.
явное приведение типов? в твоём примере его нет
зачем оно?
это только кажется, что его нет.
т.е. нужен опыт, чтобы писать так, чтобы не надо было приводить типы.
командная строка? ты вообще о чём? сейчас же XXI век на дворе, в моде мультитач, им и набрасывай
вообще, всякие *ML и хаскели вроде тоже как-то осиливают командную строку, то есть принципиальной невозможности нет
не важно каким образом будет осуществляться командная строка: текстовым вводом или мультитачем.
важнее, что это требует построчного создания и выполнения скрипта.
а статик-типизированные из-за своей компилируемости требуют перекомпиляции всего модуля, или оформление каждой строки как модуля

Marinavo_0507

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

Marinavo_0507

ну то есть ты объясни
в целевой аудитории будет много новичков, которые никогда не писали ни на С, ни на C++, ни на C# ?
если да, конечно вариант с C# отпадает

Dasar

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

Marinavo_0507

ну значит, отмазка, что их напугают стопицот ошибок, не катит

shlyumper

Удивляюсь, почему здесь никто до сих пор не написал решение на APL или J хотя бы. :o

Dasar

Удивляюсь, почему здесь никто до сих пор не написал решение на APL или J хотя бы.
оно красивое будет?

shlyumper

Гуглом пользоваться умеешь?

Papazyan

Удивляюсь, почему здесь никто до сих пор не написал решение на APL или J хотя бы. :o
Я напейсал на подобном языке. Преимущества особого тут не будет, поскольку в С# специально сделали, чтобы такая задача легко решалась.

karkar

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

Если есть слово "быстрой", то динамически типизируемые языки использовать не стоит. Если основная программа на C#, то, я предполагаю, выбор между IronRuby и IronPython. Насколько я помню, они оба очень медлительны и недоделаны. Я бы в данном случае поискал что-нибудь третье. Нельзя ли там заюзать F#? В нем и REPL, и лаконичность, и конвейерная обработка ленивых последовательностей и скорость C#'a.

psihodog

Имхо, как язык Руби много лучше Питона.
а в каком месте он лучше?
(это не для флейма, интересно просто)
я вот тут глянул 20-минутный тюториал.
кое-что понравилось, но вот это просто убило:
@names.each do |name|
puts "Hello #{name}!"
end

:crazy:

karkar

1. Логичный и последовательный. В ОО-языке длина строки это s.length, а не length(s отсортированный массив это m.sort, а не sorted(m) и т.д. При этом в стандартных классах неплохо сделано отличие меняющих объект методов от неменяющих (типа map и map!, sort и sort!).
2. Гибкий синтаксис: выбор между фигурными скобками и do end, необязательность скобок в вызовах функций...
3. Нечувствительность к отступам! Для встраиваемых скриптов это может быть особенно полезно.
4. Очень удобные параметры-блоки, фактически дающие удобный способ определения и использования ФВП.
5. Нет этих дурацких __подчеркиваний__ всюду.
6. Symbols - удобные штуки.
Все вместе это позволяет делать довольно красивые DSL'и: лаконичные и без таких жестких ограничений на layout. Да и без DSL'ей, достаточно посмотреть на приведенные в треде решения задачки. Имхо, вариант на Руби самый красивый и наглядный.
Почему-то после Руби Питон мне кажется кучей хаков, а не стройным языком.

psihodog

> Очень удобные параметры-блоки
?
> ФВП
?
> Почему-то после Руби Питон мне кажется кучей хаков, а не стройным языком.
ну... мне питон никогда особо стройным не казался, что, впрочем, не мешает ему быть весьма удобным

alfadred

> ФВП
?
Функции высших порядков.

karkar

> параметры-блоки
В приведенном примере
 

(0..99).to_a.select{|x| have38(x)}.group_by{|x| x/10}.sort{|k, v| v.length}.map{|k, v| sum(v)}

то, что в фигурных скобках - это оно и есть. Кусок кода, который может иметь параметры (заключаются в | |). Записывается после вызова метода и оказывается переданным методу в качестве аргумента, который можно вызвать или передать дальше. Типа лямбды.
Вот пример, как на них сделаны свои for и if для DSEL (это методы, но выглядят как конструкции языка):
http://thedeemon.livejournal.com/837.html
> ФВП
Функции высшего порядка.
Оставить комментарий
Имя или ник:
Комментарий: