I started using C# recently for a hobby project writing a game engine on top of Monogame, and I have been very surprised at how nice of a language C# is to use.
It has a clean syntax, decent package management, and basically every language feature I regularly reach for except algebraic data types, which are probably coming eventually.
I think the association of .NET to Microsoft tarnished my expectations.
Modern C# and .NET are great. It still suffers from the bad reputation of the Windows-only .NET Framework. It's still a quite heavy platform with a lot of features, but the .NET team invested a lot of time to make it more approachable recently.
With top level Programs and file-based apps[1] it can be used as a scripting language now, just add a shebang (#!/usr/local/share/dotnet/dotnet run) to the first line and make it executable. It will still compile to a temporary file (slow on first run), but it doesn't require a build step anymore for smaller scripts.
Sometimes I wonder if the .NET department is totally separated from the rest of Microsoft. Microsoft is so bad on all fronts I stopped using everything that has to do with it. Windows, Xbox, the Microsoft account experience, the Microsoft store, for me it has been one big trip of frustration.
Makes me think of Boo language; Boo was so good at metaprogramming and multi-phasr programming! A very fine .NET language that was so far ahead of the curve, with having the tools of that language be usable at runtime.
Alas many of the docs are offline now. But it had great quasiquotes, which let you write code that gets turned into AST that you can then process. Good macros. A programmable compiler pipeline. So much. Alas, obscured now. https://boo-language.github.io/
Boo and Nemerle both were really showing what was possible in .NET back in the early days. I still miss the metaprogramming they had, not to mention their pattern matching (which C# has closed the gap on, but is still way, way short.)
The syntax looks a bit like F#. But F# only has a few features that generous people might consider meta programming.
There was a lot of fuss about meta programming around 10-15 years ago, but it never got a lot of traction. Maybe for a good reason? I think a lot of the problems it solved, were also solved by functional programming features that slowly appeared in C# over the years.
I love (and heavily use) source generators, but the development experience is godawful. Working with the raw Roslyn types is painful at best and this is compounded by them having to be written against .NET Standard, severely limiting the use of newer .NET functionality.
Eventually I want to write a good baseline library to use for my source generators -- simplifying finding definitions with attributes, mapping types to System.Type, adding some basic pattern matching for structures -- but haven't found a way to do it that's general enough while being very useful.
I used to think so too, but I do have to complain about Microsoft doing the Microsoft thing - they have a brilliant idea (and execution), but they bury it in so much boilerplate that 99% of people who would use it are put off by it.
The amount of stuff you have to wade through here compared to something like comptime in Zig (Roslyn API, setting up the project, having VS recognize it and inject it in the compiler, debugging etc) makes usage of these an absolute pain.
A key difference is that in this C# package, `[Comptime]` is an attribute (annotation? not sure on the C# term) applied to methods. In Zig, the `comptime` keyword can be applied to pretty much any expression. In the C# package, if you want to do factorial at runtime and at compile time, (I think, from reading the README) you need to define the same function twice, one with `[Comptime]` and once without. Contrast this to Zig, where if you have a regular runtime factorial function, you can just execute it at compile time like:
const x = comptime factorial(n);
Another limitation of the C# package is it only works with primitive types and collections. Zig comptime works on any arbitrary types.
I’m annoyed they called it comptime when it isn’t the same as Zig’s more powerful comptime.
You can think of zig’s comptime as partial evaluation. Zig doesnt have a runtime type reflection system, but with comptime it makes it feel like you do.
• Supported return types:
◦ Collections: ..., List<T>, ...
◦ Note: Arrays are not allowed as return types because they are mutable. Use IReadOnlyList<T> instead.
I don't understand. Why is List<T> allowed then if it's mutable?
Array also implements IReadOnlyList if I'm not mistaken.
I think C# doesn't really have immutable collections, they just can be typecasted to IReadonly* to hide the mutable operations. But they can always be typecasted back to their mutable base implementation.
The only real immutable collections I know of, are F#s linked lists.
That said, for more complex results, you'd typically load a serialization on start.
I can see the value in this tool, but there must be a fairly limited niche which is too expensive to just have as static and run on start-up and cache, but not so large you'd prefer to just serialize, store and load.
It also needs to be something that is dynamic at compile time but not at runtime.
So it's very niche, but it's an interesting take on the concept, and it looks easier to use than the default source generators.
The use cases are different. While MSBuild tasks run during build (and partially when loading a project), typically the IDE is oblivious what happens there. The source generator runs directly inside the compiler infrastructure and thus you didn't get error highlights for code that would otherwise be only generated during build but not as you type. This makes it much more friendly than pure build-time generation of code.
It's a code generator that runs during compile time. It's a source generator that adds some generated code files to the project. So it runs way before AOT or JIT. Once AOT/JIT run, Comptime is already invisible to them, they only see the generated code from Comptime.
Does this finally allow reading string literals from files and include them into the binaries?
I've seen a Go project that was heavily using https://pkg.go.dev/embed for loading some template files, and got a bit jealous. Back in the days of .NET Framework it was common to compile file contents into resource files, but it was always quite cumbersome.
Then you can read that file from the assembly with:
assembly.GetManifestResourceStream
I'm not sure what's awkward about that, but it's nothing new.
Discoverability for this is in visual studio, if you go to file properties there's a drop-down where you choose between Content, EmbeddedResource, Ignore, etc.
That determines what happens in compile, whether it is copied to output directory, compiled into the binary, etc.
spicyusername|2 months ago
It has a clean syntax, decent package management, and basically every language feature I regularly reach for except algebraic data types, which are probably coming eventually.
I think the association of .NET to Microsoft tarnished my expectations.
andix|2 months ago
With top level Programs and file-based apps[1] it can be used as a scripting language now, just add a shebang (#!/usr/local/share/dotnet/dotnet run) to the first line and make it executable. It will still compile to a temporary file (slow on first run), but it doesn't require a build step anymore for smaller scripts.
[1]: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...
thdrtol|2 months ago
Sometimes I wonder if the .NET department is totally separated from the rest of Microsoft. Microsoft is so bad on all fronts I stopped using everything that has to do with it. Windows, Xbox, the Microsoft account experience, the Microsoft store, for me it has been one big trip of frustration.
vips7L|2 months ago
jauntywundrkind|2 months ago
Alas many of the docs are offline now. But it had great quasiquotes, which let you write code that gets turned into AST that you can then process. Good macros. A programmable compiler pipeline. So much. Alas, obscured now. https://boo-language.github.io/
daeken|2 months ago
andix|2 months ago
There was a lot of fuss about meta programming around 10-15 years ago, but it never got a lot of traction. Maybe for a good reason? I think a lot of the problems it solved, were also solved by functional programming features that slowly appeared in C# over the years.
CharlieDigital|2 months ago
daeken|2 months ago
Eventually I want to write a good baseline library to use for my source generators -- simplifying finding definitions with attributes, mapping types to System.Type, adding some basic pattern matching for structures -- but haven't found a way to do it that's general enough while being very useful.
torginus|2 months ago
The amount of stuff you have to wade through here compared to something like comptime in Zig (Roslyn API, setting up the project, having VS recognize it and inject it in the compiler, debugging etc) makes usage of these an absolute pain.
torginus|2 months ago
This is more like constrexpr than a macro system.
smcnc|2 months ago
pjmlp|2 months ago
Tiberium|2 months ago
Zambyte|2 months ago
pyrolistical|2 months ago
You can think of zig’s comptime as partial evaluation. Zig doesnt have a runtime type reflection system, but with comptime it makes it feel like you do.
orphea|2 months ago
unknown|2 months ago
[deleted]
andix|2 months ago
I think C# doesn't really have immutable collections, they just can be typecasted to IReadonly* to hide the mutable operations. But they can always be typecasted back to their mutable base implementation.
The only real immutable collections I know of, are F#s linked lists.
mfro|2 months ago
eterm|2 months ago
https://devblogs.microsoft.com/dotnet/introducing-c-source-g...
That said, for more complex results, you'd typically load a serialization on start.
I can see the value in this tool, but there must be a fairly limited niche which is too expensive to just have as static and run on start-up and cache, but not so large you'd prefer to just serialize, store and load.
It also needs to be something that is dynamic at compile time but not at runtime.
So it's very niche, but it's an interesting take on the concept, and it looks easier to use than the default source generators.
andix|2 months ago
ygra|2 months ago
rubenvanwyk|2 months ago
andix|2 months ago
betaporter|2 months ago
faithlv|2 months ago
andix|2 months ago
I've seen a Go project that was heavily using https://pkg.go.dev/embed for loading some template files, and got a bit jealous. Back in the days of .NET Framework it was common to compile file contents into resource files, but it was always quite cumbersome.
eterm|2 months ago
Discoverability for this is in visual studio, if you go to file properties there's a drop-down where you choose between Content, EmbeddedResource, Ignore, etc.
That determines what happens in compile, whether it is copied to output directory, compiled into the binary, etc.
unknown|2 months ago
[deleted]
floucky|2 months ago
mgaunard|2 months ago