Crystal's implementation wouldn't work for something like C#, though, because C# supports dynamic assembly loading at runtime and must provide reflective facilities for operating on types loaded from them. (I once wrote an extensibility system[1] and on-the-fly compiler for a game engine that took advantage of this, it was neat.)
Macros don't help you here and limiting yourself to "I can compile the whole blob at once" cuts off a lot of avenues of extensibility.
>> because the maintainers refuse to add any new syntax they now basically cram everything they need into the reflect package.
I think they want to try different avenues before to decide what features to add. Generators("go generate") are used a lot too but they are a pain to develop. Most of them still use templates or print statements instead of specilised packages such go/ast , go/types, go/parser etc to actually generate/print code. Usually you should use reflection to prototype and switch to generators only where the performance is really a big issue or where reflection can't help(i.e define new named types, import/use arbitrary packages/functions)
Alternatively, you build a type system that can express what developers actually need it to express and solve the problem without reflection at all. =)
That's easier said than done. There are tradeoffs on expressive type systems too. That being said I wouldn't mind more expressivity in the Go type system. I'm actually looking to implement my own small features(i.e optionals, variant types) in a Go superset.
Where do you think struct tags fit in all this ? do you really think go designers took the time to consider the tradeoffs of such feature ? I don't think so.
Any sufficiently advanced type system is indistinguishable from magic.
https://crystal-lang.org/docs/syntax_and_semantics/macros.ht...
It's a meta language that works at compile time. It's not just text substitution like with GCC, so the syntax can be validated. And no need for "go gen" like silly tricks.
Languages that have reflection should do everything so that using reflection is the exception, not the norm. Some languages which boast about simplicity are often the worst offenders in practice, when it comes to reflection, just look at Go code out there, full of reflection everywhere, because the language is way too simplistic for a lot of use cases. Go even allows adhoc type definition at run time, out of thin air. Is this really what gophers mean by "simplicity" ? because the maintainers refuse to add any new syntax they now basically cram everything they need into the reflect package. Then dare say its use is "not idiomatic" when they abuse reflection themselves ?