<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-298035149877685257</id><updated>2012-02-16T16:59:03.036-08:00</updated><category term='Теорема Гёделя'/><category term='Haskell'/><category term='F#'/><category term='новые возможности C#'/><category term='blog English'/><category term='поиск'/><category term='management'/><category term='стандарт C#'/><category term='алгоритмы'/><title type='text'>Nikov's blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>36</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-100054822595597397</id><published>2009-12-27T11:33:00.000-08:00</published><updated>2009-12-27T11:33:36.748-08:00</updated><title type='text'>Старое, но не стареющее :-)</title><content type='html'>&lt;object width="384" height="313"&gt;&lt;param name="movie" value="http://www.youtube.com/v/oP59tQf_njc&amp;hl=en_US&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/oP59tQf_njc&amp;hl=en_US&amp;fs=1" type="application/x-shockwave-flash" width="384" height="313" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-100054822595597397?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/100054822595597397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=100054822595597397' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/100054822595597397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/100054822595597397'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/12/blog-post.html' title='Старое, но не стареющее :-)'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-6051374728239202178</id><published>2009-12-26T09:04:00.001-08:00</published><updated>2009-12-27T11:29:27.137-08:00</updated><title type='text'>Signs</title><content type='html'>&lt;object width="417" height="253"&gt;&lt;param name="movie" value="http://www.youtube.com/v/uy0HNWto0UY&amp;hl=en_US&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/uy0HNWto0UY&amp;hl=en_US&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="417" height="253"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-6051374728239202178?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/6051374728239202178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=6051374728239202178' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/6051374728239202178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/6051374728239202178'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/12/signs.html' title='Signs'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-3914391681034308319</id><published>2009-11-28T06:59:00.000-08:00</published><updated>2009-11-28T06:59:45.958-08:00</updated><title type='text'>Знаете, чьи это фотографии?</title><content type='html'>&lt;img src="http://dl.dropbox.com/u/2637662/Faces/Male/img1350309.jpg"&gt;&lt;img src="http://dl.dropbox.com/u/2637662/Faces/Female/img1350077.jpg"&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-3914391681034308319?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/3914391681034308319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=3914391681034308319' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3914391681034308319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3914391681034308319'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/11/blog-post_28.html' title='Знаете, чьи это фотографии?'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-7441180845227025958</id><published>2009-11-17T03:32:00.000-08:00</published><updated>2009-11-17T03:32:11.320-08:00</updated><title type='text'>Полиномиальная формула простых чисел</title><content type='html'>&lt;a href="http://ru.wikipedia.org/wiki/%D0%9F%D1%80%D0%BE%D1%81%D1%82%D0%BE%D0%B5_%D1%87%D0%B8%D1%81%D0%BB%D0%BE#.D0.9F.D0.BE.D0.BB.D0.B8.D0.BD.D0.BE.D0.BC.D0.B8.D0.B0.D0.BB.D1.8C.D0.BD.D0.B0.D1.8F_.D1.84.D0.BE.D1.80.D0.BC.D1.83.D0.BB.D0.B0"&gt;здесь&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-7441180845227025958?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/7441180845227025958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=7441180845227025958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7441180845227025958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7441180845227025958'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/11/blog-post_17.html' title='Полиномиальная формула простых чисел'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-5904983017640722253</id><published>2009-11-15T12:21:00.000-08:00</published><updated>2009-11-15T12:32:34.964-08:00</updated><title type='text'>Теорема Гёделя в полиномиальной форме</title><content type='html'>&lt;p&gt;Недоказуемому утверждению, о котором говорит теорема Гёделя о неполноте, можно придать вполне осязаемый арифметический вид. А именно: для каждой непротиворечивой теории T можно указать такое целое значение параметра K, что уравнение &lt;img src="http://dl.dropbox.com/u/2637662/ude.png"&gt; не имеет решений в неотрицательных целых числах, но этот факт не может быть доказан в теории T. Более того, для каждой непротиворечивой теории можно найти бесконечное количество таких значений параметра K. Ценой увеличения количества переменных в несколько раз степень этого уравнения может быть понижена до 4. А можно, наоборот, увеличить степень, уменьшив количество переменных до 9. Подробности можно посмотреть в статье &lt;a href="http://www.ams.org/bull/1980-03-02/S0273-0979-1980-14832-6/S0273-0979-1980-14832-6.pdf"&gt;Undecidable diophantine equations&lt;/a&gt; и книге Юрия Матиясевича "Десятая проблема Гильберта".&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-5904983017640722253?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/5904983017640722253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=5904983017640722253' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/5904983017640722253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/5904983017640722253'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/11/blog-post.html' title='Теорема Гёделя в полиномиальной форме'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-4433615382727390351</id><published>2009-10-22T07:53:00.000-07:00</published><updated>2009-10-22T08:17:32.696-07:00</updated><title type='text'>Публикация файлов в Интернете</title><content type='html'>&lt;p align=justify&gt;Вам когда нибудь было нужно опубликовать какой-нибудь документ или архив в интернете, и получить прямую ссылку для его скачивания? Есть несколько сервисов, которые предоставляют такую возможность. Мне приходилось пользоваться &lt;a href="http://www.hotlinkfiles.com/"&gt;hotlinkfiles.com&lt;/a&gt; и &lt;a href="https://www.diino.com/"&gt;diino.com&lt;/a&gt;. Но первый из них ужасно медленный, а второй, к сожалению, сейчас стал платным. Между тем, есть еще один, очень простой и удобный способ. Идем на сайт &lt;a href="http://www.nabble.com/"&gt;nabble.com&lt;/a&gt;, регистрируемся, создаем mailing list с любым названием и получаем адрес для отправки сообщений в него. Потом отправляем туда письмо с аттачментом - и в ответ приходит копия этого письма, в котором аттачмент превратился в общедоступную ссылку для его скачивания. Файлы, ставшие ненужными, можно потом удалить вместе с содержащими их сообщениями через веб-интерфейс.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-4433615382727390351?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/4433615382727390351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=4433615382727390351' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4433615382727390351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4433615382727390351'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/blog-post.html' title='Публикация файлов в Интернете'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-5848215668354379678</id><published>2009-10-19T12:08:00.000-07:00</published><updated>2009-10-19T12:09:41.535-07:00</updated><title type='text'>ReSharper 5.0 EAP</title><content type='html'>&lt;a href="http://www.jetbrains.net/confluence/display/ReSharper/ReSharper+Early+Access+Program"&gt;Начался&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-5848215668354379678?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/5848215668354379678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=5848215668354379678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/5848215668354379678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/5848215668354379678'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/resharper-50-eap.html' title='ReSharper 5.0 EAP'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-4115759563996349562</id><published>2009-10-19T12:07:00.000-07:00</published><updated>2009-10-19T12:08:17.788-07:00</updated><title type='text'>Visual Studio 2010 Ultimate Beta 2</title><content type='html'>&lt;a href="http://download.microsoft.com/download/F/C/0/FC06A506-5F9D-4CD4-9849-17EA49AB30C2/vs_vstsweb.exe"&gt;Качаем&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-4115759563996349562?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/4115759563996349562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=4115759563996349562' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4115759563996349562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4115759563996349562'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/visual-studio-2010-ultimate-beta-2.html' title='Visual Studio 2010 Ultimate Beta 2'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-2766439709454181370</id><published>2009-10-15T09:35:00.000-07:00</published><updated>2009-10-15T09:38:09.318-07:00</updated><title type='text'>IntelliJ IDEA Community Edition</title><content type='html'>&lt;p align="justify"&gt;&lt;a href="http://www.jetbrains.org/pages/viewpage.action?pageId=983211"&gt;IntelliJ IDEA Community Edition&lt;/a&gt; - бесплатно и с открытым исходным кодом.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-2766439709454181370?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/2766439709454181370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=2766439709454181370' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2766439709454181370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2766439709454181370'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/intellij-idea-community-edition.html' title='IntelliJ IDEA Community Edition'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-2731393627015229065</id><published>2009-10-05T09:26:00.000-07:00</published><updated>2009-10-05T09:31:01.627-07:00</updated><title type='text'>Software Transactional Memory .NET</title><content type='html'>&lt;p align=justify&gt;Несколько интересных ссылок:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Software_transactional_memory"&gt;Software Transactional Memory&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/devlabs/ee334183.aspx"&gt;STM.NET&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/stmteam/"&gt;STM.NET Team Blog&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-2731393627015229065?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/2731393627015229065/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=2731393627015229065' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2731393627015229065'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2731393627015229065'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/software-transactional-memory-net.html' title='Software Transactional Memory .NET'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-4024867872394186217</id><published>2009-10-04T06:18:00.000-07:00</published><updated>2009-10-04T06:36:47.646-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Контравариантность в Haskell</title><content type='html'>&lt;p align="justify"&gt;&lt;a href="http://www.rsdn.ru/forum/decl/3557016.1.aspx"&gt;Писал&lt;/a&gt; на форуме про ко-/контравариантность в Scala, и подумал, что в Haskell тоже есть контравариантность, только относительно наследования между классами типов. Например, так как Ord наследуется от Eq, можно написать:&lt;/p&gt;  &lt;div style="overflow: scroll"&gt;   &lt;div style="width: 200%"&gt;&lt;pre&gt;&lt;span style="color: #008000"&gt;{-# LANGUAGE RankNTypes #-}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000FF"&gt;import&lt;/span&gt; List;&lt;br /&gt;&lt;br /&gt;foo :: Eq a =&gt; [a] -&gt; [a]&lt;br /&gt;foo = nub&lt;br /&gt;&lt;br /&gt;bar :: Ord b =&gt; (forall a. Ord a =&gt; [a] -&gt; [a]) -&gt; [b] -&gt; [b]&lt;br /&gt;bar f = sort . f&lt;br /&gt;&lt;br /&gt;x :: Ord b =&gt; [b] -&gt; [b]&lt;br /&gt;x = bar foo&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align="justify"&gt;Пример несколько искусственный, но обратите внимание, как функция foo передается в функцию bar, ожидающую аргумент с более сильным констрейнтом (Ord a), и попробуйте объяснить себе, почему это работает.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-4024867872394186217?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/4024867872394186217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=4024867872394186217' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4024867872394186217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4024867872394186217'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/haskell.html' title='Контравариантность в Haskell'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-1623341480014814557</id><published>2009-10-03T03:45:00.001-07:00</published><updated>2009-10-03T03:45:08.250-07:00</updated><title type='text'>Немного об операторе is</title><content type='html'>&lt;p align="justify"&gt;Как известно, оператор is в C# не всегда ведет себя в соответствии со спецификацией языка. Это результат того, что в рантайме работает команда IL isinst, а у нее свои представления относительно того, какие типы являются assignment compatible. Это сознательное решение, которое в команде компилятора приняли для повышения быстродействия. Однако результаты могут быть весьма странными:&lt;/p&gt;  &lt;div style="overflow: scroll"&gt;   &lt;div style="width: 200%"&gt;     &lt;pre&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;	&lt;span style="color: #0000ff"&gt;static void&lt;/span&gt; Main()&lt;br /&gt;	{&lt;br /&gt;		&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; x = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;[] { 1 };&lt;br /&gt;		Console.WriteLine(x &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DayOfWeek[]); &lt;span style="color: #008000"&gt;// True&lt;/span&gt;&lt;br /&gt;		Console.WriteLine((DayOfWeek[])x); &lt;span style="color: #008000"&gt;// System.Int32[]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;		&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; y = 1;&lt;br /&gt;		Console.WriteLine(y &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; DayOfWeek); &lt;span style="color: #008000"&gt;// False&lt;/span&gt;&lt;br /&gt;		Console.WriteLine((DayOfWeek)y); &lt;span style="color: #008000"&gt;// Monday&lt;/span&gt;&lt;br /&gt;		Console.WriteLine((DayOfWeek?)y); &lt;span style="color: #008000"&gt;// InvalidCastException&lt;/span&gt;&lt;br /&gt;	}&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-1623341480014814557?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/1623341480014814557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=1623341480014814557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1623341480014814557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1623341480014814557'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/10/is.html' title='Немного об операторе is'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-3478820463483707114</id><published>2009-09-16T09:17:00.000-07:00</published><updated>2009-09-16T09:21:06.451-07:00</updated><title type='text'>Проблема и решение</title><content type='html'>&lt;p align=justify&gt;После убивания зависшей студии из Task Manager'а столкнулся с мистической проблемой с TFS:&lt;pre&gt;&lt;br /&gt;Unexpected error encountered. It is recommended that you restart the application as soon as possible.&lt;br /&gt;&lt;br /&gt;Error: The specified module could not be found.&lt;br /&gt;&lt;br /&gt;File: vsee\internal\inc\vscomptr.inl&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;С помощью гугла решение нашлось за 15 секунд &lt;a href="http://blogs.msdn.com/mohamedg/archive/2009/03/18/one-or-more-projects-in-the-solution-could-not-be-loaded.aspx"&gt;здесь&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-3478820463483707114?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/3478820463483707114/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=3478820463483707114' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3478820463483707114'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3478820463483707114'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/09/blog-post.html' title='Проблема и решение'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-7619209082847227251</id><published>2009-09-11T10:12:00.000-07:00</published><updated>2009-09-11T10:18:02.452-07:00</updated><title type='text'>Elevate</title><content type='html'>&lt;p align=justify&gt;Появилась интересная библиотека для .NET - &lt;a href="http://srtsolutions.com/blogs/chrismarinos/archive/2009/08/19/introducing-elevate.aspx"&gt;Elevate&lt;/a&gt;, позиционирущаяся как Boost-like расширение для &lt;a href="http://en.wikipedia.org/wiki/Base_Class_Library"&gt;BCL&lt;/a&gt;. Помимо многого другого, она будет давать возможность делать pattern matching в таких языках, как C# и VB.NET. Скачивать ее исходники можно с &lt;a href="http://elevate.codeplex.com/"&gt;здесь&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-7619209082847227251?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/7619209082847227251/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=7619209082847227251' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7619209082847227251'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7619209082847227251'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/09/elevate.html' title='Elevate'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-2084469809068016121</id><published>2009-06-26T00:43:00.000-07:00</published><updated>2009-06-26T00:47:39.506-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='поиск'/><title type='text'>Bing vs. Google</title><content type='html'>&lt;p align=justify&gt;Сейчас заметил, что &lt;a href="http://google.com/"&gt;Google&lt;/a&gt; не индексирует страницы обсуждения в &lt;a href="http://ru.wikipedia.org/"&gt;Википедии&lt;/a&gt;, а &lt;a href="http://bing.com/"&gt;Bing&lt;/a&gt; индексирует.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-2084469809068016121?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/2084469809068016121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=2084469809068016121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2084469809068016121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2084469809068016121'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/06/bing-vs-google.html' title='Bing vs. Google'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-1030362523731531644</id><published>2009-06-26T00:27:00.000-07:00</published><updated>2009-06-26T00:33:47.450-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='management'/><title type='text'>Разработчики и Эйнштейн</title><content type='html'>&lt;p align=justify&gt;Steve McConnell в своей книге "Software Project Survival Guide" пишет:&lt;blockquote align=justify&gt;Software development is process of continuous discovery and invention. The atmosphere most supportive of that process is one that is relaxed and contemplative. Effective software development requires that developers achieve a level of concentration similar to that of a mathematician or physicist. Can you imagine Albert Einstein sitting at his desk while his manager berates him, "Albert, we need that theory of relatively &lt;i&gt;now&lt;/i&gt;! Hurry up!" Since software developers (&lt;i&gt;ну, по крайней мере, многие из них&lt;/i&gt;) aren’t as smart as Albert Einstein, they need an even more supportive work environment.&lt;/blockquote&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-1030362523731531644?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/1030362523731531644/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=1030362523731531644' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1030362523731531644'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1030362523731531644'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/06/blog-post_26.html' title='Разработчики и Эйнштейн'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-7387635974495588887</id><published>2009-06-24T09:52:00.000-07:00</published><updated>2009-06-24T09:57:25.879-07:00</updated><title type='text'>Задачки по программированию</title><content type='html'>&lt;p align=justify&gt;Если кто-то хочет потренироваться в решении задач по программированию повышенной сложности, то вот хороший список (включает некоторые интересные и малоизвестные задачи): &lt;a href="http://algolist.manual.ru/olimp/"&gt;http://algolist.manual.ru/olimp&lt;/a&gt;. Ну и конечно, немало интересного появляется на &lt;a href="http://www.rsdn.ru/forum/etude/"&gt;http://www.rsdn.ru/forum/etude&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-7387635974495588887?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/7387635974495588887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=7387635974495588887' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7387635974495588887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7387635974495588887'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/06/blog-post_24.html' title='Задачки по программированию'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-842447939338616601</id><published>2009-06-22T05:57:00.000-07:00</published><updated>2009-06-22T06:02:03.507-07:00</updated><title type='text'>Wolfram|Alpha</title><content type='html'>&lt;p align=justify&gt;Около месяца назад компания Wolfram Research запустила онлайновый сервис &lt;a href="http://www.wolframalpha.com/"&gt;Wolfram|Alpha&lt;/a&gt;. Фактически, это огромная база данных из различных областей (туда входит и математика, и физика, и кинематография, и биология, и много что еще), соединенная с движком Wolfram Mathematica для символических вычислений, и модулем по распознаванию запросов на естественном языке (пока только английском). Он довольно хорошо справляется с грамматическими ошибками, опечатками и пропущенными скобками. Умеет догадываться об общем виде последоватьности по ее первым членам, и находить замкнутую форму для действительного числа по его приближенному представлению. Знает множество свойств чисел и геометрических фигур. Примеры запросов, на которые можно получить ответ:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Representations+of+Pi"&gt;Representations of Pi&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=1%2B1%2F4%2B1%2F9%2B1%2F16%2B..."&gt;1+1/4+1/9+1/16+...&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Largest+prime+number"&gt;Largest prime number&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=First+prime+number+greater+than+10!"&gt;First prime number greater than 10!&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Is+E^Pi+algebraic%3F"&gt;Is E^Pi algebraic?&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=What+is+the+volume+of+dodecahedron%3F"&gt;What is the volume of dodecahedron?&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Integer+partitions+of+20"&gt;Integer partitions of 20&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Permutations+of+1%2C2%2C3%2C4"&gt;Permutations of 1,2,3,4&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=24061467864032622473692149727991"&gt;24061467864032622473692149727991&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=5.56832799683170784528481"&gt;5.56832799683170784528481&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=15th+derivative+of+arctan"&gt;15th derivative of arctan&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Roots+of+x^4%2Ba+x^3%2Bx%2B7"&gt;Roots of x^4+a x^3+x+7&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Population+of+Europe"&gt;Population of Europe&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Angles+of+triangle+5%2C12%2C14"&gt;Angles of triangle 5,12,14&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Isotopes+of+iron"&gt;Isotopes of iron&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Lowest+temperature+on+Earth"&gt;Lowest temperature on Earth&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Hemoglobin"&gt;Hemoglobin&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Number+of+cells+in+human+body"&gt;Number of cells in human body&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Number+of+species"&gt;Number of species&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Temperature+of+Ocean%2C+300+m+depth"&gt;Temperature of Ocean, 300 m depth&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=127.0.0.1"&gt;127.0.0.1&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=Intel%2C+AMD"&gt;Intel, AMD&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.wolframalpha.com/input/?i=How+old+was+Bill+Gates+in+2000%3F"&gt;How old was Bill Gates in 2000?&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;&lt;p align=justify&gt;Я разместил их окошко для запросов рядом со своим блогом, так что наслаждайтесь. :)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-842447939338616601?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/842447939338616601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=842447939338616601' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/842447939338616601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/842447939338616601'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/06/wolframalpha.html' title='Wolfram|Alpha'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-942545639433367571</id><published>2009-04-28T06:53:00.000-07:00</published><updated>2009-04-28T07:00:15.442-07:00</updated><title type='text'>Парадокс закономерности</title><content type='html'>&lt;p align=justify&gt;Один из самых интересных парадоксов с вероятностями &lt;a href="http://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%80%D0%B0%D0%B4%D0%BE%D0%BA%D1%81_%D0%B7%D0%B0%D0%BA%D0%BE%D0%BD%D0%BE%D0%BC%D0%B5%D1%80%D0%BD%D0%BE%D1%81%D1%82%D0%B8"&gt;здесь&lt;/a&gt;. Среди опрошенных мной людей мнения о нем разделились примерно поровну. Мне кажется, что я уже понимаю, как его правильно разрешить, но пока промолчу. Пишите свои мнения.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-942545639433367571?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/942545639433367571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=942545639433367571' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/942545639433367571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/942545639433367571'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/04/blog-post.html' title='Парадокс закономерности'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-1417390461494742574</id><published>2009-01-26T06:31:00.000-08:00</published><updated>2009-01-26T08:41:48.865-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Теорема Гёделя'/><category scheme='http://www.blogger.com/atom/ns#' term='алгоритмы'/><title type='text'>Теорема Гёделя для программистов</title><content type='html'>&lt;p align=justify&gt;Рассмотрим какую-нибудь математическую теорию, имеющую формальный язык для записи высказываний, фиксированный набор аксиом и правил вывода из них. Все теоремы такой теории можно получать чисто алгоритмическим путем, многократно применяя правила вывода к аксиомам и уже выведенным теоремам. Рассматриваемая теория должна иметь достаточно богатый язык, позволяющий формализовать понятие алгоритма и его остановки (таким свойством обладает, например, арифметика Пеано). Обозначим выбранную теорию T. Будем говорить, что теория правдива, если она доказывает только истинные высказывания.&lt;/p&gt;&lt;p align=justify&gt;Напишем алгоритм A(F), который принимает высказывание F на формальном языке теории T, перебирает все теоремы этой теории, и останавливается в том и только том случае, если среди них обнаруживается высказывание F (то есть, если высказывание F доказуемо в теории T).&lt;/p&gt;&lt;p align=justify&gt;Заметим, что алгоритмы записываются конечными строками в некотором конечном алфавите, поэтому их можно пронумеровать натуральными числами. Напишем алгоритм B(N, X), который принимает натуральное число N (номер некоторого алгоритма), натуральное число X (входные данные для этого алгоритма), формирует высказывание «алгоритм с номером N не остановится, получив на вход X» на формальном языке теории T и вызывает алгоритм A, передав ему это высказывание. Таким образом, B(N, X) остановится в том и только том случае, если высказывание «алгоритм с номером N не остановится, получив на вход X» доказуемо в теории T.&lt;/p&gt;&lt;p align=justify&gt;Напишем алгоритм C(N), который вызывает B(N, N). Этот алгоритм остановится в том и только том случае, если высказывание «алгоритм с номером N не остановится, получив на вход N» доказуемо в теории T.&lt;/p&gt;&lt;p align=justify&gt;Алгоритму C тоже соответствует некоторый номер K. Напишем алгоритм D, который вызывает C(K).&lt;br /&gt;&lt;p align=justify&gt;Запустим алгоритм D. Он остановится в том и только том случае, если в теории T доказуемо, что он не остановится.&lt;/p&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Если этот алгоритм в действительности остановится, то теория T не правдива (доказывает ложные утверждения).&lt;br /&gt;&lt;li&gt;Если алгоритм в действительности не остановится, то утверждение «алгоритм D не остановится» истинно, но не доказуемо в теории Т.&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-1417390461494742574?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/1417390461494742574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=1417390461494742574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1417390461494742574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1417390461494742574'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2009/01/blog-post.html' title='Теорема Гёделя для программистов'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-2753874865493955986</id><published>2008-12-19T13:39:00.000-08:00</published><updated>2008-12-19T13:47:14.086-08:00</updated><title type='text'>До чего техника дошла!</title><content type='html'>&lt;p align=justify&gt;Вышла Wolfram Research Mathematica 7. Посмотрел &lt;a href="http://www.wolfram.com/broadcast/screencasts/"&gt;презентацию&lt;/a&gt; и &lt;a href="http://www.wolfram.com/products/mathematica/newin7/"&gt;обзор новой функциональности&lt;/a&gt; на их сайте. До чего техника дошла! Казалось, об этом можно только мечтать. Но и стоит эта штуковина тоже прилично: лицензия для нового пользователя около 3000 долларов (для студентов - около 120).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-2753874865493955986?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/2753874865493955986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=2753874865493955986' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2753874865493955986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2753874865493955986'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2008/12/blog-post.html' title='До чего техника дошла!'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-2321261212536900007</id><published>2008-03-13T01:03:00.000-07:00</published><updated>2008-03-13T08:29:49.679-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='стандарт C#'/><title type='text'>Комментарии к стандарту C#</title><content type='html'>&lt;p align=justify&gt;В течение последних нескольких месяцев я работал над комментариями и замечаниями к стандарту C# 3.0 (и эта работа все еще продолжается). В общей сложности получилось несколько сотен комментариев. Возможно, несколько десятков из них попадут в следующее (третье) издание книги &lt;a href="http://www.amazon.com/Programming-Language-Microsoft-NET-Development/dp/0321334434/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1199738024&amp;sr=8-1"&gt;The C# Programming Language&lt;/a&gt;, выпускаемое издательством Addison-Wesley. Если кому-то интересно, я могу выслать по электронной почте полные результаты моей работы.&lt;/p&gt;&lt;div style="background-color: gray; overflow: hidden; height: 1px"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align=justify&gt;Выложил комментарии (в виде документа MS Word в zip-архиве) &lt;a href="http://nikov.diinoweb.com/files/comments.zip"&gt;здесь&lt;/a&gt;. На всякий случай скажу, что текст на английском.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-2321261212536900007?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/2321261212536900007/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=2321261212536900007' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2321261212536900007'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/2321261212536900007'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2008/03/c.html' title='Комментарии к стандарту C#'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-8363774954439254997</id><published>2008-02-12T02:57:00.000-08:00</published><updated>2008-02-12T03:26:13.527-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='новые возможности C#'/><title type='text'>Dynamic lookup в C#</title><content type='html'>&lt;p align=justify&gt;В следующией версии C# планируется добавить возможность помечать блоки кода, в которых производится dynamic lookup. При обращении к какому-либо члену объекта в таком блоке, наличие указанного члена будет проверяться не на этапе компиляции, а во время исполнения. Предполагается, что эта возможность облегчит написание кода для взаимодействия с COM (в частности, с Microsoft Office) и динамически типизированными языками (например, IronRuby и IronPython). Более подробно можно почитать об этом на английском языке в &lt;a href="http://blogs.msdn.com/charlie/archive/2008/01/25/future-focus.aspx"&gt;этом блоге&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-8363774954439254997?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/8363774954439254997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=8363774954439254997' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/8363774954439254997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/8363774954439254997'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2008/02/dynamic-lookup-c.html' title='Dynamic lookup в C#'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-4960860611938812421</id><published>2008-02-03T06:47:00.000-08:00</published><updated>2008-02-03T06:52:06.456-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog English'/><title type='text'>My New Blog in English</title><content type='html'>По просьбам моих англоязычных друзей и коллег я начинаю писать заметки на английском. Они будут расположены на отдельной страничке: &lt;a href="http://nikov-thoughts.blogspot.com/"&gt;http://nikov-thoughts.blogspot.com&lt;/a&gt;. Обещаю много интересного. Можете оставлять там свои комментарии на английском языке.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-4960860611938812421?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/4960860611938812421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=4960860611938812421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4960860611938812421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4960860611938812421'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2008/02/my-new-blog-in-english.html' title='My New Blog in English'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-3301996059776280030</id><published>2007-11-12T03:55:00.000-08:00</published><updated>2007-11-12T04:03:42.575-08:00</updated><title type='text'>Immutable types в C#</title><content type='html'>В последнее время много говорится о функциональном программировании применительно к .NET, поэтому я решил дать пару интересных ссылок:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Eric Lippert, один из разработчиков C#, &lt;a href="http://blogs.msdn.com/ericlippert/archive/2007/10/04/path-finding-using-a-in-c-3-0-part-two.aspx"&gt;пишет&lt;/a&gt; на своем блоге: &lt;i&gt;Immutable data structures are the way of the future in C#&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Joe Duffy &lt;a href="http://www.bluebytesoftware.com/blog/PermaLink,guid,58392086-9f4c-4e0c-82ff-05b090c09f04.aspx"&gt;рассуждает&lt;/a&gt; о том, как аннотация атрибутами и статический анализ могли бы использоваться для поддержки immutable types&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-3301996059776280030?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/3301996059776280030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=3301996059776280030' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3301996059776280030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3301996059776280030'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/11/immutable-types-c.html' title='Immutable types в C#'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-547350031348210485</id><published>2007-11-08T00:14:00.000-08:00</published><updated>2007-11-08T00:17:09.120-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='F#'/><title type='text'>Обзор языка F#</title><content type='html'>Сегодня нашел замечательный &lt;a href="http://tomasp.net/articles/fsharp-i-introduction/article.pdf"&gt;обзор языка F#&lt;/a&gt;. Если кто еще не знает, скажу, что это мультипарадигменный язык программирования из ML-семейства под платформу .NET, поддерживающий и функциональное и объектно-ориентированное программирование.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-547350031348210485?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/547350031348210485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=547350031348210485' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/547350031348210485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/547350031348210485'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/11/f.html' title='Обзор языка F#'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-7217291707233399003</id><published>2007-11-07T08:44:00.000-08:00</published><updated>2007-11-07T08:45:33.293-08:00</updated><title type='text'>Почему не удалось реализовать стандарт C# 3.0</title><content type='html'>Eric Lippert, один из разработчиков C#, &lt;a href ="http://blogs.msdn.com/ericlippert/archive/2007/11/05/c-3-0-return-type-inference-does-not-work-on-member-groups.aspx"&gt;пишет на своем блоге&lt;/a&gt;, почему в финальном варианте C# 3.0 не удалось реализовать некоторые сценарии вывода типов, закрепленные в черновике стандарта.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-7217291707233399003?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/7217291707233399003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=7217291707233399003' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7217291707233399003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/7217291707233399003'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/11/c-30.html' title='Почему не удалось реализовать стандарт C# 3.0'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-1830509389659622454</id><published>2007-11-05T23:49:00.000-08:00</published><updated>2007-11-05T23:52:40.989-08:00</updated><title type='text'>ILX</title><content type='html'>Интересную вещь сделали в Microsoft Research: &lt;a href="http://research.microsoft.com/projects/ilx/babel01.pdf"&gt;ILX&lt;/a&gt; - расширение &lt;a href="http://ru.wikipedia.org/wiki/Microsoft_Intermediate_Language"&gt;IL&lt;/a&gt; для функциональных языков.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-1830509389659622454?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/1830509389659622454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=1830509389659622454' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1830509389659622454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1830509389659622454'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/11/ilx.html' title='ILX'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-1169857449077273490</id><published>2007-11-05T12:51:00.000-08:00</published><updated>2007-11-05T12:53:37.950-08:00</updated><title type='text'>Сравнение языков программирования</title><content type='html'>Создал в Википедии статью &lt;a href="http://ru.wikipedia.org/wiki/Сравнение_языков_программирования"&gt;Сравнение языков программирования&lt;/a&gt;. Пожалуйста, исправляйте и дополняйте ее.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-1169857449077273490?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/1169857449077273490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=1169857449077273490' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1169857449077273490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/1169857449077273490'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/11/blog-post.html' title='Сравнение языков программирования'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-4316695781109943533</id><published>2007-11-05T08:10:00.000-08:00</published><updated>2007-11-05T08:17:12.750-08:00</updated><title type='text'>Отслеживание развития проекта Nemerle</title><content type='html'>Развитие проекта Nemerle (а именно, логи коммитов в репозиторий) можно отследить здесь: &lt;a href="http://cia.vc/stats/project/Nemerle"&gt;http://cia.vc/stats/project/Nemerle&lt;/a&gt;. Как видно, проект продолжает жить и развиваться.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-4316695781109943533?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/4316695781109943533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=4316695781109943533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4316695781109943533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4316695781109943533'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/11/nemerle.html' title='Отслеживание развития проекта Nemerle'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-3672939607913669400</id><published>2007-03-10T07:48:00.000-08:00</published><updated>2007-03-12T02:48:00.758-07:00</updated><title type='text'>Сравнение объектов в .NET</title><content type='html'>&lt;p align=justify&gt;За последнее время возникло несколько задач, которые заставили меня размышлять о возможных способах сравнения объектов в .NET, и я решил опубликовать часть своих размышлений.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Разумеется, в объектно-ориентированном мире понятие "равные объекты" может иметь различный смысл. В простейшем случае речь идет о ссылочном равенстве, которое проверяется с помощью статического метода &lt;nobr&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.object.referenceequals.aspx"&gt;object.ReferenceEquals&lt;/a&gt;&lt;/nobr&gt; или встроенного в C# &lt;nobr&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/53k8ybth.aspx"&gt;оператора ==&lt;/a&gt;&lt;/nobr&gt; для объектов. Речь может идти и о сравнении "внутренней структуры". Для этой цели многие типы переопределяют виртуальный метод &lt;a href="http://msdn2.microsoft.com/en-us/library/bsc2ak47.aspx"&gt;Equals&lt;/a&gt; класса &lt;nobr&gt;System.Object.&lt;/nobr&gt; Существует также удобный статический метод &lt;nobr&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/w4hkze5k.aspx"&gt;object.Equals&lt;/a&gt;&lt;/nobr&gt; с двумя аргументами, который осуществляет проверку в несколько этапов. Сначала он проверяет свои аргументы на ссылочное равенство, возвращая true в случае успеха. Затем, если оба аргумента не равны null, сравнивает их, вызывая экземплярный метод Equals у левого аргумента и возвращая его результат. Наконец, он возвращает false, если только один из аргументов равен null. Таким образом, за выбор алгоритма сравнения в данном случае "отвечает" левый аргумент.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Давайте для начала обсудим вопрос сравнения массивов. Массивы не переопределяют экземплярный метод Equals, поэтому его использование для сравнения массивов даст такой же результат, как и их сравнение на ссылочное равенство. Поэтому мы попробуем написать алгоритм сравнения массивов самостоятельно. В первую очередь нам надо убедиться, что два массива имеют одинаковый тип, что подразумевает, что они имеют одинаковое число измерений (пропустим достаточно тривиальный случай, когда тип массивов известен на этапе компиляции). Затем мы проверим, что массивы имеют одинаковую нижнюю границу и длину по каждому из измерений. И, наконец, мы последовательно сравним их элементы с помощью метода Equals до выявления первого различия. Если различие не выявлено - то массивы равны. Код на C#, реализующий данный алгоритм, может выглядеть так:&lt;/p&gt;&lt;div style="overflow: scroll"&gt;&lt;div style="width: 200%"&gt;&lt;pre class="hl"&gt;&lt;span style="color:#0000FF;"&gt;public static&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;bool&lt;/span&gt; &lt;span class="kwd"&gt;AreEqual&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;Array x&lt;span &gt;,&lt;/span&gt; Array y&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;&lt;span &gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// сравнение на ссылочное равенство&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;x &lt;span &gt;==&lt;/span&gt; y&lt;span &gt;)&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;return true&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;x &lt;span &gt;==&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;null&lt;/span&gt; &lt;span &gt;||&lt;/span&gt; y &lt;span &gt;==&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;null&lt;/span&gt;&lt;span &gt;)&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;return false&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// сравнение по типам&lt;/span&gt;&lt;br /&gt;    Type type &lt;span &gt;=&lt;/span&gt; x&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetType&lt;/span&gt;&lt;span &gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;type &lt;span &gt;!=&lt;/span&gt; y&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetType&lt;/span&gt;&lt;span &gt;())&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;return false&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// сравнение на общее число элементов&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;x&lt;span &gt;.&lt;/span&gt;Length &lt;span &gt;!=&lt;/span&gt; y&lt;span &gt;.&lt;/span&gt;Length&lt;span &gt;)&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;return false&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// сравнение нижней границы и&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// длины по каждому из измерений&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;for&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;int&lt;/span&gt; i &lt;span &gt;=&lt;/span&gt; &lt;span style="color:teal;"&gt;0&lt;/span&gt;&lt;span &gt;;&lt;/span&gt; i &lt;span &gt;&amp;lt;&lt;/span&gt; x&lt;span &gt;.&lt;/span&gt;Rank&lt;span &gt;;&lt;/span&gt; i&lt;span &gt;++)&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF;"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;x&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLowerBound&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;i&lt;span &gt;) !=&lt;/span&gt; y&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLowerBound&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;i&lt;span &gt;) ||&lt;/span&gt;&lt;br /&gt;            x&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLength&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;i&lt;span &gt;) !=&lt;/span&gt; y&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLength&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;i&lt;span &gt;))&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000FF;"&gt;return false&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000;"&gt;// перебор и сравнение элементов&lt;/span&gt;&lt;br /&gt;    IEnumerator yEnum &lt;span &gt;=&lt;/span&gt; y&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetEnumerator&lt;/span&gt;&lt;span &gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;foreach&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;&lt;span style="color:#0000FF;"&gt;object&lt;/span&gt; e in x&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;{&lt;/span&gt;&lt;br /&gt;        yEnum&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;MoveNext&lt;/span&gt;&lt;span &gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF;"&gt;if&lt;/span&gt; &lt;span &gt;(!&lt;/span&gt;&lt;span class="kwd"&gt;Equals&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;e&lt;span &gt;,&lt;/span&gt; yEnum&lt;span &gt;.&lt;/span&gt;Current&lt;span &gt;))&lt;/span&gt; &lt;span style="color:#0000FF;"&gt;return false&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF;"&gt;return true&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;&lt;span &gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;Приведенный код содержит некоторые недостатки. Во-первых, он предполагает, что перечислитель, возвращаемый методом &lt;a href="http://msdn2.microsoft.com/en-us/library/system.array.getenumerator.aspx"&gt;GetEnumerator&lt;/a&gt;, будет перебирать элементы двух массивов в одном и том же порядке. Хотя исследование кода соответствующих методов показывает, что так оно и есть, надежный код не должен использовать такую недокументированную особенность. Во-вторых, указанный перечислитель для получения элементов массива пользуется методом &lt;a href="http://msdn2.microsoft.com/en-us/library/system.array.getvalue.aspx"&gt;GetValue&lt;/a&gt;, который является не самым быстрым способом доступа к элементам в случае одномерных массивов. И, наконец, приведенный код не учитывает, что элементами массива могут быть указатели, для извлечения которых надо использовать особую технику. Давайте попробуем устранить эти недостатки.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Чтобы не зависеть от недокументированного поведения встроенного перечислителя массивов, нам надо написать алгоритм, который перебирает все возможные комбинации индексов массива некоторым определенным способом. Самый естественный способ такой. Сначала устанавливаем все индексы в наименьшие значения. Затем увеличиваем последний (самый правый) индекс, пока он не превысит наибольшего значения. После этого сбрасываем его, увеличиваем на единицу предпоследний индекс и опять начинаем увеличивать последний. При превышении каким-либо индексом наибольшего значения, мы сбрасываем его, увеличивая на единицу предыдущий индекс. Продолжаем этот процесс, пока количество полученных комбинаций индексов не станет равным количеству элементов массива. На C# этот алгоритм можно записать следующим образом:&lt;/p&gt;&lt;div style="overflow: scroll"&gt;&lt;div style="width: 200%"&gt;&lt;pre class="hl"&gt;&lt;span style="color:#0000FF"&gt;static&lt;/span&gt; IEnumerable&lt;span class="sym"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF"&gt;int&lt;/span&gt;&lt;span class="sym"&gt;[]&amp;gt;&lt;/span&gt; &lt;span class="kwd"&gt;GetIndexes&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;Array x&lt;span class="sym"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;int&lt;/span&gt;&lt;span class="sym"&gt;[]&lt;/span&gt; indexes &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span style="color:#0000FF"&gt;new&lt;/span&gt; &lt;span style="color:#0000FF"&gt;int&lt;/span&gt;&lt;span class="sym"&gt;[&lt;/span&gt;x&lt;span class="sym"&gt;.&lt;/span&gt;Rank&lt;span class="sym"&gt;];&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;for&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF"&gt;int&lt;/span&gt; i &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span style="color:teal;"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; i &lt;span class="sym"&gt;&amp;lt;&lt;/span&gt; x&lt;span class="sym"&gt;.&lt;/span&gt;Rank&lt;span class="sym"&gt;;&lt;/span&gt; i&lt;span class="sym"&gt;++)&lt;/span&gt;&lt;br /&gt;        indexes&lt;span class="sym"&gt;[&lt;/span&gt;i&lt;span class="sym"&gt;] =&lt;/span&gt; x&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLowerBound&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;i&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;for&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF"&gt;int&lt;/span&gt; j &lt;span class="sym"&gt;=&lt;/span&gt; &lt;span style="color:teal;"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; j &lt;span class="sym"&gt;&amp;lt;&lt;/span&gt; x&lt;span class="sym"&gt;.&lt;/span&gt;Length&lt;span class="sym"&gt;;&lt;/span&gt; j&lt;span class="sym"&gt;++)&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF"&gt;for&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;&lt;span style="color:#0000FF"&gt;int&lt;/span&gt; k &lt;span class="sym"&gt;=&lt;/span&gt; x&lt;span class="sym"&gt;.&lt;/span&gt;Rank &lt;span class="sym"&gt;-&lt;/span&gt; &lt;span style="color:teal;"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; k &lt;span class="sym"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:teal;"&gt;0&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt; k&lt;span class="sym"&gt;--)&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000FF"&gt;if&lt;/span&gt; &lt;span class="sym"&gt;(&lt;/span&gt;indexes&lt;span class="sym"&gt;[&lt;/span&gt;k&lt;span class="sym"&gt;] &amp;lt;=&lt;/span&gt; x&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetUpperBound&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;k&lt;span class="sym"&gt;))&lt;/span&gt; &lt;span style="color:#0000FF"&gt;break&lt;/span&gt;&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;            indexes&lt;span class="sym"&gt;[&lt;/span&gt;k &lt;span class="sym"&gt;-&lt;/span&gt; &lt;span style="color:teal;"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;]++;&lt;/span&gt;&lt;br /&gt;            indexes&lt;span class="sym"&gt;[&lt;/span&gt;k&lt;span class="sym"&gt;] =&lt;/span&gt; x&lt;span class="sym"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLowerBound&lt;/span&gt;&lt;span class="sym"&gt;(&lt;/span&gt;k&lt;span class="sym"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF"&gt;yield return&lt;/span&gt; indexes&lt;span class="sym"&gt;;&lt;/span&gt;&lt;br /&gt;        indexes&lt;span class="sym"&gt;[&lt;/span&gt;x&lt;span class="sym"&gt;.&lt;/span&gt;Rank &lt;span class="sym"&gt;-&lt;/span&gt; &lt;span style="color:teal;"&gt;1&lt;/span&gt;&lt;span class="sym"&gt;]++;&lt;/span&gt;&lt;br /&gt;    &lt;span class="sym"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="sym"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;Если вам непонятна конструкция yield return, то рекомендую прочитать эту &lt;a href="http://www.rsdn.ru/article/csharp/newincsharp.xml#EMMAG"&gt;статью&lt;/a&gt;, а еще лучше - спецификацию C# 2.0 &lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf"&gt;Ecma-334&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Давайте теперь попробуем оптимизировать работу алгоритма сравнения для случая одномерных массивов. Известно, что при работе с &lt;nobr&gt;SZ-массивами&lt;/nobr&gt; (одномерными массивами с нулевой нижней границей) могут применяться специальные инструкции &lt;a href="http://en.wikipedia.org/wiki/Common_Intermediate_Language"&gt;CIL&lt;/a&gt;, работающие эффективнее, чем вызовы соответствующих методов класса &lt;nobr&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/system.array.aspx"&gt;System.Array&lt;/a&gt;.&lt;/nobr&gt; Поэтому имеет смысл написать специальный метод для сравнения таких массивов, получающий их элементы через индексатор. Но так как тип элементов массива неизвестен на этапе компиляции, нам придется воспользоваться механизмом отражения (reflection) для вызова подходящего варианта обобщенного (generic) метода. Если вы мало знакомы с этой техникой, пожалуйста, посмотрите эту &lt;a href="http://msdn2.microsoft.com/en-us/library/ms173183.aspx"&gt;страницу&lt;/a&gt; в MSDN. Последовательность действий такова:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;убедиться, что мы имеем дело с SZ-массивом (проверить число измерений и нижнюю границу)&lt;/li&gt;&lt;li&gt;получить тип элементов массива&lt;/li&gt;&lt;li&gt;при возможности взять из кэша делегат, вызывающий подходящий обобщенный метод&lt;/li&gt;&lt;li&gt;при отсутствии делегата в кэше создать его и положить в кэш&lt;/li&gt;&lt;li&gt;вызвать метод через делегат, передав ему массивы для сравнения&lt;/li&gt;&lt;/ul&gt;&lt;p align=justify&gt;&lt;br /&gt;Вот код, реализующий данный алгоритм:&lt;/p&gt;&lt;div style="overflow: scroll"&gt;&lt;div style="width: 200%"&gt;&lt;pre class="hl"&gt;&lt;span style="color:#0000FF"&gt;public static&lt;/span&gt; &lt;span style="color:#0000FF"&gt;bool&lt;/span&gt; &lt;span class="kwd"&gt;AreEqual&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;Array x&lt;span &gt;,&lt;/span&gt; Array y&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;&lt;span &gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#008000"&gt;// ...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;x&lt;span &gt;.&lt;/span&gt;Rank &lt;span &gt;==&lt;/span&gt; &lt;span style="color:teal"&gt;1&lt;/span&gt; &lt;span &gt;&amp;amp;&amp;amp;&lt;/span&gt; x&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetLowerBound&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;span style="color:teal"&gt;0&lt;/span&gt;&lt;span &gt;) ==&lt;/span&gt; &lt;span style="color:teal"&gt;0&lt;/span&gt;&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;{&lt;/span&gt;&lt;br /&gt;        Type eltType &lt;span &gt;=&lt;/span&gt; type&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetElementType&lt;/span&gt;&lt;span &gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF"&gt;if&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;eltType&lt;span &gt;.&lt;/span&gt;IsClass&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style="color:#0000FF"&gt;return&lt;/span&gt; &lt;span class="kwd"&gt;CompareSZArrays&lt;/span&gt;&lt;span &gt;((&lt;/span&gt;&lt;span style="color:#0000FF"&gt;object&lt;/span&gt;&lt;span &gt;[])&lt;/span&gt; x&lt;span &gt;, (&lt;/span&gt;&lt;span style="color:#0000FF"&gt;object&lt;/span&gt;&lt;span &gt;[])&lt;/span&gt; y&lt;span &gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF"&gt;return&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;&lt;span style="color:#0000FF"&gt;bool&lt;/span&gt;&lt;span &gt;)&lt;/span&gt; &lt;span class="kwd"&gt;GetComparator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;eltType&lt;span &gt;).&lt;/span&gt;&lt;span class="kwd"&gt;DynamicInvoke&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;x&lt;span &gt;,&lt;/span&gt; y&lt;span &gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color:#008000"&gt;// ...&lt;/span&gt;&lt;br /&gt;&lt;span &gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000FF"&gt;delegate&lt;/span&gt; &lt;span style="color:#0000FF"&gt;bool&lt;/span&gt; F&lt;span &gt;&amp;lt;&lt;/span&gt;T&lt;span &gt;&amp;gt;(&lt;/span&gt;T&lt;span &gt;[]&lt;/span&gt; x&lt;span &gt;,&lt;/span&gt; T&lt;span &gt;[]&lt;/span&gt; y&lt;span &gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000FF"&gt;static readonly&lt;/span&gt; Type _delegateTypeStub &lt;span &gt;=&lt;/span&gt; &lt;span style="color:#0000FF"&gt;typeof&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;F&lt;span &gt;&amp;lt;&amp;gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000FF"&gt;static readonly&lt;/span&gt; MethodInfo _methodStub &lt;span &gt;=&lt;/span&gt; &lt;span style="color:#0000FF"&gt;new&lt;/span&gt; F&lt;span &gt;&amp;lt;&lt;/span&gt;&lt;span style="color:#0000FF"&gt;int&lt;/span&gt;&lt;span &gt;&amp;gt;(&lt;/span&gt;CompareSZArrays&lt;span &gt;).&lt;/span&gt;Method&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;GetGenericMethodDefinition&lt;/span&gt;&lt;span &gt;();&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#0000FF"&gt;static readonly&lt;/span&gt; Dictionary&lt;span &gt;&amp;lt;&lt;/span&gt;Type&lt;span &gt;,&lt;/span&gt; Delegate&lt;span &gt;&amp;gt;&lt;/span&gt; _cache &lt;span &gt;=&lt;/span&gt; &lt;span style="color:#0000FF"&gt;new&lt;/span&gt; Dictionary&lt;span &gt;&amp;lt;&lt;/span&gt;Type&lt;span &gt;,&lt;/span&gt; Delegate&lt;span &gt;&amp;gt;();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000FF"&gt;static&lt;/span&gt; Delegate &lt;span class="kwd"&gt;GetComparator&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;Type elementType&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;&lt;span &gt;{&lt;/span&gt;&lt;br /&gt;    Delegate comparator&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;lock&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;_cache&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF"&gt;if&lt;/span&gt; &lt;span &gt;(!&lt;/span&gt;_cache&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;TryGetValue&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;elementType&lt;span &gt;,&lt;/span&gt; out comparator&lt;span &gt;))&lt;/span&gt;&lt;br /&gt;        &lt;span &gt;{&lt;/span&gt;&lt;br /&gt;            comparator &lt;span &gt;=&lt;/span&gt; Delegate&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;CreateDelegate&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;&lt;br /&gt;                _delegateTypeStub.MakeGenericType(elementType)&lt;span &gt;,&lt;/span&gt;&lt;br /&gt;                _methodStub&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;MakeGenericMethod&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;elementType&lt;span &gt;));&lt;/span&gt;&lt;br /&gt;            _cache&lt;span &gt;.&lt;/span&gt;&lt;span class="kwd"&gt;Add&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;elementType&lt;span &gt;,&lt;/span&gt; comparator&lt;span &gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span &gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;return&lt;/span&gt; comparator&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;&lt;span &gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#0000FF"&gt;static&lt;/span&gt; &lt;span style="color:#0000FF"&gt;bool&lt;/span&gt; CompareSZArrays&lt;span &gt;&amp;lt;&lt;/span&gt;T&lt;span &gt;&amp;gt;(&lt;/span&gt;T&lt;span &gt;[]&lt;/span&gt; x&lt;span &gt;,&lt;/span&gt; T&lt;span &gt;[]&lt;/span&gt; y&lt;span &gt;)&lt;/span&gt;&lt;br /&gt;&lt;span &gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;for&lt;/span&gt; &lt;span &gt;(&lt;/span&gt;&lt;span style="color:#0000FF"&gt;int&lt;/span&gt; i &lt;span &gt;=&lt;/span&gt; &lt;span style="color:teal"&gt;0&lt;/span&gt;&lt;span &gt;;&lt;/span&gt; i &lt;span &gt;&amp;lt;&lt;/span&gt; x&lt;span &gt;.&lt;/span&gt;Length&lt;span &gt;;&lt;/span&gt; i&lt;span &gt;++)&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color:#0000FF"&gt;if&lt;/span&gt; &lt;span &gt;(!&lt;/span&gt;&lt;span class="kwd"&gt;Equals&lt;/span&gt;&lt;span &gt;(&lt;/span&gt;x&lt;span &gt;[&lt;/span&gt;i&lt;span &gt;],&lt;/span&gt; y&lt;span &gt;[&lt;/span&gt;i&lt;span &gt;]))&lt;/span&gt; &lt;span style="color:#0000FF"&gt;return false&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span &gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style="color:#0000FF"&gt;return true&lt;/span&gt;&lt;span &gt;;&lt;/span&gt;&lt;br /&gt;&lt;span &gt;}&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p align=justify&gt;Обратите внимание, что мы получаем объект MethodInfo не с помощью метода GetMethod, а через "подставной" делегат F&amp;lt;int&amp;gt; - это позволяет не хард-кодить имя метода в строковом литерале и проверять его наличие на этапе компиляции (аналогичного эффекта можно было бы добиться с помощью конструкции infoof, если бы она была в языке). Другой интересный момент - для любого SZ-массива, элементы которого имеют ссылочный тип, мы можем воспользоваться &lt;a href="http://msdn2.microsoft.com/en-us/library/aa711607(VS.71).aspx"&gt;ковариантностью массивов&lt;/a&gt; и вызывать один и тот же вариант метода сравнения, не прибегая к отражению. Вообще говоря, использование отражения и динамическое создание делегатов - это довольно медленная техника, но благодаря использованию кэширования и тому факту, что обычно в реальной программе встречается не так много различных типов объектов, мы получим значительный выигрыш.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;В следующий раз мы поговорим о том, как можно решить проблему сравнения массивов, элементами которого являются указатели.&lt;/p&gt;&lt;br /&gt;&lt;div style="background-color: gray; overflow: hidden; height: 1px"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align=justify&gt;Если вы заметили ошибочную, неточную или спорную информацию на этом блоге, пожалуйста, оставте свой комментарий или напишите &lt;a href="mailto:nikovs.blog@gmail.com"&gt;мне&lt;/a&gt; письмо. Любые вопросы, уточнения и комментарии приветствуются.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-3672939607913669400?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/3672939607913669400/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=3672939607913669400' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3672939607913669400'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/3672939607913669400'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/03/net-2.html' title='Сравнение объектов в .NET'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-562627325182180006</id><published>2007-03-03T04:50:00.000-08:00</published><updated>2007-03-03T05:02:07.475-08:00</updated><title type='text'>Brainbench</title><content type='html'>&lt;p align=justify&gt;Вчера сдал он-лайн экзамен на &lt;a href="http://www.brainbench.com/"&gt;Brainbench&lt;/a&gt; по C#. Вот &lt;a href="http://www.brainbench.com/transcript.jsp?pid=6636238"&gt;результат&lt;/a&gt;. Набрал 4.83 баллов из 5 возможных - оказалось, что этот результат лучше, чем у 99% людей, сдававших этот экзамен. Надеялся, что пройду вообще без ошибок, но что-то напутал с сигнатурами методов асинхронного вызова делегатов. Придется подучить...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-562627325182180006?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/562627325182180006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=562627325182180006' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/562627325182180006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/562627325182180006'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/03/brainbench.html' title='Brainbench'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-6827868244807107951</id><published>2007-03-02T07:39:00.000-08:00</published><updated>2007-03-03T11:22:03.667-08:00</updated><title type='text'>Look out, generics!</title><content type='html'>&lt;p align=justify&gt;Давайте рассмотрим следующий код на C#:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;public abstract class&lt;/span&gt; A&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;public abstract&lt;/span&gt; T Foo(); &lt;br /&gt;  &lt;span style="color:blue;"&gt;public class&lt;/span&gt; B : A&amp;lt;B&amp;gt; &lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color:blue;"&gt;public override&lt;/span&gt; B Foo() &lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:blue;"&gt;return null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;p align=justify&gt;Заметьте, что класс B наследуется от одного из типов, сконструированных из класса A, в который он же и вложен. При этом класс B еще и используется в качестве типа-аргумента для класса &lt;nobr&gt;A&amp;lt;B&amp;gt;.&lt;/nobr&gt; Такое наследование вполне допустимо в .NET.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;На первый взгляд указанный тип возвращаемого значения в методе &lt;nobr&gt;B.Foo()&lt;/nobr&gt; может показаться правильным, однако при компиляции этого кода мы получим ошибку:&lt;/p&gt;&lt;pre&gt;error CS0508: &lt;nobr&gt;'A&amp;lt;T&amp;gt;.B.Foo()':&lt;/nobr&gt; return type must be&lt;br&gt;&lt;nobr&gt;'A&amp;lt;T&amp;gt;.B'&lt;/nobr&gt; to match overridden member &lt;nobr&gt;'A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt;.Foo()'&lt;/nobr&gt;&lt;/pre&gt;&lt;p align=justify&gt;Действительно, полное имя типа B (точнее, ассоциированного с ним instance-типа) - это &lt;nobr&gt;A&amp;lt;T&amp;gt;.B&lt;/nobr&gt;. Давайте попробуем подставить это полное имя в наш код.&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;public abstract class&lt;/span&gt; A&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;public abstract&lt;/span&gt; T Foo(); &lt;br /&gt;  &lt;span style="color:blue;"&gt;public class&lt;/span&gt; B : A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt; &lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color:blue;"&gt;public override&lt;/span&gt; A&amp;lt;T&amp;gt;.B Foo() &lt;br /&gt;    {&lt;br /&gt;      &lt;span style="color:blue;"&gt;return null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;p align=justify&gt;На сей раз компиляция проходит без ошибок. Однако, пока остается непонятным, почему в первом примере компилятор отказался интерпретировать краткое имя B как &lt;nobr&gt;A&amp;lt;T&amp;gt;.B&lt;/nobr&gt; при указании типа возвращаемого значения в методе &lt;nobr&gt;B.Foo()&lt;/nobr&gt;. Для разъяснения этого вопроса давайте проведем маленький эксперимент:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System;&lt;br /&gt;&lt;span style="color:blue;"&gt;public abstract class&lt;/span&gt; A&amp;lt;T&amp;gt;&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;public abstract&lt;/span&gt; T Foo(); &lt;br /&gt;  &lt;span style="color:blue;"&gt;public class&lt;/span&gt; B : A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt; &lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color:blue;"&gt;public override&lt;/span&gt; A&amp;lt;T&amp;gt;.B Foo() &lt;br /&gt;    {&lt;br /&gt;      Console.WriteLine(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(B));&lt;br /&gt;      Console.WriteLine(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(A&amp;lt;T&amp;gt;.B));&lt;br /&gt;      Console.WriteLine(&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt;.B));&lt;br /&gt;      &lt;span style="color:blue;"&gt;return null&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;span style="color:blue;"&gt;public class&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;  &lt;span style="color:blue;"&gt;static void&lt;/span&gt; Main() &lt;br /&gt;  {&lt;br /&gt;    &lt;span style="color:blue;"&gt;new&lt;/span&gt; A&amp;lt;&lt;span style="color:blue;"&gt;int&lt;/span&gt;&amp;gt;.B().Foo();&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;p align=justify&gt;Результат:&lt;/p&gt;&lt;pre&gt;A`1+B[A`1+B[System.Int32]]&lt;br /&gt;A`1+B[System.Int32]&lt;br /&gt;A`1+B[A`1+B[System.Int32]]&lt;/pre&gt;&lt;p align=justify&gt;Теперь ситуация становится более-менее понятной. Тип B находится в двояком положении. С одной стороны, он вложен в &lt;nobr&gt;A&amp;lt;T&amp;gt;&lt;/nobr&gt;, поэтому видит члены внешнего класса, в частности &lt;nobr&gt;A&amp;lt;T&amp;gt;.B&lt;/nobr&gt;. С другой стороны, тип В является производным от &lt;nobr&gt;A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt;&lt;/nobr&gt;, поэтому он наследует члены базового класса, в частности &lt;nobr&gt;A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt;.B&lt;/nobr&gt;. Очевидно, что типы &lt;nobr&gt;A&amp;lt;T&amp;gt;.B&lt;/nobr&gt; и &lt;nobr&gt;A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt;.B&lt;/nobr&gt; являются различными, хотя оба имеют краткое имя B. Естественно, что при разрешении краткого имени B в данном случае предпочтение будет отдаваться унаследованному типу &lt;nobr&gt;A&amp;lt;A&amp;lt;T&amp;gt;.B&amp;gt;.B&lt;/nobr&gt; (см. &lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf"&gt;Ecma-334&lt;/a&gt;, &lt;a href="http://en.csharp-online.net/ECMA-334:_10.8_Namespace_and_type_names"&gt;10.8 Namespace and type names&lt;/a&gt;).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-6827868244807107951?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/6827868244807107951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=6827868244807107951' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/6827868244807107951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/6827868244807107951'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/03/look-out-generics.html' title='Look out, generics!'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-8301464363485194922</id><published>2007-02-24T06:38:00.000-08:00</published><updated>2007-02-25T05:42:25.023-08:00</updated><title type='text'>Сортировка списка с помощью бинарного дерева (Nemerle)</title><content type='html'>&lt;p align=justify&gt;Сегодня я хочу продемонстрировать некоторые возможности &lt;a href="http://nikovs-blog.blogspot.com/2007/02/nemerle.html"&gt;Nemerle&lt;/a&gt; на примере несложной программы: сортировка &lt;a href="http://ru.wikipedia.org/wiki/%D0%9B%D0%B8%D0%BD%D0%B5%D0%B9%D0%BD%D1%8B%D0%B9_%D1%81%D0%BF%D0%B8%D1%81%D0%BE%D0%BA"&gt;списка&lt;/a&gt; с помощью &lt;a href="http://ru.wikipedia.org/wiki/%D0%91%D0%B8%D0%BD%D0%B0%D1%80%D0%BD%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE"&gt;бинарного дерева&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Console;&lt;br /&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; Tree;&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;variant&lt;/span&gt; Tree[T] {&lt;br /&gt;  | Nil&lt;br /&gt;  | Node {&lt;br /&gt;      left : Tree[T];&lt;br /&gt;      value : T;&lt;br /&gt;      right : Tree[T];&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;module&lt;/span&gt; Program&lt;br /&gt;{&lt;br /&gt;  Main() : &lt;span style="color:blue;"&gt;void&lt;/span&gt; {&lt;br /&gt;    &lt;span style="color:blue;"&gt;def&lt;/span&gt; sort(s, c) {&lt;br /&gt;      &lt;span style="color:blue;"&gt;def&lt;/span&gt; insert(t, e) {&lt;br /&gt;        &lt;span style="color:blue;"&gt;match&lt;/span&gt;(t) {&lt;br /&gt;          | Node(l, v, r) =&gt; &lt;br /&gt;            &lt;span style="color:blue;"&gt;if&lt;/span&gt;(c(e, v) &lt; 0) &lt;br /&gt;              Node(insert(l, e), v, r)&lt;br /&gt;            &lt;span style="color:blue;"&gt;else&lt;/span&gt; &lt;br /&gt;              Node(l, v, insert(r, e))&lt;br /&gt;          | Nil =&gt; Node(Nil(), e, Nil())&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:blue;"&gt;def&lt;/span&gt; to_tree(s, tree = Nil()) {&lt;br /&gt;        &lt;span style="color:blue;"&gt;match&lt;/span&gt;(s) {&lt;br /&gt;          | h :: t =&gt; &lt;br /&gt;              to_tree(t, insert(tree, h))&lt;br /&gt;          | [] =&gt; tree&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      &lt;span style="color:blue;"&gt;def&lt;/span&gt; to_list(t, s = []) {&lt;br /&gt;        &lt;span style="color:blue;"&gt;match&lt;/span&gt;(t) {&lt;br /&gt;          | Node(l, v, r) =&gt; &lt;br /&gt;              to_list(l) + (v :: to_list(r))&lt;br /&gt;          | Nil =&gt; []&lt;br /&gt;        }&lt;br /&gt;      }&lt;br /&gt;      to_list(to_tree(s))&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span style="color:blue;"&gt;def&lt;/span&gt; c = &lt;span style="color:blue;"&gt;_&lt;/span&gt;.CompareTo(&lt;span style="color:blue;"&gt;_&lt;/span&gt;);&lt;br /&gt;    &lt;span style="color:blue;"&gt;def&lt;/span&gt; s = sort([5, 4, 8, 1, 3], c);&lt;br /&gt;    &lt;br /&gt;    WriteLine(s);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;p align=justify&gt;Идея программы состоит в следующем. Бинарное дерево может быть либо пустым (Tree.Nil), либо состоять из узла (Tree.Node), который имеет левую ветку, элемент и правую ветку. Каждая из веток, в свою очередь, тоже является бинарным деревом. Элементы в левой ветке (если таковые имеются) всегда меньше, чем элемент данного узла, а в правой - больше либо равны ему. При вставке нового элемента в дерево, он сначала сравнивается с элементом в корне, потом "соскальзывает" в соответствующую ветку, и, в конце концов, закрепляется на одном из концов дерева. Таким образом, вставка нового элемента в дерево из N элементов будет занимать в среднем log(N) сравнений. Вначале мы берем пустое бинарное дерево, и поочередно вставляем в него все элементы списка.  Поле того, как дерево построено, мы рекурсивно обходим его и собираем элементы в результирующий список, который получается отсортированным.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Обратите внимание, что нам почти нигде не пришлось явно указывать тип переменных или сигнатуру функций. Тем не менее, эта программа полностью статически типизирована - компилятор смог вывести типы всех переменных из их использования.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: gray; overflow: hidden; height: 1px"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align=justify&gt;Если вы хотите больше узнать о выводе типов, то вам &lt;a href="http://nemerle.org/Type_inference"&gt;сюда&lt;/a&gt;. Есть вопросы? Задайте их &lt;a href="mailto:nikovs.blog@gmail.com"&gt;мне&lt;/a&gt; или спросите на &lt;a href="http://rsdn.ru/forum/?group=nemerle"&gt;этом форуме&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-8301464363485194922?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/8301464363485194922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=8301464363485194922' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/8301464363485194922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/8301464363485194922'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/02/nemerle_24.html' title='Сортировка списка с помощью бинарного дерева (Nemerle)'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-949975193199796973</id><published>2007-02-23T08:04:00.000-08:00</published><updated>2007-02-24T02:28:23.697-08:00</updated><title type='text'>Кортежи в Nemerle</title><content type='html'>&lt;p align="justify"&gt;Я продолжаю цикл заметок, посвященных языку &lt;a href="http://ru.wikipedia.org/wiki/Nemerle"&gt;Nemerle&lt;/a&gt;, который я начал &lt;a href="http://nikovs-blog.blogspot.com/2007/02/nemerle.html"&gt;здесь&lt;/a&gt;. В Nemerle есть такие удобные типы данных, как &lt;a href="http://nemerle.org/Nemerle_for_OOP_Programmers_Week_3#Tuples"&gt;кортежи&lt;/a&gt; (tuples). Сегодня я решил написать о них. По сути, кортеж - это неименованный тип данных, содержащий несколько безымянных полей, доступных для чтения. Чтобы задать тип кортежа, надо задать типы всех его полей. В Nemerle тип кортежа записывается с использованием звездочки. Например,&lt;/p&gt;&lt;pre&gt;&lt;span style="color:green;"&gt;// tup имеет тип (int * double * string)&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; tup = (1, 2.1, &lt;b style="COLOR: maroon"&gt;"text"&lt;/b&gt;);&lt;/pre&gt;&lt;p align="justify"&gt;Заметьте, что я не указал тип переменной tup, компилятор вывел его, зная типы литералов, использованных при конструировании кортежа. Но я мог бы указать его и явно:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; tup : (&lt;span style="color:blue;"&gt;int&lt;/span&gt; * &lt;span style="color:blue;"&gt;double&lt;/span&gt; * &lt;span style="color:blue;"&gt;string&lt;/span&gt;) = (1, 2.1, &lt;b style="COLOR: maroon"&gt;"text"&lt;/b&gt;);&lt;/pre&gt;&lt;p align="justify"&gt;Скобки при указании типа кортежа можно опустить, а вот при его конструировании (в правой части) они нужны обязательно. Кортеж можно деконструировать, при этом скобки нужно поставить с левой стороны.&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; (n, x, s) = tup;&lt;/pre&gt;&lt;p align="justify"&gt;Это эквивалентно объявлению трех локальных переменных n, x, s и извлечению в них соответствующих полей кортежа. Типы переменных компилятор, опять-таки, выводит, зная тип переменной tup. Если нам нужно только одно поле из кортежа, мы можем не объявлять лишних переменных, а поставить вместо них специальный символ _.&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; (&lt;span style="color:blue;"&gt;_&lt;/span&gt;, x, &lt;span style="color:blue;"&gt;_&lt;/span&gt;) = tup;&lt;/pre&gt;&lt;p align="justify"&gt;В случае несовпадения количества элементов в образце с количеством элементов в кортеже, возникнет ошибка на этапе компиляции. Надо заметить, что деконструирование кортежей - это частный случай более общей техники &lt;a href="http://nemerle.org/Grok_Variants_and_matching#Matching"&gt;сопоставления с образцом&lt;/a&gt; (pattern matching), а использованные нами выражения (n, x, s) и (_, x, _) - это образцы (patterns). Идея, лежащая в основе их синтаксиса - это то, что образец, служащий для деконструирования определенного значения, выглядит так же, как и выражение, конструирующее это значение. Мы только что убедились в этом на примере кортежей. Однако, сопоставление с образцом - это большая тема, и мы поговорим о ней отдельно как-нибудь потом.&lt;/p&gt;&lt;br /&gt;&lt;p align="justify"&gt;Кортежи очень удобны, когда вам нужно вернуть из функции более одного значения. Входные параметры функции также образуют кортеж, поэтому их можно передавать в функцию и по отдельности, и как одно целое. Например, две следующие части кода эквивалентны:&lt;/p&gt;&lt;pre&gt;&lt;span style="color:green;"&gt;// Snippet 1&lt;/span&gt;&lt;br /&gt;Foo(1, 2.1, &lt;b style="COLOR: maroon"&gt;"text"&lt;/b&gt;);&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;span style="color:green;"&gt;// Snippet 2&lt;/span&gt;&lt;br /&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; tup = (1, 2.1, &lt;b style="COLOR: maroon"&gt;"text"&lt;/b&gt;);&lt;br /&gt;Foo(tup);&lt;/pre&gt;&lt;p align="justify"&gt;Это дает возможность рассматривать все функции в Nemerle (кроме функций без параметров), как принимающие один параметр. Вместе с механизмом вывода типов эта особенность дает возможность вообще опускать сигнатуру у локальных функций. Например, переворачивание списка можно реализовать так:&lt;p&gt;&lt;pre&gt;Rev[T](s : &lt;span style="color:blue;"&gt;list&lt;/span&gt;[T]) : &lt;span style="color:blue;"&gt;list&lt;/span&gt;[T] {&lt;br /&gt;    &lt;span style="color:blue;"&gt;def&lt;/span&gt; loop(&lt;span style="color:blue;"&gt;_&lt;/span&gt;) {&lt;br /&gt;        | (h :: t, a) =&gt; loop(t, h :: a)&lt;br /&gt;        | ([], a) =&gt; a&lt;br /&gt;    }&lt;br /&gt;    loop(s, [])&lt;br /&gt;}&lt;/pre&gt;&lt;p align=justify&gt;В этом примере мы видим более сложный пример сопоставления с образцом. Хотя мы будем говорить о списках в другой раз, могу пояснить, что запись (h :: t) означает список с головой h и хвостом t, а [] - пустой список. Как видите, этот синтаксис тоже может использоваться, как для конструирования списка, так и для деконструирования. Узнать о списках больше можно &lt;a href="http://nemerle.org/Nemerle_for_OOP_Programmers_Week_4#Reverse_list"&gt;здесь&lt;/a&gt;.&lt;/p&gt;&lt;p align=justify&gt;Кроме разобранного выше синтаксиса деконструирования кортежей, Nemerle позволяет получать значения их полей по индексу. При этом индексация элементов начинается с нуля.&lt;/p&gt;&lt;pre&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; tup = (1, 2.1, &lt;b style="COLOR: maroon"&gt;"text"&lt;/b&gt;);&lt;br /&gt;&lt;span style="color:blue;"&gt;def&lt;/span&gt; x = tup[1];&lt;/pre&gt;&lt;p align="justify"&gt;Здесь мы объявили переменную x, которая получает тип double и значение 2.1. Так как элементы кортежа могут иметь разные типы, а тип переменных должен быть выведен во время компиляции, кортежи разрешается индексировать только константными значениями. При этом выход индекса за допустимые пределы будет вызывать ошибку на этапе компиляции.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Внутренне кортежи представляются полиморфными (generic) типами Nemerle.Builtins.Tuple[...], определенными в сборке Nemerle.dll.  Вы можете изучить их структуру &lt;a href="http://en.wikipedia.org/wiki/.NET_Reflector"&gt;рефлектором&lt;/a&gt; или посмотреть их исходники в &lt;a href="http://nemerle.org/svn/nemerle/trunk/lib/internal-numbered.n"&gt;репозитории&lt;/a&gt;. Каждый из этих типов является производящим для всех кортежей с определенным числом элементов. Например, кортеж (int * double * string) будет представляться типом Nemerle.Builtins.Tuple[int, double, string]. При такой форме внутреннего представления кортежей число производящих типов должно быть ограничено, а следовательно, должно быть ограничено и максимальное количество элементов в кортеже. В текущей версии Nemerle оно равняется 20. Вы могли заметить, что типы с 2 и 3 параметризующими типами являются размерными типами (структурами), а остальные - ссылочными (классами). Это сделано только для целей производительности и не влияет на семантику кортежей. В некоторых случаях, когда временный кортеж используется только внутри одной функции, компилятор может применить оптимизацию и вообще исключить создание временного объекта.&lt;/p&gt;&lt;br /&gt;&lt;div style="background-color: gray; overflow: hidden; height: 1px"&gt;&lt;/div&gt;&lt;br /&gt;&lt;p align=justify&gt;Если вы заинтересовались языком &lt;a href="http://nemerle.org"&gt;Nemerle&lt;/a&gt;, обязательно прочитайте &lt;a href="http://rsdn.ru/article/nemerle/NemerleIntro.xml"&gt;эту статью&lt;/a&gt;. Есть вопросы? Задайте их &lt;a href="mailto:nikovs.blog@gmail.com"&gt;мне&lt;/a&gt; или спросите на &lt;a href="http://rsdn.ru/forum/?group=nemerle"&gt;этом форуме&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-949975193199796973?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/949975193199796973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=949975193199796973' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/949975193199796973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/949975193199796973'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/02/nemerle_23.html' title='Кортежи в Nemerle'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-298035149877685257.post-4464215071463871176</id><published>2007-02-23T02:16:00.000-08:00</published><updated>2007-02-24T01:48:52.413-08:00</updated><title type='text'>Nemerle</title><content type='html'>&lt;p align=justify&gt;Прошло около месяца, как я познакомился с языком &lt;a href="http://ru.wikipedia.org/wiki/Nemerle"&gt;Nemerle&lt;/a&gt;. Впечатления потрясающие. Это компилируемый язык со &lt;a href="http://ru.wikipedia.org/wiki/%D0%A1%D1%82%D0%B0%D1%82%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B0%D1%8F_%D1%82%D0%B8%D0%BF%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F"&gt;статической типизацией&lt;/a&gt; и &lt;a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%B1%D0%BE%D1%80%D0%BA%D0%B0_%D0%BC%D1%83%D1%81%D0%BE%D1%80%D0%B0"&gt;сборкой мусора&lt;/a&gt;, работающий под &lt;a href="http://ru.wikipedia.org/wiki/.NET"&gt;.NET&lt;/a&gt;, с интуитивно понятным C-подобным синтаксисом, полностью поддерживающий объектно-ориентированную парадигму, включая &lt;a href="http://nemerle.org/Nemerle_for_OOP_Programmers_Week_4#Parametric_polymorphism_aka_generics"&gt;полиморфные типы&lt;/a&gt; (generics). Язык довольно легок для изучения для тех, кто переходит на него с C#. Если на нем писать в стиле C#, то он позволяет записать все, что можно было бы записать на C#, но более лаконично и не менее понятно (на самом деле, в текущей версии, некоторые возможности C# недоступны, но я, наверное, напишу об этом отдельно чуть попозже). Существует даже утилита для автоматической конвертации исходников с C# на Nemerle (&lt;a href="http://nemerle.org/Cs2n"&gt;cs2n.exe&lt;/a&gt;).&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Но Nemerle предлагает еще целый ряд замечательных возможностей. Это:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span&gt;возможности функционального программирования (включая: локальные функции, передачу функций в качестве аргументов в другие функции, оптимизацию хвостовой рекурсии, лямбды, частичное применение и др.)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org/Type_inference"&gt;выведение типов&lt;/a&gt; (type inference), гораздо более мощное, чем, например, в &lt;a href="http://download.microsoft.com/download/5/8/6/5868081c-68aa-40de-9a45-a3803d8134b8/csharp_3.0_specification.doc"&gt;C# 3.0&lt;/a&gt;. В частности, поддерживается выведение сигнатуры для локальных функций&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://nemerle.org/Nemerle_for_OOP_Programmers_Week_3#Tuples"&gt;кортежи&lt;/a&gt; (tuples)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://nemerle.org/Grok_Variants_and_matching#Variants"&gt;вариантные типы&lt;/a&gt; (variants)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span&gt;&lt;a href="http://nemerle.org/Grok_Variants_and_matching#Matching"&gt;сопоставление с образцом&lt;/a&gt; (pattern matching)&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;расширения синтаксиса, возможность внедрения DSL-языков в код программы&lt;/li&gt;&lt;br /&gt;&lt;li&gt;возможность метапрограммирования (реализованная в виде типо-безопасных макросов). Фактически, многие конструкции языка, которые выглядят как встроенные (например, lock или using), реализованы как макросы, доступные по умолчанию&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Наверное, все эти возможности уже присутствовали в том или ином виде в каких-то языках. Однако я еще не встречал их все сразу в одном языке, и с таким интуитивно понятным синтаксисом.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Большим плюсом является то, что компилятор Nemerle полностью написан на управляемом (managed) коде. Более того, его исходники написаны на самом Nemerle, и они являются полностью открытыми. Да, вы можете взять из &lt;a href="http://nemerle.org/svn/nemerle/trunk"&gt;репозитория&lt;/a&gt; исполняемые бинарные файлы компилятора и его исходники, затем скомпилировать полученные исходники этими бинарниками - и вы опять получите полноценные исполняемые бинарные файлы.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Кроме того, компилятор имеет открытый API, который может свободно использоваться макросами, а также инструментами рефакторинга и интеграции с IDE. Например, если вы захотите написать плагин, обеспечивающий интеграцию Nemerle с вашей любимой IDE, вам не нужно будет писать свой парсер языка. Вы можете запросить всю необходимую информацию, например, тип символа на указанной позиции в коде, набор членов для списка завершения (completion list) или сведения о имеющихся в коде ошибках, прямо у компилятора! Также надо заметить, что компилятор создает сборки с помощью стандартного &lt;a href="http://msdn2.microsoft.com/en-us/library/8ffc3x75.aspx"&gt;Reflection.Emit&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Существует открытый &lt;a href="http://nemerle.org/bugs"&gt;баг-трекер&lt;/a&gt;, куда можно отправлять свои сообщения об ошибках и предложения по улучшению языка. Более того, вы можете получить доступ к репозиторию на запись и сами включиться в разработку! Хотя официального релиза на момент написания этой заметки еще не было (версия языка меньше единицы), язык уже завоевал большую популярность. Уже есть &lt;a href="http://rsdn.ru/article/nemerle/Nemerle.VsIntegration-ru.xml"&gt;интеграция&lt;/a&gt; языка с Visual Studio (точнее, она в процессе разработки, но ей можно пользоваться: отладчик, расцветка кода, отступы, навигация, всплывающая информация об идентификаторах и фоновая подсветка большинства ошибок). Я уверен, что в недалеком будущем появятся инструменты &lt;a href="http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D1%84%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%BD%D0%B3"&gt;рефакторинга&lt;/a&gt;, не уступающие &lt;a href="http://www.jetbrains.com/resharper"&gt;ReSharper&lt;/a&gt;'у.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;Nemerle распространяется под очень свободной &lt;a href="http://nemerle.org/License"&gt;лицензией&lt;/a&gt;. Фактически, единственное требование - это сохранить упоминание об авторских правах. Nemerle можно распространять как в бинарном виде, так и в виде исходного кода и свободно использовать в любых открытых или коммерческих проектах, как в исходном, так и в измененном виде.&lt;/p&gt;&lt;br /&gt;&lt;p align=justify&gt;На мой скромный взгляд, Nemerle уже полностью готов к тому, чтобы заменить C# в коммерческих проектах. Более того, его использование позволит увеличить производительность труда программиста в разы! Я думаю, что у этого языка очень большое будущее. Я могу откровенно сказать, что я успел полюбить Nemerle, и собираюсь писать о нем здесь в дальнейшем. Для начала я хочу дать ряд полезных ссылок, которыми вы можете воспользоваться, если заинтересуетесь этим языком (а вы должны им заинтересоваться!). Кроме того, я буду рад ответить на любые вопросы, которые у вас могут возникнуть.&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org"&gt;Сайт&lt;/a&gt; Nemerle (там вы можете найти общую информацию по языку, объяснение его концепций, учебные материалы и многое другое; ниже я привожу несколько ссылок на отдельные страницы сайта)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org/Reference_Manual"&gt;Спецификация&lt;/a&gt; языка (незаконченная)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org/Authors_and_Contact"&gt;Контакты&lt;/a&gt; с создателями и разработчиками&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org/Step_by_step_guide_to_get_Nemerle_compiler_running"&gt;Страница&lt;/a&gt; для скачивания инсталлятора (Внимание! На момент написания этой заметки там лежала очень древняя версия 0.9.3. Вы наверняка захотите после ее установки взять свежие исходники из репозитория и скомпилировать новую версию)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org/svn/nemerle/trunk"&gt;Репозиторий&lt;/a&gt; SVN (Если вы мало знакомы с SVN, то вам &lt;a href="http://ru.wikipedia.org/wiki/SVN"&gt;сюда&lt;/a&gt;. Или же вы можете сразу скачать клиент TortoiseSVN &lt;a href="http://tortoisesvn.net/downloads"&gt;здесь&lt;/a&gt;, установить его и разобраться по встроенному help'у)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://rsdn.ru/forum/?group=nemerle"&gt;Форум&lt;/a&gt; по Nemerle на русском языке&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://rsdn.ru/summary/3766.xml"&gt;Статьи&lt;/a&gt; по Nemerle на русском языке&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://blog.gmane.org/gmane.comp.lang.nemerle.devel"&gt;Конференция&lt;/a&gt; по Nemerle на английском языке, где можно встретить создателей языка&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://rsdn.ru/article/nemerle/Nemerle.VsIntegration-ru.xml"&gt;Интеграция&lt;/a&gt; Nemerle и Visual Studio (статья на русском языке, содержащая ссылки для скачивания. Если вам будет что-то непонятно, или что-то не получится, обязательно спросите на этом &lt;a href="http://rsdn.ru/forum/?group=prj.nemerle"&gt;форуме&lt;/a&gt;)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://nemerle.org/bugs"&gt;Баг-трекер&lt;/a&gt; (компилятор и интеграция)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://ru.wikipedia.org/wiki/Nemerle"&gt;Страница&lt;/a&gt; в википедии на русском&lt;/li&gt;&lt;br /&gt;&lt;li&gt; &lt;a href="http://en.wikipedia.org/wiki/Nemerle"&gt;Страница&lt;/a&gt; в википедии на английском&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ну и, конечно же, &lt;a href="http://www.google.ru/search?q=Nemerle"&gt;гугл&lt;/a&gt;!&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/298035149877685257-4464215071463871176?l=nikovs-blog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://nikovs-blog.blogspot.com/feeds/4464215071463871176/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=298035149877685257&amp;postID=4464215071463871176' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4464215071463871176'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/298035149877685257/posts/default/4464215071463871176'/><link rel='alternate' type='text/html' href='http://nikovs-blog.blogspot.com/2007/02/nemerle.html' title='Nemerle'/><author><name>nikov</name><uri>http://www.blogger.com/profile/09098804672633390029</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/-R1UoD5EEZmk/TbYxDVJJM2I/AAAAAAAAAJc/SCuA3FRsLyE/s220/nsn190.jpg'/></author><thr:total>6</thr:total></entry></feed>
