Информация об изменениях

Сообщение Re[3]: Не Bosque language от 25.04.2019 10:26

Изменено 25.04.2019 10:33 D. Mon

Re[3]: Не Bosque language
Здравствуйте, AlexRK, Вы писали:

ARK>А этот язык секретный? Информацию о нем можно "выдавать" или запрещено? Было бы интересно о нем узнать поподробнее.


Не секретный, в начале мая на dconf мои коллеги будут про него что-то рассказывать. Но он активно развивается и меняется, пока что не очень интересный.
Контекст: есть инвестиционный фонд, в нем некоторое количество аналитиков и исследователей, которым надо играться с данными, анализировать риски, строить отчеты. До этого у них был Excel, SQL и несколько разнородных финансовых систем. Плюс у разных команд накопился какой-то код на Плюсах, Шарпе, Джаве, Питоне и Ди. Запилили свой нарочито ограниченный интеграционный язык, интерпретатор которого умеет взаимодействовать с самым разным имеющимся кодом на разных языках, говорить с БД, и доступен как в отдельном репле, так и прямо из Экселя. В итоге аналитикам не надо сразу учить "настоящее" программирование на взрослых языках, где легко прострелить ногу, но возможностей у них стало намного больше, чем было с их Экселем, плюс все теперь в скриптах с контролем версий, проектами-ветками-мерджами в гитлабе, с тестами. Культурно!

Выглядит сейчас код на нем так:
posInfLinkerBreakeven_Net(iso, ent, pfolio, subPfolio) => (greeksByPfolio
                                                           |> byEPS(ent, pfolio, subPfolio)
                                                           |> filterCountry(countries[iso])
                                                          ).usdInfDelta |> sum

bucketByTenorFactorsAndWeight(bs, keyToWeight, tnrFactors) =>
    tnrFactors
    |> keys
    |> mapa(tf => ((bs
                    |> filterTenors( tenorsInTenorFactor[tf] ))[keyToWeight]
                    |> sum) / tnrFactors[tf])

fxVegaByUnderlier (ent, pfolio, subPfolio) =>
{
    dataEPS = fxVegaByPfolio
              |> byEPS(ent, pfolio, subPfolio)

    in dataEPS.underlierInfo
       |> sort
       |> uniq
       |> mapa(ulier => {"FxUnderlier" : ulier, "FxVegas" : dataEPS |> fxVegaUnderlier(ulier)})
}

posEquityStressScenario(charc, ent, pfolio, subPfolio) =>
{
    ranking = (if (charc[$-2] >= '0') && (charc[$-2] <= '9')
                 then charc[$-2:$]
                 else charc[$-1:$]
              ) |> parseInteger

    // Get data
    filtered = eqSpotGrouped[pfolio]
                        |> filterEntity(ent)
                        |> filterSubPortfolio(pfolio, subPfolio)

    sums = filtered
        |> groupByCols(["underlierInfo"])
        |> mapa(g => (g.group |> pivot(["scenarioName"], { "plBase" : sum })).plBase |> min)
        |> sort

    in sums[ranking - 1]
}

posIndexRollCS01(creditIndex, ent, pfolio, subPfolio) =>
{
    retCS01 = 0.0
    seriesData = cs01ByPfolio
                 |> byEPS(ent, pfolio, subPfolio)
                 |> cs01sPerSeries(creditIndex)

    seriesData = if tableLen(seriesData) >= 2 then seriesData else {"CS01" : [0.0, 0.0]}

  in abs(seriesData.CS01[$-1] - seriesData.CS01[$-2])
}

pivot__tableSlice(tableIn, start, end) => tableIn |> keys |> fold((r, k) => r |> addEntry(k, tableIn[k][start : end]), {})

pivot__sortedIndex(r) => iota(len(r)) |> sortBy((aI, bI) => r[aI] < r[bI])


Есть лямбды и передача первоклассных функций-замыканий туда-сюда, данные иммутабельны, if-else возвращает значение, есть литералы для массивов и "объектов" (хэш-таблиц со строковыми ключами), ряд операций вроде map ленивые, возвращают рэнджи (в терминологии Ди), поэтому композиция из нескольких map/filter не создает промежуточных массивов. Все сводится к функциям (раскинутым по модулям) и выражениям, никаких циклов, никаких записей в массивы. Типы пока что проверяются в рантайме, но скоро добавлю их вывод и статическую проверку. Реализован в виде довольно тупого интерпретатора на D. Благодаря статической интроспекции в D, подключать нативный код очень легко, все поля и методы нативных структур и объектов автоматически становятся видны из интерпретатора, и там тоже есть своя интроспекция, можно видеть содержимое модулей и объектов, имена и типы полей/методов.
Я занимаюсь сердцем интерпретатора, еще несколько человек добавляют "конечности" — то, через что он общается с экселем, БД и другими системами и кодобазами.

Из анекдотов: зимой у нас в гите появилась ветка с говорящим названием a_stack_would_be_nice. Ибо после некоторых смелых оптимизаций оказалось, что стало можно рекурсивно вызывать ф-ии (раньше рекурсия была запрещена), но полноценного стека не было — рекурсивный вызов затирал локальные переменные вызывающей ф-ии. Но реальный код при этом продолжал работать, т.к. на практике рекурсия не использовалась. Осознав беду, стек добавили. Но по-прежнему, если нет рекурсии, то вызов ф-ии не вызывает выделения памяти — место для локальных переменных преаллоцировано заранее. Это, правда, привело к другой проблеме: при выходе из ф-ии ее локальные переменные оставались живыми в памяти и не мешали сборке мусора, держась за ненужные уже данные. Так появилась ветка let_it_go, где их научили отпускать, больше не держаться.

Отдельное спасибо языку Раст: при редактировании скриптов на нашем ЯП народ просто выбирает в своем редакторе синтаксис Раста, и подсветка кода готова. Свою делать не понадобилось.
Re[3]: Не Bosque language
Здравствуйте, AlexRK, Вы писали:

ARK>А этот язык секретный? Информацию о нем можно "выдавать" или запрещено? Было бы интересно о нем узнать поподробнее.


Не секретный, в начале мая на dconf мои коллеги будут про него что-то рассказывать. Но он активно развивается и меняется, пока что не очень интересный.
Контекст: есть инвестиционный фонд, в нем некоторое количество аналитиков и исследователей, которым надо играться с данными, анализировать риски, строить отчеты. До этого у них был Excel, SQL и несколько разнородных финансовых систем. Плюс у разных команд накопился какой-то код на Плюсах, Шарпе, Джаве, Питоне и Ди. Запилили свой нарочито ограниченный интеграционный язык, интерпретатор которого умеет взаимодействовать с самым разным имеющимся кодом на разных языках, говорить с БД, и доступен как в отдельном репле, так и прямо из Экселя. В итоге аналитикам не надо сразу учить "настоящее" программирование на взрослых языках, где легко прострелить ногу, но возможностей у них стало намного больше, чем было с их Экселем, плюс все теперь в скриптах с контролем версий, проектами-ветками-мерджами в гитлабе, с тестами. Культурно!

Выглядит сейчас код на нем так:
posInfLinkerBreakeven_Net(iso, ent, pfolio, subPfolio) => (greeksByPfolio
                                                           |> byEPS(ent, pfolio, subPfolio)
                                                           |> filterCountry(countries[iso])
                                                          ).usdInfDelta |> sum

bucketByTenorFactorsAndWeight(bs, keyToWeight, tnrFactors) =>
    tnrFactors
    |> keys
    |> mapa(tf => ((bs
                    |> filterTenors( tenorsInTenorFactor[tf] ))[keyToWeight]
                    |> sum) / tnrFactors[tf])

fxVegaByUnderlier (ent, pfolio, subPfolio) =>
{
    dataEPS = fxVegaByPfolio
              |> byEPS(ent, pfolio, subPfolio)

    in dataEPS.underlierInfo
       |> sort
       |> uniq
       |> mapa(ulier => {"FxUnderlier" : ulier, "FxVegas" : dataEPS |> fxVegaUnderlier(ulier)})
}

posEquityStressScenario(charc, ent, pfolio, subPfolio) =>
{
    ranking = (if (charc[$-2] >= '0') && (charc[$-2] <= '9')
                 then charc[$-2:$]
                 else charc[$-1:$]
              ) |> parseInteger

    // Get data
    filtered = eqSpotGrouped[pfolio]
                        |> filterEntity(ent)
                        |> filterSubPortfolio(pfolio, subPfolio)

    sums = filtered
        |> groupByCols(["underlierInfo"])
        |> mapa(g => (g.group |> pivot(["scenarioName"], { "plBase" : sum })).plBase |> min)
        |> sort

    in sums[ranking - 1]
}

posIndexRollCS01(creditIndex, ent, pfolio, subPfolio) =>
{
    retCS01 = 0.0
    seriesData = cs01ByPfolio
                 |> byEPS(ent, pfolio, subPfolio)
                 |> cs01sPerSeries(creditIndex)

    seriesData = if tableLen(seriesData) >= 2 then seriesData else {"CS01" : [0.0, 0.0]}

  in abs(seriesData.CS01[$-1] - seriesData.CS01[$-2])
}

pivot__tableSlice(tableIn, start, end) => tableIn |> keys |> fold((r, k) => r |> addEntry(k, tableIn[k][start : end]), {})

pivot__sortedIndex(r) => iota(len(r)) |> sortBy((aI, bI) => r[aI] < r[bI])


Есть лямбды и передача первоклассных функций-замыканий туда-сюда, данные иммутабельны, if-else возвращает значение, есть литералы для массивов и "объектов" (хэш-таблиц со строковыми ключами), ряд операций вроде map ленивые, возвращают рэнджи (в терминологии Ди), поэтому композиция из нескольких map/filter не создает промежуточных массивов. Все сводится к функциям (раскинутым по модулям) и выражениям, никаких циклов, никаких записей в массивы. Типы пока что проверяются в рантайме, но скоро добавлю их вывод и статическую проверку. Реализован в виде довольно тупого интерпретатора на D. Благодаря статической интроспекции в D, подключать нативный код очень легко, все поля и методы нативных структур и объектов автоматически становятся видны из интерпретатора, и там тоже есть своя интроспекция, можно видеть содержимое модулей и объектов, имена и типы полей/методов.
Я занимаюсь сердцем интерпретатора, еще несколько человек добавляют "конечности" — то, через что он общается с экселем, БД и другими системами и кодобазами.

Из анекдотов: зимой у нас в гите появилась ветка с говорящим названием a_stack_would_be_nice. Ибо после некоторых смелых оптимизаций оказалось, что стало можно рекурсивно вызывать ф-ии (раньше рекурсия была запрещена), но полноценного стека не было — рекурсивный вызов затирал локальные переменные вызывающей ф-ии. Но реальный код при этом продолжал работать, т.к. на практике рекурсия не использовалась. Осознав беду, стек добавили. Но по-прежнему, если нет рекурсии, то вызов ф-ии не вызывает выделения памяти — место для локальных переменных преаллоцировано заранее. Это, правда, привело к другой проблеме: при выходе из ф-ии ее локальные переменные оставались живыми в памяти и мешали сборке мусора, держась за ненужные уже данные. Так появилась ветка let_it_go, где их научили отпускать, больше не держаться.

Отдельное спасибо языку Раст: при редактировании скриптов на нашем ЯП народ просто выбирает в своем редакторе синтаксис Раста, и подсветка кода готова. Свою делать не понадобилось.