Welcome to ITBlogs Sign in | Join | Help

Items

Своего рода заметки по любому поводу, но, конечно, в рамках IT.

Октябрь 2008 - Posts

Очень строгая типизация

Волею судеб я теперь играюсь с F#. (Сначала вроде бы увлёкся Haskell’ом, но потом понял, что F# мне как-то ближе, потому как он весь насквозь .net-ный). Если кто не знает, то язык этот – первый и пока что, кажется, единственный функциональный язык для платформы .net. Любители тонкостей скажут, что не такой уж он и функциональный, скорее мультипарадигменный (ох и сложное слово, надо его спеллчекером…), и будут правы. Так и есть, но я лично рассматриваю его как площадку для игр с функциональным программированием. И вот до чего я доигрался.

Есть у меня один микропроект. Даже не проект, а так, игрушка, которую я решил реализовать на F#, чтобы и утилитку полезную получить и с новым языком разобраться. Писал я писал, разбирался-разбирался и в один прекрасный момент понадобилось мне создать web запрос, да не простой, а с кукисами. Как бы я поступил в C#:

HttpWebRequest req =
(HttpWebRequest)WebRequest.Create("http://google.com");
req.CookieContainer.Add(new Cookie("my_cookie", "hello"));

Самая главная часть этого небольшого куска кода во второй строке, где создаётся WebRequest. Видите, как занимательно его приходится создавать? При помощи WebRequest.Create, который уже сам определяет какой конкретный тип запроса надо создать. В данном случае он создаст HttpWebRequest, поэтому преобразование типа здесь отлично сработает и даст нам доступ ко всем методам и свойствам, которые присущи http запросу.

В чём сложность с точки зрения F#? Как оказалось, в его строгой типизации.

let req = WebRequest.Create("http://google.com")
(* will cause an error *)
let httpreq = req :> HttpWebRequest

Архитектура библиотеки классов, как оказалось, не предполагает возможности создания экземпляров HttpWebRequest самих по себе, всё происходит исключительно через WebRequest.Create, а приведение типа объекта от более общего к более частному, получается, невозможно, а CookieContainer есть только в конкретном типе. Я пытался использовать обходные пути, типа Convert.ChangeType, но он, оказывается, возвращает вообще Object, и в итоге необходимо ещё более невозможное приведение типа :-)

Вот такая вот слишком строгая типизация. Если у кого есть мысли как это обойти – welcome!

Особое мнение
Вы наверняка уже слышали , что многими горячо любимый Google явил свету своё решение вечной проблемы межпроцессной коммуникации. Может быть название я подобрал не очень верное, но мне оно видится именно так. В чём суть? Суть в том, что очень часто возникает Read More...
Особое мнение

Вы наверняка уже слышали, что многими горячо любимый Google явил свету своё решение вечной проблемы межпроцессной коммуникации. Может быть название я подобрал не очень верное, но мне оно видится именно так.

В чём суть? Суть в том, что очень часто возникает необходимость заставить две части одной системы, расположенные физически на разных машинах, взаимодействовать между собой. Сделать это можно, конечно, разными способами. Самый очевидный ? использовать всем известные сокеты. Ок. О способе связи договорились, но тут возникает новая проблема: надо выбрать протокол взаимодействия. Надо сказать, что за всю историю существования телекоммуникаций, человечество придумало столько протоколов, что перечислить их все никакой википедии не хватит, но вот незадача, все они какие-то уж больно специфические. То есть, конечно, существует вероятность, что кто-то уже сталкивался с подобной проблемой и придумал специальный протокол, но гарантий нет. Остаётся только одно, сделать всё самому с нуля: определить протокол (кто? что? кому? и когда?), определить способ кодирования информации (бинарные данные, строки, XML, JSON), собственно, реализовать поддержку всего этого разнообразия и встроить в свою систему.

Решение от Google, названное, кстати, Protocol Buffers, автоматизирует последний этап, а именно, реализацию выбранного протокола. То есть теперь вся процедура будет выглядеть следующим образом:

  • создаём файл описания “.proto”
  • скармливаем его специально обученному компилятору
  • получаем рабочий код для формирования и разбора описанного протокола

Причём компилятор умеет генерировтаь код на нескольких языках: Java, Python, C++.

А теперь, внимание, вопрос! Зачем был изобретён велосипед, если есть ASN.1, который, если верить Википедии “originally defined in 1984”?

Я, конечно, понимаю, что у них там всё намного проще, чем в древнем ASN’е, но всё же… Лично мне они бы сильно упростили жизнь, если бы ничего не изобретали :-)