AVK Selected

Показавшиеся интересными, на мой вкус, посты

C# for Systems Programming

Nikkk2010 Nikkk2010

Joe Duffy's team has been designing and implementing a set of “systems programming” extensions to C# over the past 4 years.
At long last, I’ll begin sharing our experiences in a series of blog posts.

The first question is, “Why a new language?”


Ссылка
Artem Korneev
Artem Korneev
30.12.2013 11:32
Здравствуйте, Nikkk2010, Вы писали:

Наткнулся на вот эту диаграмму в блоге.

http://joeduffyblog.com/images/2013_LangQuad.jpg

Коллеги, скажите, а что вы думаете о ней? Меня интересует положение JavaScript. Часто вот в таких статьях как-то к слову говорится, что писать на JavaScript легко и просто и разработчики просто спят и видят как бы использовать JavaScript вместо всех остальных языков.
Но сколько я с ним ни сталкивался — боль и ужас. По параметрам "Safety & Productivity" я бы убрал его в левый нижний угол.

Вообще я грешил на своё плохое знание JavaScript и по возможности стараюсь это исправить — вот буквально два дня назад на распродаже купил десяток книг, из них две — по jQuery. По работе частенько приходится сталкиваться с JS, допиливая какие-нибудь веб-интерфейсы.

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

Куда бы вы поместили JavaScript на этой диаграмме?
dsorokin
dsorokin
01.01.2014 04:12
Здравствуйте, Artem Korneev, Вы писали:

AK>Наткнулся на вот эту диаграмму в блоге.


Надо понимать, что "X" — это сокращение от слова "Хаскель"?
AndrewVK
AndrewVK
01.01.2014 07:22
Здравствуйте, dsorokin, Вы писали:

D>Надо понимать, что "X" — это сокращение от слова "Хаскель"?


Хаскель уже без ГЦ обходится?
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
D. Mon
D. Mon
02.01.2014 11:28
Здравствуйте, AndrewVK, Вы писали:

D>>Надо понимать, что "X" — это сокращение от слова "Хаскель"?

AVK>Хаскель уже без ГЦ обходится?

Полагаю, в умелых руках всякие критичные к скорости циклы там можно делать без лишних аллокаций и вызова GC.
А если в целом, то согласно Страуструпу современный С++ — язык со сборкой мусора (причем плохой: на подсчете ссылок, т.е. медленной, ненадежной и небезопасной).
Evgeny.Panasyuk
Evgeny.Panasyuk
02.01.2014 11:49
Здравствуйте, D. Mon, Вы писали:

D>>>Надо понимать, что "X" — это сокращение от слова "Хаскель"?

AVK>>Хаскель уже без ГЦ обходится?
DM>Полагаю, в умелых руках всякие критичные к скорости циклы там можно делать без лишних аллокаций и вызова GC.

Как ни крути, когда в языках с GC-by-default требуется performance — от этого GC в той или иной мере пытаются избавиться.

DM>А если в целом, то согласно Страуструпу современный С++ — язык со сборкой мусора (причем плохой: на подсчете ссылок, т.е. медленной, ненадежной и небезопасной).


1. Есть интерфейс для консервативного GC.
2. Некоторые смарт-поинтеры используют подсчёт ссылок. Но они требуются только при наличии shared семантики, которая встречается крайне редко — в большинстве кода никакой ref-counting не нужен.

DM>(причем плохой: на подсчете ссылок, т.е. медленной,


Почему медленной?

DM>ненадежной


У неё есть свои предусловия, точно также как и у других GC. Утечки могут быть хоть в C#/Java/Haskell

DM>и небезопасной).


Почему небезопасной?
D. Mon
D. Mon
02.01.2014 03:47
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Как ни крути, когда в языках с GC-by-default требуется performance — от этого GC в той или иной мере пытаются избавиться.


Это неполное видение: как ни крути, в любых языках когда требуется performance — пытаются избавиться от лишних аллокаций. Но в целом согласен. Например, в С++ пытаются избавиться от shared указателей.

DM>>А если в целом, то согласно Страуструпу современный С++ — язык со сборкой мусора (причем плохой: на подсчете ссылок, т.е. медленной, ненадежной и небезопасной).

EP>1. Есть интерфейс для консервативного GC.

Это тоже медленно и ненадежно.

EP>2. Некоторые смарт-поинтеры используют подсчёт ссылок. Но они требуются только при наличии shared семантики, которая встречается крайне редко — в большинстве кода никакой ref-counting не нужен.


Это уже детали и спекуляции.

DM>>(причем плохой: на подсчете ссылок, т.е. медленной,


EP>Почему медленной?


http://research.microsoft.com/pubs/202163/rcix-oopsla-2013.pdf
http://www.cs.virginia.edu/~cs415/reading/bacon-garbage.pdf

DM>>и небезопасной).

EP>Почему небезопасной?

Потому что система типов слишком легко позволяет поиметь указатель на мертвый объект, например. Или перепутать виды указателей, использовать shared там где нужен weak или наоборот. Нет никаких гарантий, все управление памятью на честном слове держится.
Evgeny.Panasyuk
Evgeny.Panasyuk
02.01.2014 04:55
Здравствуйте, D. Mon, Вы писали:

EP>>Как ни крути, когда в языках с GC-by-default требуется performance — от этого GC в той или иной мере пытаются избавиться.

DM>Это неполное видение: как ни крути, в любых языках когда требуется performance — пытаются избавиться от лишних аллокаций.

Согласен, но в C++ это достигается легко, без потери абстракций. А в языках с GC переходят на уровень даже ниже чем C — играют массивами байт.

EP>>2. Некоторые смарт-поинтеры используют подсчёт ссылок. Но они требуются только при наличии shared семантики, которая встречается крайне редко — в большинстве кода никакой ref-counting не нужен.

DM>Это уже детали и спекуляции.

Это факт — ref counting в C++ нужен редко.

DM>>>(причем плохой: на подсчете ссылок, т.е. медленной,

EP>>Почему медленной?
DM>http://research.microsoft.com/pubs/202163/rcix-oopsla-2013.pdf

RC divides execution into three distinct phases: mutation, reference counting collection, and cycle collection.


DM>http://www.cs.virginia.edu/~cs415/reading/bacon-garbage.pdf


We have implemented both types of collector: a multiprocessor concurrent reference counting collector with cycle collection

В обоих случаях говорится про ref-counted GC со сборкой циклов. Это принципиально отличается от того что даёт std::shared_ptr — никакого cycle collection там нет

DM>>>и небезопасной).

EP>>Почему небезопасной?
DM>Потому что система типов слишком легко позволяет поиметь указатель на мертвый объект, например. Или перепутать виды указателей, использовать shared там где нужен weak или наоборот. Нет никаких гарантий, все управление памятью на честном слове держится.

При раскладывании объектов по массивам байт в управляемых языках возникают те же проблемы.
VladD2
VladD2
03.01.2014 01:51
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>2. Некоторые смарт-поинтеры используют подсчёт ссылок. Но они требуются только при наличии shared семантики, которая встречается крайне редко — в большинстве кода никакой ref-counting не нужен.


Это ты расскажи тем кто Хорм в Гуле пилит. Они в итоге замаялись с тормозным и глючным посчетом ссылок и запилили ЖЦ для плюсов. Убогий конечно, но для их задач все равно лучше чем то что можно сделать в плюсах без него.
Evgeny.Panasyuk
Evgeny.Panasyuk
03.01.2014 09:48
Здравствуйте, VladD2, Вы писали:

EP>>2. Некоторые смарт-поинтеры используют подсчёт ссылок. Но они требуются только при наличии shared семантики, которая встречается крайне редко — в большинстве кода никакой ref-counting не нужен.

VD>Это ты расскажи тем кто Хорм в Гуле пилит. Они в итоге замаялись с тормозным и глючным посчетом ссылок и запилили ЖЦ для плюсов. Убогий конечно, но для их задач все равно лучше чем то что можно сделать в плюсах без него.

А есть ссылка?
Ikemefula
Ikemefula
03.01.2014 10:37
Здравствуйте, VladD2, Вы писали:

EP>>2. Некоторые смарт-поинтеры используют подсчёт ссылок. Но они требуются только при наличии shared семантики, которая встречается крайне редко — в большинстве кода никакой ref-counting не нужен.


VD>Это ты расскажи тем кто Хорм в Гуле пилит. Они в итоге замаялись с тормозным и глючным посчетом ссылок и запилили ЖЦ для плюсов. Убогий конечно, но для их задач все равно лучше чем то что можно сделать в плюсах без него.


Похоже этот ЖЦ настолько убог, что нет никакой возможности даже проверить его работоспособности, ибо DOM ведёт себя так, как будто этот ЖЦ сделан целиком и полностью на счетчиках ссылок.
AndrewVK
AndrewVK
02.01.2014 02:39
Здравствуйте, D. Mon, Вы писали:

DM>Полагаю, в умелых руках всякие критичные к скорости циклы там можно делать без лишних аллокаций и вызова GC.


В умелях руках это можно сделать и на шарпе.

DM>А если в целом, то согласно Страуструпу современный С++ — язык со сборкой мусора (причем плохой: на подсчете ссылок, т.е. медленной, ненадежной и небезопасной).


Ты саму статью то прочти — там вполне отчетливо намекается, что основная причина отнесения JS и дотнетов с джавами к левому краю — наличие GC.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
D. Mon
D. Mon
02.01.2014 03:34
Здравствуйте, AndrewVK, Вы писали:

DM>>Полагаю, в умелых руках всякие критичные к скорости циклы там можно делать без лишних аллокаций и вызова GC.

AVK>В умелях руках это можно сделать и на шарпе.

И? Как именно это мешает хаскелю быть быстрым?
AndrewVK
AndrewVK
02.01.2014 03:49
Здравствуйте, D. Mon, Вы писали:

DM>И? Как именно это мешает хаскелю быть быстрым?


Потерял нить разговора?
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
VladD2
VladD2
03.01.2014 01:39
Здравствуйте, AndrewVK, Вы писали:

AVK>Хаскель уже без ГЦ обходится?


Жабаскрип без ЖЦ обходится. Но это ему не шибко помогает.

Что до Хаскеля, то не сказал бы, что писать на нем так уж продуктивно. Так что даже если он не будет отличатья от Си по скорости, один фиг его вряд ли ждет повсеместное применение. Это язык не для всех.
Andir
Andir
03.01.2014 04:15
Здравствуйте, VladD2, Вы писали:

VD>Жабаскрип без ЖЦ обходится. Но это ему не шибко помогает.


А как же тогда в JavaScript менеджится память?

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management
https://developers.google.com/v8/design?hl=ru#garb_coll

--
С Уважением, Andir!
using(<< RSDN@Home 1.2.0 alpha 5 rev. 74>>) { /* Работаем */ }
VladD2
VladD2
03.01.2014 01:57
Здравствуйте, Andir, Вы писали:

VD>>Жабаскрип без ЖЦ обходится. Но это ему не шибко помогает.


A>А как же тогда в JavaScript менеджится память?


На подсчете ссылок, вестимо. До недавнего времени многие реализации так были сделаны.

Я это к тому говорил, что Жабахрип он тормозом родился, тормозом и помрет. Наличие или отсутствие ЖЦ на это не сильно влияет. Главные источники тормозов в нем — это динамическая типизация и динамическая природа хранения информации. Это ограничивает оптимизации примитивными вычислениями.

У дотнета, с точки зрения оптимизаций, архитектура самая правильная. Жаль только этому делу мало внимания уделяют. Плюс есть ряд врожденных косяков. Но они не столь фатальны как Жабоскрипные.
D. Mon
D. Mon
03.01.2014 06:27
Здравствуйте, VladD2, Вы писали:

VD>Жабаскрип без ЖЦ обходится.


Это где такой?
VladD2
VladD2
03.01.2014 02:00
Здравствуйте, D. Mon, Вы писали:

VD>>Жабаскрип без ЖЦ обходится.


DM>Это где такой?


Сейчас уже редко где, но раньше был везде. Все первые версии использовали подсчет ссылок. Тормозов это только прибавляло. А главное геморроя.
D. Mon
D. Mon
03.01.2014 03:50
Здравствуйте, VladD2, Вы писали:

VD>>>Жабаскрип без ЖЦ обходится.

DM>>Это где такой?
VD>Сейчас уже редко где, но раньше был везде. Все первые версии использовали подсчет ссылок.

А, ну все ж подсчет ссылок (особенно когда он спрятан под капот) — это один из видов GC. В куче языков до сих пор используется.
Ikemefula
Ikemefula
03.01.2014 09:24
Здравствуйте, VladD2, Вы писали:

AVK>>Хаскель уже без ГЦ обходится?


VD>Жабаскрип без ЖЦ обходится. Но это ему не шибко помогает.


И давно ?
VladD2
VladD2
03.01.2014 02:04
Здравствуйте, Ikemefula, Вы писали:

I>И давно ?


С самого своего существования, если конечно, не считать подсчет ссылок видом ЖЦ.
Ikemefula
Ikemefula
03.01.2014 02:55
Здравствуйте, VladD2, Вы писали:

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


I>>И давно ?


VD>С самого своего существования, если конечно, не считать подсчет ссылок видом ЖЦ.


У тебя сведения из середины 90х

http://lmgtfy.com/?q=javascript+garbage+collection
AndrewVK
AndrewVK
03.01.2014 10:50
Здравствуйте, VladD2, Вы писали:

VD>Жабаскрип без ЖЦ обходится.


Оно и видно:
https://developers.google.com/v8/design#garb_coll
http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
VladD2
VladD2
03.01.2014 02:19
Здравствуйте, AndrewVK, Вы писали:

VD>>Жабаскрип без ЖЦ обходится.


AVK>Оно и видно:

AVK>https://developers.google.com/v8/design#garb_coll
AVK>http://blogs.msdn.com/b/ericlippert/archive/2003/09/17/53038.aspx

Это последние версии. А на протяжении 10 лет он жил на подсчете ссылок и не чавкал.

Короче, его тормоза далеко не в ЖЦ кроются. Там база гнилая.
AndrewVK
AndrewVK
03.01.2014 03:24
Здравствуйте, VladD2, Вы писали:

VD>Это последние версии.


Последние? Ты по ссылкам то сходи — статья про JScript от 2003 года. Да и V8 релизнули в 2008 году.


VD>Короче, его тормоза далеко не в ЖЦ кроются. Там база гнилая.


Ну, Даффи довольно много спорных утверждений там сделал. Бог с ним, с тормозами, тем более что он таки там самый тормозной на графике, но вот как у него safety оказалась выше и шарпа и джавы — вот это куда интереснее. И ответа на этот вопрос в его статье нет.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
gravatar
Аноним
02.01.2014 02:14
Здравствуйте, dsorokin, Вы писали:

D>Надо понимать, что "X" — это сокращение от слова "Хаскель"?


Нет, это от слов "Хрен вам".
Sharov
Sharov
01.01.2014 08:58
Здравствуйте, Artem Korneev, Вы писали:

AK>Коллеги, скажите, а что вы думаете о ней? Меня интересует положение JavaScript. Часто вот в таких статьях как-то к слову говорится, что писать на JavaScript легко и просто и разработчики просто спят и видят как бы использовать JavaScript вместо всех остальных языков.

AK>Но сколько я с ним ни сталкивался — боль и ужас. По параметрам "Safety & Productivity" я бы убрал его в левый нижний угол.

JS действительно довольно простой и мощный язык. Ну, допустим факт, что там нет встроенной поддержки, например, ООП (классического ООП).
Ну так там практически всю ООПшную инфраструктуру можно воссоздать(эмулировать), и писать вполне себе в ОО стиле. То же и с ФП.
Что касается безопасности, то тут согласен -- язык динамический, со всеми последствиями...
Так что js я поставил бы ниже шарпа и явы, но оставил бы в том же квадранте.
AndrewVK
AndrewVK
02.01.2014 02:46
Здравствуйте, Sharov, Вы писали:

S>JS действительно довольно простой и мощный язык.


JS может и простой и мощный, но он принципиально динамический, так что о safety точно говорить не приходится.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
DreamMaker
DreamMaker
01.01.2014 11:02
Здравствуйте, Artem Korneev, Вы писали:

AK>Куда бы вы поместили JavaScript на этой диаграмме?


js за гранью добра и зла...
ужас ужасный, хуже только пхп
Tom
Tom
01.01.2014 11:12
Здравствуйте, Artem Korneev, Вы писали:

AK>Коллеги, скажите, а что вы думаете о ней? Меня интересует положение JavaScript.

Я тоже когда увидел где находится жаба скрипт долго ржал. Оказывается это у нас самый безопасный язык (ага, слаботипизированный, бугага)
gravatar
Аноним
02.01.2014 01:24
Да это вообще странная идея о том, что-де на джаваскрипт проще программировать, чем на Java или C#.

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

Набирать код в Javascript нужно внимательно и напряженно, чтобы не дай бог не опечататься и ничего не перепутать, и набирать вручную приходится гораздо больше, чем в C# и подобных, из-за отсутствия подсказок, компиляции, рефакторинга и статической типизации. Ну и в Javascript есть набор совершенно диких нелогичностей в преобразованиях типов и синтаксисе, которых в C# нет, при этом в джаваскрипт ты ошибку не найдешь, пока выполнение не дойдет до этого места с нужными предварительными шагами (для получения тех данных, при которых проявляется ошибка). Ну или нужно строго 100% покрытие тестами.

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

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

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

Если все это суммировать, утверждения о более высокой производительности разработки на Javascript по сравнению, например, с C# — смехотворный бред, вызванный чьим-то больным воображением, либо какой-то миф, оставшийся от устаревших представлений. Непонятно, почему этот дурацкий миф так широко распространен и всеми так легко принимается на веру.
Sharov
Sharov
02.01.2014 10:31
Здравствуйте, Аноним, Вы писали:

А>Набирать код в Javascript нужно внимательно и напряженно, чтобы не дай бог не опечататься и ничего не перепутать, и набирать вручную приходится гораздо больше, чем в C# и подобных, из-за отсутствия подсказок, компиляции, рефакторинга и статической типизации. Ну и в Javascript есть набор совершенно диких нелогичностей в преобразованиях типов и синтаксисе, которых в C# нет, при этом в джаваскрипт ты ошибку не найдешь, пока выполнение не дойдет до этого места с нужными предварительными шагами (для получения тех данных, при которых проявляется ошибка). Ну или нужно строго 100% покрытие тестами.


Ну например в продуктах JB, которые поддерживают js имеются разнообразные code quality tools
такие как jslint, jshint, Closure linter. Т.е. выстрелить себе в ногу не дадут.
Code completion тоже имеется.

А>Еще можно добавить отсутствие нормальной модульности и отсутствие развитой стандартной библиотеки, заменяемое зоопарком вычурных нестандартных.


http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html
gravatar
Аноним
02.01.2014 12:32
Здравствуйте, Sharov, Вы писали:

S>Ну например в продуктах JB, которые поддерживают js имеются разнообразные code quality tools

S>такие как jslint, jshint, Closure linter. Т.е. выстрелить себе в ногу не дадут.
S>Code completion тоже имеется.

Спасибо за информацию. И как, добавление этих средств делает разработку на Javascript более эффективной, чем на C# c ReSharper?
VladD2
VladD2
03.01.2014 01:46
Здравствуйте, Sharov, Вы писали:

S>http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html


Вот это форменный набор приседаний. Вообще, паттерны — это список недоработок в языке. Чем меньше нужно знать паттернов при программировании на языке, тем лучше этот язык.
Ikemefula
Ikemefula
03.01.2014 09:25
Здравствуйте, VladD2, Вы писали:

S>>http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html


VD>Вот это форменный набор приседаний. Вообще, паттерны — это список недоработок в языке. Чем меньше нужно знать паттернов при программировании на языке, тем лучше этот язык.


Очень интересно, особенно с учетом того, что "паттерны" есть даже в естественном языке.
gravatar
Аноним
03.01.2014 11:42
Здравствуйте, Ikemefula, Вы писали:

I>Очень интересно, особенно с учетом того, что "паттерны" есть даже в естественном языке.


Ха, отличный пример — естественный язык! Естественные языки гораздо хуже, избыточнее и непоследовательнее, чем самые плохие из формальных искусственных языков.
Ikemefula
Ikemefula
03.01.2014 12:14
Здравствуйте, Аноним, Вы писали:

I>>Очень интересно, особенно с учетом того, что "паттерны" есть даже в естественном языке.


А>Ха, отличный пример — естественный язык! Естественные языки гораздо хуже, избыточнее и непоследовательнее, чем самые плохие из формальных искусственных языков.


Шо, в самом деле ?

Смотри: "рейз на флопе" — сразу ясно, что к чему. Куда ты собираешься бежать от таких паттернов ?
Ikemefula
Ikemefula
02.01.2014 09:20
Здравствуйте, Аноним, Вы писали:

А>Да это вообще странная идея о том, что-де на джаваскрипт проще программировать, чем на Java или C#.


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

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


Все так, правда это особенности динамических языков, а не джаваскрипта. Обычно частично решается тулами, частично — внятным подходом к дизайну.
Если заводить на каждый чих сущности и методы, то это будет ад.

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


Наоборот — набирать нужно намного _меньше_. А вот если на джаваскрипте писать "как на C#" то гораздо больше.

>рефакторинга и статической типизации. Ну и в Javascript есть набор совершенно диких нелогичностей в преобразованиях типов и синтаксисе, которых в C# нет, при этом в джаваскрипт ты ошибку не найдешь, пока выполнение не дойдет до этого места с нужными предварительными шагами (для получения тех данных, при которых проявляется ошибка). Ну или нужно строго 100% покрытие тестами.


Есть много нелогичностей, но в целом кривая вхождения довольно пологая.

А>Еще можно добавить отсутствие нормальной модульности и отсутствие развитой стандартной библиотеки, заменяемое зоопарком вычурных нестандартных.


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

Взять браузер — там одни ограничения. Серверные приложения — другие. Десктоп — третьи. Мобайл — четвертые. На кой ляд там одна библиотека, если скажем работа с файлами принципиально отличается во всех четырех случаях ?

Вместо этого можно подобрать библиотеку под конкретный случай.

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


1. в языках навроде C# слабоватый вывод типов и через это возможности ООП и ФП довольно хилые.
2. юниттесты нужны и в C#, при чем ровно там же, где и в джаваскрипте
3. запуск программы на JS большей частью ничего не стоит и да и запускать можно не программу, а один файл

А>Я не так много программировал на Javascript, так что, уверен, список недостатков можно пополнить. Хотя на Javascript можно делать веселые штуки благодаря динамике, и в отдельно взятых конкретных случаях они могут здорово сократить решение, да. Но не думаю, что таких случаев достаточно, чтобы это было существенно.


Динамика дает возможности, которых в C# нет и никогда не будет

А>Если все это суммировать, утверждения о более высокой производительности разработки на Javascript по сравнению, например, с C# — смехотворный бред, вызванный чьим-то больным воображением, либо какой-то миф, оставшийся от устаревших представлений. Непонятно, почему этот дурацкий миф так широко распространен и всеми так легко принимается на веру.


Хочешь, простой тест сделаем — регэкспы. Сильно удивишься. Или рисование в канвас.

Ну или совсем чит — правильный пайпинг на сервере, т.е. читаешь поток , обрабатываешь и одновременно отдаёшь. Выпилить такое на WCF мало кто сможет, стандартная либа первым делом пытается закачать весь стрим а уже потом разрешить процессить.
Andir
Andir
03.01.2014 04:25
Здравствуйте, Ikemefula, Вы писали:

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


см. WCF Streaming

--
С Уважением, Andir!
using(<< RSDN@Home 1.2.0 alpha 5 rev. 74>>) { /* Работаем */ }
Ikemefula
Ikemefula
03.01.2014 09:26
Здравствуйте, Andir, Вы писали:

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


A>см. WCF Streaming


Да-да, это он так и работает.
Евгений Акиньшин
Здравствуйте, Ikemefula, Вы писали:

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


I>Взять браузер — там одни ограничения. Серверные приложения — другие. Десктоп — третьи. Мобайл — четвертые. На кой ляд там одна библиотека, если скажем работа с файлами принципиально отличается во всех четырех случаях ?


А работа с потоками обычно везде одинаковая — практически везде есть базовый IStream (никогда не видел, чтобы с этим были проблемы).

Или, возьмем для примера, хотя бы коллекции и нотификации о изменениях. В том же .net все используют одни и те же IEnumerable, IList, INotifyPropertyChanged и т.д.

А на jscript каждый придумывает свою базовую библиотеку ни с чем не совместимую. В результате нельзя например написать логическую часть независимо, а потом выбрать GUI библиотеку для отображения — в каждой гуи библиотеке свой не визуальный фреймворк, со своими требованиями ко всем базовым объектам и все завязано на узел по самое ни хочу. И так во всем.

I>Вместо этого можно подобрать библиотеку под конкретный случай.


Вот только если нужно 2 библиотеки, то придется слой взаимодействия между ними писать самому, так как никаких стандартов ни на что нет.

И как вы там выкручиваетесь без элементарных типов, вроде decimal?

I>Динамика дает возможности, которых в C# нет и никогда не будет


Например?
Ikemefula
Ikemefula
03.01.2014 09:55
Здравствуйте, Евгений Акиньшин, Вы писали:

ЕА>Здравствуйте, Ikemefula, Вы писали:


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


I>>Взять браузер — там одни ограничения. Серверные приложения — другие. Десктоп — третьи. Мобайл — четвертые. На кой ляд там одна библиотека, если скажем работа с файлами принципиально отличается во всех четырех случаях ?


ЕА>А работа с потоками обычно везде одинаковая — практически везде есть базовый IStream (никогда не видел, чтобы с этим были проблемы).


В браузер тащить такие либы это мягко говоря преступление. В мобайле такая хрень требует поддержки нативных плагинов. В десктоп и сервере все более менее шоколадно, и вот, что удивтельно, есть либа которая используется и там и там — node.js.

Вообще эта хрень пролазит уже в мобайл, не сильно в курсе какие успехи.

ЕА>Или, возьмем для примера, хотя бы коллекции и нотификации о изменениях. В том же .net все используют одни и те же IEnumerable, IList, INotifyPropertyChanged и т.д.


Я про это говорил — незачем в джаваскрипте писать как в дотнете. Вместо, скажем, INotifyPropertyChanged используется key-value observer, это более мощная вещь. IList не нужен. IEnumerable помог бы, но для этого уже есть кое что в
следующем стандарте. INotifyPropertyChanged при желании реализуется очень просто — где надо, берёшь и файришь эвент

ЕА>А на jscript каждый придумывает свою базовую библиотеку ни с чем не совместимую. В результате нельзя например написать логическую часть независимо, а потом выбрать GUI библиотеку для отображения — в каждой гуи библиотеке свой не визуальный фреймворк, со своими требованиями ко всем базовым объектам и все завязано на узел по самое ни хочу. И так во всем.


I>>Вместо этого можно подобрать библиотеку под конкретный случай.


ЕА>Вот только если нужно 2 библиотеки, то придется слой взаимодействия между ними писать самому, так как никаких стандартов ни на что нет.


А мне из за этого не нравится C# и особенно — С++. Взял, например, либу где есть деревья выражений, в С++, и никуда не уедешь, потому что в другой либе всё по другому. В C# это уже не проблема, здесь C# порвёт С++ как тузик грелку, но вот мелочи всякие остаются, например мелкие структуры каждый старается сам написать, интерфейсов.
В js нет монстро-библиотек, но вот парадокс — с интеграцией возни меньше. На самом деле есть несколько стеков в джаваскрипте, и в каждом всё более менее согласовано + готовые точки расширения.


ЕА>И как вы там выкручиваетесь без элементарных типов, вроде decimal?


А зачем они нужны ?

I>>Динамика дает возможности, которых в C# нет и никогда не будет


ЕА>Например?


метапрограммирование в рантайме. На этом сделана целая куча либ.
Евгений Акиньшин
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, Евгений Акиньшин, Вы писали:


ЕА>>Здравствуйте, Ikemefula, Вы писали:


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


I>>>Взять браузер — там одни ограничения. Серверные приложения — другие. Десктоп — третьи. Мобайл — четвертые. На кой ляд там одна библиотека, если скажем работа с файлами принципиально отличается во всех четырех случаях ?


ЕА>>А работа с потоками обычно везде одинаковая — практически везде есть базовый IStream (никогда не видел, чтобы с этим были проблемы).


I>В браузер тащить такие либы это мягко говоря преступление. В мобайле такая хрень требует поддержки нативных плагинов. В десктоп и сервере все более менее шоколадно, и вот, что удивтельно, есть либа которая используется и там и там — node.js.


I>Вообще эта хрень пролазит уже в мобайл, не сильно в курсе какие успехи.


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


ЕА>>Или, возьмем для примера, хотя бы коллекции и нотификации о изменениях. В том же .net все используют одни и те же IEnumerable, IList, INotifyPropertyChanged и т.д.


I>Я про это говорил — незачем в джаваскрипте писать как в дотнете. Вместо, скажем, INotifyPropertyChanged используется key-value observer, это более мощная вещь. IList не нужен. IEnumerable помог бы, но для этого уже есть кое что в

I>следующем стандарте. INotifyPropertyChanged при желании реализуется очень просто — где надо, берёшь и файришь эвент

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

ЕА>>И как вы там выкручиваетесь без элементарных типов, вроде decimal?


I>А зачем они нужны ?


Деньги считать

I>>>Динамика дает возможности, которых в C# нет и никогда не будет


ЕА>>Например?


I>метапрограммирование в рантайме. На этом сделана целая куча либ.


Ну так в си-шарпе это тоже частенько используется — начиная от компиляции лямбд и кончая полноценной кодогенерацией с запуском компилятора. Понятно, что в динамике это будет удобнее делать, но "нет и никогда не будет" это перебор.
Ikemefula
Ikemefula
03.01.2014 02:31
Здравствуйте, Евгений Акиньшин, Вы писали:

I>>Вообще эта хрень пролазит уже в мобайл, не сильно в курсе какие успехи.


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


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

Идея простая — в приложение идёт только то, что реально используется. Незачем создавать аналог флеша или сильверлайта но на джаваскрипте.

I>>следующем стандарте. INotifyPropertyChanged при желании реализуется очень просто — где надо, берёшь и файришь эвент


ЕА>Ну так я о том же: каждый у кого возникает желание, придумывает свой, ни с чем не совместимый евент\листенер и потом сиди пиши переходники между ними.


Это больше домыслы. В основном эвенты и листенеры хорошо совместимы.

I>>А зачем они нужны ?


ЕА>Деньги считать


И указателей и всякого другого мусора тоже нет.

I>>>>Динамика дает возможности, которых в C# нет и никогда не будет


ЕА>>>Например?


I>>метапрограммирование в рантайме. На этом сделана целая куча либ.


ЕА>Ну так в си-шарпе это тоже частенько используется — начиная от компиляции лямбд и кончая полноценной кодогенерацией с запуском компилятора. Понятно, что в динамике это будет удобнее делать, но "нет и никогда не будет" это перебор.


Покажи как на C# пропатчить Console.Write
Философ
Философ
03.01.2014 09:34
Здравствуйте, Ikemefula, Вы писали:

I>Динамика дает возможности, которых в C# нет и никогда не будет


Какие?
Ikemefula
Ikemefula
03.01.2014 10:45
Здравствуйте, Философ, Вы писали:

I>>Динамика дает возможности, которых в C# нет и никогда не будет


Ф>Какие?


Метапрограммирование в рантайме и плюшки динамики — православный полиморфизм.
Философ
Философ
03.01.2014 11:32
Здравствуйте, Ikemefula, Вы писали:

I>Здравствуйте, Философ, Вы писали:


I>>>Динамика дает возможности, которых в C# нет и никогда не будет


Ф>>Какие?


I>....плюшки динамики — православный полиморфизм.


Можно подробнее?
Я полиморфизм понимаю с точки зрения классического определения, т.е. например вот так: различное поведение экземпляров производных классов.
или вот так:

Полиморфи́зм — возможность объектов с одинаковой спецификацией иметь различную реализацию. Язык программирования поддерживает полиморфизм, если классы с одинаковой спецификацией могут иметь различную реализацию — например, реализация класса может быть изменена в процессе наследования[1]. Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций».


Кстати, мы тут вообще об ООП говорим, или о чём?

I>Метапрограммирование в рантайме...


Что мешает метапрограммировать в рантайме на шарпе? CodeDOM отменили?
Ikemefula
Ikemefula
03.01.2014 12:12
Здравствуйте, Философ, Вы писали:

Ф>Можно подробнее?

Ф>Я полиморфизм понимаю с точки зрения классического определения, т.е. например вот так: различное поведение экземпляров производных классов.
Ф>или вот так:
Ф>

Ф>Полиморфи́зм — возможность объектов с одинаковой спецификацией иметь различную реализацию. Язык программирования поддерживает полиморфизм, если классы с одинаковой спецификацией могут иметь различную реализацию — например, реализация класса может быть изменена в процессе наследования[1]. Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций».


Ф>Кстати, мы тут вообще об ООП говорим, или о чём?


Мы про полиморфизм. Не совсем ясно, почему ты ООП вспомнил

Полиморфизмы они разные бывают. В C# система типов очень сильно ограничивает этот самый полиморфизм.
Пример

var f = (int x) => x * 2;




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


I>>Метапрограммирование в рантайме...


Ф>Что мешает метапрограммировать в рантайме на шарпе? CodeDOM отменили?


Вот есть у тебя метод
void Write(string data) {}


Покажи код на CodeDom, который пропатчит метод нужного экземпляр или класс и будет дополнительно файрить эвент. Для простоты возьмём Console.Write.
Evgeny.Panasyuk
Evgeny.Panasyuk
02.01.2014 11:04
Здравствуйте, Artem Korneev, Вы писали:

AK>Наткнулся на вот эту диаграмму в блоге.

AK> http://joeduffyblog.com/images/2013_LangQuad.jpg
AK>Коллеги, скажите, а что вы думаете о ней?

1. Почему Java правее C#? В Java даже структур нету. Или это обусловлено только текущим качеством оптимизаторов?
2. C++11 должен быть и выше и правее C++98 — быстрый код стало легче писать.
3. Что вообще сравнивается? Только языки или ещё и окружающая среда? Если только языки — то Java самый дубовый и непродуктивный.
4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией. Это позволяет легко писать обобщённый код. Но safety — это крайне спорный момент (опять таки — что конкретно подразумевается).
AndrewVK
AndrewVK
02.01.2014 02:46
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>1. Почему Java правее C#? В Java даже структур нету. Или это обусловлено только текущим качеством оптимизаторов?


Я так понимаю мало кто удосужился прочесть многабукав статьи. А в ней есть ответ:

Java is closer than C# thanks to the excellent work in HotSpot-like VMs which employ code pitching and stack allocation.


EP>4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией.


Практика показывает, что, начиная с некоторого, достаточно скромного размера проекта, JS становится существенно менее продуктивным, потому всякие TypeScript и появляются.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Evgeny.Panasyuk
Evgeny.Panasyuk
02.01.2014 03:11
Здравствуйте, AndrewVK, Вы писали:

EP>>1. Почему Java правее C#? В Java даже структур нету. Или это обусловлено только текущим качеством оптимизаторов?

AVK>Я так понимаю мало кто удосужился прочесть многабукав статьи. А в ней есть ответ:

Статью не читал. Из-за вот такой пропаганды она совершенна не интересна:

I’ve seen many people run away from garbage collection back to C++, with a sour taste permeating their mouths. (To be fair, this is only partly due to garbage collection itself; it’s largely due to poor design patterns, frameworks, and a lost opportunity to do better in the language.)


Поэтому и спросил что же там подразумевалось.

AVK>

AVK>Java is closer than C# thanks to the excellent work in HotSpot-like VMs which employ code pitching and stack allocation.


И как это поможет восполнить отсутствие массивов структур? Правильный memory layout данных очень важен для производительности.
Там где на Java нужна скорость — структуры вручную раскладывают по массиву байт.
Ikemefula
Ikemefula
02.01.2014 09:26
Здравствуйте, AndrewVK, Вы писали:

EP>>1. Почему Java правее C#? В Java даже структур нету. Или это обусловлено только текущим качеством оптимизаторов?


AVK>Я так понимаю мало кто удосужился прочесть многабукав статьи. А в ней есть ответ:

AVK>

AVK>Java is closer than C# thanks to the excellent work in HotSpot-like VMs which employ code pitching and stack allocation.


А что это значит ? Что это за VM такие и что такое питчинг и тд ?
D. Mon
D. Mon
03.01.2014 06:39
Здравствуйте, Ikemefula, Вы писали:

AVK>>Java is closer than C# thanks to the excellent work in HotSpot-like VMs which employ code pitching and stack allocation.

I>А что это значит ? Что это за VM такие и что такое питчинг и тд ?

Питчинг там не к месту упомянут, имхо. Это про освобождение из памяти неиспользуемого скомпиленного нативного кода.
Вот скажи, CLR умеет перекомпилировать горячие циклы в рантайме? А делать так, чтобы локальное значение reference-типа было создано не в управляемой куче, а на стеке? Вроде как HotSpot (Oracle JVM) это все делает.
VladD2
VladD2
03.01.2014 01:56
Здравствуйте, AndrewVK, Вы писали:

AVK>Я так понимаю мало кто удосужился прочесть многабукав статьи. А в ней есть ответ:

AVK>

AVK>Java is closer than C# thanks to the excellent work in HotSpot-like VMs which employ code pitching and stack allocation.


Что на практике скорее желаемое, нежели действительное. В то же Скале это ни хрена не помогает сделать for таким же быстрым как в Яве, так как он реализован как функция высшего порядка. Казалось бы мощные оптимизации явовского рантайма должны были бы нивелировать разницу, но на практике они только лишь сокращают отставание. Но оно все равно огромно.

В дотнете же оптимизации можно делать за счет использования вэйлью-типов. Так что на практике, в лучшем случае Ява стоит на одном месте по производительности.
D. Mon
D. Mon
03.01.2014 06:27
Здравствуйте, VladD2, Вы писали:

VD> В то же Скале это ни хрена не помогает сделать for таким же быстрым как в Яве, так как он реализован как функция высшего порядка.


Давно проверял?
Эта проблема была очень давно, и мне казалось, ее уже давно исправили.
VladD2
VladD2
03.01.2014 01:59
Здравствуйте, D. Mon, Вы писали:

DM>Давно проверял?

DM>Эта проблема была очень давно, и мне казалось, ее уже давно исправили.

Вообще не проверял. Слышал год назад от тех кто плотно использует Скалу. Уверен, что ничего не изменится пока они for на макросах не перепишут. Но они вроде как пока только в тестовом режиме идут. Или я отстал от жизни?
gravatar
Аноним
07.01.2014 10:13
Здравствуйте, VladD2, Вы писали:

DM>>Давно проверял?

DM>>Эта проблема была очень давно, и мне казалось, ее уже давно исправили.
VD>Вообще не проверял. Слышал год назад от тех кто плотно использует Скалу. Уверен, что ничего не изменится пока они for на макросах не перепишут. Но они вроде как пока только в тестовом режиме идут. Или я отстал от жизни?

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

val A = List(1 to 10 : _*)
A foreach println

превращается в
  @inline override final
  def foreach[B](f: A => B) {
    var these = this
    while (!these.isEmpty) {
      f(these.head)
      these = these.tail
    }
  }

а для массивов в
  override /*IterableLike*/
  def foreach[U](f: A => U): Unit = {
    var i = 0
    val len = length
    while (i < len) { f(this(i)); i += 1 }
  }


Ни в одном, ни во втором случае я не вижу проблем для оптимизатора.
Ikemefula
Ikemefula
02.01.2014 09:22
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией. Это позволяет легко писать обобщённый код. Но safety — это крайне спорный момент (опять таки — что конкретно подразумевается).


джаваскрипт исполняется в песочнице, что дает сафети.
VladD2
VladD2
03.01.2014 01:48
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией. Это позволяет легко писать обобщённый код. Но safety — это крайне спорный момент (опять таки — что конкретно подразумевается).


Лично для меня и скорость кодирования на скриптах очень спорный вопрос. Но тут на любителя. Есть люди которым динамика надет преимущество, а есть те для кого это недостаток. Я предпочитают статические проверки типов и качественный интеллисес.
Evgeny.Panasyuk
Evgeny.Panasyuk
03.01.2014 09:41
Здравствуйте, VladD2, Вы писали:

EP>>4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией. Это позволяет легко писать обобщённый код. Но safety — это крайне спорный момент (опять таки — что конкретно подразумевается).

VD>Лично для меня и скорость кодирования на скриптах очень спорный вопрос. Но тут на любителя. Есть люди которым динамика надет преимущество, а есть те для кого это недостаток.

На C#/Java обобщённый код особо не получается. На C++ с этим всё нормально, но приходится то тут, то там подсказывать компилятору (auto, decltype, template, etc).
На языках с динамической типизацией этот обобщённый код получается легко и непринуждённо, но приносятся в жертву compile-time проверки.
Собственно код на языках со статической типизацией с каждым годом становится похож на код языков с динамической типизацией (например полиморфные лямбды в C++14, или те же лямбды в C# — удобно ведь). Но динамические языки — это то что доступно здесь и сейчас.

VD>Я предпочитают статические проверки типов и качественный интеллисес.


Я думаю все предпочитают статические проверки.
gravatar
Аноним
03.01.2014 12:10
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>На C#/Java обобщённый код особо не получается. На C++ с этим всё нормально, но приходится то тут, то там подсказывать компилятору (auto, decltype, template, etc).


Чтобы проверить корректность типизации, нужно ввести ограничения, а, точнее, объяснить компилятору свои намерения формально, чтобы он и мог выполнить проверки. Ничего удивительного, что не получается написать нонсенс вроде "обобщенная функция с непонятно какой сигнатурой".

EP>На языках с динамической типизацией этот обобщённый код получается легко и непринуждённо, но приносятся в жертву compile-time проверки.


Здесь, собственно, нет никакого противопоставления: указываешь типы — получаешь проверки, не указываешь — не получаешь. Я предпочитаю проверки, ибо код, который просто написан, и для которого нет никакого обоснования корректности — бесполезен, а именно с этим и возникают проблемы. После статически типизированного языка программировать на динамическим как-то неуютно из-за невозможно проверить даже базовую корректность без запуска. Код не только пишется, но еще и читается, меняется, исполняется и отлаживается.

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

Например, что делает данная фукнция:

function concatenate(a, b);


А если так:

Matrix3x3 concatenate(Matrix3x3 a, Matrix3x3 b);


Я не знаю, каким изощренным и неземным мышлением надо обладать, чтобы сказать, что с кодом в стиле первого фрагмента работать проще?

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

EP>Собственно код на языках со статической типизацией с каждым годом становится похож на код языков с динамической типизацией (например полиморфные лямбды в C++14, или те же лямбды в C# — удобно ведь). Но динамические языки — это то что доступно здесь и сейчас.


Просто некорректное сравнение. Статическая типизация все равно остается статической, так что динамические языки — это не то, "что доступно здесь и сейчас", а скорее "не хотите ли вы из кареты пересесть в телегу". Для тебя это привлекательно звучит по какой-то причине, для других — не уверен, например, для меня — не особо.
Evgeny.Panasyuk
Evgeny.Panasyuk
03.01.2014 01:47
Здравствуйте, Аноним, Вы писали:

EP>>На C#/Java обобщённый код особо не получается. На C++ с этим всё нормально, но приходится то тут, то там подсказывать компилятору (auto, decltype, template, etc).

А>Чтобы проверить корректность типизации, нужно ввести ограничения, а, точнее, объяснить компилятору свои намерения формально, чтобы он и мог выполнить проверки. Ничего удивительного, что не получается написать нонсенс вроде "обобщенная функция с непонятно какой сигнатурой".

На C++ я спокойно могу написать функцию которая получает на вход функциональный объект, произвольный набор аргументов, применяет аргументы к функциональному объекту и возвращает результат, <b>со всеми статическими проверками</b>:
#include <iostream>

template<typename F, typename ...Args>
auto apply(F f, Args... args)
{
    return f(args...);
}

double foo(int x, double y)
{
    return x + y;
}

int main()
{
    std::cout << apply(foo, 1, 0.1);
}

Тоже самое возможно и в динамике, только менее многословно (сравни apply):
def apply(f, *args):
    return f(*args)

def foo(x, y):
    return x + y

print apply(foo, 1, 0.1)


EP>>На языках с динамической типизацией этот обобщённый код получается легко и непринуждённо, но приносятся в жертву compile-time проверки.

А>Здесь, собственно, нет никакого противопоставления: указываешь типы — получаешь проверки, не указываешь — не получаешь.

В примере выше на C++ типы не указанны, при этом все проверки происходят compile-time
Да и вообще, в большинстве кода явные типы не обязательны — и это отнюдь не означает потерю статических проверок.

А>Я предпочитаю проверки,


Я думаю все предпочитают compile-time проверки.

А>ибо код, который просто написан, и для которого нет никакого обоснования корректности — бесполезен, а именно с этим и возникают проблемы.


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

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


Я пишу и на C++, с огромным количеством статических проверок, и на динамических языках.
Везде просто нужен свой подход.

А>Код не только пишется, но еще и читается, меняется, исполняется и отлаживается.

А>Да и вообще, программа с тотальным отсутствием типов и читается-то хуже, потому что программисту, читающему код, нужно тоже выводить типы, чтобы понять, что код делает.
А>Например, что делает данная фукнция:
А>
А>function concatenate(a, b);
А>

А>А если так:
А>
А>Matrix3x3 concatenate(Matrix3x3 a, Matrix3x3 b);
А>

А>Я не знаю, каким изощренным и неземным мышлением надо обладать, чтобы сказать, что с кодом в стиле первого фрагмента работать проще?

Если у тебя concatenate работает с одним единственным типом — то лучше со вторым.
Если же это намного более мощная обобщённая функция, которая работает с разными типами, не прибитыми наследованием к конкретному интерфейсу, то второй вариант никак не получится.
Лучше всего его описать на концепциях C++:
template<SemiGroupElement T>
T concatenate(T a, T b);
А пока нет концепций, используем первый вариант:
template<typename SemiGroupElement>
SemiGroupElement concatenate(SemiGroupElement a, SemiGroupElement b);


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


Не слабо, вот конкретный пример:
template <class T, class Integer, class MonoidOperation>
T power(T x, Integer n, MonoidOperation op);
Это функция возводит x в заданную целую степень n, причём делает это достаточно оптимальным способом.
Ах да, и работает она и с целыми, и с матрицами, и со строками, и списками, и звуковыми файлами.

EP>>Собственно код на языках со статической типизацией с каждым годом становится похож на код языков с динамической типизацией (например полиморфные лямбды в C++14, или те же лямбды в C# — удобно ведь). Но динамические языки — это то что доступно здесь и сейчас.

А>Просто некорректное сравнение. Статическая типизация все равно остается статической, так что динамические языки — это не то, "что доступно здесь и сейчас", а скорее "не хотите ли вы из кареты пересесть в телегу".

Чем же оно некорректное?
Вот Python'ская лябмда:
foo(lambda x: bar(x, 1))
Вот C#:
foo(x => bar(x, 1));
C++:
foo([](auto x){ return bar(x, 1); });

Вопрос — какой тип у параметра лямбды?

А>Для тебя это привлекательно звучит по какой-то причине, для других — не уверен, например, для меня — не особо.


Да мне если честно параллельно кому это привлекательно, а кому нет.
Но факт остаётся фактом — обобщённый код на языках со статической типизацией сильно похож (отсутствием конкретных типов) на код в динамических языках.
VladD2
VladD2
03.01.2014 02:14
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>На C#/Java обобщённый код особо не получается.


Там речь о небольшой недоработке языка. В Nemerle с этим проблем нет.

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

EP>На C++ с этим всё нормально, но приходится то тут, то там подсказывать компилятору (auto, decltype, template, etc).


На С++ как раз все совсем не нормально. У него присутствуют некоторые плохие черты динамики — типы не всегда проверяются в момент их описания. Шаблоны проверяются только при раскрытии. А это усложняет диагностику ошибок, ухудшает интеллисенс (усложняет его реализацию) и создает прочие проблемы.

EP>Собственно код на языках со статической типизацией с каждым годом становится похож на код языков с динамической типизацией (например полиморфные лямбды в C++14, или те же лямбды в C# — удобно ведь). Но динамические языки — это то что доступно здесь и сейчас.


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

VD>>Я предпочитают статические проверки типов и качественный интеллисес.


EP>Я думаю все предпочитают статические проверки.


Нет. Я видел не мало людей которые думают иначе. Иначе не было бы столько поклонников Руби, Питона, ПХП, Лиспа.

В динамике намного проще использовать метапрограммирование, например. Хорошее МП в статических языках пока что есть только Немерле. И то там есть что дорабатывать.
Evgeny.Panasyuk
Evgeny.Panasyuk
03.01.2014 02:43
Здравствуйте, VladD2, Вы писали:

EP>>На C#/Java обобщённый код особо не получается.

VD>Там речь о небольшой недоработке языка. В Nemerle с этим проблем нет.

На C#/Java получится ли сделать нечто похожее на apply:
template<typename F, typename ...Args>
auto apply(F f, Args... args)
{
    return f(args...);
}
без сильного ухода в динамику?
А во многих динамических языках это доступно уже десятки лет.

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


Согласен — это недостаток.

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


А вот это неясно откуда следует.

EP>>На C++ с этим всё нормально, но приходится то тут, то там подсказывать компилятору (auto, decltype, template, etc).

VD>На С++ как раз все совсем не нормально.

Это контр-пример того, что отсутствие явного указания типов обязательно ведёт к ошибкам в runtime.

VD>У него присутствуют некоторые плохие черты динамики — типы не всегда проверяются в момент их описания. Шаблоны проверяются только при раскрытии. А это усложняет диагностику ошибок, ухудшает интеллисенс (усложняет его реализацию) и создает прочие проблемы.


Это действительно создаёт проблемы, которые требуют внимания — например, тестирования на архитипах.

EP>>Собственно код на языках со статической типизацией с каждым годом становится похож на код языков с динамической типизацией (например полиморфные лямбды в C++14, или те же лямбды в C# — удобно ведь). Но динамические языки — это то что доступно здесь и сейчас.

VD>Лябды не имеют отношения к стаике или динамике. Как и полиморфизм. К динамике имеет отношение исключительно динамическая интерпретация типа "объектов". Весь полиморфизм в динамических языках на ней основан.

Ты про содержание, а я же говорю про форму (то с чем работает программист):
foo([](auto x){ return bar(x, 1); });

foo(lambda x: bar(x, 1))

Разве не видно что статика по форме, становится похожа на динамику? Конкретные типы указываются всё реже и реже.

VD>>>Я предпочитают статические проверки типов и качественный интеллисес.

EP>>Я думаю все предпочитают статические проверки.
VD>Нет. Я видел не мало людей которые думают иначе. Иначе не было бы столько поклонников Руби, Питона, ПХП, Лиспа.

А из-за чего они думают иначе?
Они действительно против статической проверки (и принципиально не гоняют свой код по статическим анализаторам типа pylint)?
Или же они просто за те возможности которые дают динамические языки здесь и сейчас?
Это разные вещи.

VD>В динамике намного проще использовать метапрограммирование, например. Хорошее МП в статических языках пока что есть только Немерле. И то там есть что дорабатывать.


О том и речь — многие возможности динамических языков могут быть реализованы в статических, но это требует более детальной проработки синтаксиса, компиляторов и т.п.
AndrewVK
AndrewVK
03.01.2014 03:36
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>На C#/Java получится ли сделать нечто похожее на apply:

EP>
EP>template<typename F, typename ...Args>
EP>auto apply(F f, Args... args)
EP>{
EP>    return f(args...);
EP>}
EP>
без сильного ухода в динамику?


А нафига оно вообще надо такое?

EP>О том и речь — многие возможности динамических языков могут быть реализованы в статических


Ровно как и наоборот. Вопрос не в абстрактных возможностях, а в балансе плюсов и минусов.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Artem Korneev
Artem Korneev
03.01.2014 07:28
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>2. C++11 должен быть и выше и правее C++98 — быстрый код стало легче писать.


Он и так выше. А почему он должен быть правее-то?
С++11 позволяет выжать из железа тоже самое, что и С++98, просто облегчает процесс написания кода.

EP>4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией. Это позволяет легко писать обобщённый код.


Вы пробовали? У вас получалось легко писать код на JavaScript?
Я про практическую часть спрашивал. У меня JS-код шёл с большим скрипом. Забытая скобочка или, хуже того, опечатка в имени элемента — проявлялись лишь после запуска приложения. А мне нужно было писать часть, которая делает снимки фото-камерой и заливает результат на сервер. Отлаживать приходилось в эмуляторе — "сохранить, скомпилить, перезапустить, ввести все параметры.." И только после этого увидеть в консоли сообщение, что оно не нашло такого элемента.

Отсутствие автокомплита тоже огорчило. Вкупе с моим смутным пониманием самого JS, это заставляло просто искать готовые решения в интернете. Сам я не мог понять, как написать что-то более-менее сложное.

Как я сказал, я думал, что это проблемы моей компетенции. Решил подтянуть свои знания — читаю книжки. А пока поинтересовался мнением коллег.

Тут в треде упомянули инструменты от JetBrains — нужно спросить у менеджера, есть ли у нас лицензии. Может быть, чем-то улучшит ситуацию. Пока я пользовался лишь Visual Studio & Notepad++
Evgeny.Panasyuk
Evgeny.Panasyuk
03.01.2014 12:46
Здравствуйте, Artem Korneev, Вы писали:

EP>>2. C++11 должен быть и выше и правее C++98 — быстрый код стало легче писать.

AK>Он и так выше. А почему он должен быть правее-то?
AK>С++11 позволяет выжать из железа тоже самое, что и С++98

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

AK>, просто облегчает процесс написания кода.


Это "облегчает" дорогого стоит. Именно из-за отсутствия "облегчает" многие языки являются тормозными.

C++11 (а тем более C++14) как раз сильно облегчает написание быстрого кода:
1. auto/decltype — раньше вывод типов был доступен только при вызове шаблонов функций, а сейчас везде. Раньше нужно было либо использовать type-erasure (что дорого в runtime), либо добавлять дополнительные вызовы (что неудобно).
2. Лямбды — если раньше boost::bind на member function был распространён, то сейчас его заменяют лямбды — что более производительно.
3. rvalue references — есть возможность просто скомпилировать старый код новым компилятором получить и ускорение.
4. Появился perfect forwarding, который раньше использовался редко через эмуляцию. Это позволяет легко писать штуки типа vector::emplace_back

EP>>4. JavaScript можно считать более продуктивным потому, что это язык с динамической типизацией. Это позволяет легко писать обобщённый код.

AK>Вы пробовали? У вас получалось легко писать код на JavaScript?

Пробовал. Часто использую Python, иногда JavaScript — и там и там вижу преимущества динамики.

AK>Я про практическую часть спрашивал. У меня JS-код шёл с большим скрипом. Забытая скобочка или, хуже того, опечатка в имени элемента — проявлялись лишь после запуска приложения. А мне нужно было писать часть, которая делает снимки фото-камерой и заливает результат на сервер. Отлаживать приходилось в эмуляторе — "сохранить, скомпилить, перезапустить, ввести все параметры.." И только после этого увидеть в консоли сообщение, что оно не нашло такого элемента.


Unit test'ы и покрытие для динамики более критичны чем для статики.
AndrewVK
AndrewVK
03.01.2014 03:36
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Язык C позволяет выжать из железа тоже самое, но это потребовало бы целое болото кода.


На графике это вертикальная ось, а не горизонтальная
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
Evgeny.Panasyuk
Evgeny.Panasyuk
03.01.2014 03:45
Здравствуйте, AndrewVK, Вы писали:

EP>>Язык C позволяет выжать из железа тоже самое, но это потребовало бы целое болото кода.

AVK>На графике это вертикальная ось, а не горизонтальная

Если performance на графике это теоретический максимум который можно достичь сколько угодно огромным количеством неудобного кода, то Java, C# и JavaScript (за счёт типизированных массивов через asm.js) будут примерно на одной вертикальной оси.
AndrewVK
AndrewVK
03.01.2014 06:52
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Если performance на графике это теоретический максимум который можно достичь сколько угодно огромным количеством неудобного кода, то Java, C# и JavaScript (за счёт типизированных массивов через asm.js) будут примерно на одной вертикальной оси.


Не будут.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>
kaa.python
kaa.python
02.01.2014 03:43
Здравствуйте, Artem Korneev, Вы писали:

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


AK>Наткнулся на вот эту диаграмму в блоге.


AK>Коллеги, скажите, а что вы думаете о ней?


Все верно. Через 1, максимум 2 года вместо красной и загадочной X можно будет вписать Rust
Ikemefula
Ikemefula
02.01.2014 09:02
Здравствуйте, Artem Korneev, Вы писали:

AK>Но сколько я с ним ни сталкивался — боль и ужас. По параметрам "Safety & Productivity" я бы убрал его в левый нижний угол.


Боль и ужас это DOM и css. Хочешь смотреть серьезные вещи — смотри node.js , внятный АПИ большей частью и довольно предсказуемое поведение.

AK>Вообще я грешил на своё плохое знание JavaScript и по возможности стараюсь это исправить — вот буквально два дня назад на распродаже купил десяток книг, из них две — по jQuery. По работе частенько приходится сталкиваться с JS, допиливая какие-нибудь веб-интерфейсы.


Не надо путать джаваскрипт с DOM, Css и поделками навроде jQuery.

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


AK>Куда бы вы поместили JavaScript на этой диаграмме?


Примерно там, где он сейчас стоит, может быть даже чуток правее Скажем, отрисовка в канвас будет не хуже, чем мега сервелат на С#

И не совсем понятно, почему по перформансу джава правее C#, низкоуровневый перформанс в C# намного лучше, там честные оптимизации на дженериках и прочих вещах, навроде строк и типов-значений. Серверный перформанс выше в джаве и исключительно благодаря библиотекам, которым уже 20 скоро будет.
Artem Korneev
Artem Korneev
03.01.2014 07:12
Здравствуйте, Ikemefula, Вы писали:

AK>>Но сколько я с ним ни сталкивался — боль и ужас. По параметрам "Safety & Productivity" я бы убрал его в левый нижний угол.

I>Боль и ужас это DOM и css. Хочешь смотреть серьезные вещи — смотри node.js , внятный АПИ большей частью и довольно предсказуемое поведение.

А вот там где DOM и CSS — для вас там тоже боль и ужас? Я, в общем-то, эту сферу и имел в виду. Как-то вылетело из головы, что на JS нынче и серверные части пишут.
Я с node.js не сталкивался пока, мне с JS приходится работать, в основном, для обработки ввода пользователя на HTML-страничках. А год назад довелось поучаствовать в разработке Android-приложения на HTML5+JS. Если я правильно понимаю, в этих случаях node.js неприменим? Он вроде для серверной части.

I>Не надо путать джаваскрипт с DOM, Css и поделками навроде jQuery.


Ну так для браузерной части других поделок нет.

I>И не совсем понятно, почему по перформансу джава правее C#

...
I>Серверный перформанс выше в джаве

Вероятно, как раз поэтому.

I>и исключительно благодаря библиотекам, которым уже 20 скоро будет.


Пусть, благодаря библиотекам. Важен результат.
Хотя мне и то и другое кажется медленным..