LINUX.ORG.RU

GHC 9.0.1

 , ,


0

3

Вышла новая версия компилятора языка Haskell — Glasgow Haskell Compiler. Из-за значительных изменений была увеличена мажорная версия компилятора.

Основные изменения:

  • Добавлена реализация линейных типов (расширение LinearTypes). Линейные типы позволяют отслеживать использование ресурсов на стадии компиляции и могут использоваться, среди прочих вещей, для статического управления памятью в стиле Rust.
  • Новая встроенная библиотека для работы с числами неограниченного размера: ghc-bignum. Её использование помогает с переносимостью в системах, где библиотека GMP по каким-либо причинам недоступна.
  • Улучшения в кодогенераторе, значительно увеличивающие производительность многих программ.
  • Улучшения в коде проверки сравнения с образцом (pattern matching), позволяющие находить лишние проверки в случаях, где раньше это было невозможно.
  • Новый IO-менеджер для платформы Windows. Раньше на Windows был использован IO-менеджер для Unix-систем, что приводило в худшей производительности на этой платформе. Также прекращена поддержка Windows Vista. Теперь для сборки и запуска программ на Haskell требуется минимум Windows 7.
  • Добавлено расширение QualifiedDo, расширяющее возможности по переопределению поведения кода.
  • Для сборки с LLVM теперь требуется версия 9.0 или выше.

Также недавно был выпущен корректирующий релиз GHC 8.10.4, исправляющий несколько багов в ветке 8.10.

>>> Подробности

Ответ на: комментарий от MOPKOBKA

Подтверждение чего? Ты берёшь код из не самого простого проекта (компилятор) с не самой простой предметной областью и просишь случайного чувака, который этот код впервые видит и с областью может не быть знаком, объяснить что этот код делает. Я бы тебя в независимости от языка нахер послал с такими подкатами. Ты бы ещё блин попросил программиста на C++ объяснить тебе исходники LLVM.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)

Расскажите, где этот язык программирования применяется и на сколько он востребован на рынке труда?

hummer ()
Ответ на: комментарий от hummer

где этот язык программирования применяется

Применяется в программировании.

на сколько он востребован на рынке труда?

Примерно на полтора, может два. Но жабопыхокодером всё равно проще найти работу.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от hummer

В тинькове. Для понтов - одно время там шобла то ли сосачеров то ли нулячеров, короче траллей из кодача в команду пришла. А поскольку в нулевых было модно дрочить на всякие там головоломки и прочий матан в проде, то эти инцелы там укоренились.

anonymous ()
Ответ на: комментарий от MOPKOBKA

Я не знаю как оценивать скорость относительно качеств

Не удивительно, потому что ты не правильно понял фразу.

Ну если только сравнивать с шаблонным кодом буста. Я проводил эксперименты на хескелистах, даже на ЛОРе с кем то, брал кусок из GHC и просил объяснить что он делает. Не могут объяснить.

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

Ну не знаю, перенес ты стейт из структур в аргументы.

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

anonymous ()
Ответ на: комментарий от MOPKOBKA

Ну если только сравнивать с шаблонным кодом буста. Я проводил эксперименты на хескелистах, даже на ЛОРе с кем то, брал кусок из GHC и просил объяснить что он делает. Не могут объяснить.

Попробуй тот же эксперемент с си++ что ли. А то как то ненаучно.

AndreyKl ★★★★★ ()
Ответ на: комментарий от DarkEld3r

Потому что это будет уже совершенно другой язык с другой системой типов. Что получается, если иметь два разных языка в одном, ты можешь увидеть на примере C++.

Тут из-за линейных типов были дикие срачи, и в итоге в язык приняли, вроде как, меньше чем собирались. Как раз таки чтобы не получилось, что часть кода написано на одном языке, а часть – на совершенно другом.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 2)

Ну оно отрадно. Ждем, пока библиотеки поднимутся с релизами. Пока в репах этого релиза нет.

gns ★★★★★ ()
Ответ на: комментарий от MOPKOBKA

Ну если только сравнивать с шаблонным кодом буста. Я проводил эксперименты на хескелистах, даже на ЛОРе с кем то, брал кусок из GHC и просил объяснить что он делает. Не могут объяснить.

Уж не знаю насколько в GHC код хороший (и идиоматический), но сравнение с плюсовым кодом показательно: там и код стандартной библиотеки специфический, даже не обязательно в буст залазить. Тут, конечно, могут прибежать неадекватные «царепоклонники», но средний плюсовик имеет дело с более простым кодом.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Потому что это будет уже совершенно другой язык с другой системой типов. Что получается, если иметь два разных языка в одном, ты можешь увидеть на примере C++.

Мысль понял. С другой стороны, если бы в С++ не продолжали тащить фичи, то его популярность/востребованность была бы меньше.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от monk

Я давал куски а не строчку, а куском была даже не одна функция. Но тут я думаю и одной функции хватит.

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

Второе задает имя для тайпдефа, видимо нужно для совместимости с gcc, какие то алиасы.

MOPKOBKA ()
Ответ на: комментарий от MOPKOBKA

т.е. ТЫ хорошо знаешь копилятор си, а ОНИ плохое знают компилятор хаскель из этого ты делаешь выводы что хаскель прохо читается? Вот когда ОНИ объяснят тебе кусок си, но не объяснят хаскель, тогда и делай выводы.

swelf ()
Ответ на: комментарий от MOPKOBKA

Не суть, на комбинации того что ТЫ понимаешь код на какомбыто нибыло языке + они не понимают код показанный тобой на хаскеле, нельзя делать выводы о читаемости. Энивей, си, даже обезьяна прочитает, а вот сможет ли безопасно для кода отрефакторить.

swelf ()
Ответ на: комментарий от swelf

нельзя делать выводы о читаемости
си, даже обезьяна прочитает

Ок %)

MOPKOBKA ()
Ответ на: комментарий от MOPKOBKA

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

Второе задает имя для тайпдефа, видимо нужно для совместимости с gcc, какие то алиасы.

Настолько плохо, что даже не смешно. Чтобы объяснить код в стиле «вот тут объявляется функция, а вот тут дёргается оператор, а потом значение кладётся в переменную», не нужно знать вообще ничего. Ты вот можешь объяснить, что именно код по ссылке делает и зачем он нужен там? И что будет, если например его удалить? Потому что ты тут разве что синтаксис языка распарсил.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Я выделил подчеркиванием что делает код. По первой ссылке члены структуры определяются то чем идет присваивание.

Если удалить то очевидно будет сегфолт %) При попытке узнать что же скрывается за именем, структура, энум, или что то еще.

Во втором думаю просто алиас не додефайнится так как имени не будет.

MOPKOBKA ()
Ответ на: комментарий от MOPKOBKA

По первой ссылке члены структуры определяются то чем идет присваивание.

Ты слишком буквально интерпретируешь вопрос. Я тебя спрашиваю не какие инструкции выдаёт компилятор, а какой смысл у этого кода.

Если удалить то очевидно будет сегфолт %)

Кому очевидно? А если не будет? А если просто будет неинициализированная память и программа выдаст мусор в консоль?

hateyoufeel ★★★★★ ()
Ответ на: комментарий от hateyoufeel

Я тебя спрашиваю не какие инструкции выдаёт компилятор, а какой смысл у этого кода.

Создается аттрибут, который отвечает за структуры, ему нужно указать поля, данные какие то о внутренностях. Как данные указывается символ, символ это энум, имя, тип (=энум). Вместо него можно указать поля, там же список.

Кому очевидно?

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

MOPKOBKA ()
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

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

Если код вообще не вызывать, то вообще ничего не будет, ага. А что будет, если к какой-нибудь переменной там добавить +1? Или тоже нужно дальше читать?

Как я уже тебе написал (на самом деле, читателям этого треда, потому как на твоё мнение покласть), ты не объяснил ровным счётом ничего о том, что именно этот код делает. Ты просто пересказал какие там есть операторы и в каком порядке.

hateyoufeel ★★★★★ ()
Последнее исправление: hateyoufeel (всего исправлений: 3)
Ответ на: комментарий от MOPKOBKA

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

anonymous ()
Ответ на: комментарий от hateyoufeel

Это троллинг тупостью? Этот код глубже не разбирается. Глубже только разбор того как регистры скачут. Я сообщил не про действия операторов, а про действия вызываемые операторами.

Хескеллисты кстати даже и близко не могли ответить что происходит в кусках, даже предположений не было (были но слишком примитивные, по типу «тут разбирается текст»).

MOPKOBKA ()
Последнее исправление: MOPKOBKA (всего исправлений: 2)
Ответ на: комментарий от MOPKOBKA

Это троллинг тупостью?

Почему ты у меня спрашиваешь? Ты же троллишь.

Хескеллисты кстати даже и близко не могли ответить что происходит в кусках, даже предположений не было.

Сразу нахер послали? Правильно сделали.

hateyoufeel ★★★★★ ()
Ответ на: комментарий от DarkEld3r

код стандартной библиотеки специфический, даже не обязательно в буст залазить.

Так-то во всех opensource stl читаемость и понятность кода одно из требований. Иначе сторонних помощников с их патчами будет гораздо меньше…

Вот как пример, что пишут:

The STL needs to be extremely fast at runtime; speed is one of C++’s core strengths, and most C++ programs use the STL extensively. As a result, we spend more time on optimization than most general-purpose libraries. However, we’re wary of changes that improve some scenarios at the expense of others, or changes that make code significantly more complicated and fragile. That is, there’s a «complexity budget» that must be spent carefully.

fsb4000 ★★★★ ()
Ответ на: комментарий от swelf

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

anonymous ()
Ответ на: комментарий от MOPKOBKA

и список членов структуры задается энумом.

Куда он записывается? В какое поле?

И про вторую строчку аналогичный вопрос, это функция или запись в поле, если в поле, то в какое?

видимо нужно для совместимости с gcc

Ты точно по коду, а не по комментариям и идентификаторам пытаешься угадать?

P.S. Можешь ссылку на код в компиляторе хаксела дать, который твои хаскелисты «понять» не могли?

monk ★★★★★ ()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Куда он записывается? В какое поле?

amlist, я же про твои строчки веду речь, просто описываю что перед ними.

Ты точно по коду, а не по комментариям и идентификаторам пытаешься угадать?

Имена переменных методов нельзя читать? Или в чем проблема? %)

MOPKOBKA ()
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от fsb4000

Так-то во всех opensource stl читаемость и понятность кода одно из требований.

Одно из, да. Но я скорее о том, что в std будет куча шелухи вроде __ префиксов и ifdef. Конечно, это просто визуальный шум, но всё-таки чтение кода несколько усложняет.

Вот как пример, что пишут:

Ну это можно трактовать по-разному. Всё-таки в таком коде производительность важна и не всегда очевидно, где проходит грань между «разумной сложностью».

DarkEld3r ★★★★★ ()
Ответ на: комментарий от MOPKOBKA

amlist

Не угадал.

struct attr {
	struct attr *next;
	unsigned int atype:12, sz:2;
	union aarg aa[];
};

вторая попытка.

Имена переменных методов нельзя читать?

Можно. Но комментированность кода не всегда определяет читабельность языка программирования.

Иначе APL очень читабельный язык: на https://rosettacode.org/wiki/Binary_search#APL абсолютно всё понятно.

monk ★★★★★ ()
Ответ на: комментарий от monk

Не угадал.

Нет, угадал. Твоя очередь. Что это, и что тут происходит?

ptCreateStaticBinds :: HscEnv -> Module -> CoreProgram
                     -> IO ([SptEntry], CoreProgram)
sptCreateStaticBinds hsc_env this_mod binds
    | not (xopt LangExt.StaticPointers dflags) =
      return ([], binds)
    | otherwise = do
      _ <- lookupGlobal hsc_env unpackCStringName
      (fps, binds') <- evalStateT (go [] [] binds) 0
      return (fps, binds')
  where
    go fps bs xs = case xs of
      []        -> return (reverse fps, reverse bs)
      bnd : xs' -> do
        (fps', bnd') <- replaceStaticBind bnd
        go (reverse fps' ++ fps) (bnd' : bs) xs'

    dflags = hsc_dflags hsc_env


    replaceStaticBind :: CoreBind
                      -> StateT Int IO ([SptEntry], CoreBind)
    replaceStaticBind (NonRec b e) = do (mfp, (b', e')) <- replaceStatic b e
                                        return (maybeToList mfp, NonRec b' e')
    replaceStaticBind (Rec rbs) = do
      (mfps, rbs') <- unzip <$> mapM (uncurry replaceStatic) rbs
      return (catMaybes mfps, Rec rbs')

    replaceStatic :: Id -> CoreExpr
                  -> StateT Int IO (Maybe SptEntry, (Id, CoreExpr))
    replaceStatic b e@(collectTyBinders -> (tvs, e0)) =
      case collectMakeStaticArgs e0 of
        Nothing      -> return (Nothing, (b, e))
        Just (_, t, info, arg) -> do
          (fp, e') <- mkStaticBind t info arg
          return (Just (SptEntry b fp), (b, foldr Lam e' tvs))

    mkStaticBind :: Type -> CoreExpr -> CoreExpr
                 -> StateT Int IO (Fingerprint, CoreExpr)
    mkStaticBind t srcLoc e = do
      i <- get
      put (i + 1)
      staticPtrInfoDataCon <-
        lift $ lookupDataConHscEnv staticPtrInfoDataConName
      let fp@(Fingerprint w0 w1) = mkStaticPtrFingerprint i
      info <- mkConApp staticPtrInfoDataCon <$>
            (++[srcLoc]) <$>
            mapM (mkStringExprFSWith (lift . lookupIdHscEnv))
                 [ unitIdFS $ moduleUnitId this_mod
                 , moduleNameFS $ moduleName this_mod
                 ]

      staticPtrDataCon <- lift $ lookupDataConHscEnv staticPtrDataConName
      return (fp, mkConApp staticPtrDataCon
                               [ Type t
                               , mkWord64LitWordRep dflags w0
                               , mkWord64LitWordRep dflags w1
                               , info
                               , e ])

    mkStaticPtrFingerprint :: Int -> Fingerprint
    mkStaticPtrFingerprint n = fingerprintString $ intercalate ":"
        [ unitIdString $ moduleUnitId this_mod
        , moduleNameString $ moduleName this_mod
        , show n
        ]

    mkWord64LitWordRep dflags
      | platformWordSize (targetPlatform dflags) < 8 = mkWord64LitWord64
      | otherwise = mkWordLit dflags . toInteger

    lookupIdHscEnv :: Name -> IO Id
    lookupIdHscEnv n = lookupTypeHscEnv hsc_env n >>=
                         maybe (getError n) (return . tyThingId)

    lookupDataConHscEnv :: Name -> IO DataCon
    lookupDataConHscEnv n = lookupTypeHscEnv hsc_env n >>=
                              maybe (getError n) (return . tyThingDataCon)

    getError n = pprPanic "sptCreateStaticBinds.get: not found" $
      text "Couldn't find" <+> ppr n

sptModuleInitCode :: Module -> [SptEntry] -> SDoc
sptModuleInitCode _ [] = Outputable.empty
sptModuleInitCode this_mod entries = vcat
    [ text "static void hs_spt_init_" <> ppr this_mod
           <> text "(void) __attribute__((constructor));"
    , text "static void hs_spt_init_" <> ppr this_mod <> text "(void)"
    , braces $ vcat $
        [  text "static StgWord64 k" <> int i <> text "[2] = "
           <> pprFingerprint fp <> semi
        $$ text "extern StgPtr "
           <> (ppr $ mkClosureLabel (idName n) (idCafInfo n)) <> semi
        $$ text "hs_spt_insert" <> parens
             (hcat $ punctuate comma
                [ char 'k' <> int i
                , char '&' <> ppr (mkClosureLabel (idName n) (idCafInfo n))
                ]
             )
        <> semi
        |  (i, SptEntry n fp) <- zip [0..] entries
        ]
    , text "static void hs_spt_fini_" <> ppr this_mod
           <> text "(void) __attribute__((destructor));"
    , text "static void hs_spt_fini_" <> ppr this_mod <> text "(void)"
    , braces $ vcat $
        [  text "StgWord64 k" <> int i <> text "[2] = "
           <> pprFingerprint fp <> semi
        $$ text "hs_spt_remove" <> parens (char 'k' <> int i) <> semi
        | (i, (SptEntry _ fp)) <- zip [0..] entries
        ]
    ]
  where
    pprFingerprint :: Fingerprint -> SDoc
    pprFingerprint (Fingerprint w1 w2) =
      braces $ hcat $ punctuate comma
                 [ integer (fromIntegral w1) <> text "ULL"
                 , integer (fromIntegral w2) <> text "ULL"
]

hateyoufeel помогай!

MOPKOBKA ()
Последнее исправление: MOPKOBKA (всего исправлений: 2)
Ответ на: комментарий от MOPKOBKA

Нет, угадал.

Из определения struct attr *ap; и полей этой самой структуры не очевидно, что у ap нет поля amlist?

Что это, и что тут происходит?

Первая функция реализует расширение StaticPointers,формирует табличку статических ссылок и их значений.

Вторая формирует деклараций и тела функций hs_spt_init_*(void) __attribute__((constructor)) и hs_spt_fini_*(void) __attribute__((destructor))

monk ★★★★★ ()
Последнее исправление: monk (всего исправлений: 1)
Ответ на: комментарий от monk

Из определения struct attr *ap; и полей этой самой структуры не очевидно, что у ap нет поля amlist?

Я уже в IDE загрузился и проверил правильно ли я написал или нет.

Первая функция реализует расширение StaticPointers,формирует табличку статических ссылок и их значений.

Круто. Не думал что ответишь. (если конечно смысл ты полностью уловил)

MOPKOBKA ()
Последнее исправление: MOPKOBKA (всего исправлений: 1)
Ответ на: комментарий от MOPKOBKA

Я уже в IDE загрузился и проверил правильно ли я написал или нет.

И какие тогда поля у struct attr показывает твоя IDE?

Не думал что ответишь

Вторая функция тривиальная, чтобы полностью понять первую, пришлось глянуть, что вообще должно делать это расширения (то, что происходит замена результата collectMakeStaticArgs, понятно, но зачем — не очень).

monk ★★★★★ ()
Ответ на: комментарий от anonymous

питса только для программистов, и печеньки тоже.

anonymous ()
Ответ на: комментарий от MOPKOBKA

Загугли что такое «Парадокс Блаб», он, правда, про Лисп, но применим к любому нетривиальному языку.

demao ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.