An article titled "This Is What Peak Hello World Looks Like" did the rounds on Hacker News (discussion here), where someone took the plain old printf("hello, world!"); in C and transformed it step-by-step beyond recognition. This was a noble effort, but today I discovered an easier way to make Hello World more insane in a slightly different way:
$ dotnet new console -o hello -lang F# The template "Console Application" was created successfully. Processing post-creation actions... Running 'dotnet restore' on hello/hello.fsproj... Restore completed in 209.4 ms for /home/sean/dev/dotnet/hello/hello.fsproj. Restore succeeded. $ cd hello $ cat Program.fs // Learn more about F# at http://fsharp.org open System [<EntryPoint>] let main argv = printfn "Hello World from F#!" 0 // return an integer exit code
That's it, an absolute monster of a program. But wait, "This is just a plain old Hello World in .NET! What's so insane about that?" I hear you ask. Well we're not quite done yet, let's get ready to share the executable with our colleague who wants to use our app so we'll add <PublishSingleFile>true</PublishSingleFile> to hello.fsproj - which will generate a single self-contained executable binary - and publish it:
$ dotnet publish -r linux-x64 -c Release Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 5.27 sec for /home/sean/dev/dotnet/hello/hello.fsproj. hello -> /home/sean/dev/dotnet/hello/bin/Release/netcoreapp3.1/linux-x64/hello.dll hello -> /home/sean/dev/dotnet/hello/bin/Release/netcoreapp3.1/linux-x64/publish/ $ ./bin/Release/netcoreapp3.1/linux-x64/publish/hello Hello World from F#! $ ls -lh ./bin/Release/netcoreapp3.1/linux-x64/publish/hello -rwxr-xr-x 1 sean sean 78M May 17 22:47 ./bin/Release/netcoreapp3.1/linux-x64/publish/hello
There she blows! An absolute monster - a 78MB Hello World executable! This is actually a bit unfair, since it includes some stuff we might not need, so let's add <PublishTrimmed>true</PublishTrimmed> to hello.fsproj and rebuild:
$ dotnet publish -r linux-x64 -c Release Microsoft (R) Build Engine version 16.5.0+d4cbfca49 for .NET Core Copyright (C) Microsoft Corporation. All rights reserved. Restore completed in 33.8 ms for /home/sean/dev/dotnet/hello/hello.fsproj. hello -> /home/sean/dev/dotnet/hello/bin/Release/netcoreapp3.1/linux-x64/hello.dll Optimizing assemblies for size, which may change the behavior of the app. Be sure to test after publishing. See: https://aka.ms/dotnet-illink hello -> /home/sean/dev/dotnet/hello/bin/Release/netcoreapp3.1/linux-x64/publish/ $ ./bin/Release/netcoreapp3.1/linux-x64/publish/hello Hello World from F#! $ ls -lh ./bin/Release/netcoreapp3.1/linux-x64/publish/hello -rwxr-xr-x 1 sean sean 46M May 17 22:51 ./bin/Release/netcoreapp3.1/linux-x64/publish/hello
Ok, slightly better but that's still a hefty 46MB for Hello World. This is a bit disingenuous however - what's happening is that I've configured the project to be able to produce a self-contained executable, to do this the .NET Core runtime is bundled in the hello binary. So it's a little bit like distributing a little bit of application [byte]code, a bytecode interpreter, a JIT compiler and runtime libraries.