Pull to refresh
32
0
Илья Константинович Никитин @w495

Пользователь

Send message
Это ветка, конечно, похожа на холивар, но Вы приводите интересные и очень разумные аргументы, потому предлагаю продолжить.
Получат позже
Я с Вами согласен, что применять что-то пилотное в активном и критически важном проекте — не правильно. Но, как мне кажется, нужно смотреть дальше чем один проект. Живем не сегодняшним днем, и Ваши 5k строк через некоторое время могут превратиться в 50k, 500k строк (и это нормально) и их надо будет как-то поддерживать. Если есть немного свободного времени, посмотрите Cesarini F. Erlang programming, и сравните с тем что уже имеете.
язык программирования
Согласен, но как лингвист, я скажу что любые языки принципиально не эквивалентны. Сам язык, что — просто набор правил над некоторым множеством символов. Но за каждым естественным языком стоит его культура. За искусственным — парадигма, или архитектура абстрактной машины этого языка.
Знание внешней оболочки языка, без понимания основания делает человека «языковым чудищем». Вы просто спросили как пройти, а вам морду набили.
Парадигмы-то они эквивалентны, но некоторые вещи в лямда выражениях выглядят проще, удобнее, эффективнее, чем в рамках стековой машины (java, .net, python) или машины фон Неймана (C\C++, Fortran).
сделать удобную для проекта и задач платформу
По сути, тоже реализация некоторого языка, на основе существующего. А такое лучше делать на функционального подхода. + Делать платформу — это тоже время. А если она станет одноразовой, и даже частично не применимой, к чему-то другому — слишком дорого.
Локальные решения это хорошо, но только они не позволяют находить других локальных решений, которые, может быть, лучше. Траншею можно копать саперной лопаткой, а можно экскаватором. Если траншея одна в принципе, то лопатой, конечно быстрее. Она получится даже аккуратнее. А на экскаваторщика придется еще учиться. Но если траншей сотни, то лопата уже не применима.
пока компилится С-шный код.

Вот тут мне кажется, ты не прав. Что такое у тебя долго компилировалось? И как долго?
Имхо, такие 5k как раз, скомпилятся вполне себе быстро.
А как же синергетический эффект? )

в плане асинхронности добавили

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

получат имап позже

Возможно, а возможно и раньше. + есть одна важная деталь — сопровождение. Не только сегодняшним днем живем. И не в любых своих (и чужих) исходниках двухлетней давности приятно разбираться.

Как раз для изучения плюсов и минусов той или иной технологии, применительно к текущим задачам и нужны в компании консультанты.
c_port как вариант, а так, как настроите-сделаете. Обычно, да — но, это вроде как логично, но все настраиваемо. Может и erl_driver замутить.

Я во общем вас не агитирую, просто ответил, на не очень правильные аргументы с вашей стороны. А у программы все один критерий правильности: работает — значит не все плохо.

Ближе к теме:
5k хорошо комментированного, понятного кода, или как голые функции, c короткими именами и однобуквенные переменные?
Плюс, надо изобретать какие-то обертки для C-шного кода в эрланг

Для таких вещей все и придумывалось. Наш стримящий сервер был написан тоже в лохматые времена на C. Не мешает его испрльзовать через erlang. Тем более, не надо ничего изобретать!
www.erlang.org/doc/tutorial/c_port.html
Реальный пример использования:
github.com/zavr/erlxslt (многопоточная обертка над libxslt)

Программистов на эрланге у нас в команде просто нет.

Вопрос двух недель. У нас тоже не было.

Если Вы любите, TeX, пример — есть такие хорошие понятия в TeX как «блоки» и «клей». В переложении на мир технологий, erlang — и есть этот «клей». Это не просто еще один язык разработки, в том-то и его преимущество (мы же Вам не ocaml или haskell предлагаем).
Можно писать, на самом erlang все, но если уже что-то есть сделанное, не обязательно переписывать. Составные части, как мне кажется, логично продолжить писать на сях, а вот склеивать их эрлангом. Но это мое скромное мнение.
Вам, в вашей ситуации виднее.
Если я воспроизвел именно ту ошибку о которой говорил, то я немного соврал. Уж слишком давно это было. Да и во общем, вроде уже проблему решили, не актуально.

Проболема была в multipart/alternative. Т.о., с вашей стороны все было сделано, формально правильно. Однако, поведение, интерфейса почты
— странно, и несколько не предсказуемо.

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

  1. Если указать, multipart не mixed, a alternative, в mail.ru вложение приходит то в гриде просмотра почты не отображается, что есть вложение. У mail.yandex.ru показывает, что вложение есть, но в письма вложения вообще нет (скачивать нечего). То, что вложение есть показывается не сразу после получения письма, а если немного подождать. У gmail.сom все ок.
    Если я действительно, воспроизвел ту самую проблему, понятно, почему у mail.yandex.ru она не была замечена. Не факт, что внутрь письма заглядывали, когда тестировали полгода назад.

  2. Была замечена ошибка у mail.yandex.ru. Если отправлять письмо без, Content-Transfer-Encoding: base64 то в гриде просмотра почты не отображается, что есть вложение. Всего скорее проблемы в интерфейсе. Потому что поcле просмотра письма значок аттача появляется. У mail.ru все ок. У gmail.сom все ок.
  3. Если не указать disposition-params у mail.ru, то нет аттача в гриде просмотра почты. Если открыть само письмо, то аттач есть (Untitled.pdf вместо имени). Проблема всего скорее только в интерфейсе, ибо thunderbird этот аттач видит и до открытия письма. У mail.yandex.ru в этом случае вообще не показывает аттача. У gmail.сom все ок, но вложение соответсвенно называется noname (без расширения).
  4. Была замечена ошибка у mail.yandex.ru Если отправлять письмо без, content-type-params, то в гриде просмотра почты не отображается, что есть вложение. У mail.ru все ок. У gmail.сom все ок.


Несколько урезанные версии писем на которых тестировалось:
gist.github.com/b5bb40d982604b40b5b7
Полные версии продублировал на почту.
SMTP сервере.
— Клиенте.
Gen_smtp занимается отправкой, но только в качестве клиента. Отправкой занимается sendmail (как я понимаю), который находится удаленно.
Остальное, вы поняли правильно.

Возможно, как верно подметил ниже Макс, это как раз пример такого «чу́дного клиента».
Попробую сделать что вы сказали.
Писали мы клиент, который отправляет пользователю счет (с инн \ кпп, пасьянсом и барышнями) формате pdf. Использовали для сего действия gen_smtp.

Тестовые письма

Все три письма идентичны и все с вложениями. Только для последнего (первого в списке) был указан параметр application=pdf. Content-Type во всех случаях был application/pdf.
Что конкретно, мы отправлялось, не проверяли.
Если, любопытно, могу и покопаться.
Такая проблема была (и есть?) только у mail.ru.

Извиняюсь за офтоп (хотя вся ветка — оффтоп),
но на всякий пожарный приведу код:
mail(         {FromName, FromEmail}, 
                {ToName, ToEmail}, 
                Subject, 
                Body, 
                {AttachName, AttachBinary}
) -> 
    Email = {<<"multipart">>, <<"mixed">>, [
                {<<"From">>, mmh_person(FromName, FromEmail)},
                {<<"To">>, mmh_person(ToName, ToEmail)},
                {<<"Subject">>, list_to_binary(Subject)}],
            [],
            [
             %% Тело письма
             {<<"text">>,<<"plain">>, [], [], list_to_binary(Body)},
             %% Аттачменты(PDF) 
             {<<"application">>,<<"pdf">>,
                [{<<"Content-Type">>,<<"application/pdf">>},
                 {<<"Content-Transfer-Encoding">>,<<"base64">>}],
                [
                 {<<"content-type-params">>,
                [{<<"name">>, list_to_binary(AttachName)}],
                [{<<"x-unix-mode">>,<<"0644">>}]},
                {<<"disposition">>,<<"attachment">>},
                {<<"disposition-params">>,[{<<"filename">>, 
                                list_to_binary(AttachName)}]}],
                AttachBinary}
            ]},
    gen_smtp_client:send(
        {
            FromEmail,
            [ToEmail],
            mimemail:encode(Email)
        },  ?SYS_MAIL_OPTIONS
    ).

Вопрос не совсем по теме, но весьма меня волнующий.
mime вложений, разсширение, magic проверяются у вас уже или пока нет?
Помню, полгода назад с этим были проблемы. У gmail не было.
На тему языка, сейчас работаем над еще одним внутренним проектом, для которого, как мне сейчас кажется, крайне подошел бы такой специализированный язык. Надеюсь мое мнение разделят другие разработчики. Ибо сейчас это начинает превращаться в кашу из удаленных вызовов, операций с портами, исправлений проблем mochiweb.
Ну это похоже на то, о чем говорил Боб Ипполито на конфе в Яндексе. Правила отбора рекламы. В неформальной постановке правила оказались настолько сложными (а мы таки заботимся, чтобы пользователь не посмотрел слишком много рекламы), что для их формализации пришлось написать маленький интерпретатор lisp-подобного языка. По сути это просто набор фильтров. Но фильтры имеют строк действия, условия срабатывания, их можно складывать, вычитать, проводить операции как над множествами.

Из интересного:

  1. Интерпретатор не стал бутылочным горлышком, хотя мы этого ожидали. Скорость работы все равно упиралась только в базу (до его подключения упиралось в нее же).

    Офтоп:
    Во общем не удивительно, c одной стороны. Когда я тестировал erlang (R15 c HiPE) в другом проекте (http://www.slideshare.net/w-495/dsmts-diplomatext, отчати github.com/w495/ngrm-smt), то скорость была сопоставима с C. (Но, без HiPE, к сожалению, нет) Глобально сравнивал с Moses на тех же исходных данных с минимальными настройками для Moses. Локально, на сопственных сишных поделках. От питона, который, в силу обстоятельств, мы вынуждены поддерживать такого ожидать трудно (github.com/w495/ngrm-emt). ngrm-smt и ngrm-emt делают разные вещи, но ngrm-smt включает в себя часть функционала ngrm-emt.

  2. Я лично для себя познал всю мощь функций высшего порядка (lists:map, lists:filter и пр) и нативных функций работы со списком тегированных туплов (lists:key*), ибо размер кода они сильно уменьшили. В первой версии интерпретатора все писалось в стиле:

        handle_list([], Info, Opts) ->
            Info.
        handle_list([Param|Parms], Info, Opts)-> 
           Res = handle_item(Param),
           handle_list(Parms, [Res|Info], Opts).
    


    Как мне казалось, это эффективнее, чем передавать fun'ы. Но выглядело как нагромождение, чего-то несуразного, тяжело поддерживаемого. На скорость по моим замерам это не повлияло (всего скорее, повлияло на самом деле, но незначительно).
  3. Очередной раз убедились, что написание интерпретаторов на функциональных языках — не особо сложная задача. Даже при постоянно меняющихся требования. Первый раз я в этом убедился, когда за ночь написал компилятор обрезанной версии питона на lisp, еще в универе. Тогда это представлялось какой-то игрушкой. Но как оказалось подобные вещи весьма полезны. Вообще как, было написано, по-моему и М. Сипсера, чтобы решить проблему, достаточно правильно сформулировать язык ее описания. Ну вот мы и получили подтверждение.

Да, к сожалению, вслед за Бобом Ипполито, код предоставить вам не смогу. Придется поверить мне на слово.
Смотря как писать. Имхо, для некоторых задач подходит написание интерпретатора своего специфического языка (flex, bizon помогут), и написание сервера на этом специфическом языке. Правда нам было лень писать его на С, и мы написали на erlang.
Макс, оформи код, пожалуйста, через
<source lang="erlang">
    foo(X)-> {bar, X}.
</source>

А то читать, ну совсем тяжело, ни тут, ни в жж.
Дополнение: «обработка такого варианта» впринципе невозможна. Проблема в том, что аргументом декоратора может быть только литеральный терм. Т.е. fun там запрещен. До нашего parse_transform дело даже не найдет.
Код типа

-d(fun(Fun, Fargs)-> apply(Fun, Fargs) end).
function(X)->
    X.

или

-d(fun Mod:Fun/2).
function(X)->
    X.

будет отвергнут парсером еще до применения parse_transform.
Ключевой момент. В вашей реализации декоратор возвращает значение. Но должен функцию. Это позволит комбинировать декораторы в рантайме.
Точная цитата и ее окружение воспринимаются в одном контексте. Или если с внешней стороны от кавычек есть текст, точная цитата перестает быть таковой?

Ошибки поиска go.mail.ru. Точная цитата и ее окружение воспринимаются в одном контексте.
всё обойти
На этапе обучения — чтобы лучше понимать саму OTP. Только делать это надо осознано, а не с целью, сделать свое с 0 и лучше. Рано или поздно, возникают ситуации, которые уже нельзя обойти. Это редкость, но досадная. Лучше сразу понимать как и что устроено.
Продолжение: +1.
erlang:element(1, Resource). 
?

Имхо, не очевидные вещи. + Закладка на порядок. Это, таки, эффективно, но совсем не расширяемо.
Еще раз объясните, пожалуйста, зачем все это нужно и что мы с этого имеем? Почему нельзя просто вызвать модуль статические, или например передать его вторым параметром?
В таком случае да. Только это не математическое определение. Эффективно, но неудобно.
Хочется писать что-то в духе (хотя это и будет дорого по памяти):
?MEMOIZE.
fact(1) -> 1;
fact(N) when N > 1 ->
    N * fact(N - 1)

Но в этом случае, бессмысленно запоминать промежуточные результаты.
Тут это ничего не даст. Для более «сложных» примеров ваши декораторы тоже выглядят правдоподобно.
?MEMOIZE.
fib(0) -> 1;
fib(1) -> 1;
fib(N) when N > 1 ->
    fib(N - 1) + fib(N - 2)

Ключевой момент тут, что fib(N — 2) должна использовать результаты промежуточных вычислений fib(N — 1). После вычисления целевой функции хранить промежуточные результаты смысла особого не имеет, только конечный. Во общем на то и нацелен каскад непонятных функций в примере. Если их удаться удачно убрать в декоратор, то будет здорово.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity