Feb. 14th, 2016

об Rust

Feb. 14th, 2016 02:24 am
yorool_gui: (лысый)
Решил я попробовать эту штуку. Впечатление от чтения документации очень хорошие. Будто взяли Haskell и выкинули оттуда то, что все равно слишком сложно для реальной жизни - ленивость, запрет побочных эффектов (к черту монады, стрелки и прочий матан), каррирование и вообще упор на извращения над функциями. Но оставили лямбды, замыкания, тайпклассы (тут они называются traits), паттерн матчинг и вообще представление программы как набора выражений.

Но вот в реальности все пока не так здорово.

Что я хотел сделать: написать на Rust клиент для Evernote.

Оказалось, что Evernote использует для внешних клиентов протокол Thrift - некая реализация RPC, как я понял. Протокол для конкретного приложения описывается файлами с расширением .thrift, из которых строятся исходники библиотеки для любого популярного языка. Кроме Rust-а, увы.

Есть реализация компилятора thrift для Rust-а от компании terminal.com, которые Rust активно используют у себя. Но реализация сырая, под windows по умолчанию не собирается, а собранная выдает искодники на Rust, которые без правок не компилируются.

И я почти прошел все грабли, добавил все недостающие определения в сгенерированные Rust-файлы и почти собрал реализацию Evernote-протокола на Rust, но уперся в итоге в тупик, из которого хорошего выхода не нашел.

Итак мне выдается ошибка
error: the trait `thrift::protocol::ThriftTyped` is not implemented for the type `ordered_float::OrderedFloat` [E0277]

Смотрю - да действительно, они этот Trait (это примерно то же, что интерфейс в яве или чисто виртуальный класс в C++) для OrderedFloat не реализуют. Т.е. они определяют этот трейт для кучи типов:

...
impl ThriftTyped for i32 { fn typ(&self) -> Type { Type::I32 } }
impl ThriftTyped for i64 { fn typ(&self) -> Type { Type::I64 } }
impl ThriftTyped for f64 { fn typ(&self) -> Type { Type::Double } }
impl ThriftTyped for () { fn typ(&self) -> Type { Type::Void } }
impl ThriftTyped for String { fn typ(&self) -> Type { Type::String } }
impl ThriftTyped for Vec { fn typ(&self) -> Type { Type::String } }
impl ThriftTyped for Vec { fn typ(&self) -> Type { Type::List } }
...


но вот OrderedFloat среди них нет. Ну ок думаю, определю его в сгенерированном файле сам, прямо перед использованием.
Пишу что-то вроде
impl ThriftTyped for OrderedFloat { fn typ(&self) -> Type { Type::Double } }

и - херак - получаю ошибку
error: the impl does not reference any types defined in this crate; only traits defined in the current crate can be implemented for arbitrary types [E0117]

Ну да, я читал в документации об этом запрете. Чтобы избежать запутанного и непредсказуемого кода, они разрешили реализовывать трейт для типа или там, где определен сам тип, или там, где определен трейт. Т.е. я не могу взять и сказать, например, что тип i32 теперь реализует оператор '+' (а операторы тоже можно перегружать через специальные трейты) как '-' - потому что не я объявлял i32 и не я объявлял трейт Add.

Но блин, вот мне прям щас надо сделать патч, а сделать я его не могу - точнее могу, если буду править прямо библиотеку, где этот ThriftTyped объявлен. Может я так и сделаю, но скорее всего брошу эту затею - что-то костылей уже многовато.

Profile

yorool_gui: (Default)
Michael Ilyin

April 2017

S M T W T F S
      1
2 345678
910 1112131415
16171819202122
23242526272829
30      

Most Popular Tags

Page Summary

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 27th, 2017 02:37 am
Powered by Dreamwidth Studios