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.