[flame] python vs c# (re: MySQL+Apache+PHP ..)
Чо такое C#?
Я про свободные языки говорил. C# - проприетарное детище MS, и ему уготовано ровно то, что решит с ним сделать MS. Может быть он даже станет языком №1 в мире. Но C# конкурирует с Java, а Python - с Perl и PHP. линуксоиды не начнут писать на C#, b на хостингах C# не вытеснит через 5 лет PHP. А Python - может.
Python - с Perl и PHP
Почему не с Java до кучи?
Почему ты думаешь, что он "моднее" C#?Ну и в порядке холивара.
А ещё на Python пишут проекты в яндексе, его поддерживает гугл и вообще он весь из себя крутой. А C# - макагня какая-то, замена вижуал бейсика. Он даже Java вытеснить не может. Единственное оправдание существования C# - на нём пишет петя митричев.
А вообще их сравнивать некоректно. C# займёт нишу языков для проектов под заказ и автоматизации/интеграции (всё это ужасно скучное на мой вкус Python - станет самым популярным скриптовым языком и языком веба, а вечно молодой C++ останется языком для коробочных продуктов для массового пользователя. И все будут жить долго и счастливо.
вечно молодой C++ останется языком для коробочных продуктов для массового пользователя
Ставлю на Python+C[++] (то бишь чем меньше ++ тем лучше) для коробочных продуктов
Где ты видел связку Apache + Java? Я такого полового извращения не видел нигде. Только слышал краем уха но это было в те давние времена, когда Perl был так же распространён в веб, как PHP. Единственное преимущество, из-за которого юзают Java - кросплатформенность. Нахрена тебе кросплатформенность на веб-сервере? А даже если и нужна, PHP/Perl/... ничуть не менее кросплатформенны.
Почему не с Java до кучи?А, понял к чему это. Ну да, Python c C# поделят нишу Java. ХЗ, что там будет с мобилными платформами, но думаю, что на PC java умрёт, хотя и не сразу.
Я имел в виду что Питон вполне себе конкурент Жабе без привязки к Апачу — веб-программисты и на жабе бывают, и питон прекрасно подходит для разных задач, не только веб. Это не руби.
угу
Ставлю на Python+C[++] (то бишь чем меньше ++ тем лучше) для коробочных продуктовимхо, динамический язык еще не скоро станет основным для коробочного ПО.
от коробочного ПО требуется надежность и предсказуемость в мелочах - что как раз не может дать динамический язык.
Какие-то стереотипы. "Надежность и предсказуемость в мелочах" не даст сам по себе ни один язык в принципе. Поэтому без юнит и функционального внешнего тестирования все равно не обойдешься. И будет уже пофиг, динамический-не динамический.
"Надежность и предсказуемость в мелочах" не даст сам по себе ни один язык в принципе. Поэтому без юнит и функционального внешнего тестирования все равно не обойдешься.статическая типизация как раз дает надежность в мелочах - без всякого тестирования, а это есть хорошо, т.к. стоимость сопровождения падает, из-за того что писать тест на каждый чих - это очень дорого.
надежность в мелочахОк, define "надежность в мелочах"
питон прекрасно подходит для разных задач, не только веб. Это не руби.А чем Руби не угодил? Только скоростью или чем-то еще?
C# - свободный язык.
Рискну предположить, что это язык, на котором написаны около 25-30% веб-серверов в Internet.
А на PHP еще больше!
Про C# вывод сделал на основе статистики из предположения о том, что из серверов на IIS больше 2/3 написаны на C#.
Какая часть серверов на Apache использует PHP как основной язык?
имхо, динамический язык еще не скоро станет основным для коробочного ПО.
Ты путаешь статическую типизацию и надежность. Статическая типизация надежность конечно повышает, но еще ее повышает короткий читабельный текст программы, размер comunity и отсутствие кривых рук MS.
И даже если и так, то история учит, что декстопным приложениям надежность вообще говоря не нужна. Ключевое слово — MicroSoft.
Зато на питоне быстрее (и дешевле) разработка, проще сопровождение, легко модифицировать программу.
А чем Руби не угодил?
Это тот же питон со слегка измененным синтаксисом.
Имхо это просто лишний язык. Он не умер только из-за появления Rails.
То есть библиотеки там слабее, народу меньше, Ruby в итоге язык для написания веб-приложений.
У Rails есть конкурент в питоне — Django, из-за чего со временем Rails загнется.
Имхо.
Посмеялся от души.
история учит, что декстопным приложениям надежность вообще говоря не нужна. Ключевое слово — MicroSoftНу да, конечно.
Винда - охуенно надёжное приложение.
Ты вот представь, что твой продукт будут в хвост и в гриву круглосуточно и годами юзать на миллиарде различных компьютеров, с различными железячными конфигурациями, различными извращениями над ним, огромной кучей левых штуковин (Windows-приложения)... да ты бы, если бы поддерживал такое, поседел через час.
Почему ты думаешь, что он "моднее" C#?гы, лох. Он не сравнивал бидон с цешарпом, он сравнивал бидон с другими свободными языками. А сказки про свободность своей любимой поделки засунь плз себе в жопу
Ну а поскольку вряд ли на хостингах будет широко использоваться венда, то и популярности у c# в веб-программировании широкой не будет.
В чём заключается несвободность сишарпа?
пинартур, пытаться объяснить тебе вещи, с которыми ты не согласен - себе дороже. поэтому попробуй догадаться сам.
Ты просто неадекватен.
Ты путаешь статическую типизацию и надежность. Статическая типизация надежность конечно повышаетНу здесь ты согласился с предыдущим утверждением.
но еще ее повышает короткий читабельный текст программы, размер comunity и отсутствие кривых рук MS1. Интересно, как это ты возражаешь по поводу предыдущего утверждения, утверждением, никак с ним не связанным?
2. Согласен, текст короткий. Но сильно более понятным его не назовёшь.
3. Судя по запросам C# и Python в Гугл, у них примерно одинаковые сообщества.
4. Про кривые руки MS - это загон. Тем более, что не только у MS есть реализации C#. Кроме того у MS есть совместимая реализация Python.
И даже если и так, то история учит, что декстопным приложениям надежность вообще говоря не нужна. Ключевое слово — MicroSoft.То есть ты всё-таки согласен, что статическая типизация потенциально повышает надёжность, но в плюсы не записываешь, т.к. каким-то (совершенно непонятным) образом извлёк из истории Microsoft утверждение о том, что не нужна надёжность?
Зато на питоне быстрее (и дешевле) разработка, проще сопровождение, легко модифицировать программу.С чего ты это взял?
Синтаксического сахара больше в языке, есть интерпретатор, на котором быстренько можно проверить как работает та или иная функция - очень часто это гораздо более удобный подход чем юзание дебугера из иде.
Статической типизации, конечно, не хватает. Но не того убожества, что есть в императивных язычках, а нормальной, полиморфной.
И что там за сахар?
И что там за сахар?Сахар там сладенький, просто другой
вот ты заебал, посмотри уж учебник по питону. Много времени не потребуется, минут 40 - это не цешарп. Кстати, по этому поводу наблюдение: в традиционных императивных языках, вроде Це или Паскаля программы занимают много строк, но сами строки короткие. В функциональных языках вроде ML и Haskell программы занимают мало строк, но сами строки длинные. В цешарпе умудрились свести воедино два этих чудных свойства - программы занимают много строк, строки длинные.
оценивать язык по длине строчек - это 5
не люблю читать чужие выхлопы
Синтаксического сахара больше в языкеДело не в том, что я не знаю питона, а в том, что я не вижу там никакого особенного сахара в сравнении с C# кроме блоков, основанных на отступах. Это, конечно, круто, но недостаточно для наполнения смыслом цитаты.
public class FileClass
{
public static void Main
{
ReadFromFile("c:\\MyTextFile.txt");
}
static void ReadFromFile(string filename)
{
StreamReader SR;
string S;
SR=File.OpenText(filename);
S=SR.ReadLine;
while(S!=null)
{
Console.WriteLine(S);
S=SR.ReadLine;
}
SR.Close;
}
}
def main :
fl = open ("textfile")
for line in fl.xreadlines :
print line
fl.close
if __name__ == '__main__':
main
дальше продолжать?
дальше продолжать?Да-да, продолжай, продолжай!
А ты не пытался написать тоже самое на C#, но короче (зная язык, как Python)?
using System;Будешь число строчек сравнивать?
using System.IO;
class Program
{
public static void Main
{
foreach (var line in File.ReadAllLines("textfile"
Console.WriteLine(line);
}
}
main = do
s <- readFile "readfile"
putStr s
а ит кто?
Хаскель
Будешь число строчек сравнивать?
"Кого ты хотел удивить?"
print ''.join(file('test.txt').readlines.strip
Вообще, я люблю Python.
ээ.., типа после этого остается сказать cat ?
Я перевел пример на питоне несколькими постами выше в более естественную и короткую форму.
~/tmp fvv$ cat test.txt
a
b
~/tmp fvv$ cat test.py
print ''.join(file('test.txt').readlines.strip
~/tmp fvv$ python test.py
a
b
using System;
using System.IO;
class Program
{
public static void Main
{
foreach (var line in File.ReadAllLines("textfile"
Console.WriteLine(line);
}
}
import fileinput
for line in fileinput.input ('file'):
print line
ээ.. тоже самое?
Чтобы было больше похоже на cat лучше так:
~/tmp fvv$ cat cat.py
import fileinput, sys
[sys.stdout.write(line) for line in fileinput.input]
~/tmp fvv$ cat test.txt
a
b
~/tmp fvv$ cat test2.txt
foo
bar
~/tmp fvv$ cat test.txt test2.txt
a
b
foo
bar
~/tmp fvv$ python cat.py test.txt test2.txt
a
b
foo
bar
вот у cat есть еще параметры всякие, которые твоей строчкой не реализуются, очевидно.
просто сам спор про число строк странный, потому что рассматривается достаточно вырожденная задача, любое усложнение которой, приводит к сопоставимому по жирности коду. если ограничиться этой задачей, не предполагая ее усложнения, то для ее решения есть более адекватное средство из трех букв.
я вот это, наверное, имел в виду. это не возражение и не желание чему-то противоречить.
любое усложнение которой приводит к сопоставимому по жирности коду
Тут неправда.
Одинаковое усложнение задачи на Питоне и на C# приведет к программам разной длины (=жирности так же как и в случае "убогого cat".
Впрочем, объяснять зачем вообще нужны языки высокого уровня, почему их придумывают и чем один лучше другого не буду, в Гугле есть масса информации на тему.
Одинаковое усложнение задачи на Питоне и на C# приведет к программам разной длины (=жирности)Абсолютно не согласен.
Проги одинаково разрастутся.
Ты сравниваешь не языки, а стандартные библиотеки, "лаконичность" которых - одинакова.
print ''.join(file('test.txt').readlines.stripоно весь файл в память пихает?
оно весь файл в память пихает?Чёрт, папа пропалил детишек
Я перевёл написанное на Python на C#нет, неправда. В программе на цешарпе и бидоне открывался файловый объект, считывались строки, объект закрывался. Ты же потом привёл пример со считыванием из потокового объекта. Я говорю, что схожие действия дают в питоне существенно меньший объём кода.
А если xreadlines ?
Такой:
import fileinput, sys
for line in fileinput.input:
sys.stdout.write(line)
~/tmp fvv$ python cat.py test.txt test2.txt
a
b
foo
bar
хотелось бы посмотреть именно на мощность самого языка.
зы
for line in fileinput.input:а файл когда закрывается? непонятно когда?
sys.stdout.write(line)
что будет если этот кусок разбавить пересозданием файла и два раза подряд запустить?
нет, неправда. В программе на цешарпе и бидоне открывался файловый объект, считывались строки, объект закрывался. Ты же потом привёл пример со считыванием из потокового объекта. Я говорю, что схожие действия дают в питоне существенно меньший объём кода.А вот и правда ты на C# написал совсем не тоже, что на Python. Я на Python тоже могу написать эту простую программку в 15 строк.
Я не спорю, что я ответил не подобным (т.к. мой пример считывает всё сразу но смысл не в том.
Проги одинаково разрастутся.
нет, строк больше. Строки шире, за счёт совершенно бессмысмленных штучек типа var.
public class FileClassПосчитаешь строчки?
{
public static void Main
{
string S;
using(var SR=File.OpenText("c:\\MyTextFile.txt"
whileS=SR.ReadLine!=null)
Console.WriteLine(S);
}
}
Или ты будешь говорить, что языки, где фигурные скобки занимают целые строчки, да ещё и золотые строчки надо тратить на объявление переменных, аццтой по сравнению со всюду динамичным Python?
а файл когда закрывается? непонятно когда?
В конце программы.
языки, где фигурные скобки занимают целые строчки
... и где нагромождения public static void main class для программы в одно действие.
а если GC не успеет собрать всё ненужное к тому времени, как дескрипторы закончатся?
В конце программы.это и есть непонятно когда
плохой стиль, кусок кода получается неатомарный - порождает неочевидные побочные эффекты - за такой стиль руки отрывать надо.
Help on function input in module fileinput:
input(files=None, inplace=0, backup='', bufsize=0, mode='r', openhook=None)
input([files[, inplace[, backup[, mode[, openhook]]]]])
Create an instance of the FileInput class. The instance will be used
as global state for the functions of this module, and is also returned
to use during iteration. The parameters to this function will be passed
along to the constructor of the FileInput class.
я немного ошибся, там не нужно создавать временных объектов.
для программы в одно действиедля рпограмм в одно действие на C# есть PowerShell, который этого не требует, но под которым и нечего разрабатывать.
И вообще программы в одну строчку нечего рассматривать, когда разговор идёт об языках (по-разному) высокого уровня.
Хорошо, по-другому: в конце блока кода. Который обозначается отступами.
Хорошо, по-другому: в конце блока кода. Который обозначается отступами.т.е. питон автоматом чистит все неиспользуемые объекты при выходе из блока?
это действительно так? не верю. для этого надо граф ссылок считать, а это дорого.
Хорошо, по-другому: в конце блока кода. Который обозначается отступами.А Python точно себя так ведёт?
Спор не о чем. Имхо, вполне очевидно что C# громоздкий и корявый язык. Например для реализации INotifyPropertyChanged нужно писать тонну тупого кода.
Например для реализации INotifyPropertyChanged нужно писать тонну тупого кода.причем здесь язык? это же требования либы
на питоне это разве можно записать по другому? в питоне разве АОП есть?
Например для реализации INotifyPropertyChanged нужно писать тонну тупого кода.в либе WPF для этого, например, просто сделали DependencyProperty
Спор не о чем. Имхо, вполне очевидно что C# громоздкий и корявый язык. Например для реализации INotifyPropertyChanged нужно писать тонну тупого кода.Да, спор ни о чём. Ибо никто не сравнивал до сих пор языки - только библиотеки.
По выразительным способностям языки почти одинаковы, что-то там требует лишнюю строчку, что-то - там.
Думаешь, невозможно ткнуть в какое-нить узкое место Python и сказать "да вы что, это ж дерьмо, а не язык. В C# такого нет!"
Вроде да, что то связанное с пропертями и АОП в питоне как раз имеется.
просто сделали DependencyPropertyУгу, то еще чудеще.
Вроде да, что то связанное с пропернями и АОП в питоне как раз имеется.yandex пишет, что это внешняя либа.
для C# как внешняя шняга АОП тоже есть:
Для C#/VB.NET:
PostSharp
Aspect.NET
LOOM.NET
Puzzle.NAspect
AspectDNG
Aspect#
Encase
Compose*
Seasar.NET
DotSpect (.SPECT)
Как чаcть функциональности The Spring.NET Framework
По выразительным способностям языки почти одинаковы, что-то там требует лишнюю строчку, что-то - там.
Да-да, по выразительным способностям ассемблер и питон тоже примерно одинаковы.
def main :
with open ("textfile") as fl:
for line in fl.xreadlines :
print line
if __name__ == '__main__':
main
Все шарпные АОП библионеки либо тащат за собой DI, либо работают на уровне IL (PostSharp что к языку уже не имеет никакого отношения.
Давайте придумаем программу (ну не знаю, блог какой-нибудь без использования фреймворков (отдельно обговорим) и чисто на цгай). И померяем пиписьки шарпа и питона! А потом придумаем доп фичу, модифицируем и опять померяем. А иначе это спор глухих со слепыми. Одни много прогали на шарпе и мало или вообще нет на питоне - другие наоборот. Соответственно ни один не может похвастать практическим знанием и того и другого. Перейдем к практике и поставим жЫрную точку.
Я не понял, он про метапрограммирование опять? Я ж уже говорил об этом с ним
Ты ничего не знаешь про сборку мусора?
Ты ничего не знаешь про сборку мусора?я то как раз знаю, а вот ты мне кажется - приписываешь сборке мусора какие-то магические свойства.
1. Декораторами
2. В любом месте можно расширить или переопределить методы класса или уже готового экземпляра класса. Это очень полезно бывает при использовании сторонних либ. В общем, самый полноценный ООП из тех, которые бывают. Вроде в C# такого нет.
В общем, python силён в метапрограммировании. Очень красивый язык, при этом действительно лакончный..
объявление переменныхпеременных быть не должно. даже если они есть, то их тип легко выводиться => объявлений переменных быть не должно, даже var уже излишество.
ЗЫ уёбищный C, чем только КиР думали ....
В любом месте можно расширить или переопределить методы класса или уже готового экземпляра классаЯ бы не сказал, что это так уж хорошо.
наиболее "простой" способ в рамках языка реализовать фичуЧто для тебя - язык?
Сам язык с его фичами, или все стандартные функции?
Вроде да, что то связанное с пропертями и АОП в питоне как раз имеется.можно примеры кода на C# и на Python, реализующие INotifyPropertyChanged?
2. В любом месте можно расширить или переопределить методы классаА как это выглядит?
Что для тебя - язык?Что такое стандартные функции?
Сам язык с его фичами, или все стандартные функции?
В частности, в питоне может быть функция "прочитать файл и выдать все его строчки на stdout", тогда (при наличии такой функции) поставленная задача будет решаться в одну строчку (позвать эту функцию).
Но в сишарпе, даже если там и нет такой функции - её можно создать самому, после чего поставленная задача будет решаться таким же однострочником, и отличия этих однострочников будут всего лишь на уровне внешнего вида (фигурные скобки или отступы итп).
А вот если бы в сишарпе не было делегатов и анонимных функций вообще, то какую-нибудь задачу, которая на питоне (или чём-нибудь другом) решалась бы с их помощью, в сишарпе так же решить было бы нельзя - потому что это фишка языка, её реализовать самому в рамках этого языка нельзя.
В любом месте можно расширить или переопределить методы класса[Питона не знаю, поэтому рассуждения чисто из общих соображений] А хороши ли это? Писателю то конечно удобно переопределить в любом месте, а как насчет читателя? найдет ли он это место, чтобы разобрать что же все таки происходит?
Ну вот и выходит, что питон - хороший скриптовый язык, подходящий для одноразовых наколенных поделок.
можно примеры кода на C# и на Python, реализующие INotifyPropertyChanged?Странный вопрос, на C# я полагаю ты знаешь как это реализуется, а на питоне я сам не знаю, думаю это могло бы выглядеть в виде добавления декоратора к проперти. Во Flex'e по крайней мере это выглядит как то так:
[Bindable]
private var myResult:XML;
Тогда для меня это его спецификация.
А хороши ли это? Писателю то конечно удобно переопределить в любом месте, а как насчет читателя? найдет ли он это место, чтобы разобрать что же все таки происходит?
Ну, это уже не столько языка, сколько культуры программирования. На любом языке можно написать так, что нихера понятно не будет.
Для меня язык - это то, что используется разработчиками на этом языке (синтаксис, фишки, фреймворк итд) минус всё то, что может быть реализовано с помощью оставшейся части (конечно, такое определение неоднозначно, но навряд ли это действительно является проблемой).
И на поставленной тут задаче, похоже, питон от сишарпа будет отличаться только косметически (фигурные скобки итд).
Возможно, на других задачах будут и реальные отличия.
На любом языке можно написать так, что нихера понятно не будет.Но как-то странно преподносить фичу, у которой, по сути, единственный смысл - дать возможность писать так, что нихера понятно не будет, как такое огромное преимущество перед другим языком, из-за которого на другой язык надо забить.
Ну, это уже не столько языка, сколько культуры программирования.а что в данном контексте подразумевается под культурой? какие-то соглашения, которые не контролируются языком?
Но как-то странно преподносить фичу, у которой, по сути, единственный смысл - дать возможность писать так, что нихера понятно не будет, как такое огромное преимущество перед другим языком, из-за которого на другой язык надо забить.Переопределение действует только внутри той области видимости, в которой оно сделано, так что внешний пользователь его не заметит, и им будет пользоваться только тот, кто о нём знает. Ну, т.е. оно действует на вызываемые из этой области видимости методы, но после выхода из неё оно "откатывается" и пользователь работает уже в изначальном неизменённом контексте. Конечно, это опасный инструмент, но он очень мощный и позволяет иногда в две строчки сделать то, что иначе пришлось бы писать на два экрана.
PS. Я вообще в Python не силён, может я и пизжу насчёт его возможностей - когда-то изучал, а щас вот сходу не смог нийти, где написано про то, что я говорю. Может я его с Ruby путаю? Вроде нет...
C# and Python comparison
Предлагаю написать реализацию простого ThreadPool на Питоне и Шарпе и сравнить код.
Вот Шарп:
Использование:
(Не для сравнения) на моём Core2Duo 2Ghz результат такой:
Предлагаю написать реализацию простого ThreadPool на Питоне и Шарпе и сравнить код.
Вот Шарп:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace MyProgram
{
public class SimpleThreadPool : IDisposable
{
readonly Action<Exception> _errorAction;
readonly List<Thread> _threads = new List<Thread>
readonly Queue<Action> _taskQueue = new Queue<Action>
readonly object _syncObj = new object;
static readonly Action<Exception> DefaultExceptionLogger = ex => Trace.TraceWarning("Error during task execution: {0}", ex);
public SimpleThreadPool(int threadCount)
: this(threadCount, DefaultExceptionLogger)
{
}
public SimpleThreadPool(int threadCount, Action<Exception> errorAction)
{
Debug.Assert(errorAction != null);
_errorAction = errorAction;
for (int i = 0; i < threadCount; i++)
_threads.Add(CreateThread;
}
Thread CreateThread
{
Thread thread = new Thread(ThreadProc);
thread.Name = "AsyncTaskProcessor thread";
thread.IsBackground = true;
thread.Start;
return thread;
}
/// <summary>
/// Run task asynchronously
/// Beware of changing variables in closures!
/// </summary>
public void RunTask(Action task)
{
lock (_syncObj)
{
_taskQueue.Enqueue(task);
Monitor.Pulse(_syncObj);
}
}
void ThreadProc
{
for (; ; )
{
Action task;
lock (_syncObj)
{
while (_taskQueue.Count == 0)
Monitor.Wait(_syncObj);
task = _taskQueue.Dequeue;
}
try
{
task;
}
catch (Exception ex)
{
_errorAction(ex);
}
}
}
public void Dispose
{
foreach (var thread in _threads)
thread.Abort;
}
}
}
Использование:
using System;
using System.Threading;
using System.Diagnostics;
namespace MyProgram
{
class Program
{
static void Main(string[] args)
{
Process.GetCurrentProcess.PriorityClass = ProcessPriorityClass.RealTime; // Для чистоты эксперимента
using (var threadPool = new SimpleThreadPool(2
{
for (int i = 25; i <= 42; i++)
{
int tmp = i; // Дурацкое место, но без него не знаю как
threadPool.RunTask => ShowFibonacci(tmp;
}
Console.WriteLine("Press ENTER to finish");
Console.ReadLine;
}
}
static void ShowFibonacci(int number)
{
var timer = Stopwatch.StartNew;
long fibonacci = Fibonacci(number);
timer.Stop;
Console.WriteLine("Thread {0}: Fib {1} = {2}, took {3}ms", Thread.CurrentThread.ManagedThreadId, number, fibonacci, timer.ElapsedMilliseconds);
}
static long Fibonacci(long number)
{
if (number <= 2)
return 1;
return Fibonacci(number - 1) + Fibonacci(number - 2);
}
}
}
(Не для сравнения) на моём Core2Duo 2Ghz результат такой:
Press ENTER to finish
Thread 10: Fib 25 = 75025, took 2ms
Thread 10: Fib 26 = 121393, took 3ms
Thread 11: Fib 27 = 196418, took 5ms
Thread 10: Fib 28 = 317811, took 8ms
Thread 11: Fib 29 = 514229, took 19ms
Thread 10: Fib 30 = 832040, took 22ms
Thread 11: Fib 31 = 1346269, took 35ms
Thread 10: Fib 32 = 2178309, took 57ms
Thread 11: Fib 33 = 3524578, took 92ms
Thread 10: Fib 34 = 5702887, took 153ms
Thread 11: Fib 35 = 9227465, took 242ms
Thread 10: Fib 36 = 14930352, took 396ms
Thread 11: Fib 37 = 24157817, took 634ms
Thread 10: Fib 38 = 39088169, took 1042ms
Thread 11: Fib 39 = 63245986, took 1660ms
Thread 10: Fib 40 = 102334155, took 2705ms
Thread 11: Fib 41 = 165580141, took 4363ms
Thread 10: Fib 42 = 267914296, took 7104ms
---
Окей, давай языки сравним.
Питон:
a, b = f # сравни с траханьем с out parameters в шарпе. Это не одна лишняя строчка.
for i, k in enumerate(collection): # то же самое опять. KeyValuePair очень убого рядом смотрится.
x = [i + j for i in range(10) if i != 5 for j in range(10) if i > j] # УДОБНО!
дефолтные/именованные параметры. Мне доводилось с десяток оверлоадов для одной функции писать, состоящих из тупых вызовов полной версии с подставленными дефолтными параметрами, это неправильно. Плюс озвёздывачение параметров, типа func(*params, **namedparams автоматически распихивающее содержимое данного ей списка и словаря по параметрам.
И, кстати, в шарпе до сих пор нет возможность проинициализить коллекцию (EDIT: словарь! Я словарь имел в виду, но испытал помутнение рассудка!).
Ничейные функции. Если я пишу шарпокласс Func, состоящий из статических полезных методов, мне всё равно приходится каждый раз писать Func.MyUsefulMethod(...).
arr = [1, 2, 3]
print arr[1:], arr[1:1], arr[:1], arr[-1:] # и так далее. Слайсы прекрасны, без них плохо.
Динамическая типизированность позволяет не писать ту лишнюю фигню, которую ещё не успели изничтожить в шарпе, вроде километровых инициализаций List<ofSomething> полей классов.
else: у циклов. Просто приятно иногда.
Ну и ещё всякое, чего я сейчас не помню.
Шарп:
Нормальные лямбды. И запись короче, и statements могут содержать, и писать в родительские переменные. С питоновским убожеством как-то даже стыдно сравнивать.
Структуры, unsafe код. Если вдруг нужно пооптимизировать что-нибудь, это гарантированно будет возможно.
Нормальные raw string literals. Опять же, с питоновским идиотизмом не хочется сравнивать просто.
И, раз уж мы говорим о языках в смысле лёгкости написания, то статическая типизация + интеллисенс дают прирост скорости кодирования в миллион раз больший, чем тратится на явные объявления. Так есть. Плюс, нахаляву, всё-таки довольно большая часть ошибок отлавливается в компайлтайме.
И, кстати, в шарпе до сих пор нет возможность проинициализить коллекцию.что имеется ввиду?
Выше подразумевалось, насколько я понимаю, что ты можешь взять и сделать что-нибудь вроде
def open(url, new, autore):
print "Hijacked webbrowser.open:", str(url)
ShellExec(HijackedWebbrowserCmdLine(url False, True)
savedOpen = webbrowser.open
webbrowser.open = open
после чего вызвать какую-нибудь чужую функцию, использующую модуль webbrowser.
Для списков инициализаторы сделали, для объектов тоже, а для коллекций — забыли.
a = {"a" : 1, "b" : 2, "c" : 3 }Это словарь?
так коллекций или словарей?
Да, кстати, вот ещё что вспомнил:
необходимость писать self при доступе к полям класса задалбывает просто нечеловечески. В сочетании с убогими лямбдами (которые не могут изменять переменные из родительского scope по той же причине) заставляет придти к выводу, что явное объявление всё-таки лучше.
В питоне отсутствует оверлоадинг, вообще. Нет, я понимаю, что в шарпе он в трёх случаях из четырёх используется из-за отсутствия дефолтных/именованных параметров, но всё же. Поэтому мне кажется, что явное объявление типов параметров функций тоже в целом добавляет удобства.
Окей, давай языки сравним.Спасибо
Питон:
a, b = f # сравни с траханьем с out parameters в шарпе. Это не одна лишняя строчка.
int a,b;пренебрежимо мало
f(out a, out b);
for i, k in enumerate(collection): # то же самое опять. KeyValuePair очень убого рядом смотрится.весьма сомнительно. имо, одно и то же
x = [i + j for i in range(10) if i != 5 for j in range(10) if i > j] # УДОБНО!бесспорно
дефолтные/именованные параметры.от них избавились почти обоснованно, но, согласен, зря.
Плюс озвёздывачение параметровтут C# не виноват, да и params исправляют половину (хоть и без типизации, к содалению)
Ничейные функции. Если я пишу шарпокласс Func, состоящий из статических полезных методов, мне всё равно приходится каждый раз писать Func.MyUsefulMethod(...).5 символов роли не играют (не будем "мерять строчки" )
arr = [1, 2, 3]Гвидо - гений
print arr[1:], arr[1:1], arr[:1], arr[-1:] # и так далее. Слайсы прекрасны, без них плохо.
Динамическая типизированность позволяет не писать ту лишнюю фигню, которую ещё не успели изничтожить в шарпе, вроде километровых инициализаций List<ofSomething> полей классов.Некоторые вещи не просто так называются сахаром - они излишни. C# хорошо и читается, и пишется, и самодокументируется. (втч. благодаря <ofSomething>)
else: у циклов. Просто приятно иногда.
Ну и ещё всякое, чего я сейчас не помню.
Шарп:Python легко расширяется нативными библиотеками (немогим сложнее C#)
...
Структуры, unsafe код. Если вдруг нужно пооптимизировать что-нибудь, это гарантированно будет возможно.
И, раз уж мы говорим о языках в смысле лёгкости написания, то статическая типизация + интеллисенс дают прирост скорости кодирования в миллион раз больший, чем тратится на явные объявления. Так есть. Плюс, нахаляву, всё-таки довольно большая часть ошибок отлавливается в компайлтайме.Именно поэтому и не стоить экономить на единицах строчек или букав - оно очень пригодится.
x = [i + j for i in range(10) if i != 5 for j in range(10) if i > j] # УДОБНО!в чем смысл конструкции? т.е. что она вообще делает?
C# and Python comparisonКажется, там забыли про JIT для Python.
x = [i + j for i in range(10) if i != 5 for j in range(10) if i > j] # УДОБНО!в чем смысл конструкции? т.е. что она вообще делает?
print arr[1:], arr[1:1], arr[:1], arr[-1:] # и так далее. Слайсы прекрасны, без них плохов чем отличие от функции Range?
arr.Range(1, null arr.Range(1, 1 arr.Range(null, 1 arr.Range(-1, null)
IEnumerable<T> Range<T>(this IList<T> items, int? start, int? end)
{
for (int i = Math.Max(start ? 0, 0); i <= Math.Min(end ? items.Count,items.Count); ++i)
{
yield return items[i];
}
}
if i != 5а это куда делось?
Только отрицательные значения обработать надо аккуратно - они с конца считаются.
сумму считает? функцию определяет?
if i != 5Потерялось по дороге. Но ведь смысл понятен
а это куда делось?
и в итоге все равно не понял, что конструкция делаетгенерирует последовательность чисел, т.е мн-во, что я написал.
сумму считает? функцию определяет?
(в х будет массив значений в этом множестве)
генерирует последовательность чисел, т.е мн-во, что я написал.т.е. фактически?:
_.Generate(1, 10)
.Where(i => i != 5)
.SelectMany(i =>
_.Generate(1, 10)
.Where(j => i > j)
.Select(j => i + j)
)
карта бита.
1.To(10)
.Where(i => i != 5)
.SelectMany(i =>
1.To(10)
.Where(j => i > j)
.Select(j => i + j)
)
Имо, одно и то же - без разницы, как передавать параметры в метод.
Переопределение действует только внутри той области видимости, в которой оно сделано, так что внешний пользователь его не заметит, и им будет пользоваться только тот, кто о нём знает. Ну, т.е. оно действует на вызываемые из этой области видимости методы, но после выхода из неё оно "откатывается" и пользователь работает уже в изначальном неизменённом контексте. Конечно, это опасный инструмент, но он очень мощный и позволяет иногда в две строчки сделать то, что иначе пришлось бы писать на два экрана.PS. Я вообще в Python не силён, может я и пизжу насчёт его возможностей - когда-то изучал, а щас вот сходу не смог нийти, где написано про то, что я говорю. Может я его с Ruby путаю? Вроде нет...Приношу извинения, действительно нагнал. Эта фича есть в Ruby, и реализована она не так элегантно, как я описал - можно динамически расширять объекты и классы, в т.ч. переопределяя методы, однако методы переопределяются на совсем. Однако старую реализацию можно сохранить как алиас, после чего возвернуть назад, повторно перекрыв ей тот же метод. Ну, то бишь оно действительно требует гораздо более аккуртаного обращения. Так что полезность не совсем очевидна, но зато красиво. Ну и я встречал пару грамотных применений данной фичи, где оно действительно полезно.
Нечто похожее есть в JavaScript, но там оно гораздо более коряво сделано...
PS.
То бишь у питона остаются только декораторы из плюшек, ну и всякий синтаксический сахар.
Тред пул, судя по тому, что я посмотрел у тебя, вряд ли что-то покажет, то есть питонокод будет короче только за счет отсутствия скобок, отсутствия типов и кучи левого гвн, типа неймспейсов, так как собственно ничего и не делается, у тебя несколько оч мелких методов, и из них еще несколько перегруженных. Короче, от аналогичного питонокода в глазах будет рябить существенно меньше (экономия на объявлениях но ощутимой "победы" в логике не будет. Хотя...
Ссылка на сравнение нах? Кто-то говорил, что питон мегабыстр? Так не бывает - за все надо расплачиваться.Как минимум по ссылке видно, что все программы на питоне короче, чем аналогичные програмы на C#.
А мы спорим не просто о краткости. Требуется еще и четкость. Ясность. А для этого нужно видеть код.
То бишь у питона остаются только декораторы из плюшек, ну и всякий синтаксический сахар.Метаклассы тоже сахар?
Ты направо смотри. Питон молодец.
В Питоне есть аналог using и lock? (может их можно самому сделать? - в шарпе это расширять нельзя).
Как там Лямбды выглядят? Замыкания есть?
Кстати, Питон хвостовую рекурсию рюхает? (шарп - нет)
шарп - нетимхо, ты не прав
в CIL'е есть префикс tail к инструкциям возврата из функции
вряд ли основной язык не умеет ими пользоваться
В Питоне есть аналог using и lock?
with + contextlib ?
зависит от реализации. На момент 2.0, точно знаю, .нетовский не рюхал. Моновский рюхает.
Кто говорил?Аналог есть - уже ответили
Ты направо смотри. Питон молодец.
В Питоне есть аналог using и lock? (может их можно самому сделать? - в шарпе это расширять нельзя).
Как там Лямбды выглядят? Замыкания есть?
Кстати, Питон хвостовую рекурсию рюхает? (шарп - нет)
Есть, но и те и эти серьезно урезаны. Они не могут модифицировать переменные внешнего скоупа, а в лямбдах ко всему прочему еще и только экспрешнз позволительны.
Хвостовая рекурсия была. Но она не оптимизирована, хотя на моей памяти кто-то ее оптимизировал через декоратор, активно юзающий интроспекцию (конкретно стек фреймов интерпретатора) через методы стандарт либы.
Предложение "не спорить о длине строчек" мне не нравится поэтому. Оно иногда уместно, параметр "длина строчки" (или, ещё лучше, "количество синтаксических элементов") не обязательно соответствует скорости написания и скорости осознанного чтения (тоже не обязательно совпадающих которые нас, собственно, и интересуют, правда? Но часто соответствует. И даже можно учитывать то, что длина разных строчек может быть разной, как вот в питоне по сравнению с шарпом любое объявление локальной переменной короче на слово "var", но зато обращение к переменной родительского scope, если уж понадобится, будет намного длиннее и через жопу.
Поэтому я всё-таки хочу сравнивать длины строчек, количество символов и так далее.
Я всё-таки уверен, что запись через слайсы удобней, быстрее пишется и читается, чем вызов функции. Кстати, слайсам ведь и присваивать можно =) Не, это не проблема, достаточно добавить ещё AssignRange, чтобы
a[:2] = a[-2:]
превратилось в
a.AssignRange(0, 2, a.Range(a.Count - 3, 2;
Первая запись лучше.
Я хочу считать строчки в записи
a, b = f
по сравнению с
int a;
List<KeyValuePair<string, IEnumerable<string>> b;
f(out a, out b);
Подсчёт строчек и синтаксических элементов в данном случае даёт результат, вполне адекватный интересующим нас реальным вариантам удобства.
Я хочу считать символы в записи
private List<KeyValuePair<string, IEnumerable<string>> list = new List<KeyValuePair<string, IEnumerable<string>>
Она меня бесит! Так нельзя, блин!
Кстати, по поводу питоновского GC, он же всё-таки ссылки считает и удаляет сразу. Там были какие-то гарантии на что-то, разве нет?
x = [i + j for i in range(10) if i != 5 for j in range(10) if i > j] # УДОБНО!Не знаю, как правильно делать в сишарпе массивы переменной длины, но чем твоя строчка лучше пхпшного
$x = array;На одну строчку (инициализация массива) длиннее.
foreach(range(1,10) as $i) if($i != 5) foreach(range(1,10) as $j) if ($i > $j) $x[] = $i+$j;
a, b = f # сравни с траханьем с out parameters в шарпе. Это не одна лишняя строчка.А если что-нибудь вроде
class StructWithTwoFields<T1,T2> {
public T1 field1;
public T2 field2;
public StructWithTwoFields(T1 field1, T2 field2) {
this.field1 = field1;
this.field2 = field2;
}
}
сделать?
Насколько я тебя понимаю, это будет, в общем-то, то же самое.
И, кстати, в шарпе до сих пор нет возможность проинициализить коллекцию (EDIT: словарь! Я словарь имел в виду, но испытал помутнение рассудка!).ЧТо-то я не пойму, что ты имеешь в виду.
инамическая типизированность позволяет не писать ту лишнюю фигнюДело вкуса. Тебе нравится динамическая типизированность - а меня в сишарпе очень привлекает его полностью статическая типизация.
Ничейные функции. Если я пишу шарпокласс Func, состоящий из статических полезных методов, мне всё равно приходится каждый раз писать Func.MyUsefulMethod(...).Ну и что?
Рассматривай это "Func." как префикс к функции, вот и всё.
Ты ещё длиной названий стандартных функций померяйся.
Аналог есть - уже ответили
Вот на что не ответил:
(может их можно самому сделать? - в шарпе
это расширять нельзя)
Их можно сделать и расширять.
Простой пример:
from __future__ import with_statement
import time
from contextlib import contextmanager
@contextmanager
def timer(message):
start = time.time
try:
yield
except Exception, exc:
print message, 'failed:', exc
print '%s time:' % message, time.time-start
with timer('test-1'):
a = b + c
with timer('test-2'):
b = 'foo'
c = 'bar'
~/tmp fvv$ python test.py
test-1 failed: name 'b' is not defined
test-1 time: 0.000936985015869
test-2 time: 2.59876251221e-05
Как минимум по ссылке видно, что все программы на питоне короче, чем аналогичные програмы на C#.Ага - наверное, из-за того, что там функции короче и непонятнее называются.
Да, и ещё там на скобках сэкономили
Мы ведь уже не во время дискет живём, зачем экономить байты?
Ну, сказали же 'with' + contextlib. По-моему это ответ на оба подвопроса
вообще-то, если говорить строго, у цешарпа типизация динамическая, статическая она только по отношению к атомарным типам.
Нет, не правильно. В Питоне есть счетчик ссылок на объект, когда количество ссылок становится равным 0, объект удаляется.тому кто хорошо понимает устройство Питона - это что действительно так?
т.е. так же как это было в COM-е и лохматом VB?
это же тормозная лажа...
а с "островами" (с кластером - в котором есть циклические ссылки на друг друга, но при этом на этот кластер нет ссылок снаружи) как GC питона разбирается?
вообще-то, если говорить строго, у цешарпа типизация динамическая, статическая она только по отношению к атомарным типам.Да ты же упоротый! Где она динамическая? Возможность кастов ты считаешь признаком динамической типизации? Так они обязаны быть explicitly указаны статически. Полиморфизм ты считаешь признаком динамичности? Возможность динамически диспатчнуть вызов метода со статически указанными типами параметров, статически помеченный как виртуальный?
Ты хоть один динамически типизированный язык видел вообще?
Пожалуй, я начинаю относиться к твоим словам с той же готовностью вступить в дискуссию, что и к пенартуровским.
http://python.org/doc/api/refcounts.html
The reference count is important because today's computers have a finite (and often severely limited) memory size; it counts how many different places there are that have a reference to an object. Such a place could be another object, or a global (or static) C variable, or a local variable in some C function. When an object's reference count becomes zero, the object is deallocated. If it contains references to other objects, their reference count is decremented. Those other objects may be deallocated in turn, if this decrement makes their reference count become zero, and so on. (There's an obvious problem with objects that reference each other here; for now, the solution is ``don't do that.'')
http://www.python.org/doc/ext/refcounts.html
While Python uses the traditional reference counting implementation, it also offers a cycle detector that works to detect reference cycles. This allows applications to not worry about creating direct or indirect circular references; these are the weakness of garbage collection implemented using only reference counting. Reference cycles consist of objects which contain (possibly indirect) references to themselves, so that each object in the cycle has a reference count which is non-zero. Typical reference counting implementations are not able to reclaim the memory belonging to any objects in a reference cycle, or referenced from the objects in the cycle, even though there are no further references to the cycle itself.
ну да, когда один объект может иметь два типа - базового класса и производного, т.е. проверки осуществляются в рантайме, то это и называется динамической типизацией. В цешарпе этот факт обложен костылями с ниибацо крутыми названиями, но суть от этого не меняется. А статическая типизация - она, например, есть во многих функциональных языках
когда один объект может иметь два типа - базового класса и производного, т.е. проверки осуществляются в рантайме, то это и называется динамической типизацией
Охтыблин, а в Хаскеле какая типизация?
Да уж, работой с памятью питон похвастаться не может.
статическая. Объект там всегда имеет определённый и единственный тип. Этот тип может относиться к некоторому классу типов.
Ну и, основываясь на собственном опыте, могу сказать, что когда объект может иметь два типа - это пиздец.
Пример?
Собственная поделка со статической типизацией. Там был один объект, могущий обладать двумя типами. Из-за этого код транслятора очень сильно увеличился в размерах.
Вообще хотелось увидеть пример того как все плохо в C# с его базовыми и производными классами, и как тоже самое замечательно реализуется во многих функциональных языках.
инициализацию словаря к своим классу словаря применять можно?
имхо, встроенный конструкции хорошо, если это просто сахар к конструкциям, которые может развивать пользователь языка, а не жесткие конструкции, которые может менять только разработчики языка.
кхм, вот, положим, есть два класса, foo и bar, производные от некоторого базового класса lol. Мы в некоторой функции получаем некоторый экземпляр var класса типа lol. Положим, в ходе программы по логике исполнения, это должен быть объект класса foo. Пусть есть какая-то функция int bugaga (bar arg1). И мы можем вызвать её через bugaga (var as bar).
В C# нет множественного наследования?
Множественное наследование - говно.
кхм, вот, положим, есть два класса, foo и bar, производные от некоторого базового класса lol. Мы в некоторой функции получаем некоторый экземпляр var класса типа lol. Положим, в ходе программы по логике исполнения, это должен быть объект класса foo. Пусть есть какая-то функция int bugaga (bar arg1). И мы можем вызвать её через bugaga (var as bar).Ты, наверное, тут опечатался, и хотел сказать, что по логике исполнения это должен быть объект класса bar.
Иначе совершенно непонятно, что случится в таком случае:
abstract class lol { }
class foo : lol {
}
class bar : lol {
public void doBar { }
}
class Program {
private void doSomethingWithBar(bar myBar) {
myBar.doBar;
}
public void Main {
foo myFoo = new foo;
Program.doSomethingWithBarbar)myFoo);
}
}
и? это как-то отменяет де-факто динамическую типизацию для иерархий классов?
Нужно явно приводить bugagabar)var и получать вполне внятное исключение.
Ты, наверное, тут опечатался, и хотел сказать, что по логике исполнения это должен быть объект класса bar.
да, сенкс
которое рантаймовое. Таким же образом мы и в питоне можем контролировать типы переменных
Ну и замечательно, в сишарпе это делать тоже можно, как мне рассказали в соседнем треде, при таком преобразовании сам объект никуда не переводится.
Допустим. Теперь осталось узнать альтернативы.
Я просто увидел извращения, и подумал что видимо в C# нет множественного наследования, раз все через такую задницу.
Погуглил — и правда нет.
def __getitem__(self, index):
if isinstance(index, types.SliceType):
if None == index.step:
return [self[item] for item in xrange(index.start, index.stop)]
else:
return [self[item] for item in xrange(index.start, index.stop, index.step)]
else:
if index >= len(self.primes) :
extendTo = index * 2 - index // 2
i = self.primes[-1]
for counter in xrange(len(self.primes extendTo):
i += 2
while not self._AddPossiblePrime(i):
i += 2
return self.primes[index]
(хотя я неопытный питонист, может, ещё проще принято писать)
Да, конечно: пишешь у своего словаря/коллекции конструктор, принимающий "просто" словарь/коллекцию и всё.
кхм, вот, положим, есть два класса, foo и bar, производные от некоторого базового класса lol. Мы в некоторой функции получаем некоторый экземпляр var класса типа lol. Положим, в ходе программы по логике исполнения, это должен быть объект класса foo. Пусть есть какая-то функция int bugaga (bar arg1). И мы можем вызвать её через bugaga (var as bar).не пиши так
это код из разряда "сам себе злобный буратино"
отказаться от понятия класса принятого в java, c# и пр. как основного понятия языка. Всё равно, в этом виде они нечасто бывают удобны (в моих задачах в основном так, как у других не знаю).
Опять же, хочется увидит мысль выраженную в живом коде.
я на функциональных языках делал только вещи связанные со всякими синтаксическими разборами, и там их система алгебраической типизации рулит немерянно. Причём на цешарпе я бы реализовывал её как раз через дурные иерархии классов. Насчёт других областей сказать ничего не могу, т.к. нет опыта использования.
и там их система алгебраической типизации рулит немерянно.Вот и хочется увидит как она рулит. В частности реализуй тоже , и что бы оно у тебя ругалось при компиляции.
Я бы рад, да только не представляю, как реализовать эту ересь. Т.е. ещё на уровне языка идёт сопротивление написанию откровенного бреда.
О чем тогда разговор? Ты не можешь реализовать простую иерархию из трех элементов, но предлагаешь выкинуть классы как не нужные.
Зачем вообще иерархия? Нафига? Динамику плодить?
Ну так, я ещё раз объясняю на примере задач разбора текста: там часто используют шизофренические иерархии классов для представления деревьев, что даёт огромный оверхед, когда можно обойтись однострочечным описанием типа.
Сразу бы и писал что ты против наследования. Думаю да, можно обойтись только интерфейсами и что нибудь типа миксинов, но такой идеологии можно и в шарпе придерживаться, хотя это будет выглядеть жутко.
Нет, ну сколько можно? Два плюса за пост, посрамляющий Высера. Остальное - минусы за вопросы и высказывание мыслей по делу.
Что, Development самый говяный раздел форума, раз у нас на первой странице вчера не было ни одной темы с положительной репутацией?
Не то, чтобы я дрочил на репутацию, но всё это говорит о некоторой общей неадекватности людей, которые сюда пишут. Причём проявляется она, имхо, в нетерпимости и брызганье слюной во фразах вида "я не буду отвечать идиотам как ты раз ты не видишь очевидного" из лагеря сторонников Python в лагерь сторонников C# и обратно.
Надо вести дискуссии не брызжа слюной в стороны. Пора исправляться, чёрт возьми!
Просто прогнали пару скриптов, которые выставляют отрицательные оценки (или может руками было не влом выставлять):
в этом отметились:
crypto
photograff
Transmission
Dihlofos
чо, типа самый умный шоле?
Оставить комментарий
agaaaa
Почему ты думаешь, что он "моднее" C#?