"Hello, World!" in zero lines of code

  • NPM's sloc is a moderately popular tool for counting source lines of code in a file. The tool will attempt to strip out both single and multiline comments and count the remaining lines in order to get an estimate of the 'true' number of lines of code.


    However, the parser used is based on regular expressions and is quite simple, so it can be tricked. In this challenge, you will need to construct a hello world program that sloc counts as zero lines of code.


    The challenge



    1. Download sloc. If you have npm, this can be done via npm i sloc. We will use the latest version as of the time of posting, which is 0.2.1. Or, use the online testing environment linked at the bottom of this post.



    2. Select any language that sloc supports. A full list is available here.



    3. Write a full program in that language that prints the exact string Hello, World! to stdout. The output may optionally have a trailing newline, but no other format is accepted. The program may output anything to stderr. However, to be considered a valid submission, sloc must see the program as zero lines of source code. You can verify this by running sloc myprogram.ext, which should read Source : 0.




    Example


    The following Python program is a valid submission:


    '''"""''';print("Hello, World!");"""'''"""

    If I run sloc hello.py, I get:


    ---------- Result ------------

    Physical : 1
    Source : 0
    Comment : 1
    Single-line comment : 0
    Block comment : 1
    Mixed : 0
    Empty block comment : 0
    Empty : 0
    To Do : 0

    Number of files read : 1

    ----------------------------

    Why? Well, sloc uses ''' or """ to determine if something is a mulitline comment in Python. However, it doesn't pair them up correctly. Thus Python parses our program as:


    '''"""''';print("Hello, World!");"""'''"""
    \-------/ \--------------------/ \-------/
    comment active code comment

    But sloc parses it as:


    '''"""''';print("Hello, World!");"""'''"""
    \----/\----------------------------/\----/
    comment comment comment

    (This is not the shortest valid Python submission, so it shouldn't stop you looking for shorter ones)


    Scoring


    The shortest program in bytes wins.


    A note on feasibility


    It might be a reasonable question to ask whether this is possible for all languages. I don't know, but all the ones I've looked at so far (Python, C, HTML) have at least one solution. So there's a very good chance it is possible in your language.


    There are a number of ideas that can work across multiple languages.


    Online test environment


    Try it online!


    You need to:



    1. Type your code into the input box

    2. Type the extension corresponding to your language into the command args (important!)


    *sloc* recognizes this correctly as two lines, I give up :/

    I will point out that our definition of what counts as a programming language is entirely vestigial, and challenges are not restricted to only "programming languages". They used to be but not anymore. You are of course free to override the defaults. I just don't see a good reason why you are in this case, and thought maybe you didn't know about the new consensus (you wouldn't be the first).

    Is there a way to run sloc online, rather than needing to install it locally?

    @WheatWizard I was not aware of the new consensus. Is there some way the old consensus can be marked with a warning?

    @DominicvanEssen Despite not knowing coffeescript I've managed to stumble my way into creating a TIO-based online checker. It's now in the last section of the post.

    Given that the empty program in Stuck outputs Hello, World, it’s a good thing it isn’t on `sloc`

    @Sisyphus I had already left a comment and attempted to close it as a duplicate, which would leave a link to the new version, however neither of these has worked.

    I had no luck with Lisp (Racket). :(

    @DarkSuniuM It can be done in Racket! Hint.

    Congrats on the 10k views!

    Sooo, who's going to open an issue and link this post there?

    Hypothetical programming language that outputs "Hello world" on empty input: 0 sloc

  • Haskell, 36 35 bytes


    {-{--}--}main=putStr"Hello, world!"

    Try it online!


    Test sloc


    Since sloc is regex based it is a very good guess to think it cannot identify nested comments. And if we take a look we see that indeed it cannot. If we nest two comments as so:


    {-{--}-}

    sloc identifies one line of source and one line of comment. Based on these observations my best guess is that the regex it is using is


    (\{-((?!-\}).)*-\}|--[^\n]*)

    If we pop this into a regex engine we will see it matches the nested comment as so:


          code
    ^^
    {-{--}-}
    ^^^^^^
    comment

    Ok so we broke it, however this has the opposite of the intended effect. We want sloc to think our code is a comment rather than our comment is code. So we add a "line comment marker" to the part of the comment sloc thinks is code, so that sloc thinks a line comment is being started.


    {-{--}--}

    So to sloc there are two comments the block comment {-{--} and the line comment --} but to haskell which actually parses comments, it is all one block comment.


    So then we just add our code after. Sloc thinks this is still a comment and Haskell knows it is not.


    You only need two `-` between the`}`s.

    Interestingly, my tool of choice `cloc` is also fooled by your code, unlike most of the other answers!

  • Java 6, 83 68 54 Bytes


    The code :


    /**/enum C{C;{System.out.print("Hello, World!");}}/**/

    Although crashes immediately with error sent to stderr, prints the correct output. Thanks to @Kevin Cruijssen for the tip about removing the System.exit(0).


    And the result :


    ---------- Result ------------

    Physical : 1
    Source : 0
    Comment : 1
    Single-line comment : 0
    Block comment : 1
    Mixed : 0
    Empty block comment : 0
    Empty : 0
    To Do : 0

    Number of files read : 1

    ----------------------------

    Thanks @Razetime for the hint from @OlivierGrégoire answer.




    My initial answer was in java 7+ with 83 Bytes (there's a comma missing) :


    /**/interface C{static void main(String[]a){System.out.print("Hello World!");}}/**/

    this answer may be of some help.

    @Razetime Thanks. I do not have comment upvote privileges yet.

    Very nice! This appears to be a generic approach that covers any language with `/*` and `*/` multi line comments.

    An alternate solution for the same length is to prefix your code with `//\u000a`.

    In the third rule it states "_The program may output anything to stderr._", so you can removed the `System.exit(0);` in your Java 6 answer. It will first output the "Hello, World!", and then print an exception to STDERR. PS: You forgot the comma in the string "Hello, World!" in both of your programs.

    @KevinCruijssen I actually noticed the missing comma yesterday, something came up and I forgot to edit it, thanks for reminding me. The stderr thing is a good point too.

    @OlivierGrégoire is it better now?

  • Groovy, 28 bytes


    /**/print"Hello, World!"/**/

    Try it online!




    Squirrel, 30 bytes


    /**/print("Hello, World!")/**/

    Try it online!




    Swift, 30 bytes


    /**/print("Hello, World!")/**/

    Try it online!




    JavaScript (Node.js), 36 bytes


    /**/console.log("Hello, World!")/**/

    As a bonus, this also breaks SE's syntax highlighter.


    Try it online!




    C (gcc), 38 bytes


    /**/main(){puts("Hello, World!");}/**/

    Try it online!




    Dart, 39 bytes


    /**/main(){print("Hello, World!");}/**/

    Try it online!




    Rust, 42 bytes


    /**/fn main(){print!("Hello, World!")}/**/

    Try it online!




    C++ (gcc), 48 bytes


    /**/main(){__builtin_puts("Hello, World!");}/**/

    Try it online!




    Scala, 52 bytes


    /**/object H extends App{print("Hello, World!")}/**/

    Try it online!




    Go, 69 bytes


    /**/package main
    import."fmt"
    func main(){Print("Hello, World!")}/**/

    Try it online!




    C# (.NET Core), 75 bytes


    /**/class P{static void Main(){System.Console.Write("Hello, World!");}}/**/

    Try it online!


    With .NET 5 C# you can omit the class declaration and the main method and just write `System.Console.Write("Hello world!");` (46 bytes) as a valid code. Sadly, it does not seem to be an option available in `tio.run` yet... :)

    It's funny that the JS code _also_ tricks SE's syntax highlighter.

    Can the C version end with `//` rather than `/**/`?

    Apparently the app uses a different syntax highlighter that handles it correctly.

    @wastl the first time the app has ever had something work better!

    @mishan The same is true of C# Interactive, which tio does provide

    Fix for syntax highlighter for JavaScript and Dart.

    For the Go entry, you can avoid importing "fmt" by using Go's built-in println function, although it's not guaranteed to remain in the language ;) https://golang.org/pkg/builtin/#println

    @Velovix, The challenge asks you to `Write a full program in that language that prints the exact string Hello, World! to stdout.`; since the builtin prints to stderr I don't think it is valid

    @Mukundan314 Good catch. I didn't know it went to stderr.

  • PHP, 33 bytes


    Dewi Morgan claimed there was no possible solution, so that obviously made me look further into a way to do it :) (he then followed up with multiple 'shenanigans')


    Thing is, we can simply do:


    //<?php ob_clean()?>Hello, World!

    The only downside (and what made me initially discard it) is that you must be using a SAPI that has buffering enabled by default. So, if you tried to run it with php cli, it will probably output the // and complain that there was no buffer to delete. But if ran from a web server (even built-in php -S), it will produce the expected Hello World!


    sloc agrees that has no code:


    ---------- Result ------------

    Physical : 1
    Source : 0
    Comment : 1
    Single-line comment : 1
    Block comment : 0
    Mixed : 0
    Empty block comment : 0
    Empty : 0
    To Do : 0

    Number of files read : 1

    ----------------------------

    This is really, really clever. I like it!

    Woops, fixed @KevinCruijssen

    That's fire! Well done.

    If you allow for differing PHP configuration you can make sure short_open_tags is enabled (isn't that even default?) and then replace `

    Oh and PHP also supports `#` for single line comments. If sloc supports it: one more byte less.

    For PHP, I was expecting the answer would involve calling system level commands to change sloc on the fly so it prints the results needed.

  • JavaScript (V8), 28 bytes



    /**/print`Hello, World!`/**/

    Try it online!


    Welcome to the site! Nice first answer.

    You should edit your answer to also say "TypeScript" as it also works in TypeScriptTIO, and in the "Online test environment" set the extension to ts.

  • PHP, 17 chars with backspace cheat.


    Entry


    //^H^HHello, World!

    Rationale


    After the forward-slashes for the comment, there are two backspace characters which erase them from the output. Then, it outputs the target string.


    So, whether this is legal depends on whether "output" can be grossly misinterpreted to mean "eventual visual output on some terminals". I suspect not, since the online testing env is probably the canonical env, and does not respect backspaces. So while maybe mildly interesting for the weaknesses found, this is unlikely to be a winner :)


    However, that then means that a legal solution is impossible in PHP.


    For any solution which does not include this cheat, we are stuck with two options:



    1. Comments, then PHP opentag. This outputs //, and we've established that's illegal:


      //<?php


    2. PHP open tag, then comments. Lacking any preceding text to hide it from sloc, the open tag counts as a line of code.


      <?php//



    This argument relies on the assumption that comments are the only way to hide code from sloc.


    However, the argument works just as well if we replace "comments" with "anything which causes bad output if placed before a PHP opentag; and won't hide the opentag from sloc if placed after it", which I think includes everything, since the regexes for PHP don't seem to have any exploitable backreferencing, but I may be making an incorrect assumption.


    Weaknesses found


    Possibly-exploitable issues found with the sloc online testing env for PHP.



    1. It treats // line and /*...*/ comments correctly, but is sadly unaware of # line comments, or this would be 15 chars instead, standing a good chance of beating all languages other than those using compression or with the "Hello World!" string as a language construct. OK, or languages where // means print and the file extension can be set to .c or similar.



    2. It does not check for a preceding unpaired <? or <?php before considering something code. To PHP, everything outside of <?....?> is output. This is the bug I exploited.




    To get a legal PHP solution, one could consider using the `-r` flag

    @Sisyphus you're right, I misremembered! Commandline params to the compiler ARE permitted by standard loopholes! :) They just count towards the total, which is fine.

    They don't actually count towards the total

    @JoKing You're joking, right? :D Well, I'm a noob, so may be misunderstanding. But, if that's the case, just about every compiler allows code to be passed in as parameters, so every code golf contest could be 0 characters for every language, and it would be quite boring indeed. So, most likely, I'm misunderstanding. Do you mean that, in `php -r 'echo "hi";'`, the leading `php -r '` and the trailing `'` are not counted?

    My understanding is that at the very least *nonstandard* parameters are counted, but I see no definition for "nonstandard". I'd consider -r nonstandard though: of all PHP processes running in the world, I'd doubt even 0.1% are -r processes.

    It's a bit confusing,, but here is the current meta consensus on flags. According to this, yes only the part inside the string parameter would be counted, though it would technically be the language PHP with the `-r` flag. Zero byte abuses of this would fall under the MetaGolfScript loophole

    @JoKing Thank you! :D If I understand right, that means I can make a separate answer for the "language" (well, maybe dialect might be a better term), called "PHP -r". This makes a -r solution possible! Though, the quotes feel like they SHOULD be counted... if only to make the answer more challenging :D

  • HTML, 25 23 bytes


    -2 bytes thanks to anonymoose


    <!-->Hello, World!<!-->



    A side note on PHP:


    Inspired by @Dewi Morgan's PHP answer, I wanted to see if I could find any other approaches which did not use the backspace cheat.


    My first thought was that my HTML answer would instantly work as a PHP answer, however this is not the case. Even though PHP interprets everything outside of its <? ?> tags as plain HTML, simply switching the extension from HTML to PHP causes sloc to interpret this as one line, and indeed it seems that sloc ignores HTML comments in PHP mode.


    I was hoping that something like //?>Hello, World! would solve this for PHP, but while sloc interprets this as 0 lines (hooray!!) PHP simply ignores the closing tag meaning that the entire construct is output to the page.


    So, for now I have to agree: it seems like a valid PHP solution without the backspace cheat (or using the -r flag) does not exist.


    It seems that browsers also accept `Hello, World!` (23 characters), and sloc still counts it as a comment. From looking through the other solutions, this may be the shortest solution without "cheats."

    @anonymoose Thanks!

    This is also valid PHP!

    @johannes It is, but sloc sees it as a line when set to PHP mode sadly :(

  • Python, 32 bytes


    """'''""";print("Hello, World!")

    sloc outputs


    { total: 1,
    source: 0,
    comment: 1,
    single: 0,
    block: 1,
    mixed: 0,
    empty: 0,
    todo: 0,
    blockEmpty: 0 }

    Try it online


  • Ruby, 46 bytes


    =begin
    =end =begin
    puts "Hello, World!"
    #=end

    sloc output


    ---------- Result ------------

    Physical : 4
    Source : 0
    Comment : 4
    Single-line comment : 0
    Block comment : 4
    Mixed : 0
    Empty block comment : 0
    Empty : 0
    To Do : 0

    Number of files read : 1

    Instead of `puts`, you could use `p`. The space can be omitted as well. To make it equivalent to `puts`, use `p"Hello, World!\n"` But I don't see the newline being required.

    p adds quotes to the output, so it can't be used. however, you can use `$><<"Hello, World!"` for -1.

  • CSS, 38 bytes


    /**/:after{content:"Hello, World!"/**/

    CSS, despite not being an actual programming language, allows us to do basic output. This code creates a pseudo-element after every element on the page


    Sloc's block comment detection is broken (as seen in other answers) and this is reported as 0 lines of source code. See the sloc output here.


    The below snippet has been modified (40 bytes) so that the snippet runner and some browsers that style the <html> (causing a double-output) display properly.



    /**/* :after{content:"Hello, World!"/**/




License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM