codewars / runner

Issue tracker for Code Runner
33 stars 8 forks source link

Add C++ 20 #113

Open barnasm opened 3 years ago

barnasm commented 3 years ago

Please complete the following information:


:+1: reaction might help to get this request prioritized.

Urfoex commented 3 years ago

Probably still needs some time to mature. From ~ half a year ago, the support of version 20 features in compilers is still lacking a bit… https://github.com/codewars/runner/issues/42#issuecomment-719843559

Out of curiosity: Which features are you looking for?

barnasm commented 3 years ago

Some of the new features in std may help us write more compact code that is easier to read. for example std :: ranges, std :: to_array, std :: span, std :: map :: contains, std :: vector :: erase etc. Maybe that doesn't seem like a big deal, but I'd like to practice, learn and take advantages of the latest available standards.

So I will ask the opposite question. Which lack of compiler functionality prevents us from adding C ++ 20 support?

Urfoex commented 3 years ago

Ranges can at least be used somewhat with ranges-v3 library: https://github.com/codewars/runner/issues/42

Yeah, such neat methods would be nice. Doing latest C++ version, and then coming to some prior version, complaining that some things are not there, is always a little confusing. In such cases I just copy-paste the fitting old code.

Personally I would like to see the following still missing features:

But then again, for solving problems, they are not that much needed.

Also, currently Clang is used for compiling: https://github.com/codewars/runner/issues/42#issuecomment-719410228 With MSVC or GCC there would already be a bit more support.

All in all, definitively +1 for new version ^^

kazk commented 3 years ago

Which lack of compiler functionality prevents us from adding C ++ 20 support?

Technically, nothing prevents adding support (maybe the test framework need another patch, but haven't tried yet). I just don't want users to get confused and complain (e.g., "X is in C++20, but doesn't work on Codewars"). Unlike most of the languages with versions that describes the implementation, C++20 is a standard and compilers are still working on it. We show compiler name and version, but users won't look up the compiler support status.

That being said, we can add support sometime soon if C++ users think it's ready.

With MSVC or GCC there would already be a bit more support.

We can use GCC if necessary. I think Clang was chosen because of the better error messages many years ago. As far as I know, GCC got much better.

/cc @error256 @hobovsky

wrazik commented 3 years ago

Any update here?

As the compiler version is known, users can check support for a specific feature. C++ people are aware that C++20 is not fully supported in gcc & clang (MSVS is already feature-complete!)

C++20 changes significantly way of writing the code - concepts, ranges, coroutines. Algorithms will look totally different. C++20 is a must-have!

As already mentioned, it would be great to have ranges-v3 & fmtlib also available.

kazk commented 3 years ago

Any update here?

I'm waiting for feedback.

As already mentioned, it would be great to have ranges-v3 & fmtlib also available.

fmt and ranges-v3 are already supported.

wrazik commented 3 years ago

What feedback do you need? There is never too soon to upgrade the compiler :) Compiler support for C++20 features is available here: https://en.cppreference.com/w/cpp/compiler_support/20 . Gcc has better support for ranges so I would vote for switching to gcc. There is no significant difference in error readability nowadays.

I don't think you should wait till all features will be implemented. Missing stuff is rather minor, all game-changers (modules, ranges, concepts, couroutines) are there.

hobovsky commented 3 years ago

I am sorry, but I missed the notification that you mentioned me.

Unfortunately, as you probably noticed, my C++ skills are really rusty (I stopped doing professional C++ a couple of weeks before C++11 got published) and I am completely out of the loop when it comes to compilers, support matrices, most of modern features (modern as in C++11 and newer ;) ) so I have no strong opinion on whether C++20 is good to go or not.

The one thing I know I like about C++20 is formatting, improvements to containers (contains, yay!), and concepts (if I only wrap my mind around how to use them). However I'd definitely vote for C++20 if it'd mean anything better than Igloo ;)

There are two new members who are very active in area of C++ authoring, I could bring this topic to their attention and see what others think :)

wrazik commented 3 years ago

The difference between C++17 and C++20 is bigger than the difference between C++03 and C++11. It will really make a difference.

wtlgo commented 3 years ago

Hello, In my opinion, it would be better to wait a little bit more till compilers fully support C++20, but the current coverage by the most popular compilers is pretty enough to be useful. Though, I wouldn't for example use it in my personal projects yet.

mere-human commented 2 years ago

This issue is still relevant. Now Clang has support for most of the C++20 features. Using C++20 will allow to write more compact code using the best practices. Switching from C++17 to C++20 we will not lose anything. The same C++17 code is still valid. Clang C++20 status: https://clang.llvm.org/cxx_status.html#cxx20 https://libcxx.llvm.org/Status/Cxx20.html

Hariom-Algo commented 1 year ago

Any update ?

FilipPlotnicki commented 1 year ago

The ability to use c++20 features would be really helpful

ozz-life commented 11 months ago

New Year 2024 is coming soon...

bernb commented 11 months ago

Being restricted to C++17 makes it hard to use codewars to improve my C++ skills. I want to train good practice of today and the forseeable future, not good practice of 5 years ago that's already deprecated when it comes idiomatic C++.

Waldisss commented 8 months ago

When will C++20 be added?

kazk commented 8 months ago

I'm hoping sometime soon. I started looking into adding C++20 support before the end of the year. Testing with Igloo seems to be working, at least for the very basic tests, but I'm hesitating to continue using it with so many known issues.

Qualified doesn't use Igloo, so code runner currently supports GoogleTest and Criterion for C++ as well. I haven't been able to make these work with C++20 yet.

Catch2 mentioned in #52 is very nice and lightweight, so that's an option too.

Obviously, changing the test framework means all the existing kata must be updated manually, so this is not an easy decision to make.

What do you guys think?

hobovsky commented 8 months ago

Obviously, changing the test framework means all the existing kata must be updated manually, so this is not an easy decision to make.

Step 1: Create a 1 dan task for a script to migrate kata from one format to another. Step 2: Create a collectible badge for a user who converts most kata manually. Step 3: Wait.

Even better incentive could be making the obsolete C++ translations untrainable, and encourage the community members to fill the void.

Okay, but seriously now: I have never used neither Catch2 nor GoogleTest, so I have no preference. Heck, since custom assertion messages have been added to Snowhouse, the framework is at least bearable. However, what I would really like to get from the update of C++ setup is having snippets as separate translation units, or, ideally, possibility to represent solution snippet and preloaded as a pair of header file + implementation file.

Ad amount of kata and backwards compatibility: there's ~1200 C++ kata which would require an update. A lot, but still fewer (by a lot) than amount of kata which require(d) update for JS or Python. I know that update of C++ code would be more complex than JS or Python, but I would estimate the amount of effort as similar, and not much higher. Great effect would be that redoing C++ translations would hopefully help to get rid of really, really many terrible setups and designs: remove terrible requirements for rounding, strict float equality assertions, fix functions with bad or non-idiomatic signatures, adding random tests, improving structure of test cases, adding feedback for failing tests...

kazk commented 8 months ago

Yeah, we're doing that with GoogleTest. Qualified allows users to create files in the project directory, but also supports the minimal format like Codewars. In that mode, we create include/challenge.h from preloaded, src/solution.cpp from solution, and tests/test_solution.cpp from tests. {src,tests}/CMakeLists.txt are dynamically generated based on the list of input files. The tests have the target lib (src/) linked and uses header files in indlude/.

If we're making the setup incompatible, there's no reason to keep using Igloo.

kazk commented 7 months ago

Created https://github.com/codewars/next-cpp to show how the next C++ version may be supported, and to experiment publicly. I haven't had the chance to document it well, but I hope it's clear enough.

I didn't create container images, but you should be able to play with them if you have newish C++ compiler, CMake and Ninja. I'll accept PRs for Dockefiles. Feel free to contribute in any way.

Some feedback/help I'm looking for:

hobovsky commented 7 months ago

Don't we have some kata with custom stringifier?

I do not think you need to worry about these. Currently, in Snowhouse-based kata, the custom stringizers are used for one of two reasons: stringification of types not supported by default stringifier in assertion messages, and accuracy of floats in failure messages. The code of the stringifier is not referenced directly by any code of kata, so it can be removed and snippets will continue to compile (only messages will change at runtime). I expect the new framework to have some other way of solving the problem of presentation of data in texts (titles, messages, logs, whatever).

One potential problem can be direct calls to Stringizer<T>::stringify(T data) by some tests as a "lazy" way to stringify vectors, but these should not be many, and should be easy to fix by replacing with fmt or manual implementation.


I can try to set up GTest and Catch2 in my local VS and translate some kata and see how it goes. I do not know what kata can be especially tricky, except a couple of template metaprogramming ones ("factorial in compile time" etc), or macros, because they require the solution to be put in a header file - what might look awkward if challenge.h would be created from Preloaded, and what would make the preloaded, well, a solution :) Additionally, preloaded snippet cannot be edited while solving, so there is no way for users to write a part of a solution in the challenge.h. I do not know what kata use any complex setup, but if you could provide some info like:

then I could take a look.


To be honest I do not really see a good way to fit the C++ compilation model into the 3 snippets we have now. I think that repurposing preloaded will not prove to work well, and that ideal solution would be to introduce two more tabs (for solution.h visible to authors and users, and preloaded.h editable only by authors), or employ some runner-side preprocessing and use markers in submitted code snippets like:

//CW SOLUTION_H
... declaraitions, templates which are a part of solution

//CW SOLUTION_CPP
... definitions, private solution stuff

The markers and preprocessing could be potentially backed by the #line X some_filename directive. I know that preprocessing in the runner is not a great thing, but since a solution to a vast majority of kata is a single function which can be re-declared in tests, such markers could be made optional and used only for kata which find them necessary.

hobovsky commented 7 months ago

FYI https://github.com/codewars/next-cpp/issues/1

armeanco commented 7 months ago

By updating the Kata we pursue the functionality indistinguishability? If so, I can't imagine particularly impossible one, but I can imagine the ones for which it would require time to make it proper. I personally think that it doesn't matter if we switch from the recent test framework to a newer one (despite the Authors/Translators who prefer to keep it as it is for some reasons).

kazk commented 7 months ago
  • what C++ kata has a Preloaded snippet (except stringizer)

See https://gist.github.com/kazk/3732ef1b693a3c4483a0b8e75f0b524a for a list with a basic summary for each. There are some kata with only #include and/or using std;.

image


Kata with #define in preloaded:

  1. Expression Transpiler
    #define require(e) if (!(e)) return 0
  2. Image Processing
    #define C(e) static_cast<char> (e)
  3. Parenthesis detector
    #define RealAssert Assert
    #define RealFailure Failure
  4. Parenthesis detector++
    #define EpicFail42 Assert::Failure

Kata with #undef in preloaded:

  1. Versions manager
    // this prevents weird collisions with the standard library macros
    #undef major
    #undef minor

Kata with template in preloaded were all stringizer/generic printer/test helpers.

kazk commented 7 months ago

To be honest I do not really see a good way to fit the C++ compilation model into the 3 snippets we have now. I think that repurposing preloaded will not prove to work well

Yeah, that's what I expected.

@ggorlen How is CCC C++ working for Qualified?

that ideal solution would be to introduce two more tabs (for solution.h visible to authors and users, and preloaded.h editable only by authors)

This won't happen. I can see Codewars eventually adding support for projects challenges (allows you to add files) like Qualified in the future.

employ some runner-side preprocessing and use markers in submitted code snippets

Yeah, I guess we can support this for when the default doesn't work well. The runner can see if any markers are included and handle the submission differently.

The markers and preprocessing could be potentially backed by the #line X some_filename directive.

Can you elaborate this directive?

hobovsky commented 7 months ago

See https://gist.github.com/kazk/3732ef1b693a3c4483a0b8e75f0b524a for a list with a basic summary for each.

Looking briefly through the list, there is nothing in preloaded what couldnt be worked around:

As a bottom line, if there were no preloaded.h, and only preloaded.cpp, I think majority of kata could be made to work (not the other way round tho).

The interesting part which you did not show is solutions (and maybe solution setups) which contain template keyword or #define directive, as these are effective only in a translation unit they reside. As an effect, if they would be located in an implementation file (i.e. solution.cpp), these things will not be possible to be tested. Solutions which are meant to be templates or macros have to be placed in a header file, and have to be included by tests (with some cave-ats, but generally they do).

Another idea: declare tasks which require users to provide solutions in a form of a template or a macro as unsupported. It would be a pity because it would prevent template metaprogramming tasks (or make them difficult to author), but most probably would also remove the necessity of having solution headers (if we verify, and agree, that re-declarations in tests work and are OK).


Can you elaborate this directive?

It's just a shot and it depends on what configuration of snippets will be finally used. Generally, the #line directive modifies behavior of __LINE__ and __FILE__ macros, which are eventually used by test macros like assertions when reporting failures. But since the test macros are usually present in test snippets (duh), it most probably will not be as useful as I thought it might be.

kazk commented 7 months ago

The interesting part which you did not show is solutions

48 kata with template/#define in the reference solution: https://gist.github.com/kazk/094df9ae7d5994f96e0bffa57ef3390a

hobovsky commented 7 months ago

Cool, I will try to do something useful with the lists over the weekend.

error256 commented 7 months ago

As an effect, if they would be located in an implementation file (i.e. solution.cpp), these things will not be possible to be tested.

I think it's only a problem if there are both headery and linkable entities? Otherwise it should be possible to #include <solution.cpp> in the tests.

hobovsky commented 7 months ago

IT might be just me, but something rubs me really bad when I see implementation files included as header files. Technically these are just files like every other so yeah, why not, but OTOH I am not sure I would call a setup which relies on including *.cpp files a step in a direction of a better, clearer setup. Maybe if the runner saved the snippets as both, a cpp file and a h file, then it would allow for clearer includes.

I will try to pick some kata from the lists and see if they can be set up in a way which would benefit from the #include "solution" or #include "preloaded".


EDIT: I took the kata Compile time #1 Factorial, which can be tricky in a new setup because its solution is a template. By applying Unnamed's suggestion I managed to run it locally after adding #include "solution.cpp" to tests snippet. So it works (for this kind of kata), but but the location of the solution.cpp has to be easily reachable from the tests snippet (the same directory, or a documented relative path, or added to location of includes in command line), and I still do not like the fact that the included file has an extension .cpp.

I will check if there are kata which mix linkable and non-linkable stuff in a solution, what would make this approach not valid for them.

EDIT: I took a look at kata which mix linkable and non-linkable elements in a solution. There is a bunch of them, and they fail to run in their current form, but since the mixed stuff is in majority cases helper functions, they can be fixed and made compliant to the #include "solution" idea. Examples can be the "Moves in squared strings" series, where solution is a class, and author's solution uses a class definition with method declarations, and method definitions outside of the class. The solution does not compile this way in a new setup, but moving the definitions inside of the class fixes the problem. But even then, the restriction of not having method definitions outside of a class looks to me as imposed somewhat artificially and I am not sure I would like to force authors to follow some specific patterns, and disallow some other patterns which are generally valid in the language.

The only kata which seems to be impossible to fit into a setup without distinct snippets for solution.h and solution.cpp (or preloaded.h and preloaded.cpp) seem to be the Unique In Order and I think the Adapter Pattern - Geese to Ducks.

greg-gorlen-andela commented 7 months ago

@kazk I skimmed the thread but I'm not sure I'm totally ramped up and understand the issues at hand, so bear with me.

@ggorlen How is CCC C++ working for Qualified?

Do you mean "how does it work?" or "how is it working out for us?"--I assume the latter. I haven't had any blockers, just some fussiness figuring out name clashes between the solution and preloaded files, or something along those lines that I can't remember too well. I haven't worked on the C++ content in a good while.

Let me know if there are any particular concerns and I'll see what I can offer.

hobovsky commented 7 months ago

I created a prototype of a setup using a preprocessor: https://github.com/codewars/next-cpp/pull/4 . Please note that it's by no means normative and I just hacked something to make it work in my local docker, and many things are most probably not suitable for a final CW setup. I will try to add more examples of snippets from migrating existing, potentially problematic kata, showcasing various approaches.

kazk commented 7 months ago

Thanks Greg. Yeah, I mostly wanted to know if you saw any limitations or had any suggestions to how the classic code challenge works for C++.

Thanks @hobovsky. I'll take a look.

Feliks-WR commented 3 months ago

Use GCC. It even support C++23 already!

hobovsky commented 3 months ago

Possibly superseded by #307