Hacker News new | ask | show | jobs
by chrisb 3167 days ago
I'm the original author of DotNetAnywhere.

For all its flaws (and there are quite a few) it was a very interesting learning exercise, and it worked better than I ever really expected ;)

I don't really intend to ever do any more work on it, especially now that there are open source "real" implementations. But it's been nice to see it used in Blazor :)

If you have any questions about it, please ask.

3 comments

Firstly, thanks for writing it!

Here's my questions (assuming you can remember from 6+ years ago):

1) What was the hardest part of .NET to understand and/or implement?

2) Were there any surprising things about the .NET runtime/specification that you learnt about along the way?

3) Should JIT.c really be called Interpreter.c :-)

My memory is a little vague...

But I'm fairly sure the hardest part to implement was the support for generic types/methods. It made all the code that handles types way more complex (as expected I suppose!), and there's definitely a bug or two remaining. Correctly handling open/closed generic types and construction of types from generic arguments was painful. It didn't help that I initially implemented only non-generic type support, then had to hack generics into it. Were I to start again I'd implement the whole thing in a generic-first way.

The design of classes/structs and they they interact with generics is nice. And the `constained` IL prefix is a really neat optimization to avoid boxing. The use of type-agnostic CIL instructions (e.g. `add` can work on int, float, ...) is also a nice touch.

JIT literally stands for "Just In Time". It doesn't say what it's actually doing just-in-time ;) So (in my opinion) JIT.c is correct. It's translating CIL opcodes to dna-internal opcodes, which it does just-in-time just before a method is executed for the first time. The reason it does this at all is because there are many things to resolve when working from CIL that it's much better to do just once rather than every time a method is executed. A simple example is method references, which are by name in CIL, but are a simple pointer in dna-internal opcodes.

Thanks so much for your replies, very informative.

r.e. 'JIT v Interpreted', I should've checked wikipedia, it backs up what you're saying:

> Most often this consists of translation to machine code, which is then executed directly, but can also refer to translation to another format

From https://en.wikipedia.org/wiki/Just-in-time_compilation

This may be a selfish request but would you consider moving the original repo to it's own organization? The canonical repo gets a higher placement in search results and for link juice.

Plus if you were to move it to it's own repo/organization, it would allow the forks to submit their changes upstream and have one master repo instead of multiple forks with their own changes.

I probably won't get around to doing this.

But someone else is very welcome to do so :)

Pinged you on GitHub but you'll need to initiate the transfer to move the repo: https://help.github.com/articles/transferring-a-repository-o...
The main reason i move from c# to “typescript js” because c# not working on client side web. I love c#, maybe if dotNetAnywhere is ready for production, i start using c# again. Keep the good work. Maybe someday aspcore, xamarin and dotNetAnywhere. It would be awesome
Sadly DotNetAnywhere definitely isn't ready for production, and by the sounds of it Blazor is not either (I'm not involved in Blazor).

It's possible some of the other DNA forks mentioned here may be more suitable for production, I'm not sure.

But because those are weekend projects. There are enough microsoft or microsoft-related people getting excited about it that I hope microsoft will put its strength behind a production version. That would certainly make a lot of sense.