codewars / codewars-runner-cli

Old CodeRunner project. See https://github.com/codewars/runner instead.
GNU Affero General Public License v3.0
402 stars 141 forks source link

Haskell GHC 8 support #454

Closed Voileexperiments closed 6 years ago

Voileexperiments commented 7 years ago

So, now that Node 8 support is finally done (#432), what about Haskell 8 which also ends with a 8? I know of some power Haskell users who really need Haskell 8 to do their new and fancy things.

More specifically, what can be done to speed up the process of integrating Haskell 8 into CW?

MarisaKirisame commented 7 years ago

❤️ 👏 👍 👏 😄 👏 If You Are Happy and You Know It Clap Your Hands!

jhoffner commented 7 years ago

Is Haskell 8 fully compatible with 7? If so then we can just update the version, otherwise both versions will need to live on the same docker image.

I'm not going near any of this since I don't know anything about Haskell.

More specifically, what can be done to speed up the process of integrating Haskell 8 into CW?

  1. Fork this repo
  2. Make your changes
  3. Submit a PR

:)

kazk commented 7 years ago

If it's not compatible, we can have multiple GHC versions using stack if I remember correctly. Or introduce images tagged with versions.

@jhoffner what does failing spec in README mean?

hspec!!! An older version is running on CW & Qualified that is fully functional

I've read somewhere that Haskell needs some rework and tests has some issues due to how Codewars customized it. I can't remember where I saw this.

jhoffner commented 7 years ago

The Haskell image used on our servers hasn't been updated in a long time. For a while I wasn't able to fix it myself without investing a lot of time into it. It was frozen, but now its passing its specs so I'm re-adding it to the staging servers and will be testing, along with the other new languages. At the very least it looks like it will get bumped to version 7.10.

kazk commented 7 years ago

I don't think it's implemented correctly. image

The output format is wrong (leading spaces by me):

<DESCRIBE::>twoOldestAges
  <DESCRIBE::>[1,5,87,45,8,8]
    <IT::>should return (45,87) given [1,5,87,45,8,8] as input
      <PASSED::>Test Passed
    <COMPLETEDIN::>

  <DESCRIBE::>[6,5,83,5,3,18]
    <IT::>should return (18,83) given [6,5,83,5,3,18] as input
      <PASSED::>Test Passed
    <COMPLETEDIN::>
  <COMPLETEDIN::>
<COMPLETEDIN::>0.0017 seconds
kazk commented 7 years ago

Ok, I couldn't understand existing code so I just implemented from scratch for my side project. If compatibility is not an issue, I can try to adapt this.

Example test from their website:

<DESCRIBE::>Head
<IT::>returns the first element of a list
<PASSED::>Test Passed
<COMPLETEDIN::>
<IT::>returns the first element of an *arbitrary* list
<PASSED::>Test Passed
<COMPLETEDIN::>
<IT::>throws an exception if used with an empty list
<PASSED::>Test Passed
<COMPLETEDIN::>
<COMPLETEDIN::>

Can also be nested

<DESCRIBE::>Head
<DESCRIBE::>Prelude.head
<IT::>returns the first element of a list
<PASSED::>Test Passed
<COMPLETEDIN::>
<IT::>returns the first element of an *arbitrary* list
<PASSED::>Test Passed
<COMPLETEDIN::>
<IT::>throws an exception if used with an empty list
<PASSED::>Test Passed
<COMPLETEDIN::>
<COMPLETEDIN::>
<COMPLETEDIN::>

I haven't done test duration and the failure message is not pretty.

kazk commented 7 years ago

Maybe upgrading GHC from 7.10.3 to 8.0.x is fine, but the packages we install might have issues. For example, Hspec changed some types in Test.Hspec.Formatters so we need to rewrite the formatter if we want GHC 8.0.2.

LTS 6.24 (current)

LTS 7.24

LTS 8.22

bkaestner commented 6 years ago

Could we at the same time please deprecate the use of Test.Hspec (the codewars module) and instead provide a proper Test.Codewars.Runner or similar module with a stable API?

The current shadowing method is easy to break, as far as I can see.

kazk commented 6 years ago

@bkaestner I'd like to get rid of the shadowing in the new version and keep the current one as is for existing contents. Using Hspec with hspec-discover (to support multiple test files) and specifying custom formatter should be enough:

-- Main.hs
-- Automatically included
module Main where

import Test.Hspec.Runner
import Test.Hspec.Formatters
import Formatter (codewars)
import qualified Spec

main :: IO ()
main = hspecWith defaultConfig {configFormatter = Just codewars} Spec.spec
-- Spec.hs
-- Automatically included
{-# OPTIONS_GHC -F -pgmF hspec-discover -optF --module-name=Spec #-}
-- ExampleSpec.hs
module ExampleSpec (spec) where

import Test.Hspec -- not shadowed
import Example.Solution

spec :: Spec
spec = do
  describe "Example" $ do
    --- ...

If you know better ways to do this, please let me know.

bkaestner commented 6 years ago

That sounds reasonable, although your explicit support of multiple test files sound strange. As long as CW didn't change the katas testflow, there should be only one test file, right?

kazk commented 6 years ago

Currently yes, but adding multiple files support for Qualified.io is planned (maybe for Codewars as well). Using hspec-discover allows that without further changes in the future.

bkaestner commented 6 years ago

Sounds good so far. The only possible draw-back I can see is that Spec's or describe's type might change in a future hspec version and break the spec in ExampleSpec, but that's rather unlikely.

Do you want to publish Formatters on Hackage/Stackage? That could help with multiple GHC versions.

MarisaKirisame commented 6 years ago

What if we use stackage and pin the version for GHC8? No future breakage will happend, and we can upgrade all packages in batch (one for GHC 9, etc)

bkaestner commented 6 years ago

@kazk do you have a public repository where you work on that runner?

@MarisaKirisame I think that's what I had in mind, but we're could be talking about different things.

MarisaKirisame commented 6 years ago

@bkaestner to be clear, I mean we froze every package along with a ghc version, no upgrade, so no compatibility problem. And when we introduce another ghc version, we upgrade the package, but keep the old package in the old docker file. This can be done in hackage.

kazk commented 6 years ago

@bkaestner Sorry for the late reply. I just made a repository for the custom Hspec formatter. The new runner will do something similar to this:

stack runghc -- -ilibrary:src:test test/Main.hs

and is independent from the container images (it's not inside like the current one) allowing us to treat the environment mostly immutable. So in the future when we want GHC 9, we'll just make a new container image with packages compatible with that GHC, while leaving GHC 8 one alone.

@MarisaKirisame Yeah, I'm planning to use LTS Haskell 10.3 for this.


By the way, I've joined Qualified.io officially and will be leading the new code runner project that I've been working on for the past few months. So 2018 will be a pretty exciting year :) I haven't added much features to the new one yet (focused on the compatibility with this one), but there're few new languages (Julia, Fortran, PowerShell, NASM) and more up to date language versions (Elixir 1.6, Ruby 2.5, Swift 4). I'll try to add Haskell there soon.

kazk commented 6 years ago

Added Haskell GHC 8.2 (LTS Haskell 10.4) to the new runner. I don't know when we can make this available yet, but we're going to start testing the new runner and the infrastructure against real traffic soon.

kazk commented 6 years ago

Just an update, we're planning to release new languages and language versions tonight. This includes Haskell GHC 8.2. Note that the old one (GHC 7.10.3) will continue to work as is.

Sorry this took a long time and I appreciate your patience. As some of you already know, it was delayed because I was refactoring the entire system. The process of adding a new language version should be much easier in the future.

One major change is that tests now use Hspec directly (see the wiki page for basic example). Also, some packages are available and I'm open to suggestions.

Haskell wasn't well supported before since no one on the core team knew the language. I'll try my best to change that :)

Voileexperiments commented 4 years ago

@kazk Almost all Haskell katas has been updated to ghc 8.x, with a few exceptional cases that can't be fixed yet. Though I think you need to do these additional things:

  1. Double-check any katas which is still ghc 7.x only since when I double-check some of the katas they were removed from the list but did not have ghc 8.x enabled, aka some katas might be slipping off the net
  2. Search for any test suites with string quickCheck/quickCheckWith (case sensitive) because I do recall there are a few katas using that
  3. Search for usages of System.Random (aka searching for the string import System.Random) in test suites and preferably migrate them to Test.QuickCheck (though this is not at a very high priority)
kazk commented 4 years ago

Thanks!

  1. Found 1 new kata that doesn't have GHC 8.2 support. https://github.com/codewars/codewars.com/wiki/List-of-Haskell-Kata-to-Update#list-of-kata
  2. Found 38. https://github.com/codewars/codewars.com/wiki/List-of-Haskell-Kata-to-Update#list-of-kata-with-quickcheckquickcheckwith
  3. Found 62. https://github.com/codewars/codewars.com/wiki/List-of-Haskell-Kata-to-Update#list-of-kata-with-import-systemrandom