
Exploring the new .NET “dotnet” CLI - Nelkins
http://www.hanselman.com/blog/ExploringTheNewNETDotnetCommandLineInterfaceCLI.aspx
======
alpb
In case you missed: "dotnet compile --native" is basically like the Go
compiler, it statically links all the DLLs and produces a single PXE/ELF
executable.

This is the most exciting thing for me in the new dotnet CLI as a person
writing Go full-time at Microsoft. Most developers will be able to take
advantage of single-binary shipping, they'll just put that in a Docker
container and happily run everywhere.

~~~
userbinator
If I'm reading the article correctly, that's a 656KB "Hello World" binary.
_671,644 bytes_ just to print a single string to standard output and exit?
That is smaller than the whole .NET framework, but considering that a real
native "Hello World" binary is <1KB, what's the other 655KB doing?

~~~
nolok
While your point is absolutely true, the rule of thumb in those case is that
the growing curve in file size is not linear; while the very minimal
executable already brings lots of things it doesn't need, adding
functionalities make it grow slowly (since a lot is already there).

Not saying this is not an issue (although it isn't really in most fields,
except for things like embedded), but that the 656 KB for "Hello World" is
because of the "upfront cost" in binary size.

I have spent sometime developing in Delphi years back, and this was even more
true with it (simple hello world GUI app was over a megabyte [create new
project and compile], complex GUI app was barely above it).

~~~
oblio
Plus embedded environments which have problems with an executable weighing
656KB aren't really a good target for .NET, to start with.

------
m0dest
I'm so happy to see arguments specified with "-" and "\--" (UNIX-style)
instead of "/" (DOS-style).

The DOS-style CLI arguments used by Microsoft's other command line tools seem
like such a stubborn throwback to a long-lost war. "/" won the battle for
folder path separators (see: URLs) and "-" won the battle for argument
delimiters.

~~~
david-given
Fun fact: most MS kernels, including DOS, supported "/" as a path separator.
They were just filtered out of the command lines by the argument passing code.

There was a system call which would tell the argument parser that you wanted a
different switch character, and if you changed it to, say, "-", then "/" would
work. Of course, not everything used the standard argument parser, so if you
_did_ change this you ended up in a world of pain because your tools would
start behaving inconsistently, but it was theoretically possible.

I've seen references to this code existing as late as XP, but I don't do
Windows any more, so can't comment on later versions.

~~~
nolok
In terms of file path, windows seems to always support \\\ or /, both in API
or in software like Explorer. That's still true for Windows 10.

That leads to some interesting answers on stackoverflow sometimes about cross
compatibility, where the correct answer of "use whatever constant your
language has for directory separator" gets down-voted in favor of "use forward
slash everywhere".

~~~
pjmlp
Because it isn't the correct answer.

Many applications assume \ and deal with paths directly, instead of using the
Windows APIs for path manipulation.

This means the moment your application gives a / to another application, there
is a high probability that it will break, regardless of what the Windows API
supports.

Even cmd doesn't handle / properly.

~~~
nolok
I know, you will notice I said above "the correct answer [...] gets down-
voted", I was not suggesting using forward slash was the way to go.

You can take it as a side criticism of how things are turning sour on
stackoverflow with "popular" being more valuable that "right", I guess.

------
Nelkins
I think the most exciting thing about this is the AOT compilation into a
single binary (Go-style), something I've wanted for a long time [1].

[1]
[https://news.ycombinator.com/item?id=9590213](https://news.ycombinator.com/item?id=9590213)

~~~
frik
Aren't the plans for AOT to work only with WinStore apps?

~~~
math
no - they first mentioned plans for cross platform go-style single binary
compilation at connect (one of the videos here I believe:
[https://channel9.msdn.com/Events/Visual-Studio/Connect-
event...](https://channel9.msdn.com/Events/Visual-Studio/Connect-event-2015/))
and I'm pretty sure they've subsequently talked about it in more detail in one
of the community standups.

~~~
mintplant
What's the difference between a "go-style" binary and any other statically-
linked binary?

~~~
math
I wrote go-like because I think of C#/.NET and go as somewhat comparable and
I'm not aware of any other language in a similar class that produces
statically-linked binaries. However I'm pretty ignorant, so would not be
surprised if there are many ... examples?

~~~
pjmlp
Any programming language that has AOT compilation to native code among its
implementation choices.

There are plenty to choose from, but if you want a list:

PL/I, Algol, PL/M, Quick Basic, Turbo Basic, Quick Pascal, Turbo Pascal, C,
C++, Ada, Eiffel, Haskell, Objective-C, OCaml, Delphi, Oberon, Oberon-2,
Component Pascal, Mesa, Modula-2, Modula-2+, Modula-3,...

~~~
qwertyuiop924
Do all of those support static linking with the default tooling? (That is to
say, not just hypothetical support, but actual support)

Jeez.

~~~
pjmlp
Of course, once upon a time static linking was the only way.

It is dynamic linking that is hard to implement, not the other way around.

~~~
qwertyuiop924
I KNOW that. I just wanted to know if the native compilers for the languages
you mentioned supported static compilation either through a switch or by
default, or if it's something that somebody else would have to write.

~~~
pjmlp
Initially by default, many of them are older than OSes with dynamic linking
support.

The ones with compilers that also support dynamic linking, either via a switch
or via explicit dynamic modules.

------
simula67
> I think folks using and learning .NET should have the same experience as
> with Go or Ruby. > Easy Compile and Run > Just "dotnet run" and it compiles
> AND executes

As someone who does not follow the .NET landscape that closely can anyone
explain why this is a big deal ? Java has been able to do 'javac Hello.java;
java Hello' for as long as I can remember. If this was so important why are
they getting around to it only now ?

~~~
alkonaut
If java did the same it would be "java Hello" regardless of whether it was
built or not. It would compile _and_ run, or just run if it was already
compiled. Not sure why that is a big deal but I do think the separation
between jre and sdk in java is mostly a headache. I understand the end user
doesn't need all the docs etc., but shipping the compiler with the runtime,
why not?

~~~
pjmlp
It is been done for years by third party JVM vendors, but apparently many are
too focused on the OpenJDK.

Also, since Java 8 you can package everything together with the reference JDK,
no need for third party tools any longer. This will be improved with the Java
9 modularity and possible AOT compilation in Java 10.

------
donatj
Dumb question, but if I install this on OS X does it support VB.Net or just
C#?

I have a ton of old CLI apps I wrote in VB.Net 10 years or so ago and it would
be interesting to port them. Mono's support for VB.Net last I tested was _not
good_.

~~~
iheartmemcache
This looks like it includes C#, VB.NET, F#, and any other language that
targets the CLR (Common Language Runtime, i.e., Microsoft's JVM). edit:
Apparently not. Mea culpa!

Also, I don't know how long ago you tried Mono + VB, but especially since MS
started collaborating with Mono and offering upstream first-party support (~2
years), support for the IL has been almost production quality. (Now it _is_
production quality - I'm running some of my customer ASP.NET applications
which was built around the NHibernate rather than EF/MS SQL on full Linux
infrastructure).

Satya is making a ton of bold moves that are basically antithetical compared
to the Ballmer-era MS. Visual Studio Code (yet-another-electron-based-editor)
and Community, along with the ridiculous amount of open stuff on Github has
effectively eliminated the vendor-lock-in stronghold that Microsoft previously
had. Residual Office renewals and upgrades on the MS SQL stack will only get
them so far. They're going full Docker[1] support on the new Windows Server
stack, as well as full .NET support _off_ the Windows stack, which is
interesting to say the least. I wonder if we'll start seeing them buying out
companies that are traditionally aligned with more-open-sourcey.

A bold move they could make would be buying out Cognitect. Datomic could be a
_perfect_ fit for them. Integrate Visual Studio support (e.g. as good as
IntelliJ/Cursive) and give CLJS first-party support (let Nolen take a lead
spot on the TypeScript team) in VS and it could be a steal at even a few
hundred million dollars. The talent (Hickey+Nolen) the developers who they
bring over + the perception shift within the dev community + the Datomic
itself is likely worth a half a billion to MS.

[1]
[http://www.hanselman.com/blog/BrainstormingDevelopmentWorkfl...](http://www.hanselman.com/blog/BrainstormingDevelopmentWorkflowsWithDockerKitematicVirtualBoxAzureASPNETAndVisualStudio.aspx)

~~~
Flow
TypeScript(and even C#) is a huge step backwards compared to Clojure and
ClojureScript. Immutability is a clumsy thing in TypeScript whereas it's
concise and natural in Clojure and ClojureScript.

I doubt a bright person such as David Nolen would like to work with TypeScript
as it is right now.

IMHO of course.

~~~
iheartmemcache
I'm pretty sure a few tens of millions (lets say Nolen has 5% equity? I think
give or take a few points, that's about right) for 4 years (generally the buy-
out terms for a pair of golden-handcuffs) and the freedom to choose the
direction in which TS goes (notice I did say "Lead" \-- his role would have to
be essentially Anders or Meijer's level for it to go through I'm sure) would
be equally amenable for all parties involved. (I don't think you understand
the freedom engineers at that level in MS get, especially post-Ballmer).
Immutability sucks in TS? Oh well, here David, take 5-10 SDEs and do whatever
you want.

MS gets the Clojure (and maybe more importantly the CLJS userbase), Cognitect
gets massive reach (CLJS is subsidized solely by the licensing of Datomic by
strict revenue), MS' corporate customers get Datomic. Just going by the
direction MS has been in lately ("embrace & extend") under the new anti-
Ballmer role, floating an offer of 300-500 million would be beneficial to
everyone involved. Let's say there are conservatively 100k Clj(s) users out
there right now using Clojure + Sun's JVM. At 300 million that's 3k per active
developer acquired right off the bat. You'll lose maybe 10% of the users who
live-by-their-Macbook-and-die-by-their-iPhone. Even at 600 million, that's
still a cheap price to pay.

------
merb
Oh my god. That is more than promising. That is really really awesome.

Finally Microsoft will put something of that is useful for everybody.

------
jmspring
I learn a lot from Hanselman, and as someone bridging multiple languages,
platforms, and sdks while at MSFT, this is a new one for me.

I'm adding this to my list for potential 20% time project exploration.

Cross platform and cross language have their interesting aspects...

------
recursive
C# has had a command line compiler since... forever. Is the big news just
--native mode?

~~~
enricosada
the --native already exists, it's not a dotnet cli thing

dotnet is a wrapper ( like git command ) for multiple executable, to replace
msbuild as project file + build tool and add some new functionalities (
restore nuget packages, etc )

i think the real news is having a dumb project.json (nuget deps,source
files,etc) and a xplat tool ( dotnet ) who read this project.json, and can
restore packages, compile ( --native too ), publish, packages as another nuget
package, etc.

All that xplat and multiple language. c# works, F# got merged last week, other
coming next.

Some example commands:

\- `dotnet new` scaffold a new project ( really simple atm )

\- `dotnet restore` read dependencies from the project.json and download nuget
packages

\- `dotnet compile` call the csc compiler ( with a wrapper `dotnet-compile-
csc` ) with source files, defines, references from project.json, etc

There is a good split of responsabilities, you can call dotnet-compile-csc if
you want. dotnet cli bundle the roslyn compiler ( c#, vb ) and f# compiler, so
ready to go

for example `dotnet compile`.

dotnet compile read project.json and call ( for c# ) the `dotnet-compile-csc`
passing source list, defines, references, etc. dotnet-compile-csc doenst know
about project.json, and call csc ( the c# compiler ). if --native, the `dotnet
compile` then call a compiler from .net bytecode to native code

It's more like a replacement for msbuild, with a really good command line
story, and a common project file ( project.json ) who can be used from visual
studio or vs code, or others ide ( it's a json file, dumb )

~~~
iheartmemcache
Completely off topic but I think I saw some of your work in the F# repo being
merged upstream. Congratulations if I'm not confusing you with someone else!

~~~
enricosada
thx

------
ZenoArrow
For those interested in projects like this, would recommend following the
development of Xebec, it's a very new project (no code releases yet), but aims
to offer a much simpler build system for F# projects:

[http://7sharpnine.com/Xebec/](http://7sharpnine.com/Xebec/)

------
pedrow
Can anyone clarify - does this support any .NET language (C#, F#, mixed
language)? In the 'fabulous' example, I can't see where the source code for
"Hello World" actually is.

~~~
bjg
Looks like they have compiler support for only C# (csc), and F# (fsc) right
now.

[https://github.com/dotnet/cli/tree/master/src/Microsoft.DotN...](https://github.com/dotnet/cli/tree/master/src/Microsoft.DotNet.Tools.Compiler.Csc)

[https://github.com/dotnet/cli/tree/master/src/Microsoft.DotN...](https://github.com/dotnet/cli/tree/master/src/Microsoft.DotNet.Tools.Compiler.Fsc)

~~~
enricosada
dotnet cli is a new project. It use some good ideas from aspnet/dnx like
project.json, but it's more easy to work with, less magic, more language
agnostic.

c# is used to bootstrap all tools, so it's the first supported language and
the default. Nightly, dev build have f# support, but it's a beta ( merged last
week, but it's ok ).

f# dotnet cli (the wrapper for f# compiler) is a beta, but moving fast, not
much todo. For example the f# support in dotnet new is in a pull request.

The F# compiler built for coreclr ( bundled with dotnet cli, so ready to go )
is working pretty much, some stuff missing ( portable pdb for example ),

f# coreclr is open source
[https://github.com/Microsoft/visualfsharp](https://github.com/Microsoft/visualfsharp)

------
tomcam
Preach it, brother. That would get this former Microsoftie back to the fold.

------
csours
.Net CLI, so ... powershell?

This looks pretty cool. I wish powershell were slightly easier to set up and
use, and that there was a repo for extensions other than "google it and then
download".

~~~
travem
Have you seen the capabilities enabled by the PowerShell Gallery[1] (script
and module repository) and the PowerShellGet cmdlets[2] (for interacting with
repositories like PowerShell Gallery)? It looks like a useful approach to
solving this particular issue.

[1] [https://technet.microsoft.com/en-
us/library/dn807169.aspx](https://technet.microsoft.com/en-
us/library/dn807169.aspx) [2]
[https://www.powershellgallery.com/](https://www.powershellgallery.com/)

------
dcw303
It's a nice idea, and anything that gives .NET developers more power at the
command line is going to get a thumbs up from me. But "one command to rule
them all" does feels a little broad. To take a ruby/rails/linux equivalent,
this is apt-get, ruby, irb, rails and gem all rolled up together.

Perhaps I'm just overly familiar with the unix small tools philosophy.

~~~
enricosada
there are multiple executables

the dotnet is like git, so `dotnet compiler` just call `dotnet-compiler`

the first level tools ( dotnet-compile, dotnet-restore ) read the project json
( the only supported project file atm ) and pass argument to second level
tools.

for example:

\- dotnet compiler call dotnet-compile

\- dotnet-compile read source files, references, defines from project.json and
call dotnet-compile-csc with the source files as arguments.

\- dotnet-compile-csc call csc

\- if --native, another .net bytecode to native tools is called

and csc (csharp compiler) is bundled with the dotnet cli package.

