Why does Crystal's macro syntax for iterating differ from the rest of Crystal
Asked Answered
B

1

5

Coming from the Ruby world, I instantly understood why Crystal chose not to implement a for method. But then I was surprised to see that Crystal does implement a for method for macros. I was even more surprised to find that macros don't allow an enumerable (.each, etc) syntax (i.e. {% ["one", "two", "three"].each do |value| %} isn't valid macro syntax).

Is there a logical reason for this syntax difference? It's possible that the answer is simply ~"because the devs decided that macro syntax looks like x, and non-macro syntax looks like y", but I'm guessing that there is more to it then that (an arbitrary syntax inconsistency seems like a flaw).

Thanks!

Briolette answered 30/12, 2017 at 19:15 Comment(4)
I guess the macros syntax is intended to somewhat resemble a templating engine like Liquid.Doyledoyley
@JohannesMüller If they simply mimicked an existing templating language, shouldn't they go with ERB? (this seems obvious to me, but maybe it's not obvious?) Maybe they tried something like regular Crystal syntax and it was hard to read. I'm very curious to see if the thought process is documented anywhere.Briolette
I'm not sure if it played a role in the initial proposal, but ERB-like syntax is used by Crystal's integrated ECR templates. Using that same syntax for macros would be confusing and make it impossible to use macros in ECR files (not that that should be such a good practice, but it is possible).Doyledoyley
You should open an issue about changing this. I'd support your proposed syntax. In terms of answering your history question, that's be one for the manas team.Shadshadberry
P
7

The main reason is that when the parser parses foo.bar do |arg| ... end, it expects an expression after |arg|, not %}, which is a parse error. So to allow that we'd need to enhance the parser (which is already quite complex) to take that into account. for was decided because of this, but also to make it clear that it's just not regular crystal but a different thing (it's an interpreted subset of crystal and the standard library).

Another reason is that if each and other iteration methods are allowed, why not while and until? That could allow endless loops in macros, which with just for aren't possible, so you can guarantee a macro finishes executing. Which... is actually not true given that we have run inside macros.

So I think I'm not opposed to change the language to allow each, each_with_index, etc., inside macros, and allow that syntax, and eventually remove for from the macro language. Opening an issue requesting this is a good way in this direction.

Procryptic answered 1/1, 2018 at 23:46 Comment(1)
I created an issue for this: github.com/crystal-lang/crystal/issues/5506. Personally, I don't feel qualified to push strongly in any direction, but I am interested to see what others think about the current syntax.Briolette

© 2022 - 2024 — McMap. All rights reserved.