<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Дмитрий Нестерук</title>
	<atom:link href="http://nesteruk.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://nesteruk.wordpress.com</link>
	<description>Блог о программировании — C#, F#, C++, архитектура, и многое другое</description>
	<lastBuildDate>Tue, 24 Jan 2012 10:42:53 +0000</lastBuildDate>
	<language>ru</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='nesteruk.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/46e0cad6558c5915dd7536a1281e4978?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Дмитрий Нестерук</title>
		<link>http://nesteruk.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://nesteruk.wordpress.com/osd.xml" title="Дмитрий Нестерук" />
	<atom:link rel='hub' href='http://nesteruk.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Итоги 2011 года</title>
		<link>http://nesteruk.wordpress.com/2011/12/31/year-2011-results/</link>
		<comments>http://nesteruk.wordpress.com/2011/12/31/year-2011-results/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 10:36:26 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=879</guid>
		<description><![CDATA[Сейчас блоггеры усиленно подводят итоги уходящего года, и я тут подумал&#160;&#8211; а чем я хуже? Мне тоже есть что рассказать! Рассказывать я буду конечно про технические вещи, с которыми успел &#8220;поиграться&#8221; в 2011 году. Поехали&#8230; ПО, которое удалось зарелизить: JetBrains ReSharper SDK, включая онлайн документацию. Также получилось добавить одну фичу непосредственно в ReSharper. ActiveMesa R2P&#160;&#8212; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=879&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Сейчас блоггеры усиленно подводят итоги уходящего года, и я тут подумал&nbsp;&ndash; а чем я хуже? Мне тоже есть что рассказать! Рассказывать я буду конечно про технические вещи, с которыми успел &ldquo;поиграться&rdquo; в 2011 году. Поехали&hellip;</p>
<p>ПО, которое удалось зарелизить:</p>
<ul>
<li>
<p><a href="http://www.jetbrains.com/resharper/download/index.html" title="http://www.jetbrains.com/resharper/download/index.html">JetBrains ReSharper SDK</a>, включая онлайн документацию. Также получилось добавить <a href="http://blogs.jetbrains.com/dotnet/2011/03/resharper-enhances-suggestions-with-explanations/" title="http://blogs.jetbrains.com/dotnet/2011/03/resharper-enhances-suggestions-with-explanations/">одну фичу</a> непосредственно в ReSharper.</p>
</li>
<li>
<p><a href="http://activemesa.com/r2p" title="http://activemesa.com/r2p">ActiveMesa R2P</a>&nbsp;&mdash; обновления для ReSharper 6.0 и 6.1, также несколько фич по запросам пользователей (что особенно приятно). Появилось много классных вещей, без которых я и сам уже жить не могу. Впрочем, пишется в основном для себя, так что это понятно.</p>
</li>
<li>
<p><a href="http://activemesa.com/mathsharp" title="http://activemesa.com/mathsharp">ActiveMesa MathSharp</a>&nbsp;&mdash; нужно иметь много наглости чтобы просить почти 100 долларов за приложение, которое писалось максимум неделю. И покупают ведь! Первое приложение которое я выпускаю по ClickOnce, и не без факапов конечно же, но тем не менее&hellip; теперь точно понятно, что пользователи готовы качать 100-мегабайтный инсталлятор .Net 4 и их это не особо напрягает.</p>
</li>
</ul>
<p>Языки и их использование:</p>
<ul>
<li>
<p><a href="http://dlang.org/" title="http://dlang.org/">D</a>&nbsp;&mdash; открытие года для меня. Уже успел купить и прочитать книжку Александреску а также попробовать пописать на нем. Впечатления крайне позитивные, несмотря на отсутствие 64-битной поддержки а также явную &ldquo;недопиленность&rdquo; стандартной библиотеки Phobos. D&nbsp;&ndash; это язык на котором хочется писать и шипить ПО, в том числе и кросс-платформенное. Настоятельно рекомендую!</p>
</li>
<li>
<p><a href="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)" title="http://en.wikipedia.org/wiki/C_Sharp_(programming_language)">C#</a>&nbsp;&mdash; продолжаю пользоваться, всем в принципе доволен. Обрастаю библиотеками с методами расширений, т.к. в любом проекте одно и то же, снова и снова. Также активно использую <a href="http://devtalk.net/csharp/chained-null-checks-and-the-maybe-monad/">монаду Maybe</a> для R2P.</p>
</li>
<li>
<p><a href="http://en.wikipedia.org/wiki/C%2B%2B" title="http://en.wikipedia.org/wiki/C%2B%2B">C++</a>&nbsp;&mdash; продолжаю пользоваться, нововведения меня не очень затронули, в основном использую &ldquo;хорошо забытое старое&rdquo; а также типичный стэк&nbsp;&ndash; <a href="http://threadingbuildingblocks.org/" title="http://threadingbuildingblocks.org/">Intel TBB</a>, <a href="http://openmp.org" title="http://openmp.org">OpenMP</a>, <a href="http://msdn.microsoft.com/en-us/library/t467de55(v=VS.100).aspx" title="http://msdn.microsoft.com/en-us/library/t467de55(v=VS.100).aspx">SIMD</a>.</p>
</li>
<li>
<p><a href="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/" title="http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/">F#</a>&nbsp;&mdash; пришел к выводу что он очень хорош для определенного круга задач, и не очень хорош для всего что требует серьезного использования ООП. При написании MathSharp, да и вообще парсеров, он очень полезен. Для математики тоже весьма неплох, хотя тут уже его приемущества чисто психологические (т.е. это приемущества для математиков, но не для меня).</p>
</li>
<li>
<p><a href="http://www.pokemon.com/" title="http://www.pokemon.com/">JavaScript</a>&nbsp;&mdash; практически не использую напрямую, пишу все на C# и транскомпилирую через SharpKit (см. ниже). За пределами <code>$.getJSON()</code> стараюсь вообще не трогать.</p>
</li>
</ul>
<p>Программы и компоненты, которые продолжают давать ощутимые бенефиты:</p>
<ul>
<li>
<p><a href="http://www.devexpress.com/Subscriptions/DXperience/winforms.xml" title="http://www.devexpress.com/Subscriptions/DXperience/winforms.xml">Контролы DevExpress (WinForms)</a>&nbsp;&mdash; использую их с 2006 года и в целом доволен, особенно доволен стилизацией, до которой конкурентам далеко. Контролы DX продолжают лидировать в плане красивости UI, а это важно для пользователей.</p>
</li>
<li>
<p><a href="http://software.intel.com/en-us/articles/intel-parallel-studio-home/" title="http://software.intel.com/en-us/articles/intel-parallel-studio-home/">Intel Parallel Studio</a>&nbsp;&mdash; до черного пояса Intel мне как до луны, но инструментарием я продолжаю пользоваться, причем весьма успешно. Как ни странно, мне намного больше импонирует использование связки C# &amp; IntelCPP чем связки C# &amp; C++/CLI.</p>
</li>
<li>
<p><a href="https://bitbucket.org/nesteruk/typografix" title="https://bitbucket.org/nesteruk/typografix">TypograFix</a> продолжает развиваться, улучшаться, и этот пост я пишу, конечно же, на нем. (Через RDC, сидя на Mac&rsquo;е.)</p>
</li>
</ul>
<p>Программы и компоненты которые понравились и стали частью процесса:</p>
<ul>
<li>
<p><a href="http://www.innovasys.com/products/dx2011/overview.aspx" title="http://www.innovasys.com/products/dx2011/overview.aspx">Innovasys Document!X</a>&nbsp;&mdash; теперь это моя стандартная тула для генерирования документации (CHM и Web) как для коммерческих, так и для OSS проектов. Действительно хороший продукт, который стоит своих денег.</p>
</li>
<li>
<p><a href="http://www.red-gate.com/products/dotnet-development/smartassembly/" title="http://www.red-gate.com/products/dotnet-development/smartassembly/">Red Gate SmartAssembly</a>&nbsp;&mdash; все любят ругать Red Gate за Reflector, но продукт SmartAssembly они выкупили у другой компании, и продукт это неплохой. SA&nbsp;&ndash; это обфускатор, <a href="http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx" title="http://research.microsoft.com/en-us/people/mbarnett/ilmerge.aspx">ILMerge</a> и репортилка исключений в одном флаконе. Да, ценник &ldquo;зашкаливает&rdquo;, но мне очень нравится функционал и UI. Нет, я не страдаю любовью к обфускаторам т.к. считаю эту затею бессмысленной, но вот красивый exception reporting многого стоит.</p>
</li>
<li>
<p><a href="http://wix.sourceforge.net/" title="http://wix.sourceforge.net/">WiX</a>&nbsp;&mdash; да-да, бесплатный пакет для создания инсталляторов существует уже давно, но &ldquo;распробовал&rdquo; его я только в этом году. Теперь все инсталляторы которые не используют ClickOnce делаются именно на WiX. Единственное, чего не хватает&nbsp;&ndash; это фич автообновления. Правда автообновление уже давно перестало быть большой проблемой. Но все равно хочется иметь его &ldquo;из коробки&rdquo;.</p>
</li>
<li>
<p><a href="http://www.actiprosoftware.com/products/dotnet/windowsforms/syntaxeditor/default.aspx" title="http://www.actiprosoftware.com/products/dotnet/windowsforms/syntaxeditor/default.aspx">ActiPro Syntax Editor (WinForms)</a>&nbsp;&mdash; казалось бы, что особенного в контроле-редакторе который показывает подсветку синтаксиса и code completion для C#? А то, что процесс динамического прототипирования можно сделать более &ldquo;цивильным&rdquo;. А динамическое прототипирование дает настолько серьезный прирост производительности, что не делать его уже кажется грехом. Впрочем, мне кажется я никогда не смогу объяснить людям все его бенефиты. Что же, это не критично.</p>
</li>
<li>
<p><a href="http://sharpkit.net/" title="http://sharpkit.net/">SharpKit</a>&nbsp;&mdash; транскомпилятор из C# в JavaScript. Чтобы не писать JS, который есть зло и должен умереть, хотя кто-то и соглашается на нем писать. Тулкит имеет завязки на разные фреймворки вроде jQuery, да и свои байндинги писать на так уж сложно.</p>
</li>
</ul>
<p>Программы, которые я больше не планирую использовать:</p>
<ul>
<li>
<p>SQL Server и другие RDBMS, а также такие ORM-фреймворки как Telerik OpenAccess. <a href="http://www.mongodb.org/" title="http://www.mongodb.org/">MongoDB</a> хватает &ldquo;за глаза&rdquo;, и подход NOSQL идеален для большинства задач. Единственное исключение пока это embeddability, и тут я пожалуй продолжу пользоваться SQL CE (например в том же R2P), т.к. хороших альтернатив мало.</p>
</li>
<li>
<p>IIS и ASP.NET MVC&nbsp;&mdash; с момента моего перехода на подход <a href="http://spbaltnet.podfm.ru/solo/40/" title="http://spbaltnet.podfm.ru/solo/40/">JS+REST</a>, эти технологии оказались нерелевантными. Хотя, по правде сказать, я по-прежнему использую IIS 6 для хостинга WCF REST приложений, но по крайней мере клиентскую часть я писать на ASP.NET больше не намерен.</p>
</li>
<li>
<p><a href="http://www.ndepend.com/" title="http://www.ndepend.com/">NDepend</a>&nbsp;&mdash; в нем есть полезные фичи, но они запрятаны под слоями академичного анализа который, если честно, не очень-то полезен для анализа моего кода. Гораздо полезнее обычные механизмы статического анализа.</p>
</li>
<li>
<p><a href="http://www.typemock.com/isolator-product-page" title="http://www.typemock.com/isolator-product-page">Typemock Isolator</a>&nbsp;&mdash; я на самом деле давно забросил использование такой &ldquo;тяжелой артиллерии&rdquo;, но недавно попробовал снова и был разочарован: оказалось что в VS Ultimate Typemock генерит много багов, и умеет работать только при определенно выставленной конфигурации, которая меня не устраивает.</p>
</li>
<li>
<p>Telerik MVC поскольку его <a href="http://kendoui.com" title="http://kendoui.com">больше не существует</a> :) не говоря уже о том что я больше не буду писать под ASP.NET.</p>
</li>
</ul>
<p>Технологии, которые удивили или порадовали:</p>
<ul>
<li>
<p><a href="http://www.amazon.com/Kindle-DX-Wireless-Reader-3G-Global/dp/B002GYWHSQ" title="http://www.amazon.com/Kindle-DX-Wireless-Reader-3G-Global/dp/B002GYWHSQ">Kindle DX</a>&nbsp;&mdash; пожалуй лучшее мое приобретение года. Вопрос о покупке iPad&rsquo;а даже не стоял, а KDX я прикупил после долгих раздумий и не сожалею&nbsp;&ndash; уже прочитал на нем уйму книг. Глаза он щадит, размер вменяемый для чтения &ldquo;почти А4&rdquo;. Есть конечно фейлы&nbsp;&ndash; бесплатный 3G не работает в России и Латвии (в Скандинавии&nbsp;&ndash; на ура), браузер допотопный, WiFi нету, и книжки которые продает Amazon (типа &lsquo;Kindle Edition&rsquo;) покупать нельзя т.к. все листинги кода в них&nbsp;&ndash; битмапы, оптимизированные под &ldquo;маленький&rdquo; киндл. Что просто чудовищно. PDF FTW.</p>
</li>
<li>
<p><a href="http://www.microsoft.com/windowsphone/en-us/default.aspx" title="http://www.microsoft.com/windowsphone/en-us/default.aspx">Windows Phone 7</a>&nbsp;&mdash; честно скажу: я ожидал увидеть очередное мертворожденное детище. А получилась операционка с уникальным, красивым user experience. Ведь могут когда захотят! Теперь остается ждать планшетов, хотя скажу сразу: если iPad 3 будет выпущен с Retina Display, куплю не задумываясь, ибо хочется, наконец-то, вменяемого разрешения. Если оно будет, можно будет и PDFы попробовать читать, и travel guides всякие, комиксы, и так далее&hellip;</p>
</li>
<li>
<p><a href="http://qt.nokia.com/products/developer-tools/" title="http://qt.nokia.com/products/developer-tools/">Qt Creator</a>&nbsp;&mdash; не совсем &ldquo;моё&rdquo;, конечно, но Qt Creator порадовал тем что он, во-первых, работает, а во-вторых даже более-менее понятен. В принципе, если приложение действительно нужно сделать кросс-платформенным, то я бы скорее смотрел на Qt чем на Java или AIR. И все это в очередной раз подчеркивает, что если хочешь чтобы твой алгоритм был кросс-платформенным, пиши его на С++. Ну или на С, это тоже сработает.</p>
</li>
</ul>
<p>Что технологического я ожидаю в 2012 году:</p>
<ul>
<li>
<p>Запуск <a href="http://www.ianquigley.com/A75_New_features_of_VS2012_revealed.html" title="http://www.ianquigley.com/A75_New_features_of_VS2012_revealed.html">Visual Studio 2012</a>, в комплекте с поддержкой Metro-style apps, AMP и отладкой на GPU, C#5 и так далее. Запуск новой Студии в Петербурге буду проводить лично, если только Microsoft не передумает и не снимет снова Прибалтийскую для эвента на 500 человек как на <a href="http://nesteruk.wordpress.com/2010/04/15/st-petersburg-vs2010launch/" title="http://nesteruk.wordpress.com/2010/04/15/st-petersburg-vs2010launch/">запуск 2010й</a>. Впрочем, я не против, так и так.</p>
</li>
<li>
<p><a href="https://groups.google.com/forum/#!topic/altnet-spb/nszzP-hy1VI" title="https://groups.google.com/forum/#!topic/altnet-spb/nszzP-hy1VI">Разработческая конференция на пароме</a>, курсирующем по скандинавии. С последующими туристическими ответвлениями. Будет весело.</p>
</li>
<li>
<p>Смерть и/или перерождение <a href="http://www.rim.com/" title="http://www.rim.com/">RIM</a>. Серьезно, что же с ними будет? Кто-нибудь может себе представить WP7 на Blackberry?</p>
</li>
</ul>
<p>Ну и наконец:</p>
<ul>
<li>
<p>В 2012м я окончательно уеду из <a href="http://lurkmore.to/%D0%AD%D1%82%D0%B0_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B0" title="http://lurkmore.to/%D0%AD%D1%82%D0%B0_%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B0">России</a> (куда&nbsp;&ndash; пока секрет, скажу лишь что это не Англия и не Швеция). Впрочем, произойдет это небыстро&nbsp;&ndash; переезд это дело мутное, нужно сделать 1000 дел, все проверить-перепроверить, совершить несколько плановых полетов. Главное что это произойдет&nbsp;&ndash; понимание этого уже радует.</p>
</li>
</ul>
<p>P.S.: <strong>С Новым Годом!!!</strong></p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/life/'>Life</a>, <a href='http://nesteruk.wordpress.com/category/technology/'>Technology</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/879/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/879/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/879/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/879/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/879/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/879/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/879/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/879/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=879&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/12/31/year-2011-results/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Лайфхак с использованием строковых литералов</title>
		<link>http://nesteruk.wordpress.com/2011/12/17/string-literal-lifehack/</link>
		<comments>http://nesteruk.wordpress.com/2011/12/17/string-literal-lifehack/#comments</comments>
		<pubDate>Fri, 16 Dec 2011 22:30:22 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[resharper]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=869</guid>
		<description><![CDATA[Хочу рассказать про лайфхак с использованием стороковых литералов. Строковый литерал сам по себе&#160;&#8211; достаточно унылая вещь, но есть один нюанс&#160;&#8211; лексер языкового сервиса (если у вас такой имеется) хорошо понимает начало и конец литерала, и может разом выдать содержимое как System.String. А получив полноценную CLR-строку, с ней можно очень много всего сделать. Да, сразу подчеркну&#160;&#8211; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=869&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Хочу рассказать про лайфхак с использованием стороковых литералов. Строковый литерал сам по себе&nbsp;&ndash; достаточно унылая вещь, но есть один нюанс&nbsp;&ndash; лексер языкового сервиса (если у вас такой имеется) хорошо понимает начало и конец литерала, и может разом выдать содержимое как <code>System.String</code>. А получив полноценную CLR-строку, с ней можно очень много всего сделать.</p>
<p>Да, сразу подчеркну&nbsp;&ndash; лайфхак этот не очень-то зависит от языка, хотя конечно я его использую в C#.</p>
<h3>Строка как магический псевдоконструктор</h3>
<p>Первое наблюдение&nbsp;&ndash; это то что <strong>многие объекты поддерживают метод <code>Parse()</code></strong>&nbsp;&ndash; не только <code>int</code> или <code>decimal</code>, но такие объекты как <code>DateTime</code>, <code>TimeSpan</code>, <code>XElement</code> и так далее. Это значит что написав строку, отдаленно похожую на дату, я могу сконвертировать ее в правильный вызов конструктора <code>DateTime</code>:</p>
<p><img src="http://activemesa.com/Images/R2P/StringToDateTime.png" alt="" style="border:0;" /></p>
<p>Особенно эффектно это выглядит для XML, где сложный кусок этого языка может превратиться в красивую цепочку из конструкторов <code>XElement</code>, <code>XAttribute</code> и так далее.</p>
<h3>Строка как неживая часть кода</h3>
<p>Языки можно мешать&nbsp;&ndash; например HTML и C# в MVCшных вьюшках. И если вы не боитесь временно&nbsp;&ndash; примерно на долю секунду которая нужна чтобы выполнить контекстное действие&nbsp;&ndash; потерять контроль над кодом, то кто мешает вам, например, делать string splicing в PHP-стиле, но в коде C#?</p>
<p>Вот что я имею ввиду:</p>
<p><img src="http://activemesa.com/Images/R2P/SpliceString.png" alt="" style="border:0;" /></p>
<p>В примере выше, мы вставили идентификаторы C# прямо в строку, а потом вызвали контекстное действие, которое заменило всю строку на правильный вызов <code>String.Format()</code>.</p>
<h3>Строка как мимолетно существующий DSL</h3>
<p>В погоне за оператором <code>?.</code> (цепочная процерка на <code>null</code>), многие сели на Roslyn и аналогичные вещи. Но ведь проблема цепочной проверки может очень просто решиться если вместо введения оператора мы дороворимся, что любое выражение в форме <code>a.b.c</code> может быть написано как строковый литерал и, мановением волшебной палочки превратиться в</p>
<p><pre class="brush: csharp;">
a == null ? null : (a.b == null ? null : a.b.c)
</pre>
<p>Ну или что-то в этом духе. Опять же, строка которая толком ничего не означает может быть развернута вот в такое. Код, конечно, не очень читабельный. Но всяко лучше чем пытаться делать то же самое руками.</p>
<p>
  <small>Внимательные читатели заметят, что то же самое можно извлечь и из вполне валидного идентификатора. Что ж, не спорю. Мне просто лень по нему гулять&nbsp;&ndash; для меня сделать <code>string.Split()</code> намного проще :)</small>
</p>
<p>Подобных встроенных DSLов можно сделать море. Например, можно взять нотацию HTML Zen и из этого строкового литерала создать декларацию XLinq которая соответсвует исходному коду. Возможности безграничны.</p>
<h3>Как это работает</h3>
<p>Сразу скажу&nbsp;&ndash; реализовать подобное <strong>тривиально</strong>. Для Решарпера, нужно просто контекстное действие, которое говорит вам что вы «на строке», создает новый кусок кода, и делает обмен:</p>
<p><pre class="brush: csharp;">
[ContextAction(Group = &quot;C#&quot;, Name = &quot;Hide string value&quot;,
  Description = &quot;Ensures the string is not human-readable in code.&quot;,
  Priority = 15)]
public class StringHideRealValueCA : IContextAction
{
  private readonly IList&lt;IBulbItem&gt; items = new List&lt;IBulbItem&gt;();
  private readonly ICSharpContextActionDataProvider provider;
  public StringHideRealValueCA(ICSharpContextActionDataProvider provider)
  {
    this.provider = provider;
  }
  public bool IsAvailable(IUserDataHolder cache)
  {
    var e = provider.GetSelectedElement&lt;ICSharpLiteralExpression&gt;(true, true);
    if (e != null &amp;&amp; e.IsConstantValue())
    {
      if (e.ConstantValue.IsString())
      {
        var s = (string)e.ConstantValue.Value;
        if (!string.IsNullOrEmpty(s))
          items.Add(new StringHideRealValueImpl(provider, e));
      }
    }
    return items.Count &gt; 0;
  }
  public IBulbItem[] Items
  {
    get { return items.ToArray(); }
  }
}
</pre>
<p>В коде выше, <code>StringHideRealValueProvider</code> прячет естественную строку, подменяя ее Base64-закодированной строкой. Вот, собственно, реализация:</p>
<p><pre class="brush: csharp;">
private class StringHideRealValueImpl
{
  // очевидные методы опущены
      protected override Action&lt;ITextControl&gt; ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
  {
    CSharpElementFactory factory = CSharpElementFactory.GetInstance(provider.PsiModule, true);
    var value = literal.ConstantValue.Value as string;
    if (value != null)
    {
      string encoded = Convert.ToBase64String(Encoding.Unicode.GetBytes(value));
      ICSharpExpression ex = factory.CreateExpressionAsIs(
        string.Format(&quot;System.Text.Encoding.Unicode.GetString(System.Convert.FromBase64String(\&quot;{0}\&quot;))&quot;, encoded));
      literal.ReplaceBy(ex);
    }
    return
      tc =&gt; provider.PsiFile.OptimizeImportsAndRefs(
        provider.Document.DocumentRange.CreateRangeMarker(provider.Document), false, true, progress);
  }
}
</pre>
<p>Если коротко, в замену существующему литералу создается выражение (через вызов <code>CreateExpressionAsIs</code>), а потом банально втыкается в замен существующей строки. На базе этого вы можете писать свои механизмы подмены&nbsp;&ndash; это тривиально!</p>
<h3>Заключение</h3>
<p>Пример выше&nbsp;&ndash; это маленький лайфхак который иногда помогает писать код быстрее. String splicing особенно полезен, хотя нужно приучить себя им пользоваться. Помните&nbsp;&ndash; эти строки только несколько секунд «магические», а потом перестают существовать совсем. Так что ничего страшного.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/resharper-2/'>resharper</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/869/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/869/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/869/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/869/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/869/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/869/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/869/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/869/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=869&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/12/17/string-literal-lifehack/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://activemesa.com/Images/R2P/StringToDateTime.png" medium="image" />

		<media:content url="http://activemesa.com/Images/R2P/SpliceString.png" medium="image" />
	</item>
		<item>
		<title>Воскрешение языка С++</title>
		<link>http://nesteruk.wordpress.com/2011/10/30/cplusplus-resurrection/</link>
		<comments>http://nesteruk.wordpress.com/2011/10/30/cplusplus-resurrection/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 21:13:44 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cplusplus]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=854</guid>
		<description><![CDATA[Сдается мне, что на всей нашей круглой планете вряд ли можно найти человека, который мог бы с уверенностью сказать, в чем заключается стратегия Microsoft относительно разработки в целом. Жив ли WPF, что будет с Silverlight для веба, откуда такой ажиотаж вокруг HTML 5 и причем тут, наконец, С++? Иногда мне кажется что ни у кого [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=854&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>
  <img class="alignright" src="http://nesteruk.org/pix/0/ebb7a797-5f72-448d-8950-1b2cb8ff1f8d.png" alt="" style="border:0;" align="right" /><br />
Сдается мне, что на всей нашей круглой планете вряд ли можно найти человека, который мог бы с уверенностью сказать, в чем заключается стратегия Microsoft относительно разработки в целом. Жив ли WPF, что будет с Silverlight для веба, откуда такой ажиотаж вокруг HTML 5 и причем тут, наконец, С++? Иногда мне кажется что ни у кого нет ответов на эти вопросы, и что в погоне за добычей (добычей тут может быть, например, рынок планшетов), не возбраняется полностью смешать все карты и начать заново.
</p>
<p>Тем не менее, мы должны признать, что по крайней мере в свете анонсов касательно <a href="http://tirania.org/blog/archive/2011/Sep-15.html" title="http://tirania.org/blog/archive/2011/Sep-15.html">WinRT</a>, язык программирования С++ снова становится более актуальным чем ранее. Да и не только сам С++. Ведь фактически то, что нас ждет, это некая реинкарнация COM, правда с другими терминами и, возможно, меньшим количеством проблем. (Ведь неслучайно PIA &ndash; Primary Interop Assembly &ndash; расшифровывается также как Pain In the Ass;)</p>
<p>Если быть честно-откровенными, то тот С++ который предлагает нам Microsoft &ndash; это совсем не «стандартные» плюсы. Хотя, точно так же как и в случае с C++/CLI, остается возможность использования «труъ» кода, который был написан ранее. Но вот уже в 3й раз нам предлагают некую магию.</p>
<p>Почему в 3й? Ну, 1м разом я считаю все те изменения языка, которые не были стандартизованы. С Java/Visual J++ такое не прошло т.к. там правила ныне отошедшая на покой компания Sun, в случае же с С++ не нашлось стороны, которая единолично планировала бы получать доходы с этого языка. Поэтому Microsoft могла сделать все, что угодно &ndash; добавить поддержку свойств (да-да, свойств в стиле C#) с помощью <code>__declspec(property)</code>, замутить поддержку COM с помощью <code>#import</code>, ну и так далее. Вторым вмешательством в С++ можно считать MC++ и с последствии С++/CLI, который добавил массу ненужных ключевых слов, а также эти ненавистные шляпки (^) для классов. Ну и так далее.</p>
<p>Впрочем, создание C++/CLI было вынужденным. Я это начал понимать только тогда, когда начал встречать кросс-платформенные (!) библиотеки на С++ которые компилировались, помимо обычного С++, еще и с «управляемой прослойкой» для .Net языков. Идея в принципе оказалась правильной &ndash; дать .Net разработчикам всю мощь С++ библиотек без особого напряжения в виде P/Invoke или надобности обращать С++ библиотеки в COM.</p>
<p>Ну и наконец, шаг 3й &ndash; это полностью узаконить любые новшества в С++ сделав его одним из официальных языков разработки для Windows. Это на самом деле лицемерие &ndash; ведь для Windows итак можно писать на «плюсах» используя MFC или даже WTL. Но уверен что мало кто этим занимается. Потери от этого больше, чем потери от требования наличия .Net Framework Client Profile на компьютере. Кстати &ndash; недавно в процессе тестирования лицезрел что происходит если поставить ClickOnce-программу которая использует .Net 4 на Windows XP. Инсталлятор сам скачивает и устанавливает framework. Это конечно нехилый download, но большинство людей 100-мегабайтные файлы уже практически не пугают.</p>
<p>Так вот, хотите вы этого или нет, С++ будет использоваться Microsoft в своих целях, связанных с разработкой под Windows. Но это конечно не значит что вы не сможете получить от этого бенефиты, даже если пишете на .Net.</p>
<h3>Приемущества С++</h3>
<p>Давайте определимся с тем, что же дает нам С++ чего не может дать тот же C#.</p>
<p><strong>Ручное управление памятью.</strong> У меня в голове иногда случаются страшные баталии, связанные с тем, нужно ли делать объект структурой или классом. В принципе, в .Net нам пытаются навязать ограничение, связанное с размером объекта &ndash; дескать, если маленький то можно и структуру, а иначе ни-ни. Но это подразумевает что мы, разработчики, наивно делаем pass by value и тем самым поедаем память. Что не всегда так.</p>
<p><strong>Доступ к высокопроизводительным инструкциям процессора.</strong> Возьмем например SIMD. Думаю можно с большой степенью уверенности сказать, что JIT-компилятор не оптимизирует и никогда не будет оптимизировать код под SIMD. Соответственно, мы с Microsoft.Net начинаем проигрывать даже Mono, где есть <a href="http://tirania.org/blog/archive/2008/Nov-03.html" title="http://tirania.org/blog/archive/2008/Nov-03.html">соответствующий пакет</a>.</p>
<p><strong>Прямой доступ к намного более зрелым и продуманным библиотекам.</strong> Это более сумеречный бенефит, т.к. API таких библиотек порой ужасно. Но надо смотреть не только на API но и на производительность.</p>
<p>О да, я же забыл упомянуть о самом важном &ndash; Microsoft ныне разрабатывает свои библиотеки для С++. Примером такой библиотеки может быть вышеупомянутая <a href="http://msdn.microsoft.com/en-us/library/dd492418.aspx" title="http://msdn.microsoft.com/en-us/library/dd492418.aspx">Parallel Patterns Library</a> (PPL), которая с одной стороны может считаться «неуправляемым» аналогом .Net&rsquo;ного TPL, а с другой &ndash; конкурентом <a href="http://threadingbuildingblocks.org/" title="http://threadingbuildingblocks.org/">Intel Threading Building Blocks</a> (TBB). Но на этом все не останавливается &ndash; Microsoft работает еще на одной библиотекой под названием <a href="http://blogs.msdn.com/b/vcblog/archive/2011/06/15/introducing-amp.aspx" title="http://blogs.msdn.com/b/vcblog/archive/2011/06/15/introducing-amp.aspx">C++ Accelerated Massive Parallelism</a> (AMP), которая будет заниматься поддержкой вычислений как на CPU так и на GPU.</p>
<p>Программирование для GPU заслуживает отдельную заметку. На данный момент, графические процессоры можно программировать с помощью OpenCL (вариации языка С++ для различных устройств), <a href="http://www.nvidia.ru/object/cuda_home_new_ru.html" title="http://www.nvidia.ru/object/cuda_home_new_ru.html">CUDA C</a> (подобия С++ для чипов NVidia, кстати с прекрасным тулсетом для Visual Studio). Существуют также решения на .Net, такие как исследовательский проект <a href="http://research.microsoft.com/en-us/projects/accelerator/" title="http://research.microsoft.com/en-us/projects/accelerator/">Microsoft Accelerator</a> (который, насколько я знаю, также работает с FPGA) или коммерческое решение <a href="http://www.tidepowerd.com/" title="http://www.tidepowerd.com/">GPU.NET</a>.</p>
<h3>Недостатки С++</h3>
<p>С++ архаичен. Использовать его для ООП &ndash; делать себе плохо. Даже со всеми новшествами C++ 2011 является динозавром, пусть и динозавром который пока не думает вымирать. С другой стороны, С++ прекрасно подходит для производительных алгоритмов.</p>
<p>Приведу пример. Мне в <a href="http://bitbucket.org/nesteruk/typografix" title="http://bitbucket.org/nesteruk/typografix">TypograFix</a> нужно обрабатывать <code>Bitmap</code>&rsquo;ы. Если использовать .Net, то единственная возможность получить более-менее вменяемую скорость по обработке картинок &ndash; это использовать <code>unsafe</code>. Что как бы само по себе не очень эффективно, но даже если у вас получится, вы не сможете эффективно настроить параллелизацию unsafe кода. (Автор пробовал использовать TPL и <code>unsafe</code>, с весьма мутными результатами.)</p>
<p>Еще одна проблема &ndash; это нехватка инструментария. Отладчики конечно есть, но вот анализа кода в стиле Решарпера мне очень нехватает. А ведь это как раз тот «небезопасный» язык, в котором так нужны всяческие проверки, причем чем их больше, тем лучше.</p>
<p>Это основные недостатки, но есть и масса других. <a href="http://drdobbs.com/blogs/cpp/228701711" title="http://drdobbs.com/blogs/cpp/228701711">Скорость компиляции</a>, неинформативность ошибок, итд, итп. Масса компромиссов, на которые можно пойти в погоне за производительностью.</p>
<h3>AMP</h3>
<p>У инициативы AMP есть одно существенное приемущество &ndash; над этой технологией работают AMD и NVidia, две компании которые держат рынок графических карт (лично я тяготею к AMD потому что у них есть <a href="http://www.amd.com/us/products/technologies/amd-eyefinity-technology/Pages/eyefinity.aspx" title="http://www.amd.com/us/products/technologies/amd-eyefinity-technology/Pages/eyefinity.aspx">Eyefinity</a>). Работают они над ней, конечно, с Microsoft, т.к. у всех трех компаний есть уклон в сторону различных процессоров. Кстати, в случае с Microsoft, это конечно же ARM, о котором вы все уже наверняка наслышаны. Соответственно идея, как мне кажется, в том, чтобы иметь код (возможно даже код низкого уровня &ndash; драйвера, кодеки, и т.п.) который мог бы выжать максимум возможностей из любого процессора.</p>
<p>С другой стороны, по крайней мере для GPU, поддержка идет по наименьшему знаменателю, и этот знаменатель называется <a href="http://en.wikipedia.org/wiki/DirectCompute" title="http://en.wikipedia.org/wiki/DirectCompute">DirectCompute</a>. Поэтому неизвестно, будет ли AMP настолько эффективен как например CUDA C или кросскомпиляция, скажем, C# в NVidia <a href="http://en.wikipedia.org/wiki/Parallel_Thread_Execution" title="http://en.wikipedia.org/wiki/Parallel_Thread_Execution">PTX</a> (именно это делает GPU.NET). Также непонятно, придется ли писать fallback-код для CPU в случае отсутствия девайса с поддержкой DirectCompute &ndash; если это придется делать, то часть шарма данного подхода пропадет, т.к. это точно не «write once, run everywhere».</p>
<h3>Intel C++</h3>
<p>Microsoft не является единственной компанией, которая выпускает компилятор С++. Intel тоже делает компилятор, в большей степени заточенный на свои процессоры, с неплохой интеграцией в Visual Studio. Важен не только сам компилятор (а он хорош), но и тулсет &ndash; отладчик, профилировщик, библиотеки. Все это на высоте. Библиотеки, например, работают более резво на процессорах AMD чем библиотеки самой AMD.</p>
<p>На сегодняшний день я готов работать только с компилятором Intel. Я не использую C++/CLI, мне хватает P/Invoke. На самом деле, технология P/Invoke &ndash; настолько простая и понятная, что я не чувствую особого стеснения когда пишу часть проекта на C# а часть на С++. Что P/Invoke не поддерживает так это, конечно же, ООП и возможность передавать туда-сюда классы, но тут я скажу вот что: если вы используете С++ именно для ООП (или для взаимодействия с .Net) &ndash; вы делаете что-то не так. На С++ нужно писать производительные алгоритмы, или использовать уже существующие библиотеки (например, Intel TBB, <a href="http://software.intel.com/ru-ru/articles/intel-mkl/" title="http://software.intel.com/ru-ru/articles/intel-mkl/">MKL</a> или <a href="http://software.intel.com/en-us/articles/intel-ipp/#support" title="http://software.intel.com/en-us/articles/intel-ipp/#support">IPP</a>). Потреблять ООП-структуры там бесполезно, но с другой стороны, не возбраняется потреблять оттуда COM. Например, когда только вышли библиотеки Direct2D/DirectWrite, я захотел ими воспользоваться в WPF-проекте и просто написал C++ DLL&rsquo;ку, которая рисовала в «залоченый» <code>System.Drawing.Bitmap</code>. Никаких проблем.</p>
<h3>OpenMP</h3>
<p><a href="http://en.wikipedia.org/wiki/OpenMP" title="http://en.wikipedia.org/wiki/OpenMP">OpenMP</a> &ndash; это поддержка декларативной параллелизации на С++. Это может показаться шуткой, но на самом деле это старая, проверенная временем технология, которая работает. Для большинства случаев data-level параллелизации в стиле <code>parallel_for()</code> подходит именно OpenMP. Я много где использую именно OpenMP, оставляя Intel TBB для более сложных задач, где автоматический подход не сработает.</p>
<p>Конечно, в .Net есть некий аналог &ndash; использование TPL и надежда на то, что JIT-компилятор магическим способом оптимизирует и «векторизует» сгенерированный код. Но это достаточно наивно. Пока вы проверяете индекс элемента доступа к массиву, вы теряете в производительности. Как только вы это отключите, у вас начнутся уже другие проблемы.</p>
<p>Если честно, я не большой фанат TPL. Для простеньких случаев в которые не хочется вникать, я просто пишу <code>Parallel.Invoke</code> или вставляю <code>AsParallel()</code> в цепочку LINQ-запроса и надеюсь на лучшее. Но если мне нужно почитать <a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0" title="http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0">дистанцию Левенштейна</a> на огромном наборе данных, то я даже напрягаться не буду &ndash; отошлю все данные в неуправляемый код, а там уж сделаю все «правильно».</p>
<h3>Заключение</h3>
<p>Я надеюсь, что повышенное внимание к С++ приведет к улучшению редактора. Правильный IntelliSense уже будет достижением. А что еще надо &ndash; ах да, возможно какой-нибудь генератор P/Invoke оберток и соответствующей документации для того чтобы упростить процесс.</p>
<p>К слову скажу, что недавно пытался найти нормальный блог по С++ путем вбивания &ldquo;с++ блог&rdquo; в гугле. Гугл выдал какой-то мусор. Если кто-то знает интересные блоги на русском, дайте ссылочку в комментариях. Спасибо.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/programming/'>Programming</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/cplusplus/'>cplusplus</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/854/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/854/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/854/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=854&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/10/30/cplusplus-resurrection/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://nesteruk.org/pix/0/ebb7a797-5f72-448d-8950-1b2cb8ff1f8d.png" medium="image" />
	</item>
		<item>
		<title>Язык программирования D</title>
		<link>http://nesteruk.wordpress.com/2011/08/28/d-programming-language/</link>
		<comments>http://nesteruk.wordpress.com/2011/08/28/d-programming-language/#comments</comments>
		<pubDate>Sun, 28 Aug 2011 18:14:49 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[D]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=834</guid>
		<description><![CDATA[У любого вменяемого программиста который сталкивается с языком программирования С++ должно рано или поздно возникать чувство отвращения и полной богозабытости. И если в случае с Java кто-то еще может поспорить что &#8220;светлое будущее впереди&#8221; (фиаско с Java 7 как бы намекает), то с С++ мне кажется определились все: и те кто недавно перешли или решили [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=834&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img src="http://nesteruk.org/pix/0/661674fe-a3a7-455b-8277-93fadb714b33.png" class="alignright" align="right" alt="" style="border:0;" />У любого вменяемого программиста который сталкивается с языком программирования С++ должно рано или поздно возникать чувство отвращения и полной богозабытости. И если в случае с Java кто-то еще может поспорить что &ldquo;светлое будущее впереди&rdquo; (фиаско с Java 7 как бы намекает), то с С++ мне кажется определились все: и те кто недавно перешли или решили просто попробовать, и те кто с ним работают десятилетиями.</p>
<p>С++ устарел. Программы на С++, как бы красиво они не выглядели, не соответствуют современным реалиям. Попытки пропатчить C++ под 0x/2011 выглядят трезвыми только на фоне того, что в &ldquo;плюсах&rdquo; появились лямбда-выражения, а в Java 7 у Oracle нехватило силенок их сделать.</p>
<p>Вообще, мне по большому счету все равно. Все равно насчет Java-стека т.к. на Java я не пишу, на Scala меня не тянет (синтаксис F# на порядок лучше, имхо). С другой стороны, у меня есть небольшие &ldquo;вкрапления&rdquo; С++ в проекты, поэтому о них наверное стоит рассказать.</p>
<h3>Зачем нужен С++?</h3>
<p>Конкретно мне С++ нужен для параллелизации. Нет, поймите меня правильно, я ни в коей случае не против TPL и всяких прелестей вроде <code>Parallel.For</code> или <code>AsParallel()</code>. Более того, все что я сейчас делаю с коллекциями обычно содержит использование TPL т.к. это достаточно безопасный способ ускорить программу.</p>
<p>Но есть ряд областей где .Net-а мало. Возьмем например обработку изображений &ndash; даже если вы напишете обработку Bitmap&rsquo;а в <code>unsafe</code> режиме на C#, это все равно будет существенно медленнее чем использование C++. Особенно если учесть, что в плюсах есть доступ к SSE (<code>__mm_mul_ps</code> и все такое). И самое главное, что манипуляций-то никаких особо не нужно, т.к. класс <code>System.Drawing.Bitmap</code> может выдать указатель на фиксированный блок памяти, который в последствии можно через P/Invoke передать в тело метода на C++. А дальше можно использовать все прелести OpenMP, Threading Building Blocks, а также мощный инструментарий.</p>
<p>Кстати о&hellip; думаю стоит пояснить, что я религиозно использую <strong>стек Intel</strong>, т.е. <a href="http://software.intel.com/en-us/articles/intel-parallel-studio-home/" title="http://software.intel.com/en-us/articles/intel-parallel-studio-home/">Intel Parallel Studio</a> со всеми прелестями. Это важно потому что инструментарий этот достаточно хороший и много чего умеет, компилятор С++ от Microsoft в былые годы (до Intel) был ооочень слабоват &ndash; в те времена, чтобы заработали примеры из <a href="http://www.amazon.com/Generative-Programming-Methods-Tools-Applications/dp/0201309777" title="http://www.amazon.com/Generative-Programming-Methods-Tools-Applications/dp/0201309777">Generative Programming</a>, нужно было использовать KAI C++, Metrowerks или еще какой-то сторонний компилятор. Мне правда повезло &ndash; на шаблонное метапрограммирование я так и не подсел, хотя идея конечно заманчива.</p>
<p>Итак, если прорезюмировать то, зачем мне С++ нужен, должен сказать, что нужен он для производительности в параллелизуемых алгоритмах. Для нативных библиотек С++ не критичен, т.к. всегда можно написать P/Invoke обертку или скачать уже готовую, а вот для новых, свежих алгоритмов &ndash; при условии что они не требуют качественного библиотечного окружения &ndash; С++ очень даже подходит.</p>
<h3>А причем тут D?</h3>
<p>Я уже давно хотел попробовать D, но все нехаватало времени. Теперь же у меня получилось истратить день на изучение особенностей языка и выборочное читание частей <a href="http://www.amazon.com/D-Programming-Language-Andrei-Alexandrescu/dp/0321635361" title="http://www.amazon.com/D-Programming-Language-Andrei-Alexandrescu/dp/0321635361">The D Programming Language Александреску</a>. Книга, кстати, классная &ndash; объем информации большой, написано с долей весьма своеобразного юмора.</p>
<p>Собственно использование D под Windows требует от вас две вещи.</p>
<p>Во-первых, нужно скачать компилятор. Инсталлятор (MSI) все делает сам, напрягаться толком не нужно.</p>
<p>Во-вторых, хоть это и опционально, можно скачать IDE или пакет поддержки уже существующей IDE. Я конечно же скачал <a href="http://dsource.org/projects/visuald" title="http://dsource.org/projects/visuald">Visual D</a> &ndash; пакет для Visual Studio. Особенности пакета:</p>
<ul>
<li>
<p>Позволяет создавать проекты на языке D и конфигурировать их</p>
</li>
<li>
<p>Весьма слабо поддерживает IntelliSense &ndash; можно сказать что поддержки практически нет</p>
</li>
<li>
<p>Есть отладка (YMMV, конечно же)</p>
</li>
<li>
<p>Все это, увы, 32-bit</p>
</li>
</ul>
<p>Одна из фееричных особенностей использования D &ndash; это то, что <strong>компиляция практически моментальна</strong>. Всем кто привык работать со студией это должно выносить мозг. Вы нажали F6, и программа скомпилировалась &ndash; вот так, просто.</p>
<h3>D vs. C++</h3>
<p>В чем же приемущества D? Попробую перечислить то, что бросилось в глаза:</p>
<ul>
<li>
<p>Нет этого бреда с заголовочными файлами, <code>#pragma once</code> и т.п. Порядок файлов в проекте тоже не важен (F#, я смотрю на тебя). Пишешь <code>module foo</code> в одном файле и <code>import foo</code> в другом.</p>
</li>
<li>
<p>Строки&hellip; строки вменяемы, почти как в C#. Почти потому что остались извраты с UTF-16 и UTF-32 для тех кто знает в этом толк. Да, естественно что до .Net в плане глобализации не дотянуть &ndash; но цель не в этом.</p>
</li>
<li>
<p>Сборка мусора. При этом можно выделять память собственноручно если вдруг у вас приступ мазахизма.</p>
</li>
<li>
<p>Свойства! Java и С++ могут убить себя об стену, <code>__declspec(property)</code> идет лесом. Свойства, имхо, должны быть в любом современном языке программирования. И тут они есть, и ими приятно пользоваться.</p>
</li>
<li>
<p>Piece de resistance: ключевое слово <code>mixin</code>. Самый вменяемый подход к метапрограммированию, который просто ставит в угол Boo, Nemerle и иже с ними.</p>
</li>
</ul>
<p>Язык D отличается очень продуманным, вменяемым дизайном и при этом не несет с собой кучу устаревшей/спорной идеологии на тему того что, например, публичные поля это плохо, надо делать свойства.</p>
<h3>Mixin</h3>
<p>Как работает метапрограммирование в языках вроде Boo? Там с помощью цитирования создается объектная модель кода &ndash; например <code>[| x + y |]</code> превращается в <code>BinaryExpression</code>. Вставки из реального мира делаются с помощью splice-оператора <code>$</code>. Тем самым, чтобы <em>хоть что-то</em> сгенерировать, нужно уметь создавать объектную модель нужного кода.</p>
<p>В большинстве случаев это вообще не нужно. Гораздо проще взять и сгенерировать строку (на подобии T4), которая создает текстовое представление и добавляет его в исходный код на этапе компиляции. Это в 100 раз проще чем мучаться с объектной моделью компилятора.</p>
<p>В языке D, инструкция <code>mixin</code> просто принимает строку. Напишите <code>mixin("string Name;")</code> и вы добавили в класс поле <code>Name</code>. Тривиально. Естественно что строки можно не только передавать напрямую, но и создавать отдельные функции, которые <em>исполняются на этапе компиляции</em>. Это решает проблему метапрограммирования в большинстве случаев.</p>
<h3>Недостатки</h3>
<p>Куда же без них. Вот то, что я успел заметить:</p>
<ul>
<li>
<p>Дебаггер порой идет совсем не туда куда нужно. Вложенные функции и делегаты дебажатся &ldquo;с грехом пополам&rdquo;.</p>
</li>
<li>
<p>Конкретно под Windows, D компилируется только в 32-bit.</p>
</li>
<li>
<p>Стандартные библиотеки конечно не дотягивают до какой-нть STL но они намного более вменяемы. Так что это палка о двух концах.</p>
</li>
<li>
<p>Стандартных библиотек на самом деле две &ndash; Phobos и Tango. Какую использовать &ndash; непонятно. В Phobos я уже столкнулся с недопиленностью &ndash; например <code>std.xml</code> сейчас переписывается.</p>
</li>
<li>
<p>Никто пока не воспринимает D серьезно. Даже у F# больше exposure чем у D, что собственно понятно &ndash; ведь F# продвигает Microsoft и этот язык активно используется в quant finance.</p>
</li>
<li>
<p>IntelliSense не работает в Visual D. Надо будет еще глянуть на D-IDE которая, кстати, написана под .Net 4 :)</p>
</li>
</ul>
<h3>Впечатления</h3>
<p>Мне D <em>очень понравился</em>. Это язык с максимальным уровнем вменяемости и достаточно низким уровнем шума. Если вам не нужно завязок на 100 библиотек, D позволит вам быстро разрабатывать и компилировать ваш код. При этом вы не теряете в выразительности &ndash; тут и делегаты, и события, и вложенные функции, функциональные литералы (= лямбда-выражения), не говоря уже о совсем продвинутых вещах вроде вариадичных шаблонов.</p>
<p>Резюмируя, должен сказать что D меня очаровал, и в ближайшее время я планирую его использовать к некритичных, non-production проектах дабы прочувствовать все его возможности. А они, судя по первичным наблюдениям, весьма обширны.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/d/'>D</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/834/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/834/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/834/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=834&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/08/28/d-programming-language/feed/</wfw:commentRss>
		<slash:comments>66</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://nesteruk.org/pix/0/661674fe-a3a7-455b-8277-93fadb714b33.png" medium="image" />
	</item>
		<item>
		<title>Нужен ли математикам статический анализ?</title>
		<link>http://nesteruk.wordpress.com/2011/08/18/do-quants-need-static-analysis/</link>
		<comments>http://nesteruk.wordpress.com/2011/08/18/do-quants-need-static-analysis/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 19:22:54 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[math]]></category>
		<category><![CDATA[quant]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=825</guid>
		<description><![CDATA[Есть такая профессия, в которой люди на 50% процентов занимаются программированием, но при этом сидят на порой весьма &#8220;несовременных&#8221; технологиях, пишут в основном на С++, и никаких особых бенефитов от IDE вообще не имеют. И при этом не жалуются. В этом посте &#8211; про то, кто эти люди, чем они заниматся и чем мы можем [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=825&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Есть такая профессия, в которой люди на 50% процентов занимаются программированием, но при этом сидят на порой весьма &ldquo;несовременных&rdquo; технологиях, пишут в основном на С++, и никаких особых бенефитов от IDE вообще не имеют. И при этом не жалуются. В этом посте &ndash; про то, кто эти люди, чем они заниматся и чем мы можем сделать их жизнь лучше.</p>
<h3>Знакомьтесь &ndash; квонты</h3>
<p><a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%B2%D0%BE%D0%BD%D1%82" title="http://ru.wikipedia.org/wiki/%D0%9A%D0%B2%D0%BE%D0%BD%D1%82">Квонт</a>, он же quant (quantitative analyst &ndash; численный, так сказать, аналитик) &mdash; это человек, который занимается применением математики в финансах, часто &ndash; для создания торговых систем, т.е. программ, которые занимаются автоматизированной торговлей на бирже. Эти люди &ndash; чаще всего магистры или PhD в области физики (да-да) или математики (в частности, с дипломами вроде MFE &ndash; Masters in Financial Engineering), в некоторых случаях, с дипломом <a href="http://www.cqf.com/" title="http://www.cqf.com/">CQF</a> (один из очень небольшого кол-ва &ldquo;неакадемических&rdquo; дипломов) или даже с MBA Finance или а ля.</p>
<p>Квонты (я бы называл их кв<em>а</em>нтами) программируют в очень узком ключе &ndash; их в большинстве случаев не волнуют новые тренды в Asp.Net или новых языках вроде Scala или D. Они живут в совершенно другой реальности, где доминантным маст-хэв языком был, есть и будет С++. Конечно, есть варинты (например, вспомним <a href="http://www.janestcapital.com/" title="http://www.janestcapital.com/">Jane Street</a> и их любовь к OCaml), но суть остается одна &ndash; эти разработчики привыкли работать с достаточно ограниченным tool support, и не особо от этого страдают. Ведь согласитесь, для того чтобы эффективно выполнять математические рассчеты нужно лишь чтобы у вас худо-бедно работал intellisense, и то, это не так критично если нужно вызвать что-то вроде <code>std::min()</code>.</p>
<p>Соответственно, текущее положение вещей наводит на мысль, что людям которые используют в основном C++ (а также MATLAB, VBS, R, ну и другие языки на вкус) tool support как бы не очень нужен.</p>
<h3>И все же&hellip;</h3>
<p>Приведу конкретный пример. На многих графических устройствах, операция <code>a*x+b</code> оптимизирована и проходит быстрее, чем умножение и сложение отдельно. Соответственно, когда я работаю с GPU.NET, у меня есть в <a href="http://activemesa.com/r2p" title="http://activemesa.com/r2p">R2P</a> контекстное действие, которое превращает все, что похоже на &ldquo;умножение-в-сложении&rdquo; на вызов вроде <code>DeviceMath.MultiplyAdd(a, x, b)</code>. Мелочь, а приятно, и программу ускоряет.</p>
<p>И это далеко не частный случай. Вот еще пример &ndash; допустим что вы попросили студента за еду реализовать вам ряд формул в коде, и студент в качестве реализации написал что-то вроде <code>y = a * Math.Pow(x, 2.0) + b * x</code>. Бред, не так ли?</p>
<p>И тут снова можно включить &ldquo;электронный мозг&rdquo; статического анализатора и начать помогать несчастному разработчику. Для начала ему нужно объяснить, что считать ряды Тэйлора в подобном случае раз, эээ, в 50 медленнее чем сделать <code>x*x</code>. Но даже объяснив это, вы получите вот такой результат:</p>
<p><pre class="brush: csharp;">
y = a * x * x + b * x;
</pre>
<p>Это тоже не очень-то эффективно. Ведь тут целых 3 умножения, хотя можно обойтись двумя:</p>
<p><pre class="brush: csharp;">
y = x * (a * x + b);
</pre>
<p>Опаньки, а это факторизация, задачка уже посложнее, особенно в контексте статического анализа. Тем не менее, она решабельна, и позволит квонту хоть немного но ускорить вычисления.</p>
<h3>А это имеет смысл?</h3>
<p>Действительно, кому нужна скорость? Ну, наблюдения показывают что ряд задач (например, Монте-Карло симуляции) очень любят кушать CPU. Микрооптимизация вычислений &ndash; это как раз то, что позволит аналитику протестировать свою стратегию быстрее, на большем объеме данных.</p>
<p>Еще одна полезная, хотя и тривиальная вещь &ndash; это рефакторинги с уклонов в сторону параллелизации &ndash; например рефакторинг <code>for</code> и <code>foreach</code> циклов в параллельные с сохранением правильной семантики. То есть, если разработчик написал</p>
<p><pre class="brush: csharp;">
int [] elems = new int[] { ⋮ };
int sum = 0;
foreach (var e in elems) sum += e;
</pre>
<p>то почему бы нам не дать ему возможность отрефакторить этот цикл в параллельный:</p>
<p><pre class="brush: csharp;">
Parallel.ForEach(elems, () =&gt; 0, 
                 (n, loopState, localSum) =&gt; 
                 {
                   localSum += n;
                   return localSum;
                 },
                 localSum =&gt; Interlocked.Add(ref sum, localSum));
</pre>
<p>У меня в R2P уже реализованы некоторые приведения простых циклов в параллельные, но это большая задача, и за один день ее не решить.</p>
<h3>Другие языки?</h3>
<p>Я привел пример поддержки C#, т.к. не знаю доступной инфраструктуры для написания рефакторингов для С++ или (это было бы еще интересней) для CUDA C. Было бы интересно услышать мнение читателей насчет применимости всех этих идей.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/c-2/'>c++</a>, <a href='http://nesteruk.wordpress.com/tag/math/'>math</a>, <a href='http://nesteruk.wordpress.com/tag/quant/'>quant</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/825/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/825/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/825/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/825/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/825/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/825/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/825/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/825/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=825&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/08/18/do-quants-need-static-analysis/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Управление подписками на события</title>
		<link>http://nesteruk.wordpress.com/2011/08/02/managing-event-subscriptions/</link>
		<comments>http://nesteruk.wordpress.com/2011/08/02/managing-event-subscriptions/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 03:27:48 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[rx]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=818</guid>
		<description><![CDATA[Итак, небольшая заметка на тему того, как я работаю с подписками на события. Проблема такая: у меня есть XMPP-клиент, он генерирует тучу событий, которые хочется отловить, но помимо этого, еще иногда нужно делать reset этому клиенту, напрочь удаляя все подписки и создавая новые. Для начала, я создаю класс DisposableCollection который умеет вызывать Dispose() на каждом [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=818&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Итак, небольшая заметка на тему того, как я работаю с подписками на события. Проблема такая: у меня есть XMPP-клиент, он генерирует тучу событий, которые хочется отловить, но помимо этого, еще иногда нужно делать reset этому клиенту, напрочь удаляя все подписки и создавая новые.</p>
<p>Для начала, я создаю класс <code>DisposableCollection</code> который умеет вызывать <code>Dispose()</code> на каждом элементе коллекции:</p>
<p><pre class="brush: csharp;">
public sealed class DisposableCollection : Collection&lt;IDisposable&gt;, IDisposable
{
  public void Dispose()
  {
    foreach (var obj in this)
      obj.SafeDispose();
  }
}
</pre>
<p><code>SafeDispose()</code> в коде выше &ndash; это всего лишь <code>Dispose()</code> с проверкой на <code>null</code>. Метод также возвращает «флаг успешности», что порой бывает полезно.</p>
<p><pre class="brush: csharp;">
public static bool SafeDispose(this IDisposable thіs)
{
  if (thіs != null)
  {
    thіs.Dispose();
    return true;
  }
  return false;
}
</pre>
<p>Еще один extension method &mdash; это инверсия потока управления для добавления элементов в коллекцию:</p>
<p><pre class="brush: csharp;">
public static T AddTo&lt;T&gt;(this T thіs, Collection&lt;T&gt; coll)
{
  coll.Add(thіs);
  return thіs;
}
</pre>
<p>А теперь всем этим можно пользоваться. Для подписок используем ReactiveExtensions.</p>
<p><pre class="brush: csharp;">
public sealed class XmppConnectionManager : IResetable
{
  private XmppClient client;
  private DisposableCollection subscriptions;
  private void InitializeEvents()
  {
    // wire up events
    Observable.FromEventPattern&lt;ExceptionEventArgs&gt;(x =&gt; client.OnError += x, x =&gt; client.OnError -= x)
      .Subscribe(x =&gt; OnError(x.EventArgs))
      .AddTo(subscriptions);
    Observable.FromEventPattern&lt;EventArgs&gt;(x =&gt; client.OnLogin += x, x =&gt; client.OnLogin -= x)
      .Subscribe(x =&gt; OnLogin(x.EventArgs))
      .AddTo(subscriptions);
    ...
  }
}
</pre>
<p>Соответственно, если нужно вдруг отписаться от всех подписок, это делается очень быстро:</p>
<p><pre class="brush: csharp;">
subscriptions.SafeDispose();
</pre>
<p><strong>А теперь загадка</strong>: почему методы расширения, приведенные выше, компилируются несмотря на название параметра <code>thіs</code>? Дам намек: как ключевое слово имя параметра не подсветилось.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/c/'>C#</a>, <a href='http://nesteruk.wordpress.com/category/net/rx/'>rx</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/818/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/818/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/818/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/818/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/818/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/818/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/818/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/818/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=818&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/08/02/managing-event-subscriptions/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Оптимизация математических выражений для CPU и GPU</title>
		<link>http://nesteruk.wordpress.com/2011/07/14/math-parsing-optimization/</link>
		<comments>http://nesteruk.wordpress.com/2011/07/14/math-parsing-optimization/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 19:47:53 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=803</guid>
		<description><![CDATA[Когда я создавал MathSharp, я преследовал вполне простую цель &#8212; мне нужно было чтобы уравнения, которые записали инженеры, могли быть точно и аккуратно переведены из языка формул на язык C#. На практике, это означает, что написав красивое уравнение вроде его можно автоматически сконвертировать во что-то подобное: Код выше, как вы видите, оптимизирует количество умножений, и [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=803&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Когда я создавал <a href="http://activemesa.com/mathsharp" title="http://activemesa.com/mathsharp">MathSharp</a>, я преследовал вполне простую цель &mdash; мне нужно было чтобы уравнения, которые записали инженеры, могли быть точно и аккуратно переведены из языка формул на язык C#. На практике, это означает, что написав красивое уравнение вроде <img src='http://s0.wp.com/latex.php?latex=y+%3D+ax%5E2%2Bbx%2Bc&amp;bg=ffffff&amp;fg=1c1c1c&amp;s=0' alt='y = ax^2+bx+c' title='y = ax^2+bx+c' class='latex' /> его можно автоматически сконвертировать во что-то подобное:</p>
<p><pre class="brush: csharp;">
public void y(double a, double b, double c, double x)
{
  return x*(a*x + b) + c;
}
</pre>
<p>Код выше, как вы видите, оптимизирует количество умножений, и в общем случае, MathSharp старается срезать стоимость вычислений к абсолютному минимуму, не прибегая в этом к <a href="http://en.wikipedia.org/wiki/Fast_inverse_square_root" title="http://en.wikipedia.org/wiki/Fast_inverse_square_root">особо извращенным методам</a>.</p>
<p>Код выше легко генерить, и созданное AST позволит вам создать код на любом языке, будь то на C#, F# или C++. Но зачем останавливаться на этом?</p>
<p>Недавно, я начал работать с <a href="http://www.tidepowerd.com/" title="http://www.tidepowerd.com/">GPU.NET</a>. Несмотря на наблюдения автора одной не особо хорошо отрецензированной <a href="http://www.rsdn.ru/article/dotnet/CudaLibs.xml" title="http://www.rsdn.ru/article/dotnet/CudaLibs.xml">статьи</a> на RSDN, библиотека работает, и подход мне нравится. А поэтому, мне пришла в голову (гениальная?) мысль &mdash; MathSharp может оптимизировать код не только для CPU но и для GPU! В результате, наша функция выше может выглядеть вот так:</p>
<p><pre class="brush: csharp;">
public void y(double a, double b, double c, double x)
{
  return DeviceMath.MultiplyAndAdd(DeviceMath.MultiplyAndAdd(a, x, b), x, c);
}
</pre>
<p>Суть тут в том, что некоторые GPU обрабатывают вычисление <img src='http://s0.wp.com/latex.php?latex=ax%2Bb&amp;bg=ffffff&amp;fg=1c1c1c&amp;s=0' alt='ax+b' title='ax+b' class='latex' /> еще быстрее, чем эти операции отдельно (типа <a href="http://en.wikipedia.org/wiki/Multiply-accumulate_operation" title="http://en.wikipedia.org/wiki/Multiply-accumulate_operation">пруф</a>). И это только вершина айсберга &mdash; по-хорошему, вариантов для оптимизации &ndash; масса.</p>
<p>Кстати, MathSharp &mdash; это такой небольшой пруф того, что приложение может быть написано на F#, использовать функциональные фишки (алгебраические типы, рекурсивный частичный паттерн-матчинг) и при этом жить, продаваться, развиваться. Правда если хотите tool support то вам скорее <a href="https://github.com/ActiveMesa/FSharper" title="https://github.com/ActiveMesa/FSharper">сюда</a> &mdash; увы, я решил что делать из FSharper коммерческий продукт &ndash; слишком сложно. Основная причина &ndash; что F# не &ldquo;тянет&rdquo; чтобы парсить сам себя. По скорости не тянет. На GPU может и можно, но это нужно исследовать.</p>
<p>Ну и напоследок &ndash; кто-нибудь может посоветовать workflow engine для коротких операций? Не workflow foundation со всем его багажом, а что-нибудь легковесное, чтобы можно было &ldquo;самодокументировать&rdquo; алгоритмы через какой-нть fluent interface или dsl. Заранее спасибо.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/technology/'>Technology</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/803/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/803/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/803/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=803&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/07/14/math-parsing-optimization/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Распределенная разработка и проект FreeSpace</title>
		<link>http://nesteruk.wordpress.com/2011/06/16/distributed-development-project-freespace/</link>
		<comments>http://nesteruk.wordpress.com/2011/06/16/distributed-development-project-freespace/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 20:00:08 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Computation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[freespace]]></category>
		<category><![CDATA[xmpp]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=784</guid>
		<description><![CDATA[Пришло время рассказать про тот проект, про который я говорил в моем последнем подкасте. Проект называется FreeSpace (рабочее название, но мне нравится) и затрагивает, конечно же, вопрос распределенного управления программным кодом. Иначе говоря, я строю инфраструктуру для эффективной разработки с использованием большого количества машин. С чего все начиналось Когда я обитал в сфере финансового программирования [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=784&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Пришло время рассказать про тот проект, про который я говорил в моем <a href="http://spbaltnet.podfm.ru/solo/36/" title="http://spbaltnet.podfm.ru/solo/36/">последнем подкасте</a>. Проект называется FreeSpace (рабочее название, но мне нравится) и затрагивает, конечно же, вопрос распределенного управления программным кодом. Иначе говоря, я строю инфраструктуру для эффективной разработки с использованием большого количества машин.</p>
<h3>С чего все начиналось</h3>
<p>Когда я обитал в сфере финансового программирования (было же такое), одна из задач была в том, чтобы &ldquo;сливать&rdquo; воедино финансовые показатели из различных источников. Начиналось все достаточно просто &ndash; берем какую-то котировку, делаем для нее квантизацию (это когда нужно подсчитать агрегированные значения за последнюю минуту/час/день и т.п.) а потом начинаем считать всякие показатели (к пр. движимое среднее). Сейчас такие задачи делаются с помощью Reactive Extensions, под которым, должен сказать, аггрегаторы и квантизаторы выглядят не лучшим образом. Тогда же это делалось более примитивными методами. Но не суть&hellip;</p>
<p>Так вот, в те времена подход <a href="http://gpgpu.org/" title="http://gpgpu.org/">GPGPU</a> был не ахти какой популярный, и соответственно все утыкалось в слабый перформанс моего одноядерного процессора. И, естественным путем, я набрел на то, что по-хорошему нужно использовать <em><font face="Candara" />несколько машин</font></em> чтобы все эффективно считать. Механизмы общения между компьютерами в те времены были ни ахти какие, соответственно использовались такие извращения как <a href="http://www.nservicebus.com/" title="http://www.nservicebus.com/">NServiceBus</a>/MSMQ которые, конечно, имеют свои приемущества, но все же &ldquo;не айс&rdquo;.</p>
<p>Самым прикольным было написать <a href="http://bitbucket.org/nesteruk/mdxconsole" title="http://butbucket.org/nesteruk/mdxconsole">консоль</a>, которая показывала бы как моя сеть в realtime обсчитывала те или иные показатели. Более того, в те времена я также использовал нейронные сети (MLPs w/backpropagation) и у меня даже остался код, которые по объектным моделям сетей генерировал диаграммы в PowerPoint. Забавное было зрелище.</p>
<h3>Сети &ndash; это же так соблазнительно!</h3>
<p>Качество работы на среднестатистической &ldquo;винде&rdquo; прогрессивно снижается. Когда я начинал программировать на Visual Studio 97, в моем компьютере было 16Мб (мегабайт!!!) RAM, но при этом все работало. Сейчас такой experience можно получить разве что скачав EVC++ 4 (завидую эмбедщикам!). У нас же в плане разработки все плохо &ndash; сплошные тормоза. Вон только вчера коллега рассказал, что получил удовольствие от использования Visual Studio 2008 для части ReSharper SDK. Когда я его спросил что у него за машина, оказалось что и 16Gb RAM и SSD у него присутствуют. Так что делаем выводы&hellip;</p>
<p>Все это наводит на достаточно печальные мысли. Компьютеры будут становиться быстрее, но &ldquo;затыки&rdquo; в производительности будут, и со временем они будут все больше и больше. А нам нужно разрабатывать, а не ждать 15 минут пока полсотни референсов в проект добавятся (таргет-файлы рулят!).</p>
<p>Поэтому единственная вменяемая стратегия, к которой я на данный момент пришел сводится к следующим вещам.</p>
<p>Во-первых, я ратую за <strong>экологичное программирование</strong>, т.е. если вы используете машину для разработки, не стоит на ней ставить доменный контроллер, IIS, AppFabric и еще 100500 различных сервисных примочек. Ни в коем случае не стоит ставить серверные технологии которые используют SQL Server т.к. эта штука сама по себе съест 1-2Gb оперативки, так она еще и будет диск дергать даже когда никто к ней не обращается. А потом, в один прекрасный день, вы увидите что вместо того чтобы разрабатывать, вы думаете как бы засунуть SQL Server&rsquo;ный кэш в RAM. Или что-то в этом духе.</p>
<p>Во-вторых, я за <strong>распределенную разработку</strong>. Писать код можно и на одном компьютере. Но держите свои затраты к минимуму. Ставьте десктопную ось (да-да, сейчас модно ставить 2008R2 везде где не попадя, я тоже на это попался в свое время). Если можете себе это позволить &ndash; ставьте XP. Windows, VS и ReSharper/dotTrace/dotCover/TortoiseXxx &ndash; плагины, естественно по вкусу. Остальное &ndash; в топку! А точнее на другой компьютер.</p>
<h3>Что это дает?</h3>
<p>Я уже слышу крики в стиле &ldquo;мне всего и так хватает!&rdquo;. Что же, если вам итак хорошо, рад за вас. Это как <a href="http://www.codinghorror.com/blog/2004/06/multiple-monitors-and-productivity.html" title="http://www.codinghorror.com/blog/2004/06/multiple-monitors-and-productivity.html">извечная дискуссия про мониторы</a> &ndash; каждому свое. Но если говорить о <em><font face="Candara" />приемуществах</font></em> такого подхода, то их масса.</p>
<p>Главное приемущество &ndash; это <strong>моментальный фидбэк</strong>. Представьте, что у вас есть солюшн который собирается, скажем, две минуты. Две минуты &ndash; это <em><font face="Candara" />вечность</font></em>. Особенно если билд провалился с какой-то дурацкой ошибкой которую не отловил статический анализатор. Да, мы говорим не про простенькие проектики, мы говорим например про системы где смешан С++ (адски медленная компиляция), C# и Java (да-да, Java &ndash; она примешана тут осознанно). Если учесть сложность cross-VM конфигов, все это дело работает не так быстро как хотелось бы.</p>
<p>Так вот, представьте себе систему, где фидбэк по сборке, тестам, и даже покрытию (хотя с покрытием сложнее) получается <em><font face="Candara" />моментально</font></em>. Причем он никак не затрагивает ваш разработческий комп, т.к. мы договорились держать его стерильным. Моментальный фидбэк стоит многого! Особенно это затрагивает такую проблему как тестирование на staging-серверах. На Хабре был <a href="http://habrahabr.ru/blogs/net/120755/" title="http://habrahabr.ru/blogs/net/120755/">пост</a> про то, надо ли стабить репозитарии. Так вот что я думаю &ndash; <em><font face="Candara" />если вы можете себе это позволить, тестируйте на staging-базах</font></em>! Главное чтобы эти тесты не вызывали затыков. А если вызывает затыки &ndash; просто добавьте <del>воды</del> машин!</p>
<p>Второе приемущество &ndash; это то, что <strong>ничего не отвлекает</strong>. Я категорически против подхода, когда люди в свою Студию устанавливают 1000 различных дополнений для всяких микро-фич которые, особенно если они используют визуальные элементы, тормозят все до такого состояния, что работать невозможно. Но я не столько про стороннии фичи говорю, сколько про два основных источника потери времени &ndash; компиляцию и тестирование. Давайте обсудим их более детально.</p>
<h3>Компиляция</h3>
<p>Разработчики С++ уже давно поняли что сборка проектов должна быть распределенной, и на рынке есть для этого <a href="http://www.electric-cloud.com/" title="http://www.electric-cloud.com/">соответствующие</a> <a href="http://www.xoreax.com/" title="http://www.xoreax.com/">решения</a>. Но если вы думаете, что в .Net все лучше, то вы правы только отчасти. Да, .Net собирается быстрее, хотя я <em><font face="Candara" />уверен</font></em> что новый C#5 компилятор будет намного медленнее в силу своей managed структуры. Опять же, еще один аргумент в том, что де нынче MSBuild поддерживает параллелизацию напрямую, и тем самым грамотное использование MSBuild вместе с правильной, loosely coupled архитектурой, как бы избавляет нас от проблем с медленной компиляцией.</p>
<p>А вот и нет!</p>
<p>На практике все сводится к следующим моментам. Во-первых, <strong>стоимость компиляции связана не только с созданием сборок</strong> &ndash; компиляция как таковая включает в себя массы различных процессов, таких как кастомные task-и которые вы используете. Например, процесс XSLT-трансформации путем какого-нть <a href="http://msbuildtasks.tigris.org/" title="http://msbuildtasks.tigris.org/">community task</a>&lsquo;а может стоить намного больше чем компиляция.</p>
<p>Во-вторых, этот аргумент <strong>не применим на mixed-mode проектах</strong>. С++ играет по своим правилам, особенно если вы делаете что-то сложное. Да, ваша сборка <em><font face="Candara" />может</font></em> скомпилироваться параллельно с другими. Но это не покрывает изначальную проблему &ndash; она скомпилируется медленно. Это, кстати, влияет не только на С++ &mdash; даже тот же F# компилируется медленнее (что понятно), не говоря уже про языки вроде Scala (reminder: Scala компилируется в <strong>10</strong> раз медленнее Java).</p>
<p>В третьих, все как-то забыли что <strong>некоторым проектам нужно собирать несколько конфигураций</strong>. В этом случае параллелизация на уровне конфигураций имеет смысл &ndash; тут мы билдим staging, а тут &ndash; production. Естественно, никто не мешает настроить разные конфигурации на разных build-системах. Действительно, на практике многие разработчики используют TeamCity для параллелизации подобных задач. Одна из самых популярных &ndash; параллелизация тестирования. Кстати о нем&hellip;</p>
<h3>Тестирование</h3>
<p>Тестирование бывает разным. Одно дело когда вы нажали F5 на проекте, который открывает VS в дебаг-режиме. Если у вас комп с 4Gb RAM и Раптором &ndash; вы попали. Можете смело идти за кофе/чаем/печеньками. Отладочный экспириенс будет адским. Да &ndash; и не думайте что удаленная отладка вам поможет. Во-первых, вы замахаетесь ее настраивать (у меня на это полдня ушло), но даже настроив, вы сразу поймете, что игра не стоит свеч &ndash; идея неплохая, но скорость &ndash; улиточная. Snail speed. Если действительно хочется делать отладку на другой машине, более вменяемым решением <em><font face="Candara" />мне лично</font></em> кажется использование VMWare Workstation. Но так или иначе, тормоза будут.</p>
<p>Но я сейчас немного не про это, а скорее про банальное unit/integration-тестирование. Сейчас в этой сфере ведется работы по разным направлениям &ndash; например работы связанные с автопрогоном только тех тестов, которые были затронуты изменениями в коде. Примеры таких программ &ndash; <a href="http://www.ncrunch.net/" title="http://www.ncrunch.net/">NCrunch</a> и <a href="http://continuoustests.com/" title="http://continuoustests.com/">Mighty Moose</a>. А теперь угадайте, какой основной смысл этих программ? Правильно &ndash; экономия ресурсов. Вызывать только те тесты которые <em><font face="Candara" />были затронуты</font></em>. А не все подряд.</p>
<p>На самом деле, это очень сложная задача. В чем проблема вызова абсолютно всех тестов? Правильно, в том, что эти тесты могут задевать сотню различных систем. Да-да, я не только про юнит-тесты говорю, но и про интеграционные тесты &ndash; включая те, которые например дергают реальные базы или устройства. Их-то тоже хочется тестировать, причем опять же вопрос ставится так: если мы можем тестировать постоянно &ndash; почему бы не делать это? Лично я &ndash; ярый сторонник <a href="http://devtalk.net/dotnet/continuous-testing/" title="http://devtalk.net/dotnet/continuous-testing/">непрервыного тестирования</a>. И не только по комиту &ndash; а например по любому компилу. Сделал тестовую сборку &ndash; она <em><font face="Candara" />сразу же</font></em> ушла в тестирование. Если что упало &ndash; результаты <em><font face="Candara" />сразу же</font></em> возвращаются к разработчику.</p>
<h3>Так что там про FreeSpace?</h3>
<p>FreeSpace &ndash; это мое новое детище. FreeSpace &ndash; это Windows-сервис который можно устанавливать на любые машины где угодно. Фактически, этот сервис объединяет машины в ботнет, который умеет заниматься распределенной компиляцией, тестированием, развертыванием, и так далее. FreeSpace работает как на реальных так и на виртуальных машинах, неприхотлив (дружит с ХР) и требует <em><font face="Candara" />минимальное кол-во конфигурирования</font></em>.</p>
<p>FreeSpace использует XMPP (в частности &ndash; библиотеку <a href="http://www.ag-software.de/matrix-xmpp-sdk/" title="http://www.ag-software.de/matrix-xmpp-sdk/">MatriX</a>) и механизмы облачной синхронизации файлов. XMPP гарантирует что машины могут беспрепятственно коммуницировать между собой, при условии что у вас стоит XMPP-сервер (поставить какой-нть <a href="http://www.ejabberd.im/" title="http://www.ejabberd.im/">ejabberd</a> занимает полминуты). А механизмы облачной синхронизации позволяют гарантировать, что на всех инстансах одни и те же файлы. Поскольку сервис работает через MEF, файлы можно обновлять динамически.</p>
<p>Основная цель FreeSpace &ndash; <strong>балансировка нагрузки</strong>, т.е. составление сбалансированных планов исполнения. Собственно выполнение задач на себя берут уже готовые тулзы. Для компиляции, например, это может быть MSBuild, для тестирования &ndash; <a href="http://gallio.org/" title="http://gallio.org/">Gallio</a>. Суть в том, что имея информацию о всех нодах в сети, а также агентах на этих нодах (на одной ноде можно бегать более одного агента), можно сформировать сбалансированный план компиляции или тестирования, который оптимально использует все доступные ресурсы и при этом <em><font face="Candara" />уважает предпочтения самого нода</font></em>, т.е. знает что нельзя перегружать нод, который уже занят или имеет какие-то другие обязанности.</p>
<p>Одно из приемуществ FreeSpace &ndash; системе полностью плевать на домены. Синхронизация через XMPP способна игнорировать все firewall&rsquo;ы и протаскивать трафик <a href="http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol#XMPP_via_HTTP_transport" title="http://en.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol#XMPP_via_HTTP_transport">через порт 80</a>, если это надо (ну, это теоретически&hellip; это нужно тестировать). При этом трафик можно шифровать, так что идея о том что де кто-то украдет контрольные данные в транзите или подменит их тоже отпадает. А сами файлы синхронизуются с помощью изначально безопасной системы (так по крайней мере нам говорят), поэтому кроме как на нодах к ним не достучаться. И даже достучавшись, система-то распределенная, так что всей картины все равно не получите &ndash; хотя конечно подразумевается, что нодам вы доверяете.</p>
<h3>Более сложные задачи</h3>
<p>Есть более сложные задачи, которые пока не решить ну никак. Во-первых, было бы здорово вынести за пределы компьютера разработчика весь статический анализ и сделать некий &lsquo;FxCop/R#/whatever as a service&rsquo;. Если это сделать, и если это хоть как-то параллелизуемо (есть подозрение что не очень), это позволит делать намного более глубокий/затратный анализ и тем самым получать намного более умные эвристические подсказки.</p>
<p>Покрытие &ndash; запредельно затратная операция, поэтому вынести его наружу тоже хотелось бы. Это, правда, менее приоритетная задача, т.к. я не большой фанат покрытия. Но с другой стороны, имея уже готовый механизм для измерения покрытия (к пр., <a href="http://www.jetbrains.com/dotcover/" title="http://www.jetbrains.com/dotcover/">dotCover</a>), я не вижу никаких причин не применять измерение покрытия, скажем, к разным тестовым фиксчам на разных машинах. Главное чтобы можно было слить все результаты воедино и как-то их продемонстрировать. (Прошу заметить, что в отличии от результатов тестирования, результаты покрытия таки требуют наличие локальной Visual Studio для подсветки и навигации. То же отчасти верно и для обычного юнит-тестирования, хотя там и не нужно вклиниваться в редактор.)</p>
<p>Зато что я люблю так это всякий спекулятивный процессинг. Я бы с удовольствием воспользовался, например, механизмами <a href="http://msdn.microsoft.com/en-us/magazine/hh148145.aspx" title="http://msdn.microsoft.com/en-us/magazine/hh148145.aspx">мутационного тестирования</a>. Ну или например я бы с радостью гонял тесты на производительность параллельных алгоритмов варьируя разные параметры, такие как, к примеру, degree of parallelism.</p>
<h3>Вместо заключения</h3>
<p>FreeSpace разрабатывается в первую очередь не как коммерческий продукт, а как система, которая сможет, при наличии достаточного количества машин, существенно сэкономить количество времени, требуемое для работы с крупными проектами. Соответственно, пишу я ее в основном для себя, с уклоном в те проблемы (например, тестирование в виртуальной среде &ndash; VMM/HyperV) которые являются для меня наиболее насущными.</p>
<p>Я давно не писал в этот блог, но теперь буду писать почаще, особенно если кому-то данная тема покажется интересной. И естественно, я выпущу дистрибутив системы как только у меня будет что релизить. Основной concern в данном случае в том, что я очень хочу сделать систему обновляемой, чтобы она и ее плагины (я использую плагин-архитектуру на основе MEF) могли автоматически обновляться по мере выхода новых версий.</p>
<p>А пока всё! Comments welcome!&nbsp;■</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/computation/'>Computation</a>, <a href='http://nesteruk.wordpress.com/category/development/'>Development</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/freespace/'>freespace</a>, <a href='http://nesteruk.wordpress.com/tag/xmpp/'>xmpp</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/784/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/784/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/784/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=784&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/06/16/distributed-development-project-freespace/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Хранение preset-ов в setting-ах</title>
		<link>http://nesteruk.wordpress.com/2011/06/05/presets-in-settings/</link>
		<comments>http://nesteruk.wordpress.com/2011/06/05/presets-in-settings/#comments</comments>
		<pubDate>Sun, 05 Jun 2011 20:22:37 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=780</guid>
		<description><![CDATA[Сегодня я зарелизил версию 1.7.2 Типографикса, добавив всего одну фичу &#8211; возможность держать несколько наборов настроек. Сделал я это для того, чтобы можно было сохранять настройки редактора для разных платформ &#8211; в моем случае, для этого блога и devtalk, а также для Хабра, ГДН, CodeProject&#8217;а и других систем. Примечательно то, что простенькая задача сохранить в [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=780&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Сегодня я зарелизил версию 1.7.2 Типографикса, добавив всего одну фичу &ndash; возможность держать несколько наборов настроек. Сделал я это для того, чтобы можно было сохранять настройки редактора для разных платформ &ndash; в моем случае, для этого блога и devtalk, а также для Хабра, ГДН, CodeProject&rsquo;а и других систем.</p>
<p>Примечательно то, что простенькая задача сохранить в словарике несколько пресетов и потом записать все это в <code>Properties.Settings</code> превратилась в непростую затею.</p>
<h3>Первая попытка</h3>
<p>Сначала я сделал все правильно: создал <code>Dictionary&lt;string, ConversionOptions&gt;</code>, то есть мэп названий пресетов на их значения, и тупо попробовал записать все это в настройки. Ничего не получилось. Оказывается, большое количество классов в WPF (такие как <code>Color</code> или <code>Thickness</code>) не сериализуются! Это значит, что по сути дела чтобы сериализовать тип мне нужно их выкинуть!</p>
<p>Следующей проблемой оказалось то, что .Net бросал исключение при попытке сериализовать событие <code>PropertyChanged</code>. Это правда очень быстро релилось прописыванием <code>[field: NonSerialized]</code>, но толком делу не помогло.</p>
<h3>Вторая попытка</h3>
<p>Проблема в том, что несмотря на то, что все работало, настройки отказались записывать <code>Dictionary&lt;&gt;</code>. Никаких исключений не было, тип просто не сохранялся в <code>Properties.Settings</code> и воответственно при попытке считать, возвращался <code>null</code>.</p>
<p>Самое простое в этом случае (точно так же как и в случае с несериализуемыми типами) &ndash; это сконвертировать структуру не в XML а в&hellip; JSON! (Формат выбран произвольно.) Соответственно, я скачал <a href="https://github.com/ServiceStack/ServiceStack.Text" title="https://github.com/ServiceStack/ServiceStack.Text">ServiceStack.Text</a> и заменил тип свойств в <code>Settings</code> на <code>string</code>. В результате, сериализация происходит вот так:</p>
<p><pre class="brush: csharp;">
Settings.Default[&quot;OptionPresets&quot;] =
  JsonSerializer.SerializeToString(OptionPresets, typeof (Dictionary&lt;string, ConversionOptions&gt;));
</pre>
<p>Ну а что касается тех «несериализуемых» полей то, увы, приходится делать строковые или аналогичные backing fields, со всемы вытекающими последствиями.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/c/'>C#</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/780/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=780&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/06/05/presets-in-settings/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Бесшумный компьютер для разработчика</title>
		<link>http://nesteruk.wordpress.com/2011/05/21/noiseless-computer-for-developers/</link>
		<comments>http://nesteruk.wordpress.com/2011/05/21/noiseless-computer-for-developers/#comments</comments>
		<pubDate>Sat, 21 May 2011 13:11:19 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=767</guid>
		<description><![CDATA[В процессе разработки я готов слушать любой шум, при условии что этот шум создал я и дал на него согласие. В идеале же я предпочитаю тишину, а следовательно шумные компьютеры не для меня. Только вот проблема: мне банально лень исследовать вопросы шумоизоляции и строить кастомные решения.[1] К счастью есть подход который масштабируется. Бесшумый источник питания [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=767&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>В процессе разработки я готов слушать любой шум, при условии что этот шум создал я и дал на него согласие. В идеале же я предпочитаю тишину, а следовательно шумные компьютеры не для меня. Только вот проблема: мне банально лень исследовать вопросы шумоизоляции и строить кастомные решения.[<a href="#Reference1" title="Поправка: рано или поздно я буду строить систему с водяным охлаждением &ndash; только для того чтобы разобраться как это работает и насколько это сложно. Но это хобби и к делу не относится." name="BackReference1">1</a>] К счастью есть подход который масштабируется.</p>
<h3>Бесшумый источник питания</h3>
<p>До поры до времени, источники питания без вентиляторов были мусором &ldquo;по показателям&rdquo;, и приходилось терпеть[<a href="#Reference2" title="На самом деле &ndash; не совсем. Я недавно выкинул систему 5-летней давности которая была фактически бесшумной поскольку использовала внешний адаптер вместо полноценного PSU и была построена на базе Pentium M (да-да, десктоп на ноутбучной платформе). К сожалению, когда я еще был идиотом и не обвешал все бесперебойниками, один перепад напряжения спалил мне трансформатор в этом компьютере, и с тех пор этот комп жил в кладовке с воткнутым в него убогим 350W PSU. Недавно я набрался смелости и снес этот &ldquo;проваленный эксперимент&rdquo; на помойку." name="BackReference2">2</a>]. Это время прошло. Теперь качественные и тихие PSU доступны всем и каждому. Конечно, основная их польза &ndash; при построении HTPC, но для офиса они тоже идеально подходят (а вот для геймеров &ndash; нет, ибо максимум 400W).</p>
<p>Безвентиляторные (fanless) PSU предсказуемо используют радиатор. Лучший по моему субъективному ощущению (после прочтения обзоров) &ndash; <a href="http://www.scan.co.uk/products/400w-silverstone-st40nf-s-nightjar-80-plus-bronze-86-eff-fanless-0db-atx-23" title="http://www.scan.co.uk/products/400w-silverstone-st40nf-s-nightjar-80-plus-bronze-86-eff-fanless-0db-atx-23">Silverstone Nightjar</a>.</p>
<p align="center"><img src="http://www.overclockers.ua/news/power/104138-silverstone-nightjar-st40nf.jpg" alt="" style="border:0;" /></p>
<p>Полный обзор, если кто сомневается, можно почитать <a href="http://www.hardwaresecrets.com/article/869" title="http://www.hardwaresecrets.com/article/869">тут</a>. Стоимость &ndash; около $180. В России, естественно, не продается.</p>
<h3>Бесшумный кулер</h3>
<p>Я сам не очень верил в то что можно иметь беззвучное неводяное охлаждение. Оказывается можно. Порыскав на <a href="http://www.frostytech.com/top5heatsinks.cfm" title="http://www.frostytech.com/top5heatsinks.cfm">Frosty&#8217;s</a> я увидел в лидерах по уровню шума кулер <a href="http://www.scythe-usa.com/product/cpu/036/scorc1000_detail.html" title="http://www.scythe-usa.com/product/cpu/036/scorc1000_detail.html">Scythe Orochi</a>. Пошел, купил, установил и доволен.</p>
<p align="center"><img src="http://alienbabeltech.com/main/wp-content/uploads/2009/04/scythe-orochi-cpu-cooler-04.jpg" alt="" style="border:0;" /></p>
<p>С кулером поставляется 14-сантиметровый вентилятор но мне он не нужен (да и в корпус не поместится). Обзор сего чуда можно почитать <a href="http://www.frostytech.com/articleview.cfm?articleID=2258" title="http://www.frostytech.com/articleview.cfm?articleID=2258">тут</a>. Стоимость &ndash; около $60. В России было очень сложно найти. Сейчас его в России не найти, да и на Западе тоже &ndash; он discontinued и его заменят обновленной моделью. Ждем-с.</p>
<h3>Бесшумное все остальное</h3>
<p>Тут все как бы тривиально &ndash; например, графических карт без вентиляторов масса. Неигровых, конечно, но мы про офисные компьютеры говорим. Если у вас несколько мониторов, то вам подойдет что-то вроде этого:</p>
<p align="center"><img src="http://images.nvidia.com/products/quadro_nvs_450/quadro_nvs_450_3qtr_low.png" alt="" style="border:0;" /></p>
<p>Это <a href="http://www.nvidia.com/object/product_quadro_nvs_450_us.html" title="http://www.nvidia.com/object/product_quadro_nvs_450_us.html">nVidia Quadro NVS 450</a>. Такая карта тянет 4 монитора и не жужжит.[<a href="#Reference3" title="Я тут сильно лукавлю: сам работаю на 3-х мониторах (4-й стоит в сторонке и пока ничего не делает). Более того, не все мои экраны подключены к одному компьютеру, хотя и управляются одной с одной пары мышь-клавиатура. Но это уже тянет на отдельный пост :)" name="BackReference3">3</a>] (Да, 4 монитора, если надо больше, можно добавить Quadro NVS 295 &ndash; <a href="http://superuser.com/questions/257571/is-there-a-pcix1-video-card-that-plays-nice-with-pcix16-video-cards" title="http://superuser.com/questions/257571/is-there-a-pcix1-video-card-that-plays-nice-with-pcix16-video-cards">почти пруфлинк</a>.) Карточка стоит $550.[<a href="#Reference4" title="Такая сумма за графическую карточку &ndash; это дороговато, особенно если учесть что Eyefinity 6 поддерживает сразу 6 мониторов а карточки стоят где-то $500 на Амазоне. Тем не менее, такие монстрообразные карты откровенно шумят, что как бы портит всю идею этого поста." name="BackReference4">4</a>] В России&hellip; да, что там говорить, берите <a href="http://www.amazon.com/PNY-Quadro-NVS-Graphics-Card/dp/B001QVPG8I/ref=sr_1_4?ie=UTF8&amp;s=miscellaneous&amp;qid=1305979217&amp;sr=8-4" title="http://www.amazon.com/PNY-Quadro-NVS-Graphics-Card/dp/B001QVPG8I/ref=sr_1_4?ie=UTF8&amp;s=miscellaneous&amp;qid=1305979217&amp;sr=8-4">на Амазоне</a>.[<a href="#Reference5" title="Товарищ Суворов и его коллеги, которые работают на 3-х мониторах (за одно это респект), исповедуют другой подход: основной графической карточкой поддерживают 2 экрана, а третий&mdash;с помошью подпиленной x16 карточки, воткнутой в x4 слот. Да-да, это реально, хотя судя по всему не везде работает." name="BackReference5">5</a>]</p>
<p>Насчет жестких дисков тут все понятно. Либо вы берете SSD и проблема отпадает, либо ставите диск на 5200RPM и проблема тоже отпадает (только работать становится намного сложнее). Главное не баловаться дешевыми неопробованными дисками (у меня тут есть Hitachi на 1Gb &ndash; такой слона разбудит) и не пытаться думать что какой-нибудь Raptor (даже под RAID) &ndash; хорошее решение.[<a href="#Reference6" title="Рапторы &ndash; имеется ввиду Western Digital VelociRaptor &ndash; производительные 10kRPM диски которые, тем не менее, адски жужжат и тем самым меня бесят." name="BackReference6">6</a>]</p>
<p align="center"><img src="http://exempt.files.wordpress.com/2010/08/intel_x25-m_ssd1.jpg?w=700" alt="" style="border:0;" /></p>
<p>Диск выше &ndash; Intel X25-M на 160Gb &ndash; стоит $430 <a href="http://www.amazon.com/Intel-2-5-Inch-X25-M-Mainstream-SSDSA2MH160G2C1/dp/B002IGT7IU/ref=sr_1_4?ie=UTF8&amp;qid=1305979892&amp;sr=8-4" title="http://www.amazon.com/Intel-2-5-Inch-X25-M-Mainstream-SSDSA2MH160G2C1/dp/B002IGT7IU/ref=sr_1_4?ie=UTF8&amp;qid=1305979892&amp;sr=8-4">на Амазоне</a>. В России, впрочем, найти его тоже <a href="http://scorpion.ru/descr1921140387" title="http://scorpion.ru/descr1921140387">не проблема</a>.</p>
<p>Да, и&hellip; если у вас жужжит DVD- или BR-драйв, советом помочь не смогу ибо такого добра у меня уже несколько лет не водилось. Впрочем, уверен что для дисководов сущуствуют всякие антивибрационные решения.</p>
<h3>Заключение</h3>
<p>Вот собственно и всё. Я надеюсь что мне удалось показать то, как &ldquo;малой кровью&rdquo; сделать компьютер бесшумным. Конечно, сделать это не так-то просто хотя бы потому что в &ldquo;этой стране&rdquo; компьютерное оборудование а) в основном ширпотреб; и b) с неприличной наценкой, но по крайней мере, предложенное мною решение может масштабироваться и не требует огромных временных затрат.</p>
<h3>Заметки</h3>
<ol>
<li><a name="Reference1"></a><a href="#BackReference1" title="Back to text">&uarr;</a> Поправка: рано или поздно я буду строить систему с водяным охлаждением &ndash; только для того чтобы разобраться как это работает и насколько это сложно. Но это хобби и к делу не относится.</li>
<li><a name="Reference2"></a><a href="#BackReference2" title="Back to text">&uarr;</a> На самом деле &ndash; не совсем. Я недавно выкинул систему 5-летней давности которая была фактически бесшумной поскольку использовала внешний адаптер вместо полноценного PSU и была построена на базе Pentium M (да-да, десктоп на ноутбучной платформе). К сожалению, когда я еще был идиотом и не обвешал все бесперебойниками, один перепад напряжения спалил мне трансформатор в этом компьютере, и с тех пор этот комп жил в кладовке с воткнутым в него убогим 350W PSU. Недавно я набрался смелости и снес этот &ldquo;проваленный эксперимент&rdquo; на помойку.</li>
<li><a name="Reference3"></a><a href="#BackReference3" title="Back to text">&uarr;</a> Я тут сильно лукавлю: сам работаю на 3-х мониторах (4-й стоит в сторонке и пока ничего не делает). Более того, не все мои экраны подключены к одному компьютеру, хотя и управляются одной с одной пары мышь-клавиатура. Но это уже тянет на отдельный пост :)</li>
<li><a name="Reference4"></a><a href="#BackReference4" title="Back to text">&uarr;</a> Такая сумма за графическую карточку &ndash; это дороговато, особенно если учесть что Eyefinity 6 поддерживает сразу 6 мониторов а карточки стоят где-то $500 <a href="http://www.amazon.com/Diamond-Radeon-Eyefinity-PCI-Express-5870PE52G/dp/B003EYV0PI/ref=sr_1_1?ie=UTF8&amp;qid=1305982067&amp;sr=8-1" title="http://www.amazon.com/Diamond-Radeon-Eyefinity-PCI-Express-5870PE52G/dp/B003EYV0PI/ref=sr_1_1?ie=UTF8&amp;qid=1305982067&amp;sr=8-1">на Амазоне</a>. Тем не менее, такие монстрообразные карты откровенно шумят, что как бы портит всю идею этого поста.</li>
<li><a name="Reference5"></a><a href="#BackReference5" title="Back to text">&uarr;</a> Товарищ <a href="http://alexeysuvorov.wordpress.com">Суворов</a> и его коллеги, которые работают на 3-х мониторах (за одно это респект), исповедуют другой подход: основной графической карточкой поддерживают 2 экрана, а третий&mdash;с помошью подпиленной x16 карточки, воткнутой в x4 слот. Да-да, это реально, хотя судя по всему не везде работает.</li>
<li><a name="Reference6"></a><a href="#BackReference6" title="Back to text">&uarr;</a> Рапторы &ndash; имеется ввиду <a href="http://scorpion.ru/descr1916524787" title="http://scorpion.ru/descr1916524787">Western Digital VelociRaptor</a> &ndash; производительные 10kRPM диски которые, тем не менее, адски жужжат и тем самым меня бесят.</li>
</ol>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/computer/'>Computer</a>, <a href='http://nesteruk.wordpress.com/category/hardware/'>Hardware</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/767/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/767/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/767/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/767/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/767/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/767/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/767/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/767/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=767&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/05/21/noiseless-computer-for-developers/feed/</wfw:commentRss>
		<slash:comments>45</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://www.overclockers.ua/news/power/104138-silverstone-nightjar-st40nf.jpg" medium="image" />

		<media:content url="http://alienbabeltech.com/main/wp-content/uploads/2009/04/scythe-orochi-cpu-cooler-04.jpg" medium="image" />

		<media:content url="http://images.nvidia.com/products/quadro_nvs_450/quadro_nvs_450_3qtr_low.png" medium="image" />

		<media:content url="http://exempt.files.wordpress.com/2010/08/intel_x25-m_ssd1.jpg" medium="image" />
	</item>
		<item>
		<title>Новости (Апрель 2011)</title>
		<link>http://nesteruk.wordpress.com/2011/04/17/news-april-2011/</link>
		<comments>http://nesteruk.wordpress.com/2011/04/17/news-april-2011/#comments</comments>
		<pubDate>Sun, 17 Apr 2011 14:53:46 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[freespace]]></category>
		<category><![CDATA[mathsharp]]></category>
		<category><![CDATA[spbaltnet]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=755</guid>
		<description><![CDATA[Этот пост новостного типа &#8211; расскажу про то, что произошло и про то, что происходит. С удовольствием написал бы технический пост, но пока все очень туманно &#8211; может чуть позже. Итак&#8230; Релиз MathSharp Давным-давно я попал на проект, где при разработке программ нужно было переводить математические формулы в код. Тогда я только и думал о [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=755&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Этот пост новостного типа &ndash; расскажу про то, что произошло и про то, что происходит. С удовольствием написал бы технический пост, но пока все очень туманно &ndash; может чуть позже. Итак&hellip;</p>
<h3>Релиз MathSharp</h3>
<p>Давным-давно я попал на проект, где при разработке программ нужно было переводить математические формулы в код. Тогда я только и думал о том, как все это автоматизировать дабы конвертировать формулы в код автоматически. И вот спустя несколько лет, я создал проект <strong>ActiveMesa MathSharp</strong>. MathSharp &ndash; это программа, которая умеет переводить контент из формата MathML (который можно получить из Microsoft Word 2007/2010, MathType, Maple и других систем) в код на языках C# или F#.</p>
<p>Вот небольшой видеоролик, в котором показано как работает MathSharp:</p>
<p style="text-align:center;"><div class='embed-vimeo' style='text-align:center;'><iframe src='http://player.vimeo.com/video/22251021' width='640' height='480' frameborder='0'></iframe></div></p>
<p>Если коротко &ndash; вы пишете</p>
<p align="center">
  <img src="http://www.codeproject.com/KB/recipes/mmlsharp/MmlSharp2.jpg" alt="" style="border:0;" />
</p>
<p>а оно переводит это в</p>
<p><pre class="brush: csharp;">
p = rho*R*T + (B_0*R*T-A_0-((C_0) / (T*T))+((E_0) / (Math.Pow(T, 4))))*rho*rho +
    (b*R*T-a-((d) / (T)))*Math.Pow(rho, 3) +
    alpha*(a+((d) / (t)))*Math.Pow(rho, 6) +
    ((c*Math.Pow(rho, 3)) / (T*T))*(1+gamma*rho*rho)*Math.Exp(-gamma*rho*rho);
</pre>
<p>Если вам понравилась идея, само приложение можно найти тут:&nbsp;<a href="http://activemesa.com/mathsharp" title="http://activemesa.com/mathsharp">http://activemesa.com/mathsharp</a>. Стоит оно $95 &ndash; дешевле чем один инженерный час, так что если оно кому-то сэкономит хоть час работы, значит выгода уже есть.</p>
<p>P.S.: этот релиз позволил мне получить следующие &quot;ачивменты&quot;:</p>
<ul>
<li>Зарелизил проект написанный на F# (есть соблазн накатать статейку для <a href="http://fprog.ru" title="http://fprog.ru">fprog.ru</a>)</li>
<li>Зарелизил самообновляемое приложение</li>
</ul>
<h3>Возобновление встреч Spbalt.net</h3>
<p><img src="http://spbalt.net/content/spbalt.net.jpg" alt="" class="alignright" style="border:0;" />После небольшого перерыва мы возобновляем наши встречи &ndash; уже в другом месте, в помещении которое любезно предоставляет нам компания <a href="http://dataart.ru" title="http://dataart.ru">DataArt</a>. Первые мои семинары проводились именно в DataArt под флагом их DataArt Way. Собственно там все и началось. Так что я доволен что мы сможем снова там встречаться.</p>
<p>Следующая встреча пройдет в четверг 21го. Будет рассказ про создание back-end&rsquo;а для MMO RPG. Подробности тут: <a href="http://spbalt.net/home/meetings/27">http://spbalt.net/home/meetings/27</a></p>
<h3>Новый проект</h3>
<p>После релиза MathSharp нужно чем-то снова заняться, поэтому я решил написать что-то посложнее. Сейчас я в стадии R&amp;D экспериментирую с идеей code provider&rsquo;ов (по аналогии с type provider&rsquo;ами). Идея в том, чтобы иметь распределенные сервисы, которые могли бы заниматься не столько анализом сколько порождением нового кода на основе декларативных моделей.</p>
<p>Для тех из вас кому интересно что стало с <a href="http://activemesa.com/fsharper" title="http://activemesa.com/fsharper">FSharper</a>&rsquo;ом, могу сказать что на данный момент проект приостановлен &ndash; в основном потому, что надо было делать MathSharp &ndash; но возможно я и вернусь к нему. &ldquo;Ничего обещать не буду.&rdquo;</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/life/'>Life</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/freespace/'>freespace</a>, <a href='http://nesteruk.wordpress.com/tag/mathsharp/'>mathsharp</a>, <a href='http://nesteruk.wordpress.com/tag/spbaltnet/'>spbaltnet</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/755/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/755/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/755/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=755&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/04/17/news-april-2011/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://www.codeproject.com/KB/recipes/mmlsharp/MmlSharp2.jpg" medium="image" />

		<media:content url="http://spbalt.net/content/spbalt.net.jpg" medium="image" />
	</item>
		<item>
		<title>Коротко про type forwarding</title>
		<link>http://nesteruk.wordpress.com/2011/04/06/on-type-forwarding/</link>
		<comments>http://nesteruk.wordpress.com/2011/04/06/on-type-forwarding/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 11:33:29 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[type forwarding]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=748</guid>
		<description><![CDATA[Представьте, что у вас есть SDK, состоящий из огромного количества библиотек, и что любому пользователю вашего SDK нужно для нормальной работы подключить штук 15-20 DLLек, причем конечный пользователь может даже не знать заранее, какие именно библиотеки нужны. Эта ситуация &#8211; весьма неприятная. Все мы знаем, что Visual Studio 2010 добавляет новые ссылки на библиотеки с [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=748&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Представьте, что у вас есть SDK, состоящий из огромного количества библиотек, и что любому пользователю вашего SDK нужно для нормальной работы подключить штук 15-20 DLLек, причем конечный пользователь может даже не знать заранее, какие именно библиотеки нужны. Эта ситуация &ndash; весьма неприятная. Все мы знаем, что Visual Studio 2010 добавляет новые ссылки на библиотеки с черепашьей скоростью, и что трудозатраты по добавлению ссылок равны факториалу (!!!) от количества ссылок которые вы добавляете.</p>
<p>Очевидно, нужно искать возможность как-то улучшить user experience. Не имея возможности просто сделать <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;displaylang=en" title="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=22914587-b4ad-4eae-87cf-b14ae6a939b0&amp;displaylang=en">ILMerge</a> на все сборки, у нас тем не менее есть возможность сделать нечто не менее эффективное &ndash; а именно создать прокси-сборку для всех типов внутри сборок, и воспользоваться фичей под названием type forwarding, для того чтобы вызывались именно конечные сборки нашего SDK.</p>
<h3>Как работает type forwarding?</h3>
<p>Поддержка <a href="http://msdn.microsoft.com/en-us/library/ms404275.aspx" title="http://msdn.microsoft.com/en-us/library/ms404275.aspx">type forwarding</a> была добавлена в .Net 2.0 для того чтобы авторы библиотек могли мигрировать типы из одной сборки в другую, не ломая в процессе код пользователей и не требуя перекомпиляции.</p>
<p>Вот как это работает. Есть у меня сборка <code>FirstAssembly</code>, а в ней тип <code>С</code>:</p>
<p><pre class="brush: csharp;">
// FirstAssembly.dll
public class С {}
</pre>
<p>Далее, другой пользователь пишет свой код, ссылаясь на <code>FirstAssembly.dll</code>:</p>
<p><pre class="brush: csharp;">
С с = new С();
</pre>
<p>Все хорошо, но вдруг я решил передвинуть мой тип <code>C</code> в сборку <code>SecondAssembly.dll</code>, при этом не меняя пространства имен и имени самого типа. Тогда я делаю следующее:</p>
<ul>
<li>Удаляю реализацию класса <code>С</code> в <code>FirstAssembly.dll</code> и переношу его в <code>SecondAssembly.dll</code></li>
<li>Добавляю ссылку на <code>SecondAssembly.dll</code> в <code>FirstAssembly.dll</code></li>
<li>Иду в <code>FirstAssembly</code>, открываю там <code>AssemblyInfo.cs</code> и в нем пишу магическую строчку<br />
<pre class="brush: csharp;">
[assembly: TypeForwardedTo(SomeNamespace.C)]
</pre>Эта директива намекает пользователям, что де тип <code>C</code> переехал, и теперь находится в другой сборке.
</li>
</ul>
<p>Атрибут сборки на момент компиляции <code>FirstAssembly.dll</code> превращается в следующую директиву:</p>
<p><pre class="brush: csharp;">
.class extern forwarder SomeNamespace.C
{
  .assembly extern SecondAssembly
}
</pre>
<p>Иначе говоря, все, что у нас получается &ndash; это лишняя директива которая подсказывает, что если клиент ищет в нашей сборке тип <code>Somenamespace.C</code> но не находит его, имеет смысл поискать этот тип в сборке <code>SecondAssembly.dll</code>.</p>
<h3>Обсуждение</h3>
<p>Во-первых, следует заметить что какой-то особой поддержки type forwarding со стороны Visual Studio не существует &ndash; в лучшем случае, при попытке сослаться на тип из сборки который «переехал», помимо обычной ошибки Visual Studio намекнет вам, что тип «мигрировал» и что для успешной компиляции вам стоит добавить ссылку на <code>SecondAssembly.dll</code>.</p>
<p>В контексте SDK, следует заметить, что</p>
<ul>
<li>Вы не можете просто поставлять набор из огромного количества директив <code>TypeForwardedTo</code> и компилировать код. В момент компиляции нужны ссылки на реальные сборки или же на некие прокси, которые в точности повторяют структуру тех сборок, на которые нужно ссылаться.</li>
<li>В момент исполнения, мы не можем «выкинуть» прослойку, т.к. тогда непонятно откуда брать информацию о местоположении реальных сборок.</li>
<li>Фактически, требуются две прокси-сборки. Одна &ndash; это прокси для компиляции, вторая &ndash; с набором директив type forwarding для исполнения.</li>
</ul>
<p>Теперь я пытаюсь понять, правильный ли это подход, и если да &ndash; как заставить <a href="http://www.mono-project.com/Cecil" title="http://www.mono-project.com/Cecil">Mono.Cecil</a> делать из «реальных» сборок прокси с пустышками вместо методов. ▪</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/type-forwarding/'>type forwarding</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/748/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/748/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/748/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/748/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/748/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/748/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/748/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/748/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=748&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/04/06/on-type-forwarding/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Создание сервиса WCF REST с поддержкой JSONP</title>
		<link>http://nesteruk.wordpress.com/2011/03/24/create-wcf-rest-jsonp-service/</link>
		<comments>http://nesteruk.wordpress.com/2011/03/24/create-wcf-rest-jsonp-service/#comments</comments>
		<pubDate>Thu, 24 Mar 2011 16:58:35 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[jsonp]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[wcf]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=741</guid>
		<description><![CDATA[Мне всегда импонировали фреймворки и языки, которые делались для того, чтобы сделать &#8220;простые вещи простыми, а сложные вещи возможными&#8221;. Надеясь именно на подобный расклад вещей, я решил посмотреть на то, как нынче делаются REST сервисы в WCF без помощи каких-либо библиотек (OpenRasta, MindTouch DReAM) или шаблонов вроде WCF REST Starter Kit. В этом посте &#8211; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=741&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Мне всегда импонировали фреймворки и языки, которые делались для того, чтобы сделать &ldquo;простые вещи простыми, а сложные вещи возможными&rdquo;. Надеясь именно на подобный расклад вещей, я решил посмотреть на то, как нынче делаются REST сервисы в WCF без помощи каких-либо библиотек (<a href="http://trac.caffeine-it.com/openrasta" title="http://trac.caffeine-it.com/openrasta">OpenRasta</a>, <a href="http://www.mindtouch.com/products/dream" title="http://www.mindtouch.com/products/dream">MindTouch DReAM</a>) или шаблонов вроде <a href="http://aspnet.codeplex.com/wikipage?title=WCF%20REST" title="http://aspnet.codeplex.com/wikipage?title=WCF%20REST">WCF REST Starter Kit</a>. В этом посте &ndash; мои заметки насчет того, как все вышло.</p>
<h3>Мотивация</h3>
<p>Почему REST? Все очень просто &ndash; мне нынче импонируют идеи сайтов, которые находятся полностью на клиенте и работают с серверами именно через REST а не через <code>WS-*</code> или какие-то кастомные RPC-байндинги. REST &ndash; это тривиальная парадигма и, казалось бы, любой более менее продвинутый фреймворк должен позволять быстро и эффективно создавать REST-сервисы.</p>
<p>Поэтому я решил испробовать простенький сценарий &ndash; взять мой <a href="http://devtalk.net/fsharp/conversation-engine-websharper/" title="http://devtalk.net/fsharp/conversation-engine-websharper/">диалоговый фреймворк</a> написанный на WebSharper и перетащить все данные на сервер, осуществив взаимодействие через REST.</p>
<h3>Сущности</h3>
<p>Первое что я обычно делаю в проекте который хранит данные &ndash; это конечно <code>Install-Package norm</code> дабы добавить драйвер NoRM для MongoDB. Коллега Суворов конечно <a href="http://alexeysuvorov.wordpress.com/2011/03/11/mongodb-csharp-driver-part2/" title="http://alexeysuvorov.wordpress.com/2011/03/11/mongodb-csharp-driver-part2/">рекоммендует</a> якобы официальный драйвер от 10gen, но у меня итак все работает, в т.ч. Linq, поэтому зачем напрягаться?</p>
<p>Как вы помните, NoRM немного замусоривает наш объект, но он все еще остается &ldquo;почти POCO&rdquo;. WCF же в долгу не остается, и &ldquo;домусоривает&rdquo; объект еще больше, прописывая свои аттрибуты. В результате получаем классы подобные этому:</p>
<p><pre class="brush: csharp;">
[DataContract]
public class ConversationItem
{
  public ConversationItem()
  {
    Id = ObjectId.NewObjectId();
  }
  [DataMember, MongoIdentifier] public string Id { get; set; }
  [DataMember] public string PartyId { get; set; }
  [DataMember] public string Speech { get; set; }
  [DataMember] public List&lt;string&gt; EnableList { get; set; }
  [DataMember] public List&lt;string&gt; DisableList { get; set; }
}
</pre><br />
<h3>Начинаем писать сервис</h3>
<p>Первое что нужно сделать &ndash; удалить к черту сгенерировнный интерфейс &ndash; сервис проживет и без него, а <code>[ServiceContract]</code> можно навесить прямо на класс сервиса. Далее, можно создавать методы, но на них тоже нужно навесить аттрибуты, в частности:</p>
<ul>
<li><code>OperationContract</code> для того чтобы пометить что это часть сервиса.</li>
<li><code>WebGet</code> дабы прописать шаблон вызова а также форматы запроса и ответа.</li>
<li><code>JSONPBehavior</code>, но он из коробки не поставляется, и мы о нем поговорим попозже.</li>
</ul>
<p>Вот пример декорированного метода:</p>
<p><pre class="brush: csharp;">
[OperationContract]
[WebGet(UriTemplate = &quot;/c/{id}&quot;, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[JSONPBehavior(callback = &quot;callback&quot;)]
public Conversation GetInitialConversationItems(string id)
{
  ...
}
</pre>
<p>Итак, &ldquo;из коробки&rdquo; мы получаем достаточно простой метод, но не хватает двух вещей &ndash; обработки ошибок и поддержки JSONP, без которой вы ничего кроссдоменно не вызовете.</p>
<h3>Обработка ошибок</h3>
<p>Для того чтобы возвращать всякие статус коды вроде Not Found, нужно перехватить выходящий ответ из <code>WebOperationContext</code> и прописать в него информацию о том, что собственно пошло не так. Например:</p>
<p><pre class="brush: csharp;">
using (var db = GetDB())
{
  var conversation = db.Query&lt;Conversation&gt;().FirstOrDefault();  
  if (conversation == null)
  {
    var resp = WebOperationContext.Current.OutgoingResponse;
    resp.StatusCode = HttpStatusCode.NotFound;
    resp.StatusDescription = &quot;Could not find conversation with id='{0}'.&quot;.ƒ(id);
    return null;
  } 
  else
  {
    return conversation;
  }
}
</pre><br />
<h3>JSONP</h3>
<p>Феноменально, но факт &ndash; WCF не поставляется с поддержкой JSONP. К счастью, Microsoft дает такую поддержку в примерах, и то как она выглядит является хорошей демонстрацией того, как гибок WCF в плане расширения.</p>
<p>Всего для поддержки JSONP нужно добавить 5 классов. Детально я описывать их не буду, опишу только вкратце.</p>
<ol>
<li>Во-первых, нужна реализация аттрибута <code>JSONPBehavior</code> который я уже описывал. Фактически, этот аттрибут навешивает на операцию объект типа <code>IParameterInspector</code>, который перед вызовом прописывает в свойства исходящего сообщение свойство типа <code>IMessageProperty</code> для JSON.</li>
<li>Класс <code>JSONMessageProperty</code> &ndash; это всего лишь обертка для лишнего кусочка метаданных который поставляются поведением. Применим этот довесок только для callback-параметра. Для тех кто забыл, callback-параметр это то с помошью чего данные <code>data</code> возвражаются через запрос <code>http://somewhere.com/x?callback=y</code> как <code>y(data)</code>, прописываются в <code>&lt;script&gt;</code> и исполняются.</li>
<li>Далее формируется фабрика <code>JSONPEncoderFactory</code>, которая производит энкодеры типа <code>JSONPEncoder</code>. Сам энкодер, казалось бы, тривиален &ndash; все, что он должен сделать так это обернуть вызов в название callback&rsquo;а и вернуть его. Но поскольку его метод <code>WriteMessage()</code> перегружен, его приходится вызывать в нескольких местах.</li>
</ol>
<p>Для того чтобы получить всю поддержку JSONP полностью, нужно скачать <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&amp;displaylang=en" title="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35ec8682-d5fd-4bc3-a51a-d8ad115a8792&amp;displaylang=en">набор примеров по WCF</a> c MSDN.</p>
<h3>Web.config</h3>
<p>Несмотря на то, что все, в принципе можно сделать в коде, на практике приходится достаточно сильно шаманить с <code>Web.config</code> ом дабы все заработало. В частности, нужно прописать новый binding:</p>
<p><pre class="brush: csharp;">
&lt;bindings&gt;
  &lt;customBinding&gt;
    &lt;binding name=&quot;jsonpBinding&quot;&gt;
      &lt;jsonpMessageEncoding/&gt;
      &lt;httpTransport manualAddressing=&quot;true&quot;/&gt;
    &lt;/binding&gt;
  &lt;/customBinding&gt;
&lt;/bindings&gt;
</pre>
<p>А также добавить расширение для кодировки JSONP:</p>
<p><pre class="brush: csharp;">
&lt;extensions&gt;
  &lt;bindingElementExtensions&gt;
    &lt;add name=&quot;jsonpMessageEncoding&quot;
    type=&quot;ConversationServer.JsonpSupport.JsonpBindingExtension, ConversationServer&quot;/&gt;
  &lt;/bindingElementExtensions&gt;
&lt;/extensions&gt;
</pre><br />
<h3>Удаление .svc</h3>
<p>Для REST-сервисов окончание <code>.svc</code> на конце сервиса как-то нелепо. К счастью его очень просто удалить. Для этого, мы можем создать свой собственный модуль который игнорирует это окончание:</p>
<p><pre class="brush: csharp;">
public class RestModule : IHttpModule
{
  public void Init(HttpApplication context)
  {
    context.BeginRequest += (sender, args) =&gt;
    {
      var ctx = HttpContext.Current;
      var path = ctx.Request.AppRelativeCurrentExecutionFilePath;
      int i = path.IndexOf('/', 2);
      if (i &gt; 0)
      {
        var svc = path.Substring(0, i) + &quot;.svc&quot;;
        var rest = path.Substring(i, path.Length - i);
        var qs = ctx.Request.QueryString.ToString();
        ctx.RewritePath(svc, rest, qs, false);
      }
    };
  }
  public void Dispose()
  {
  }
}
</pre>
<p>А далее просто прописываем его в секцию <code>system.web</code> в <code>Web.config</code>:</p>
<p><pre class="brush: csharp;">
&lt;system.web&gt;
  &lt;compilation debug=&quot;true&quot; targetFramework=&quot;4.0&quot; /&gt;
  &lt;customErrors mode=&quot;Off&quot;/&gt;
  &lt;httpModules&gt;
    &lt;add name=&quot;NoMoreSVC&quot; type=&quot;ConversationServer.RestModule, ConversationServer&quot;/&gt;
  &lt;/httpModules&gt;
&lt;/system.web&gt;
</pre>
<p>Вот собственно и все.</p>
<h3>Заключение</h3>
<p>Мой небольшой эксперимент по использованию WCF REST показал что, как и во многих других случаях, приходится даже для простенького сервиса городить громозкие структуры. К счастью, сделав это один раз, можно потом копировать реализацию в различные проекты.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/jsonp/'>jsonp</a>, <a href='http://nesteruk.wordpress.com/tag/rest/'>rest</a>, <a href='http://nesteruk.wordpress.com/tag/wcf/'>wcf</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/741/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/741/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/741/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=741&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/03/24/create-wcf-rest-jsonp-service/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Парсим HTML Zen на F#, FsLex и FsYacc</title>
		<link>http://nesteruk.wordpress.com/2011/03/03/parsing-htmlzen-fsharp-fslex-fsyacc/</link>
		<comments>http://nesteruk.wordpress.com/2011/03/03/parsing-htmlzen-fsharp-fslex-fsyacc/#comments</comments>
		<pubDate>Thu, 03 Mar 2011 12:22:51 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[f#]]></category>
		<category><![CDATA[fslex]]></category>
		<category><![CDATA[fsyacc]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=733</guid>
		<description><![CDATA[Все наверное так или иначе слышали про HTML Zen и про то, как он спасает при написании HTML. Но мало кому приходит в голову написать свою собственную реализацию, когда есть готовая на Python&#8217;е. На самом деле, собственная реализация позволяет добавлять собственные конструкты, нужные только вам. Давайте попробуем реализовать базовые конструкты HTML Zen. Для этого мы [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=733&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Все наверное так или иначе слышали про HTML Zen и про то, как он спасает при написании HTML. Но мало кому приходит в голову написать свою собственную реализацию, когда есть готовая на Python&rsquo;е. На самом деле, собственная реализация позволяет добавлять собственные конструкты, нужные только вам.</p>
<p>Давайте попробуем реализовать базовые конструкты HTML Zen. Для этого мы воспользуемся языком F#, библиотекой тестирования <a href="http://fsunit.codeplex.com/" title="http://fsunit.codeplex.com/">FSunit</a>. Будем писать программу в стиле TDD. Я пожалуй назову ее FSharpZen, так интересней.</p>
<p>Исходный код можно найти тут: <a href="https://bitbucket.org/nesteruk/fsharpzen">https://bitbucket.org/nesteruk/fsharpzen</a></p>
<h3>Базовые случаи</h3>
<p>Весь HTML Zen &ndash; это набор трансформаций. Например, на входе <code>a</code>, а на выходе <code>&lt;a href="|"&gt;&lt;/a&gt;</code>, где <code>|</code> обозначает финальное положение каретки. Следовательно, можно как минимум написать следующий тест:</p>
<p><pre class="brush: fsharp;">
[&lt;TestFixture&gt;]
type ``Basic transformation tests`` ()=
  [&lt;Test&gt;] member test.
    ``Empty input should yield empty output`` () =
      Zen.html &quot;&quot; |&gt; should equal &quot;|&quot;
</pre>
<p>Это счастье совсем не компилируется, поэтому нам придется как минимум предоставить хоть какую-то реализацию, например:</p>
<p><pre class="brush: fsharp;">
module FSharpZen.Zen
let html input = &quot;&quot;
</pre>
<p>В результате, конечно, получим &ldquo;красный&rdquo; тест:</p>
<p><pre class="brush: fsharp;">
Expected string length 1 but was 0. Strings differ at index 0.
Expected: &quot;|&quot;
But was:  &lt;string.Empty&gt;
-----------^
</pre>
<p>Ну а дальше мы &ldquo;жульничаем&rdquo; и наш тест проходит. Не забываем сказать спасибо Решарперу, который поддерживает F#-тесты out-of-the-box.</p>
<h3>Пустые тэги</h3>
<p>Дефолтное поведение HTML Zen такое, что при написании, скажем, буквы <code>z</code> разворачивается шаблон <code>&lt;z&gt;|&lt;/z&gt;</code>. С другой стороны, <code>hr</code> определенно превращается в <code>&lt;hr/&gt;|</code>, а <code>img</code> &ndash; в <code>&lt;img src="|"&gt;&lt;/img&gt;</code>.</p>
<p><pre class="brush: fsharp;">
[&lt;Test&gt;] member test.
  ``Simple entity should be in a closed tag`` () =
    Zen.html &quot;c&quot; |&gt; should equal &quot;&lt;c&gt;|&lt;/c&gt;&quot;
[&lt;Test&gt;] member test.
  ``Self-closing entity should yield a self-closing tag`` () =
    Zen.html &quot;br&quot; |&gt; should equal &quot;&lt;br/&gt;|&quot;
[&lt;Test&gt;] member test.
  ``Entity should have appropriate attributes generated and placeholder set accordingly`` () =
    Zen.html &quot;a&quot; |&gt; should equal &quot;&lt;a href=\&quot;|\&quot; title=\&quot;\&quot;&gt;&lt;/a&gt;&quot;
</pre>
<p>Теперь у нас есть 3 use-case&rsquo;а: просто тэги, тэги которые не нуждаются в закрывающем тэге, и тэги которые имеют сложную начинку. Второй и третий случай &ndash; специальные, поэтому мы можем попробовать их выделить&hellip;</p>
<p><pre class="brush: fsharp;">
let singularEntities = [&quot;hr&quot;; &quot;br&quot;; &quot;img&quot;]
let neededAttributes = [
                         &quot;a&quot;, [&quot;href&quot;, &quot;title&quot;];
                         &quot;img&quot;, [&quot;src&quot;, &quot;alt&quot;]
                       ]
</pre>
<p>TDD по наивности своей рекоммендует &ldquo;самое простое работающее решение&rdquo; которое в нашем случае выглядит примерно вот так:</p>
<p><pre class="brush: fsharp;">
let html input =
  if input |&gt; String.IsNullOrEmpty then &quot;|&quot;
  else
    let sb = StringBuilder()
    sb.Append (&quot;&lt;&quot; + input) |&gt; ignore
    for a in neededAttributes do
      match a with
      | i, attributes when i = input -&gt;
        let firstAtt = List.head attributes
        sb.Append(&quot; &quot; + firstAtt + &quot;=\&quot;|\&quot;&quot;) |&gt; ignore
        attributes |&gt; List.tail 
                   |&gt; List.iter (fun f -&gt; sb.Append(&quot; &quot; + f + &quot;=\&quot;\&quot;&quot;) |&gt; ignore)
      | _ -&gt; ()
    // see if this is a self-closing tag
    let isSelfClosing = List.exists (fun f -&gt; f = input) singularEntities
    let pipe = if sb.ToString().Contains(&quot;|&quot;) then &quot;&quot; else &quot;|&quot;
    sb.Append(if isSelfClosing then &quot;/&gt;&quot; + pipe else &quot;&gt;&quot; + pipe + &quot;&lt;/&quot; + input + &quot;&gt;&quot;) |&gt; ignore
    sb.ToString()
</pre>
<p>До элегантности тут как до Китая. Вывода напрашивается два:</p>
<ul>
<li>Нужны какие-то структуры для того чтобы отражать структуру тэгов, особенно когда будут вложенные, с аттрибутами, и т.д.</li>
<li>Нужно учиться лучше парсить строки. То, что мы делаем выше &ndash; &ldquo;не по паттернам&rdquo;.</li>
</ul>
<h3>FsLex и FsYacc</h3>
<p>Лучший способ парсить &ndash; это взять что-то уже готовое (хотя до меня это иногда туго доходит). Поэтому для парсинга наших магических строк мы возьмем <a href="http://fsharppowerpack.codeplex.com/" title="http://fsharppowerpack.codeplex.com/">F# Power Pack</a>, и скачаем через VS Extension Manager шаблон проекта под названием <a href="http://visualstudiogallery.msdn.microsoft.com/a075ff98-7e6f-47ce-a23c-838c1e488046/" title="http://visualstudiogallery.msdn.microsoft.com/a075ff98-7e6f-47ce-a23c-838c1e488046/">F# Parser Language Starter</a>. Это позволит нам получить пример, в котором есть три важных файла, а именно:</p>
<ul>
<li><code>Ast.fs</code> &mdash; определение синтактического дерева. В нашем случае оно достаточно простое.</li>
<li><code>Lexer.fsl</code> &mdash; определение &ldquo;лексем&rdquo;, т.е. различных кусков строки, которые формируют выражение HTML Zen.</li>
<li><code>Parser.fsy</code> &mdash; собственно парсер, который определяет то, как лексемы становятся чем-то осмысленным.</li>
</ul>
<p>В сгенерированном примере получается калькулятор<sup><a href="#Reference1" title="Кстати, пример кривой &ndash; попробуйте например ввести 2-2 и у вас парсер моментально накроется &ndash; а все из-за попытки взять минус перед 2кой как префикс-оператор. :)" name="BackReference1">1</a></sup>, нам же остается только поменять его чтобы начали поддерживаться наши собственные структуры.</p>
<h3>AST</h3>
<p>Итак, для нашего магического синтаксиса нам нужно определить тот набор элементов дерева, который мы фактически готовы подерживать. Это включает в себя как минимум следующие конструкции<sup><a href="#Reference2" title="Тут я немного отклонился от &ldquo;кошерного&rdquo; HTML Zen который, на мой взгляд, достаточно избыточен. В частности, я заменил &gt; на + а &ldquo;оригинальный&rdquo; + попросту проигнорировал." name="BackReference2">2</a></sup>:</p>
<ul>
<li>Идентификаторы, такие как <code>div</code>, <code>href</code> и так далее. Они парсятся &ldquo;как есть&rdquo;.</li>
<li>Классы, т.е. при при написании <code>a.b</code> мы получаем <code>&lt;a href="|" class="b"&gt;&lt;/a&gt;</code>.</li>
<li>Идентификаторы, т.е. <code>a#b</code> ставовится <code>&lt;a id="b" href="|"&gt;&lt;/a&gt;</code>.</li>
<li>Множители, т.е. <code>hr*2</code> дает нам <code>&lt;hr/&gt;&lt;hr/&gt;</code>. Между тэгами, между прочим, фигурирует <code>\n</code> &ndash; это вынужденная мера для таких ситуаций как <code>ol&gt;li*2</code>.</li>
<li>Вложенные тэги &ndash; например, <code>ol+li</code> становится <code>&lt;ol&gt;&lt;li&gt;|&lt;/li&gt;&lt;/ol&gt;</code>, с соответствующими переносами и отступами.</li>
</ul>
<p>Теперь попробуем перевисти все эти идеи на структуры F#. У меня получилось примерно следующее:</p>
<p><pre class="brush: fsharp;">
type ZenExpression =
  | ZenExpression of Expression list
and Expression =
  | Expression of Identifier * Qualifier list
and Identifier =
  | Identifier of string
and Qualifier =
  | ClassQualifier of string
  | IdentityQualifier of string
  | CardinalityQualifier of int
</pre>
<p>Строго говоря, то, что вы видите выше &ndash; уродство. С этим очень сложно работать. К тому же, нет никаких ограничений на количество идентификатов или показателей размерности (а ведь элемент может иметь только один квалификатор каждого типа). Ну да ладно, эту проблему мы разрулим позже.</p>
<h3>Лексер</h3>
<p>Лексер у нас будет простенький. Во-первых, нужно определить регулярные выражения для всех полезных конструктов:</p>
<p><pre class="brush: fsharp;">
let digit = ['0'-'9']
let letter = ['a'-'z'] | ['A'-'Z']
let letterOrDigit = letter | digit
let whitespace = [' ' '\t' ]
let newline = ('\n' | '\r' '\n')
</pre>
<p>Ну а теперь, нужно определить какие конструкты будут производится из регулярных выражений. Нам нужны:</p>
<ul>
<li>Строки (возможно с числами) для идентификаторов и квалификаторов.</li>
<li>Операторы для разделения квалификаторов (<code>.</code>, <code>#</code>, <code>+</code> и <code>*</code>)</li>
<li>Числа для квалификатора размерности</li>
</ul>
<p>Следовательно, получаем следующее определение:</p>
<p><pre class="brush: fsharp;">
rule tokenize = parse
| whitespace	   { tokenize lexbuf }
| newline        { tokenize lexbuf }
| letterOrDigit+ { STRING(lexeme lexbuf) }
| digit+         { INT32(Int32.Parse(lexeme lexbuf)) }
// Operators
| &quot;+&quot;            { PLUS }
| &quot;#&quot;            { HASH }
| &quot;*&quot;            { TIMES }
| &quot;.&quot;            { DOT }
// EOF
| eof   { EOF }
</pre><br />
<h3>Парсер</h3>
<p>Определив лексемы, нам нужно научиться парсить их и превращать их комбинации в элементы AST. Для этого пойдет следующее определение:</p>
<p><pre class="brush: fsharp;">
start: exprs { ZenExpression($1) }
exprs:
  | exp PLUS exprs EOF { Expression($1) :: $3 }
  | exp EOF { [Expression($1)] }
exp:
  | STRING quals { (Identifier($1), $2) }
  | STRING { (Identifier($1), []) }
quals:
  | qual quals { $1 :: $2 }
  | qual { [$1] }
qual:
  | DOT STRING  { ClassQualifier($2) }
  | HASH STRING { IdentityQualifier($2) }
  | TIMES INT32 { CardinalityQualifier($2) }
</pre>
<p>Помимо того, что списки чего бы то ни было создаются рекурсивно, тут нет ничего необычного.</p>
<h3>Принтер</h3>
<p>Ну а теперь самое сложное. Помните я сказал, что та структура в которую мы парсим &ndash; убогая и избыточная? Так вот, сейчас вы увидите насколько неудобно такую штуку печатать.</p>
<p>Во-первых, код забрасывается кучей вспомогательных функций для поиска квалификаторов определенного типа. Например:</p>
<p><pre class="brush: fsharp;">
let rec private getId qualifierList =
  match qualifierList with
  | IdentityQualifier(id) :: t -&gt; Some(id)
  | h :: t -&gt; getId t
  | [] -&gt; None
</pre>
<p>Потом, приходится (не знаю в какой уже раз) делать вменяемый билдер для кода:</p>
<p><pre class="brush: fsharp;">
type CodeBuilder() =
  let sb = StringBuilder()
  let mutable indent = 0;
  member this.GetIndent() =
    System.String.Empty.PadRight(indent * 2)
  member this.AppendWithIndent (text:string) = 
    sb.Append(this.GetIndent()).Append(text) |&gt; ignore
  member this.Append (text:string) = 
    sb.Append(text) |&gt; ignore
  member this.NewLine() = sb.AppendLine() |&gt; ignore
  member this.Indent() = indent &lt;- indent + 1
  member this.Unindent() = indent &lt;- indent - 1
  override this.ToString() = sb.ToString()
</pre>
<p>Потом нужен поистине гигантский кусок кода для того чтобы распарсить все кейсы &ndash; конструкция весьма громоздкая:</p>
<p><pre class="brush: fsharp;">
let rec private print expressions (builder:CodeBuilder) =
  match expressions with
  | h :: t -&gt;
    builder.AppendWithIndent &quot;&lt;&quot;
    match h with
    | Expression(name, qual) -&gt;
      builder.Append name
      // id it if has any
      match getId qual with
      | Some(id) -&gt; builder.Append(&quot; id=\&quot;&quot; + id + &quot;\&quot;&quot;)
      | _ -&gt; ()
      // needed attributes
      let needed = getNeededAttributes name
      needed |&gt; List.iter(fun n -&gt; builder.Append(&quot; &quot; + n + &quot;=\&quot;|\&quot;&quot;))
      // classes
      let classes = getClasses qual
      if classes &lt;&gt; List.empty then
        builder.Append(&quot; class=\&quot;&quot;)
        builder.Append(System.String.Join(&quot; &quot;, classes))
        builder.Append(&quot;\&quot;&quot;)
      // if self-closing, then close it
      let selfClosing = singularEntities |&gt; List.exists(fun f -&gt; f = name)
      if selfClosing then builder.Append &quot;/&gt;|&quot;
      else builder.Append &quot;&gt;&quot;
      // if there's more stuff in there, add it
      if t &lt;&gt; List.empty then
        builder.Indent()
        builder.NewLine()
        print t builder
        builder.NewLine()
        builder.Unindent()
        
      if not selfClosing then
        builder.Append(&quot;|&lt;/&quot; + name + &quot;&gt;&quot;)
  | _ -&gt; 
    builder.Append &quot;|&quot;
</pre>
<p>А вот собственно как все запускается:</p>
<p><pre class="brush: fsharp;">
let html input = 
  let lexbuf = LexBuffer&lt;char&gt;.FromString(input)
  let parsed = Parser.start Lexer.tokenize lexbuf
  let builder = new CodeBuilder()
  match parsed with
  | ZenExpression(items) -&gt; print items builder
  let pre = builder.ToString() |&gt; Seq.toList
  let rec clean input metBar =
    match input with
    | '|' :: t when not metBar -&gt; '|' :: clean t true
    | '|' :: t when metBar -&gt; clean t true
    | h :: t -&gt; h :: clean t metBar
    | [] -&gt; []
  let lst = clean pre false
  System.String(lst |&gt; List.toArray)
</pre>
<p>Излишние телодвижения у нас от того, что мы в принтере генерируем избыточное число кареток. Нужно удалить все кроме первой, а более элегантного способа я не знаю (хотя не исключаю что он существует).</p>
<h3>Заключение</h3>
<p>В очередной раз у меня сомнения. Количество телодвижений для того чтобы реализовать парсер примерно в 10 раз больше чем когда я все это писал &ldquo;в лоб&rdquo; на C#. FxLex и FsYacc обладают практически нулевой диагностичностью, никакого IntelliSense нет, такое впечатление что блуждаешь в потемках. Что касается принтера, опять же, структура на которую все было &ldquo;замэплено&rdquo; очень неудобна; намного быстрее было бы использовать ООП. Плюшки FP вроде паттерн-матчинга и прочего тут совсем не амортизировались.</p>
<h3>Заметки</h3>
<ol>
<li><a name="Reference1"></a><a href="#BackReference1" title="Back to text">&uarr;</a> Кстати, пример кривой &ndash; попробуйте например ввести <code>2-2</code> и у вас парсер моментально накроется &ndash; а все из-за попытки взять минус перед 2кой как префикс-оператор. :)</li>
<li><a name="Reference2"></a><a href="#BackReference2" title="Back to text">&uarr;</a> Тут я немного отклонился от &ldquo;кошерного&rdquo; HTML Zen который, на мой взгляд, достаточно избыточен. В частности, я заменил <code>&gt;</code> на <code>+</code> а &ldquo;оригинальный&rdquo; <code>+</code> попросту проигнорировал.</li>
</ol>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/net/f/'>f#</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/fslex/'>fslex</a>, <a href='http://nesteruk.wordpress.com/tag/fsyacc/'>fsyacc</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/733/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/733/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/733/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/733/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/733/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/733/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/733/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/733/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=733&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/03/03/parsing-htmlzen-fsharp-fslex-fsyacc/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Уравнения на F# проще чем на C#?</title>
		<link>http://nesteruk.wordpress.com/2011/02/05/are-fsharp-equations-easier-than-csharp/</link>
		<comments>http://nesteruk.wordpress.com/2011/02/05/are-fsharp-equations-easier-than-csharp/#comments</comments>
		<pubDate>Sat, 05 Feb 2011 07:52:32 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[f#]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=718</guid>
		<description><![CDATA[На недавней встрече, посвещенной языку F#, я показал как якобы «элегантно» можно описывать математические функции на F#. А сейчас сел и задумался &#8211; так ли это на самом деле? Давайте разберемся. Квадратное уравнение Начнем с примера, приведенного мною на встрече &#8211; решения квадратного уравнения. Казалось бы &#8211; что может быть проще? Сразу можно сделать несколько [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=718&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>На <a href="http://spbalt.net/Home/Meetings/25" title="http://spbalt.net/Home/Meetings/25">недавней встрече</a>, посвещенной языку F#, я показал как якобы «элегантно» можно описывать математические функции на F#. А сейчас сел и задумался &ndash; так ли это на самом деле? Давайте разберемся.</p>
<h3>Квадратное уравнение</h3>
<p>Начнем с примера, приведенного мною на встрече &ndash; решения квадратного уравнения. Казалось бы &ndash; что может быть проще?</p>
<p align="center"><img src="http://nesteruk.org/pix/0/4d155c02-150c-48b9-a862-c6ac1cfb5d6b.png" alt="" style="border:0;" align="center" class="aligncenter" /></p>
<p>Сразу можно сделать несколько сравнений C# и F# для этого примера:</p>
<ul>
<li>Возвращаются 2 значения, а следовательно F# выигрывает за счет того что не надо писать <code>Tuple.Create</code>, а тому кто эти значения получит не надо использовать абсолютно ничего не значащие свойства <code>Item1</code> и <code>Item2</code></li>
<li>Математические binding&rsquo;и у F# намного «ближе» чем у C#, а следовательно в этом случае (да и в общем), ваш код на F# не будет испачкан явным вызовом статических функций вроде <code>Math.Sqrt</code>. Меня всегда это бесило в C# т.к. сложные вычисления становится еще сложнее читать.</li>
<li>Ни C# ни F# не умеют работать с оператором ±. Но если в C# нам придется тупо вызывать вычисления дважды, в F# мы можем просто определить функцию конечного вычисления, а потом передать в нее операторы <code>(+)</code> и <code>(-)</code>.</li>
</ul>
<p>В результате получим следующее сравнение:</p>
<p>
  <strong>C#</strong>
</p>
<p><pre class="brush: csharp;">
public Tuple&lt;double,double&gt; SolveQuadraticEquation(double a, double b, double c)
{
  double discRoot = Math.Sqrt(b*b-4.0*a*c);
  double x1 = (-b + discRoot) / (2 * a);
  double x2 = (-b - discRoot) / (2 * a);
  return Tuple.Create(x1, x2);
}
</pre>
<p>
  <strong>F#</strong>
</p>
<p><pre class="brush: fsharp;">
let solveQuadratic a b c =
  let disc = b * b - 4.0 * a *c
  let calc op = (op (-b) (sqrt disc)) / (2.0*a)
  (calc (+), calc(-))
</pre>
<p>Пока что разница небольшая &ndash; в одну строчку, если не считать фигурных скобок. А спорим я могу сократить эту разницу практически до нуля? Вот, пожалуйста:</p>
<p>
  <strong>C#</strong>
</p>
<p><pre class="brush: csharp;">
public Tuple&lt;double, double&gt; SolveQuadraticEquation(double a, double b, double c)
{
  double q = -0.5 * (b + Math.Sign(b) * Math.Sqrt(b * b - 4 * a * c));
  return Tuple.Create(q / a, c / q);
}
</pre>
<p>
  <strong>F#</strong>
</p>
<p><pre class="brush: fsharp;">
let solveQuadraticEquation a b c =
  let q = -0.5 * (b + (sign b |&gt; float) * sqrt(b * b - 4.0 * a * c))
  (q / a, c / q) //           ^^^^^^^^ WTF?!?
</pre>
<p>Пример на F# должен вызвать у вас возмущение &ndash; с какой это радости результат <code>(sign b)</code> должен быть приведен к типу <code>float</code>?<sup><a href="#Reference1" title="Напоминаю, что float в F# &ndash; это double в C#. А C#-ный float в F# называется float32." name="BackReference1">1</a></sup> А дело все в непродуманности API, согласно которому <code>sign(x)</code> &ndash; это всегда <code>int</code> (могли бы сделать тем же типом что и аргумент), а также крайне жесткой системе типов в которой <code>float + int * float</code> не воспринимается и никак не вычисляется.</p>
<p>Такое странное поведение F# унаследовано из OCaml и требуется для правильного вывода типов. Если вам действительно интересны причины &ndash; можно <a href="http://cs.hubfs.net/forums/thread/3391.aspx" title="http://cs.hubfs.net/forums/thread/3391.aspx">почитать тут</a>. Мне же это лишь палки в колеса. Да, и я знаю что можно было бы написать <code>sign(float b)</code> или что-то в этом роде. Тут как бы без разницы, все равно «не очень».</p>
<h3>Комплексные решения</h3>
<p>Ну да ладно, а вот вопрос &ndash; что будет если дискриминанта (&Delta;) меньше нуля? С одной стороны, и C# и F# поддерживает комплексные типы данных (см. System.Numerics). Если сделать вид что мы все будем передавать как комплексные числа (так проще?), то получим вот такой вот код:</p>
<p>
  <strong>C#</strong>
</p>
<p><pre class="brush: csharp;">
public Tuple&lt;Complex, Complex&gt; SolveQuadraticEquation3(double a, double b, double c)
{
  double det = b * b - 4 * a * c;
  double absRoot = Math.Sqrt(Math.Abs(det));
  Complex root = det &lt; 0 ? new Complex(0, absRoot) : new Complex(absRoot, 0);
  Complex q = -0.5 * (b + Math.Sign(b) * root);
  return Tuple.Create(q / a, c / q);
}
</pre>
<p><strong>F#</strong></p>
<p><pre class="brush: fsharp;">
let solveQuadratic3 a b c =
  let complex v = Complex(v, 0.0)
  let det = b * b - 4.0 * a * c
  let absRoot = sqrt(det |&gt; abs)
  let root = if det &lt; 0.0 then Complex(0.0, absRoot)
                          else Complex(absRoot, 0.0)
  let q = -(complex 0.5) * ((complex b) + (sign b |&gt; float |&gt; complex) * root)
  (q / complex(a), complex(c) / q)
</pre>
<p>Эээ, ну что я могу сказать? F# определенно превносит массу головной боли. Проблема тут как раз в том, что в C# нам доступны операторы автоконверсии вроде <code>float</code>&rarr;<code>Complex</code>, но в F# они попросту не работают! Поэтому вы можете либо определить их как функции (благо у них есть имя <code>op_Implicit</code>), либо же просто вызвать конструктор как делаю я.<sup><a href="#Reference2" title="Тут еще хочется заметить что if который выбирает какой Complex создавать как бы не нужно &mdash; можно было вместо этого написать Complex.Sqrt(new Complex(b*b-4*a*c, 0.0)). Проблема только в том что в результате этого вычисления Real-значение будет чуточку отличаться от нуля. Например sqrt(Complex(-4.0, 0.0)) равен (1.22460635382238E-16, 2)." name="BackReference2">2</a></sup></p>
<h3>Заключение</h3>
<p>То ли я чего-то недопонимаю, то ли F# действительно неудобен для работы с математикой? Ведь если нужно каждый <code>int</code> кастовать во <code>float</code>, а каждый <code>float</code> в <code>Complex</code>, и так далее, то это же сколько лишнего, никому не нужного и мешающего восприятию кода надо написать?</p>
<p>Критика welcome! А то может я что не так написал?</p>
<h3>Заметки</h3>
<ol>
<li><a name="Reference1"></a><a href="#BackReference1" title="Back to text">&uarr;</a> Напоминаю, что <code>float</code> в F# &ndash; это <code>double</code> в C#. А C#-ный <code>float</code> в F# называется <code>float32</code>.</li>
<li><a name="Reference2"></a><a href="#BackReference2" title="Back to text">&uarr;</a> Тут еще хочется заметить что <code>if</code> который выбирает какой <code>Complex</code> создавать как бы не нужно &mdash; можно было вместо этого написать <code>Complex.Sqrt(new Complex(b*b-4*a*c, 0.0))</code>. Проблема только в том что в результате этого вычисления Real-значение будет <em><font face="Trebuchet MS" />чуточку</font></em> отличаться от нуля. Например <code>sqrt(Complex(-4.0, 0.0))</code> равен <code>(1.22460635382238E-16, 2)</code>.</li>
</ol>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/c/'>C#</a>, <a href='http://nesteruk.wordpress.com/category/net/f/'>f#</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/718/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/718/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/718/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/718/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/718/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/718/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/718/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/718/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=718&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/02/05/are-fsharp-equations-easier-than-csharp/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://nesteruk.org/pix/0/4d155c02-150c-48b9-a862-c6ac1cfb5d6b.png" medium="image" />
	</item>
		<item>
		<title>Коротко про WebSharper и сайтлеты</title>
		<link>http://nesteruk.wordpress.com/2011/01/19/on-websharper-and-sitelets/</link>
		<comments>http://nesteruk.wordpress.com/2011/01/19/on-websharper-and-sitelets/#comments</comments>
		<pubDate>Wed, 19 Jan 2011 20:53:19 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[f#]]></category>
		<category><![CDATA[sitelet]]></category>
		<category><![CDATA[websharper]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=704</guid>
		<description><![CDATA[Этот пост &#8211; про WebSharper в целом и про сайтлеты в частности. Как я уже писал, WebSharper &#8211; это идея создания сайтов полностью на языке F#. У этой идеи есть несколько модельных реализаций, а точнее три &#8211; через Asp.Net, Asp.Net MVC и так называемые сайтлеты &#8220;sitelets&#8221;. Концепция Меня во всей этой концепции интересуют именно сайтлеты. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=704&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img src="http://nesteruk.org/pix/0/1ac970e1-40cf-4dc7-ac88-adc39a02a8e5.png" class="alignright" alt="" style="border:0;" />Этот пост &ndash; про <a href="http://websharper.com" title="http://websharper.com">WebSharper</a> в целом и про сайтлеты в частности. Как я уже писал, WebSharper &ndash; это идея создания сайтов полностью на языке F#. У этой идеи есть несколько модельных реализаций, а точнее три &ndash; через Asp.Net, Asp.Net MVC и так называемые сайтлеты &ldquo;sitelets&rdquo;.</p>
<h3>Концепция</h3>
<p>Меня во всей этой концепции интересуют именно сайтлеты. В отличии от использования Asp.Net-конструктов (пусть и на F#), сайтлеты &ndash; наиболее &ldquo;трушная&rdquo; концепция, в которой сгенерированный код будет <strong>полностью отвязан</strong> от Asp.Net и, впоследствии, от IIS.</p>
<p>Теперь о том <em><font face="Trebuchet MS" />как</font></em> это делается. На самом деле, основной концепцией является конверсия F# в JavaScript/CSS/HTML на этапе компиляции. Делается это за счет аттрибута под названием <code>ReflectedDefinitionAttribute</code> который, имея alias под названием <code>JavaScriptAttribute</code>, используется перед методами, которые нужно сконвертировать в JavaScript.</p>
<p>Что этот аттрибут делает? Он заставляет компилятор F# сохранить логические конструкты метода вместо того чтобы просто его компилировать. А тут включается постпроцессинг WebSharper&rsquo;а, который берет это &ldquo;отраженное определение&rdquo; и, на его основе, формирует некий промежуточный слой JavaScript. Промежуточный слой нужен потому, что мэпить F# на JavaScript не так-то просто.</p>
<p>Простой код который вы напишете вот так</p>
<p><pre class="brush: fsharp;">
[&lt;JavaScript&gt;]
let rec Fact n =
  match n with
  | n when n &lt; 2 -&gt; 1
  | n -&gt; n * Fact1 (n - 1)
</pre>
<p>может быть в последствии вызван со страницы напрямую &ndash; ведь все остальное, что есть на странице тоже определено через F#, конвертированный в JS и HTML.</p>
<h3>Вызовы серверных методов</h3>
<p>Мне очень понравилось что механизм вызова методов очень прозрачный. Метод помеченный как <code>[&lt;JavaScript&gt;]</code> вызывается как JS прямо у клиента, в то время как метод помеченный как <code>[&lt;Rpc&gt;]</code> хостится на сервере (как это будет сделано в полноценных сайтлетах &ndash; непонятно), и соответственно его вызов со страницы дергает сервер.</p>
<p>На данный момент механизм поведения Rpc-методов такой: если метод возвращает какое-то значение, то вызов является блокирующим. Если метод возвращает <code>unit</code> &ndash; его вызов считается асинхронным и тем самым, если вы повесили на него брейкпоинт (да, это можно делать), вы можете остановиться в нем не тогда, когда ожидаете.</p>
<h3>Формирование контента</h3>
<p>ВебШарпер не отказывается от идеи шаблонов! По крайней мере сайтлеты на текущем этапе предоставляют возможность писать шаблоны в HTML, который потом компилируется&hellip; в F#! Что намного более извращенно чем то, что делает Asp.Net MVC, например. Но мы сейчас не об этом.</p>
<p>Дело в том, что сам по себе WebSharper предоставляет возможность формировать HTML путем использования HTML-подобных конструктов в F#. Механизм, с помощью которого организовано создание HTML весьма забавно. В модуле <code>IntelliFactory.Html.Tags</code> есть определения для большого количества тэгов, например <code>H1</code>. Каждый тэг &ndash; это функция, которая сама по себе берет список, состоящий из нескольких &ldquo;нодов&rdquo;, которые могут формировать как аттрибуты данного тэга, так и его начинку. Например, чтобы сделать заголовок с текстом, мы пишем следующее:</p>
<p><pre class="brush: fsharp;">
H1 [Text &quot;Title&quot;]
</pre>
<p>В примере выше, метод <code>Text</code> определяет, что его аргумент &ndash; это действительно текст. Вместо него, мы бы могли например использовать <code>Attr</code> чтобы указать что это аттрибут.</p>
<p>Теперь насчет композиции. Композиция &ndash; это <em><font face="Trebuchet MS" />центральная</font></em> особенность ВебШарпера, которая очень хорошо выделяет его по сравнению с тем же Asp.Net MVC. В данном случае, для вкладывания HTML-элементов друг в друга, мы можем использовать оператор <code>-&lt;</code>. Например:</p>
<p><pre class="brush: fsharp;">
Div [Attr.Style &quot;padding: 5px;&quot;] -&lt; [
  P [Text &quot;Hello&quot;]
]
</pre><br />
<h3>События</h3>
<p>Обработка событий в F# делается путем еще одного полезного оператора <code>|&gt;!</code>. Этот оператор делает подписку на событие, и одновременно возвращает созданный элемент, что обязательно в условиях механики работы WebSharper. Вот небольшой пример:</p>
<p><pre class="brush: fsharp;">
let update () =
  // обработка события
 
let input = Input [Attr.Type &quot;Text&quot;]
Form [
  label &quot;First Name: &quot;
  input |&gt;! OnKeyUp (fun _ _ -&gt; update ())
]
</pre>
<p>Опять же, интересно тут то, что не важно, где располагается метод <code>update()</code> &ndash; на сервере или на клиенте.</p>
<h3>Это вам не MVC!</h3>
<p>Сейчас устраивать гонения на MVC <a href="http://www.gotdotnet.ru/blogs/sanchez911/9266/" title="http://www.gotdotnet.ru/blogs/sanchez911/9266/">модно</a>, многие уходят на Rails (в т.ч. всем известный <a href="http://www.osherove.com/blog/2011/1/2/the-journey-begins-and-why-it-starts-with-ruby.html" title="http://www.osherove.com/blog/2011/1/2/the-journey-begins-and-why-it-starts-with-ruby.html">Рой Ошеров</a>), поэтому я решил тоже подлить масла в огонь хотя, по-хорошему, ВебШарпер является частью Asp.Net инфраструктуры. Но это пока сайтлеты полностью не дописаны. Так вот, понятное дело, что в функциональной парадигме, создание сайтов выглядит несколько по-другому.</p>
<p>Для начала, давайте познакомимся с концепцией &ldquo;формлетов&rdquo;. <a href="http://bugsquash.blogspot.com/2011/01/simple-implementation-of-formlets-in-f.html">Формлет</a> &ndash; это возможность описания того, какие данные нужно получать в форме и как пройдет валидация. Например:</p>
<p><pre class="brush: fsharp;">
[&lt;JavaScript&gt;]
let BasicInfoForm () : Formlet&lt;BasicInfo&gt; =
  Formlet.Yield (fun name age -&gt; { Name = name; Age = age })
  &lt;*&gt; Input &quot;Name&quot; &quot;Please enter your name&quot;
  &lt;*&gt; InputInt &quot;Age&quot; &quot;Please enter a valid age&quot;
</pre>
<p>Формлеты можно &ldquo;обрамлять&rdquo; (типичный паттерн Декоратор) в различные другие конструкты, функционально добавляя им кнопки Submit/Reset, настройки, и так далее. Формлеты можно инстанциировать у себя в коде, причем с ними можно делать вещи, которые в том же MVC делать очень сложно. Например, допустим у вас сайт где можно разместить резюме, и вы хотите чтобы человек мог внести данные о всех местах где он работал. Для этого, вы делаете формлет, который инкапсулирует все данные о работе (где, когда, итп.) а потом одной строчкой кода говорите &ldquo;их может быть несколько&rdquo;. И все! Композиционная структура сделает все сама за себя.</p>
<p>Так вот, о чем мы? После того как мы сделали несколько формлетов, их можно выстроить в цепочку, так что нажав Submit на одном, мы перейдем к другому. Эта &ldquo;концепция&rdquo; именуется flowlet&rsquo;ом (или flowlet&rsquo;ами). Выражается это следующим образом.</p>
<p>Во-первых, есть некий workflow под названием <code>Flowlet.Do</code> этот вокрфлоу умеет показывать формы в тот момент, когда они учавствуют по правую сторону <code>let!</code>, и сохранять их возвращенные значения (да-да, форма это функция, а ее return value &ndash; это то, что пользователь ввел). После этого, путем <code>return!</code> происходит &ldquo;типа возврат&rdquo; из этой цепочки, то есть мы можем, например, предоставить фунцию, которая получит результаты formlet&rsquo;ов и выведет из них полезные значения на экран.</p>
<p>На самом деле, механика всего этого чуть-чуть сложнее. Во-первых, конечным результатом выражения <code>Formlet.Do</code> все равно должен быть <code>Formlet</code>, то есть создав элемент, вам придется его конвертировать. Но это не сложно! А во-вторых, весь этот computational expression должен быть передан в функцию <code>Formlet.Flowlet</code> для того чтобы оркестровать такое феерическое действие.</p>
<p><pre class="brush: fsharp;">
Formlet.Do {
  let! w = welcomeForm
  let! c = consentForm
  return! Formlet.OfElement (proc w c)
}
|&gt; Formlet.Flowlet
</pre><br />
<h3>Представление</h3>
<p>На данный момент презентация сего фееричного действия организована в терминах Asp.Net&rsquo;ного <code>WebControl</code>, от которого наследует ВебШарперный контрол, давая нам возможность засунуть в него целиком наш pagelet. Pagelet &ndash; это еще одна абстракция в стиле &ldquo;нечто что может фигурировать на странице&rdquo;. Логика мне не ясна, но на данный момент pagelet&rsquo;ом являются текст, <code>Element</code> (это просто элемено HTML) или <code>Flowlet</code>.</p>
<p>Понятное дело, что формирование отдельного <code>WebControl</code>-а не означает создание странички целиком. И вот тут начинаются странности.</p>
<p>Дело в том, что для сайтлетов у нас генерируются 3 проекта, а именно:</p>
<ul>
<li>Проект Asp.Net, который содержит некоторые ресурсы (например CSS), но в будущем скорее всего не будет нужен вообще. По крайней мере, сейчас для сайтлетов он служит заглушкой со ссылкой на &ldquo;настоящий сайт&rdquo;.</li>
<li>Проект сожержащий сайтлет.</li>
<li>Проект с шаблонами.</li>
</ul>
<p>Проект с шаблонами &ndash; это возможность делать, фактически, master-странички со вставками, определеными в F#. Вы уже догадались почему нужно конвертировать HTML в F#? Поясню: в основном проекте, у нас появляется возможность <em><font face="Trebuchet MS" />строготипизированно</font></em> определить, что мы помещаем в различные секции шаблона. Обычно туда помещяется либо наш F#-созданный HTML, либо&hellip; наш <code>WebControl</code>, конечно же!</p>
<p>За этим всем стоит разве что само определение сайта. Там собраны все шаблоны, и еще есть некий plumbing для того чтобы все работало.</p>
<h3>Размышления</h3>
<p>Для меня, идеальным кажется сайт, который существует целиком на клиенте, а с сервером общается только через REST или более продвинутую парадигму <em><font face="Trebuchet MS" />a la</font></em> NetKernel. Поэтому в случае с ВебШарпером (надеюсь мне авторы простят русификацию названия), то чего хочу видеть я &ndash; это полную отвязку от Asp.Net и IIS. Я точно не знаю когда это будет, но коллеги подсказывают мне, что релиз WebSharper 2.0 будет отвязан от Asp.Net, в то время как полноценная поддержка сайтлетов с отвязкой от IIS будет в последующем релизе. Главное, что для перехода на Linux (а это основная цель) не надо будет ничего переписывать. По крайней мере я на это надеюсь.</p>
<p>Теперь что касается <em><font face="Trebuchet MS" />юзабельности</font></em> сего фреймворка. Понятное дело что вкуривать сложную DSL и писать на F# &ndash; занятие не для слабонервных, но лично меня технические трудности не очень беспокоят. Композициональность, если так можно выразиться, фреймворка впечатляет, ровно как и его возможность быстро оборачивать такие JS библиотеки как JQueryUI, YUI или даже RxJS! Это означает что в F# можно получить унифицированную, строготипизированную модель, которая будет сама подсказывать как использовать тот или иной фреймворк и упрощать работу с ним.</p>
<h3>Анонсы</h3>
<p>Коротко о главном. Во-первых, Петербургская Группа Alt.Net планирует провести 3х-часовую встречу посвещенную F#. Максим Моисеев и я будем рассказывать про все, начиная с основных понятий и заканчивая спекуляциями на тему type provider&rsquo;ов. Встреча пройдет 3го Февраля в офисах Exigen, и в ближайшее время мы вывесим анонс на сайтах Ineta и Spbalt.net.</p>
<p>Во-вторых, на выходных периодически происходят неформальные встречи участников сообщества. Встречи происходят в моем офисе (территориально 3 мин. от м. Автово), так что если вы живете в Питере и у вас есть желание убить выходной копаясь в F# (или еще какой-нть интересной фигне) с единомышленниками, напишите мне и мы обсудим. Писать лучше по скайпу &mdash; <code>dmitri.nesteruk</code>.</p>
<p>На этом все. Comments welcome!</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/net/f/'>f#</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/sitelet/'>sitelet</a>, <a href='http://nesteruk.wordpress.com/tag/websharper/'>websharper</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/704/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/704/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/704/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/704/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/704/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/704/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/704/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/704/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=704&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/01/19/on-websharper-and-sitelets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://nesteruk.org/pix/0/1ac970e1-40cf-4dc7-ac88-adc39a02a8e5.png" medium="image" />
	</item>
		<item>
		<title>Технологии на моей тарелке</title>
		<link>http://nesteruk.wordpress.com/2011/01/07/tech-on-my-plate/</link>
		<comments>http://nesteruk.wordpress.com/2011/01/07/tech-on-my-plate/#comments</comments>
		<pubDate>Fri, 07 Jan 2011 16:44:01 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[f#]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[dotnetrdf]]></category>
		<category><![CDATA[good relations]]></category>
		<category><![CDATA[gpu.net]]></category>
		<category><![CDATA[mindtouch]]></category>
		<category><![CDATA[netkernel]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=694</guid>
		<description><![CDATA[За последние несколько месяцев, мне под руки попался ряд технологий которые я, без стороннего влияния, наверняка никогда бы и не узнал. Причина этому во-первых в том, что я слишком сильно &#8220;залип&#8221; в инфраструктуре .Net и языке C# чтобы отчетливо видеть что-то за ее пределами. Тем самым, &#8220;отлипание&#8221; для меня &#8211; процесс болезненный. А целью этого [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=694&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>За последние несколько месяцев, мне под руки попался ряд технологий которые я, без стороннего влияния, наверняка никогда бы и не узнал. Причина этому во-первых в том, что я слишком сильно &ldquo;залип&rdquo; в инфраструктуре .Net и языке C# чтобы отчетливо видеть что-то за ее пределами. Тем самым, &ldquo;отлипание&rdquo; для меня &ndash; процесс болезненный. А целью этого поста является кратко осветить те технологии, с которыми я познакомился &ndash; мало ли, может кому-то еще интересно будет.</p>
<h3>F#</h3>
<p>Писать на F# демо-программки и делать на нем что-то существенное &ndash; это совершенно разные вещи. Когда начинаешь массово плодить код на F#, начинаешь понимать всю упадочность своего понимания мира. Например, я достаточно долго писал <code>member this.Something with get() = ...</code> вместо аналогичного варианта <code>member this.Something = ...</code>. Ну и тяга к скобочкам и излишним аннотациям типов (даже там где и ежу понятно что это за тип будет) &ndash; это тоже наследие использования C# где все прописывается.</p>
<p>F# поражает скудностью поддержки в студии. На одной из моих машин вылетела поддержка IntelliSense (полностью!), на другой &ndash; F# проекты по F5 только компилируются но не запускается отладчик. Очевидно что-то тут не так. Я конечно предпринимаю <a href="http://activemesa.com/fsharper" title="http://acivemesa.com/fsharper">усилия</a> для того чтобы работать с F# было более гуманно, но пока что нужно делать основные вещи, такие как лексер и парсер. Адаптировать их из сорцов F#-а &mdash; дело не для слабонервных.</p>
<h3>WebSharper</h3>
<p><img class="alignright" src="http://nesteruk.org/pix/0/1ac970e1-40cf-4dc7-ac88-adc39a02a8e5.png" alt="" style="border:0;" align="right" />Я упомянул <a href="http://websharpercom" title="http://websharpercom">этот фреймворк</a> в моем <a href="http://spbaltnet.podfm.ru/solo/28/" title="http://spbaltnet.podfm.ru/solo/28/">первом сольном подкасте</a>, сказав что он позволяет делать сайты, полностью оторваные от Asp.Net и IIS. Не знаю, один ли я страдаю такой неприязнью к IIS, но на данный момент для меня нет антидота: тот релиз Вебшарпера который состоялся недавно еще не поддерживает вторую версию Sitelet&rsquo;ов, в которой как раз и должна быть поддержка создания полностью независимых сайтов. Что-то мне подсказывает, правда, что Адам Границ и компания планируют вообще сделать чуть ли не свой веб-сервер.</p>
<p>Так или иначе, я продолжаю эксперименты с Web#, а как только появятся новые сайтлеты, я начну тестировать все это дело уже на Linux. Интересно, что хоть технология и F#, нельзя сказать что она как-то связана с .Net или Microsoft.</p>
<h3>NetKernel</h3>
<p><img src="http://t2.gstatic.com/images?q=tbn:ANd9GcR4nk9TsFsbj11Nt2PHBYMH8qoedNLzedu7yvv6HuLx5gPR1k8Z" alt="" class="alignright" style="border:0;" align="right" />Во-первых, NK &ndash; это Java-стек, но меня это не пугает т.к. ничего страшного там нет. NK &ndash; это реализация ресурсно-ориентированной парадигмы, которая сейчас будоражит умы всех кто занимается коммуникационными технологиями, например та же комманда WCF. По сути дела, RoC в представлении NK &ndash; это REST&rsquo;ообразная концепция, которая предоставляет как бы аусторсинг веб-архитектуры, позволяя разработчикам писать компоненты, которые работают через ресурсы, запросы на ресурсы, конверсию различных типов ресурсов, и так далее.</p>
<p>NK это, если хотите, эволюция REST, и является интересной технологией (более живой чем существующие .Net аналоги) которая понравится тем, кто доселе работал с такими вещами как WCF REST.</p>
<h3>Семантический Веб</h3>
<p>Про семантический веб я <a href="http://nesteruk.wordpress.com/2010/12/12/a-few-words-on-semantic-web/" title="http://nesteruk.wordpress.com/2010/12/12/a-few-words-on-semantic-web/">уже писал</a>, поэтому ограничусь конкретикой, а именно теми библиотеками, которые применимы к данной задаче.</p>
<p>Во-первых, это <a href="http://www.dotnetrdf.org/" title="http://www.dotnetrdf.org/">DotNetRdf</a> &ndash; собственно библиотека, которая позволяет работать с RDF и поддерживает различные форматы хранилищ. Кстати, недавно нашел в блоге <a href="http://blog.abodit.com/2011/01/a-semantic-web-ontology-triple-store-built-on-mongodb/" title="http://blog.abodit.com/2011/01/a-semantic-web-ontology-triple-store-built-on-mongodb/">попытку создания</a> semantic triple store на MongoDB.</p>
<p>Еще один аспект моих исследований связан уже с конкретикой, а именно с онтологией <a href="http://www.heppnetz.de/projects/goodrelations/" title="http://www.heppnetz.de/projects/goodrelations/">Good Relations</a> и ее нынешней поддержкой гуглом (их Rich Snippets). Изначально у меня была идея попробовать подобавляеть поддержку всего этого в <a href="http://activemesa.com/r2p" title="http://activemesa.com/r2p">R2P</a> чтобы с этим было легче работать, но потом я узнал что модели Xml и Html в моем любимом Решарпере не имеют общего корня, что означает что, по сути дела, все пришлось бы делать дважды. Возможно когда-нибудь у меня дойдут до этого руки.</p>
<p>Так вот, в попытках найти возможность создать .Net объектную модель из OWL-файла, описывающего GR, я набрел на <a href="http://rowlex.nc3a.nato.int/" title="http://rowlex.nc3a.nato.int/">проект ROWLEX</a>, в котором поставляется утилита именно для этого. Интересно, а можно ли как-то автоматически брать данные со страниц, записывать их в эту модель и потом заталкивать все в MongoDB без каких-либо лишних действий? Подозреваю что все несколько сложнее&hellip;</p>
<h3>MindTouch</h3>
<p><img src="http://t2.gstatic.com/images?q=tbn:ANd9GcSRdCfnPy473CyduJ48wFbv0fv5qDkZ8S2E-wY_AgMyU9kAWG3D" alt="" style="border:0;" class="alignright" align="right" />Я занимался исследованием <a href="http://mindtouch.com" title="http://mindtouch.com">MindTouch</a> в двух направлениях &ndash; в попытке понять, можно ли использовать эту штуку для документирования API большого программного продукта, а также мне хотелось понять, можно ли использовать его вместо SharePoint для внутренних целей.</p>
<p>По первому вопросу у меня нет ответа. Бесплатная версия MT шикарна, и покрывает 99% того что мне лично нужно. Поэтому в личных целях я начал ее использовать. Что же касается построения на нем портала разработчиков, то тут все неоднозначно. Я не decision maker в данном вопросе, но лично меня никто не убедил отдавать за коммерческий вариант этой штуки большие деньги.</p>
<p>Я рекоммендую всем скачать MindTouch Core (бесплатную версию) и поиграть с ней. Это действительно стоит того! Это по сути дела Wiki/CMS которая хорошо подходит для документации. Чудес в этом мире не бывает, но штука красивая, и я ей доволен.</p>
<h3>TidePowerd GPU.NET</h3>
<p>Поскольку несколько лет назад я плотно занимался GPGPU и даже сам эксплуатировал pixel shader&rsquo;ы через Direct3D, наличие .Net библиотеки мне импонирует &ndash; давно пора. Тем более что трансляция IL во что-то еще &ndash; процесс весьма понятный и реализуемый без особых проблем. Библиотека <a href="http://www.tidepowerd.com/" title="http://www.tidepowerd.com/">GPU.Net</a> &ndash; это как раз оно и есть. Еще одна абстракция чтобы облегчить нам жизнь.</p>
<p><del>Признаюсь что я только лишь посмотрел вебинар &ndash; я не игрался еще с самой библиотекой т.к. не было времени. Все впереди :)</del><strong>Update: </strong>уже успел созвониться с директором Tidepowerd &ndash; разговор шел в основном в ключе поддержки конкретно F# в GPU.NET. Заинтересованность определенно есть, так что рано или поздно замутим совместный конференс с Саймом, Границем, и партнерами. Как что состоится &ndash; обязательно напишу.</p>
<h3>Fusion IO</h3>
<p><a href="http://www.fusionio.com/" title="http://www.fusionio.com/">Fusion IO</a> &ndash; компания, которая за 3 года получила 300 миллионов долларов инвестиций. Их &ldquo;фишка&rdquo; &ndash; высокоскоростные хранилища данных, и когда я говорю &ldquo;хранилище&rdquo;, подразумевается PCI-карта с SSD-устройствами на ней. Конечно, Fusion IO говорит что их устройства &ndash; это <em><font face="Candara" />не</font></em> SSD, но на самом деле их отличие в качественном ПО (в плане прошивки их ASIC), а есть ли у них что-то кардинально новое &ndash; не знаю. Надо получить образец (надеюсь дадут) и самому посмотреть.</p>
<p>Хотя если по мне, так более интересной фишкой является <a href="http://ru.wikipedia.org/wiki/Nvidia_Tegra" title="http://ru.wikipedia.org/wiki/Nvidia_Tegra">NVidia Tegra</a> &ndash; нам уже 10 лет назад нужно было иметь нормальные <a href="http://en.wikipedia.org/wiki/System-on-a-chip" title="http://en.wikipedia.org/wiki/System-on-a-chip">SoC</a>-решения. Те же Fusion IO могли бы засунуть на свои карты контроллер и несколько FPGA которые я бы мог &ldquo;флэшить&rdquo; и им цены бы не было! Вот интересно &ndash; Intel уже начал нервничать или еще нет? Ведь по мне так самое главное это избавиться от ситуации когда я не могу иметь масштабно-инвариантную систему, а должен на каждый процессор закупать еще и материнскую плату, память, жесткий диск, и так далее. Надеюсь скоро эти телодвижения станут пережитками прошлого.</p>
<p>Кстати о Tegra&hellip; двухъядерные процессоры в мобильных телефонах это круто или как?</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/net/f/'>f#</a>, <a href='http://nesteruk.wordpress.com/category/gpu/'>GPU</a>, <a href='http://nesteruk.wordpress.com/category/hardware/'>Hardware</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/dotnetrdf/'>dotnetrdf</a>, <a href='http://nesteruk.wordpress.com/tag/good-relations/'>good relations</a>, <a href='http://nesteruk.wordpress.com/tag/gpu-net/'>gpu.net</a>, <a href='http://nesteruk.wordpress.com/tag/mindtouch/'>mindtouch</a>, <a href='http://nesteruk.wordpress.com/tag/netkernel/'>netkernel</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/694/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/694/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/694/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/694/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/694/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/694/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/694/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/694/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=694&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/01/07/tech-on-my-plate/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://nesteruk.org/pix/0/1ac970e1-40cf-4dc7-ac88-adc39a02a8e5.png" medium="image" />

		<media:content url="http://t2.gstatic.com/images?q=tbn:ANd9GcR4nk9TsFsbj11Nt2PHBYMH8qoedNLzedu7yvv6HuLx5gPR1k8Z" medium="image" />

		<media:content url="http://t2.gstatic.com/images?q=tbn:ANd9GcSRdCfnPy473CyduJ48wFbv0fv5qDkZ8S2E-wY_AgMyU9kAWG3D" medium="image" />
	</item>
		<item>
		<title>Полезный набор Live Template&#8217;ов</title>
		<link>http://nesteruk.wordpress.com/2011/01/03/useful-live-templates/</link>
		<comments>http://nesteruk.wordpress.com/2011/01/03/useful-live-templates/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 00:41:01 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[ReSharper]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=690</guid>
		<description><![CDATA[Я уверен, что многие из вас видели огромное количество open-source проектов, которые предлагают наборы сниппетов для Visual Studio. С одной стороны, конечно, подобные проекты &#8211; пустая трата времени обычного разработчика, т.к., говоря образно, к вам в монастырь приходит некто со своим уставом и диктует, что для счастливой и вечной жизни вам нужно таки заучить несколько [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=690&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Я уверен, что многие из вас видели огромное количество open-source проектов, которые предлагают наборы сниппетов для Visual Studio. С одной стороны, конечно, подобные проекты &ndash; пустая трата времени обычного разработчика, т.к., говоря образно, к вам в монастырь приходит некто со своим уставом и диктует, что для счастливой и вечной жизни вам нужно таки заучить несколько комманд, которые вы потом будете использовать. Согласитесь, не глупо ли?</p>
<p>Но применения у снипетов есть, причем не частные а именно общие. И этот пост &ndash; попытка продемонстрировать набор темплейтов, который может пригодиться каждому.</p>
<h3>Предыстория</h3>
<p>Дело это происходило несколькими годами ранее, когда я еще был наивный и глупый и верил в светлое безкризисное будущее. В то время, мне в голову стукнула идея попробовать как-то расширить механизм сниппетов дабы попробовать попередавать в сниппеты параметры. Поскольку делать это в принципе невозможно (сорри!), в результате я обратился к кодогенерации, <a href="http://csn.codeplex.com/" title="http://csn.codeplex.com/">замутил проект</a> и даже опубликовал на CodeProject <a href="http://www.codeproject.com/KB/cs/gensnippets.aspx" title="http://www.codeproject.com/KB/cs/gensnippets.aspx">не очень то популярную статью</a>.</p>
<p><strong>Идея была хорошая, но в результате получился трэш.</strong> И я бы рад забыть про эту идею не наткнись я, уже в 2010м году, на программу под названием CodeRush. Эта программа &ndash; плагин для производительности для Visual Studio &ndash; основной своей фичей мнит как раз реализацию удобых темплейтов которые позволяют&hellip; ну, по сути дела они делают то же что и обычные сниппеты для студии, но с одним капитальным различием.</p>
<p><strong>В CodeRush используются только стандартные конструкции.</strong> Например, шорткаты для создания класса, метода, свойства. Написав <code>c</code>, создается класс. Написав <code>ms</code>, создается метод, который возвращает строку. А написав, например, <code>pl.s</code>, создается свойство типа <code>List&lt;string&gt;</code>.</p>
<p>Все подобные конструкты мы создаем каждый день в нашей работе. Это вещи, которые могут сэкономить массу времени людям которые, например, имея отличные знания C# не очень ориентируются в том как создавать типы на F#. <strong>И тут меня осенило.</strong> Ведь я, фактически, могу сам создать свой стандартный словарь сокращений для различных .Net-конструктов, выбрав те механизмы и типы, который лично я считаю наиболее удобными. Более того, я могу воспользоваться всей мощью мною любимого Решарпера, дабы иметь доступ к дополнительной, нужной мне информации &ndash; например к названию типа, в котором я сейчас нахожусь.</p>
<p>И понеслось&hellip;</p>
<h3>Стандартный Словарь</h3>
<p>Первым делом, мне пришлось выбрать те основные конструкты, которые будут доступны пользователю. Я выбрал следующие:</p>
<ul>
<li>
<p><code>class</code></p>
</li>
<li>
<p><code>static class</code></p>
</li>
<li>
<p><code>interface</code></p>
</li>
<li>
<p><code>struct</code></p>
</li>
<li>
<p><code>enum</code></p>
</li>
<li>
<p><code>abstract class</code></p>
</li>
<li>
<p>Тестовый класс (с аттрибутом <code>TestFixture</code> и дефолтным методом с аттрибутом <code>Test</code>)</p>
</li>
</ul>
<p>Что касается начинки класса, то мне понравились следующие элементы:</p>
<ul>
<li>
<p>Private field</p>
</li>
<li>
<p>Private static field</p>
</li>
<li>
<p>Private readonly field</p>
</li>
<li>
<p>Public method</p>
</li>
<li>
<p>Test method (то же самое что и public method, но помечен как <code>[Test]</code>)</p>
</li>
<li>
<p>Auto-property (другие типы свойств делать не захотелось т.к. это уже реализовано в Решарпере через рефакторинги)</p>
</li>
<li>
<p>Dependency property (то же самое что <code>propdp</code> в студии, только не надо писать лишний раз имя содержащего класса)</p>
</li>
</ul>
<p>Теперь что касается типов. На вкус и цвет, как говориться, товарищей нет, поэтому в плане примитивных <code>ValueType</code> все может и понятно, а вот из reference types пришлось выбирать. В результате получилось вот это:</p>
<ul>
<li>
<p>Примитивные типы: <code>bool, char, float, byte, double, int, string, long, uint, Guid, DateTime</code></p>
</li>
<li>
<p>Более сложные типы: <code>Exception, StringBuilder, List&lt;T&gt;, HashSet&lt;T&gt;</code> (на самом деле не уверен что конкретно этот тип много кто использует), <code>Dictionary&lt;T,U&gt;</code></p>
</li>
</ul>
<p>Вполне очевидно, что пользователи могут предпочесть другие типы, но я не могу поддержать их все. Один тип, который я решил поддержать отдельно &ndash; это <code>IEnumerable&lt;T&gt;</code>. Помните я публиковал небольшой пост о <a href="http://nesteruk.wordpress.com/2010/09/28/possible-csharp-5-features/" title="http://nesteruk.wordpress.com/2010/09/28/possible-csharp-5-features/">возможных фичах C#5</a>? Так вот, оттуда я вычерпнул идею превратить <code>~</code> (тильду) в аналог IEnumerable. На практике, это значит что написав <code>m~s</code> вы получите метод, который возвращает <code>IEnumerable&lt;string&gt;</code>.</p>
<h3>Реализация</h3>
<p>Первое, что я сделал &ndash; это взял типичный шаблон Решарпера и пропустил через <code>XSD.EXE</code>, получив объектное представление. После этого, сделал для каждой концепции массив, и поместил все во вложенные циклы: типы объектов (класс, метод, и т.д.), типы значения, различные вариации вроде массивов или <code>Nullable</code>.</p>
<p>Отдельный код с циклом создал и для дженериков, чтобы был вариант как задать тип руками <code>List&lt;MyType&gt;</code>, так и сделать &ldquo;шаблоный&rdquo; тип &ndash; например <code>vl.s</code> делает <code>List&lt;string&gt;</code>.</p>
<p>Остальное все дело техники. Создать XML-файл из готовых кусочков совсем несложно, на самом деле. Правда результат получился немаленький &ndash; аж 1Мб (на текущий момент) шаблонов, в количестве где-то 1200 штук. И это, понятное дело, еще не все &ndash; ведь будут новые идеи, захочется добавлять полезные фичи. Но это как пойдет.</p>
<h3>Дайте Мне Скорее!</h3>
<p>Скачать все темплейты можно <a href="http://nesteruk.org/files/CommonLiveTemplates.xml" title="http://nesteruk.org/files/CommonLiveTemplates.xml">тут</a>. Чтобы их установить, сначала идем в меню ReSharper&rarr;Live Templates, потом в открывшемся окне нажимаем кнопочку Import, выбираем XML-файл. И ждем. Долго. Очень долго. Ведь шаблонов &ldquo;за тыщу&rdquo;. Ну а потом собственно пользуемся.</p>
<p>Вообщем, шаблон я выложил, но это work in progress, так что если что &mdash; пишите комментарии! Спасибо!</p>
<hr />
<p><strong>P.S.</strong> С Новым 2011м Годом! Я на самом деле не склонен подводить итоги, поэтому скажу кратко &ndash; я даже не 2010й год отдельно рассматриваю, а полосу 2008-2010, в которой, увы, было очень мало радостей &ndash; а точнее, почти не было. И хоть и хочется сказать что &ldquo;кризис ушел&rdquo;, на самом деле это, конечно же не так. Но не знаю как вам, а лично мне остается одно: работать, работать, работать.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a>, <a href='http://nesteruk.wordpress.com/category/c/'>C#</a>, <a href='http://nesteruk.wordpress.com/category/resharper/'>ReSharper</a>  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/690/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/690/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/690/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=690&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2011/01/03/useful-live-templates/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Горячая подмена в .Net приложениях</title>
		<link>http://nesteruk.wordpress.com/2010/12/29/hot-swap/</link>
		<comments>http://nesteruk.wordpress.com/2010/12/29/hot-swap/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 22:03:54 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[resharper]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=686</guid>
		<description><![CDATA[Дело было вечером, делать было нечего, вот и решил я написать еще один сугубо технический пост про то, как делать &#8220;горячую подмену&#8221; сборок в приложениях. Напомню, что это уже второй пост на эту тему (вот первый), но в этом посте я хочу более детально рассказать (не вдаваясь в самые мясистые детали) о том, что же [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=686&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Дело было вечером, делать было нечего, вот и решил я написать еще один сугубо технический пост про то, как делать &ldquo;горячую подмену&rdquo; сборок в приложениях. Напомню, что это уже второй пост на эту тему (вот <a href="http://nesteruk.wordpress.com/2010/11/11/dynamic-prototyping/" title="http://nesteruk.wordpress.com/2010/11/11/dynamic-prototyping/">первый</a>), но в этом посте я хочу более детально рассказать (не вдаваясь в самые мясистые детали) о том, что же такое горячая подмена и как она делается.</p>
<h3>Суть задачи</h3>
<p>Я пишу плагин для Решарпера. Чтобы заниматься отладкой этого плагина, мне нужно запускать дополнительный инстанс Visual Studio, который занимает нехилое кол-во времени при стартапе. И понятное дело что при каждом изменении с моей стороны нужно запускать этот процесс снова, благо Edit &amp; Continue &ndash; это миф, и там реально ничего не работает.</p>
<p>Мне это не нравится. Я хочу чтобы было лучше.</p>
<p>В частности, я хочу редактировать плагин прямо при исполнении и чтобы &ldquo;все работало&rdquo;. Сразу. Без задержек. И тут-то возникают проблемы.</p>
<h3>Как это решается сейчас</h3>
<p>Допустим у меня есть некий класс который наследует от <code>BulbItemImpl</code> &mdash; не важно что это за класс, суть не важна. Важно, в основном то, что этот класс создают другие мои классы в плагине примерно вот так:</p>
<p><pre class="brush: csharp;">
// вот мой класс
class MyItem : BulbItemImpl
{
  ...
}
 
// и вот как я его создаю
var i = new MyItem(...);
</pre>
<p>Соответственно если я хочу подменить реализацию <code>MyItem</code>, я не смогу больше делать <code>new</code>, т.к. в том случае будет создаваться <em><font face="Trebuchet MS" />старый</font></em> MyItem, а не новый.</p>
<h3>Вклиниваем контейнер</h3>
<p>Следовательно, я делаю небольшой трик: без особого детерминизма я втыкаю Unity как статический класс с соответствующим набором extension методов:</p>
<p><pre class="brush: csharp;">
public static class ContainerExtensions
{
  static UnityContainer container;
  
  static ContainerExtensions()
  {
    container = new UnityContainer();
  }
  
  static TBase Get&lt;TBase,TImpl&gt;(this object o, params object [] args)
  {
    return container.Resolve&lt;TBase&gt;(typeof(TImpl).Name, new InjectionConstructor(args));
  }
  
  static void Set&lt;TBase&gt;(this object o, Type implType)
  {
    container.RegisterType(typeof(TBase), implType, typeof(TImpl).Name);
  }
}
</pre>
<p>Вот такое вот шаманство. Ничего странного не находите? Как насчет <code>typeof(TImpl).Name</code>? Давайте поясню что тут происходит. У нас <em><font face="Trebuchet MS" />много</font></em> классов наследуют от <code>BulbItemImpl</code>, следовательно нам как бы некошерно просто делать <code>container.RegisterType&lt;BulbItemImpl,MyItem&gt;</code> потому что эта регистрация будет 100 раз перекрыта. Поэтому мы делаем <em><font face="Trebuchet MS" />именную</font></em> регистрацию по имени типа конечного результата. Это будет полезно дальше.</p>
<h3>Делаем Impl-прослойку</h3>
<p>Итак, у нас есть класс который выглядит, например, вот так:</p>
<p><pre class="brush: csharp;">
public sealed class RequireOrEnsureBulbItem : BulbItemImpl
{
    // Fields
    private readonly string block;
    private readonly IMethodDeclaration method;
    private readonly ICSharpContextActionDataProvider provider;
    private readonly string text;
    // Methods
    public RequireOrEnsureBulbItem(ICSharpContextActionDataProvider provider, IMethodDeclaration method, string text, string block);
    protected override Action&lt;ITextControl&gt; ExecuteTransaction(ISolution solution, IProgressIndicator progress);
    // Properties
    public override string Text { get; }
}
</pre>
<p>Соответственно, мы берем и переименовываем этот класс, добавляя префикс <code>Impl</code>.</p>
<p>Теперь, берем и делаем его копию. Копия эта является прозрачным прокси поверх оригинала. Копия содержит инстанс <code>Impl</code>-типа:</p>
<p><pre class="brush: csharp;">
private BulbItemImpl impl;
</pre>
<p>который инициализируется в конструкторе:</p>
<p><pre class="brush: csharp;">
public RequireOrEnsureBulbItem(ICSharpContextActionDataProvider provider,
  IMethodDeclaration method, string text, string block)
{
  impl = this.Get&lt;BulbItemImpl,RequireOrEnsureBulbItemImpl&gt;(
    provider, method, text, block);
}
</pre>
<p>и используется для всех пробросов вызовов методов (в т.ч. свойств), например</p>
<p><pre class="brush: csharp;">
public override string Text { get { return impl.Text; } }
</pre><br />
<h3>Что дальше?</h3>
<p>Мы только что разделили один класс на интерфейс, который загружается единожды, и реализацию, которую можно, в принципе, менять в контейнере. Но как? На самом деле &ndash; очень просто. Для начала давайте решим как мы будем знать что можно редактировать а что нет. Лучший способ &ndash; пометить это типы (это <em><font face="Trebuchet MS" />сгенерированные</font></em> <code>Impl</code>-типы) каким-нибудь аттрибутом вроде <code>[Editable]</code>. Тогда мы будем всегда знать <em><font face="Trebuchet MS" />что</font></em> можно генерировать а что нет.</p>
<p>Теперь берем, и как я уже описал, открываем редактор на этот <code>Impl</code>-тип. Следует помнить что редактируем мы тип <em><font face="Trebuchet MS" />без названия</font></em> <code>Impl</code>, т.к. только для него у нас есть сорцы. Мы ничего не переименовываем, а просто создаем новый тип (наследующий, в данном примере, от <code>BulbItemImpl</code>) и регистрируем его в контейнере.</p>
<p><pre class="brush: csharp;">
this.Set&lt;BulbItemImpl&gt;(GeneratedType);
</pre>
<p>Теперь, по новому запросу будет выдаваться новый тип, в то время как если старый тип загружен где-то в памяти, мы будет продолжать им пользоваться.</p>
<h3>Заключение</h3>
<p>То что я описал выше &ndash; это и есть &ldquo;горячая подмена&rdquo; функционала. С помощью нее я могу редактировать плагин прямо в момент исполнения, проверять API, тестировать новые идеи и при этом не напрягаться с перезапуском отладчика. Понятное дело что отладка динамически сгенерированных сборок у меня не работает (не напрягаюсь я на тему PDB), но это не так критично как получить ответ на простой вопрос &ldquo;работает оно или нет?&rdquo;.</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/net/'>.NET</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/resharper-2/'>resharper</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/686/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/686/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/686/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=686&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2010/12/29/hot-swap/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>
	</item>
		<item>
		<title>Немного о Семантических Сетях</title>
		<link>http://nesteruk.wordpress.com/2010/12/12/a-few-words-on-semantic-web/</link>
		<comments>http://nesteruk.wordpress.com/2010/12/12/a-few-words-on-semantic-web/#comments</comments>
		<pubDate>Sun, 12 Dec 2010 18:53:16 +0000</pubDate>
		<dc:creator>Dmitri</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[metadata]]></category>
		<category><![CDATA[rdfa]]></category>
		<category><![CDATA[semantic web]]></category>

		<guid isPermaLink="false">http://nesteruk.wordpress.com/?p=677</guid>
		<description><![CDATA[Современные стандарты представления данных в интернете разработаны в основном не для машин, а именно для людей. Так, например, написав информацию о себе в таблице HTML я могу передать эту информацию другим людям, но компьютер воспримет её просто как текст. Тэги в этой статье компьютер видит не как теги, а как простые ссылки. Иначе говоря, обычная [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=677&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Современные стандарты представления данных в интернете разработаны в основном не для машин, а именно для людей. Так, например, написав информацию о себе в таблице HTML я могу передать эту информацию другим людям, но компьютер воспримет её просто как текст. Тэги в этой статье компьютер видит не как теги, а как простые ссылки. Иначе говоря, обычная верстка не дает достаточной информации для того чтобы компьютер мог самостоятельно разобраться в том, что же за данные вывешены у меня на сайте.</p>
<p>В этом посте я хочу коротко описать концепцию <em><font face="Trebuchet MS" />семантической сети</font></em> и поговорить о некоторых методах ее реализации. Этот пост коротко резюмирует результаты моих исследований за последние несколько недель.</p>
<p><img src="http://culturalsemanticweb.files.wordpress.com/2006/10/pic_fivea.JPG?w=700" alt="" class="aligncenter" /></p>
<h3>Нехватка данных</h3>
<p>Когда я говорю что компьютеру не распознать что значит информация у меня на сайте &ndash; я лукавлю. Если вы&mdash;Яндекс, вы можете просто нанять толпу С++ программистов которые понапишут вам массу алгоритмов, которые научат систему разпознавать тип данных прямо по его содержимому. На сегодняшний день, этот подход неизбежен, но нельзя сказать что этому нет альтернатив.</p>
<p>Одна вполне вменяемая альтернатива &ndash; это когда автор сайта сам &ldquo;подсказывает&rdquo; системе какие данные как воспринимать. Например, Google любит данные в форматах <a href="http://googlewebmastercentral.blogspot.com/2009/05/introducing-rich-snippets.html" title="http://googlewebmastercentral.blogspot.com/2009/05/introducing-rich-snippets.html">Google Rich Snippets</a>. Наличие данных в этих форматах позволяет Гуглу, например, показывать на поисковой странице рейтинг товара или его цену.</p>
<p>
  <img class="aligncenter" src="http://nesteruk.files.wordpress.com/2010/12/09-5-10droolingdogsnippetmetadatacircled.png?w=300" alt="" style="border:0;" />
</p>
<h3>А зачем?</h3>
<p>Ну вот представьте: у нас есть в интернете куча магазинов, торгующих оргтехникой, например компьютерами. Я знаю что самые хорошие цены в Штатах, и готов <del>воевать</del>дружить с таможней, но мне нужно для начала найти все магазины с определенным товаром, а потом выбрать тот, который является самым &ldquo;приемлимым&rdquo; с точки зрения, например, цены.</p>
<p>И тут возникает проблема: магазины эти не публикуют свои прайс-листы в каком-то универсальном формате. Порой, цены вообще вывешены в табличках, а скачивать все это дело через <code>WebRequest</code>, парсить и интегрировать в BizTalk мне лень &ndash; нет, я <em><font face="Trebuchet MS" />могу</font></em> это сделать, и это кстати является моей &ldquo;продуктовой специализацией&rdquo;, если так можно выразиться, но это болезненно.</p>
<p>Поэтому, я предпочитаю данные которые реализуют известную <em><font face="Trebuchet MS" />онтологию</font></em> (т.е. схему описания данных), такую например как <a href="http://www.heppnetz.de/projects/goodrelations/" title="http://www.heppnetz.de/projects/goodrelations/">Good Relations</a>. Эта онтология позволяет продавцам публиковать <em><font face="Trebuchet MS" />универсальный</font></em> набор данных по своим продуктам. Данные, которые потом <a href="http://www.google.com/support/webmasters/bin/answer.py?answer=186036" title="http://www.google.com/support/webmasters/bin/answer.py?answer=186036">распарсит Google</a> а я, как пользователь, смогу получить из них выписку.</p>
<p>Что интересней, так это то, что при таком раскладе дел, мне Google вообще-то не нужен &ndash; мне нужен свой &ldquo;паук&rdquo; или агент который сам будет шастать по интернету в поисках магазинов с нужной продукцией.</p>
<h3>Механизмы</h3>
<p>Для описания &ldquo;дополнительных&rdquo; данных в структуре сайта есть много вариантов, один из которых называется <a href="http://en.wikipedia.org/wiki/RDFa" title="http://en.wikipedia.org/wiki/RDFa">RDFa</a> или RDF для аттрибутов. Идея тут примерно такая: вместо того, чтобы в сайте создавать <em><font face="Trebuchet MS" />отдельные</font></em> страницы с метаданными, мы <em><font face="Trebuchet MS" />добавляем</font></em> эти данные в уже существующие страницы как атрибуты. Например:</p>
<p><pre class="brush: csharp;">
&lt;div xmlns:dc=&quot;http://purl.org/dc/elements/1.1/&quot;&gt;
   &lt;h2 property=&quot;dc:title&quot;&gt;The trouble with Bob&lt;/h2&gt;
   &lt;h3 property=&quot;dc:creator&quot;&gt;Alice&lt;/h3&gt;
   ...
&lt;/div&gt;
</pre>
<p>Для тех, кому RDFa в новость, у W3C есть неплохой <a href="http://www.w3.org/TR/xhtml-rdfa-primer/" title="http://www.w3.org/TR/xhtml-rdfa-primer/">вводный документ</a>, описывающий технологию более детально. Хотя сама по себе идея, конечно же, примитивна.</p>
<p>На этом этапе вам уже должно быть понятно, что нам просто нужен удобный инструмент, который позволит людям вносить в существующие структуры данных семантическую информацию (semantic annotation). Один из инструментов, который позволит делать это на клиентской стороне &ndash; это <a href="http://aloha-editor.com/" title="http://aloha-editor.com/">редактор Aloha</a>. Проект сам по себе интересный, но возможность семантических аннотаций &ndash; это очень полезно для встраивания в CMS которую можно например поставлять бизнесу для самостоятельного введения данных по продуктам.</p>
<h3>Счастье на сервере</h3>
<p>Что касается клиенской части все понятно &ndash; нам нужно аннотировать XHTML. А что насчет серверной? Тут опять же есть варианты, один из которых предоставят (я надеюсь) авторы <a href="http://www.intellifactory.com/products/wsp/Home.aspx" title="http://www.intellifactory.com/products/wsp/Home.aspx">WebSharper</a>. Для тех кто не знает, поясню что WebSharper &ndash; это аналог GWT на F#. Иначе говоря, идея в том что F# транслируется в HTML+JavaScript+CSS+сторонние библиотеки вроде JQuery. Сейчас WebSharper еще не достиг коммерческого состояния, но у него уже есть две плюшки, которые хочется получить &ldquo;чем скорее тем лучше&rdquo;. Во-первых, это возможность полной отвязки от серверной части, т.е. перевод сайта в чистый JS-driven клиент который может работать на Mono и тем самым освободить нас от обслуживания IIS. Вторая интересная фича &ndash; это возможность создания &ldquo;плагинов&rdquo;, т.е. встраивания кастомных компонент которые изменяют процесс трансформации F# в JavaScript.</p>
<p>Почему это актуально? Элементарно, Ватсон &mdash; нам нужен этот механизм чтобы мы могли создавать решения, которые позволяли бы делать семантические аннотации путем описания всего этого счастья в F#, с дальнейшей эмиссией &ldquo;кошерного&rdquo; HTML. Ведь это всяко лучше чем копаться прямо в HTML, не так ли?</p>
<h3>Заключение</h3>
<p>Понятное дело, что я описал только те аспекты, которые я смог исследовать в данный момент. По мере накопления опыта и знаний будут дополнительные посты на эту тему.</p>
<p>Прошу читателей простить редкость и меньшую содержательность постов &ndash; увы, текущее положение дел такого, что я занимаюсь вещами, в которых разбираюсь на весьма поверхностном уровне. Не то чтобы я жалуюсь на жизнь &ndash; наоборот, это очень весело, и заставляет увидеть мир по-новому.</p>
<p>Ждите скорых обновлений!</p>
<br />Filed under: <a href='http://nesteruk.wordpress.com/category/internet/'>Internet</a> Tagged: <a href='http://nesteruk.wordpress.com/tag/metadata/'>metadata</a>, <a href='http://nesteruk.wordpress.com/tag/rdfa/'>rdfa</a>, <a href='http://nesteruk.wordpress.com/tag/semantic-web/'>semantic web</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/nesteruk.wordpress.com/677/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/nesteruk.wordpress.com/677/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/nesteruk.wordpress.com/677/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/nesteruk.wordpress.com/677/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/nesteruk.wordpress.com/677/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/nesteruk.wordpress.com/677/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/nesteruk.wordpress.com/677/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/nesteruk.wordpress.com/677/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=nesteruk.wordpress.com&amp;blog=373435&amp;post=677&amp;subd=nesteruk&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://nesteruk.wordpress.com/2010/12/12/a-few-words-on-semantic-web/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f01cbd2238e2a78e4c43fa596f51d6a1?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">nesteruk</media:title>
		</media:content>

		<media:content url="http://culturalsemanticweb.files.wordpress.com/2006/10/pic_fivea.JPG" medium="image" />

		<media:content url="http://nesteruk.files.wordpress.com/2010/12/09-5-10droolingdogsnippetmetadatacircled.png?w=300" medium="image" />
	</item>
	</channel>
</rss>
