pawn-lang / compiler

Pawn compiler for SA-MP with bug fixes and new features - runs on Windows, Linux, macOS
Other
306 stars 72 forks source link

Macro overloading #292

Open samphunter opened 6 years ago

samphunter commented 6 years ago

Is this a BUG REPORT, FEATURE REQUEST or QUESTION?:

What you expected to happen:

Make macro overloading allowed.

For example, we should allow:

define Func(%0,%1)

define Func(%0)

These would be checked in the order they are found and first matching overload would be used. This would allow us to get rid of the ridiculous amount of tag hacking in many advanced libraries, such as YSI.

Not that it is not fun to bend our minds over what those over-complicated macros from time to time, but it is not practical.

kasias69 commented 6 years ago

that´s a good idea !

YashasSamaga commented 6 years ago
#define Func(%0,%1)
#define Func(%0)

is ambiguous.

The second match pattern can match everything that matches the first match pattern.

I would vote in favor of function overloading but not macro overloading. Why would you want to overload macros?

samphunter commented 6 years ago

[It] is ambiguous. The second match pattern can match everything that matches the first match pattern. I would vote in favor of function overloading but not macro overloading. Why would you want to overload macros? I don't think any language supports macro overloading.

I said explicitly that first match would be applied and this is already used extensively in YSI and other includes. It is just achieved using tricks with tags, which make the code extremely unreadable. It would also be much simpler to do than function overloading and much more useful.

Y-Less commented 6 years ago

How would you differentiate between overloads and accidental redefinitions (which are currently warned for)?

samphunter commented 6 years ago

How would you differentiate between overloads and accidental redefinitions (which are currently warned for)?

Other than checking, whether the patterns are same, you could not. But I think this would still be worthwhile sacrifice.

(Thinking about it, this is the preffered option:) Other option would be to make a new syntax, something like:

odefine Func(%0, %1)

odefine Func(%0)

O for overloaded. Mixing overloaded and standard macro would trigger redefinition warning as well.

Y-Less commented 6 years ago

I'm going to make the same reply to two issues, because my objection to both is the same (and other issues as well):

PAWN has two groups of users - the advanced users, who tend to be the sort of people who comment on bleeding-edge compiler issues and make propsals (i.e. us); and average users who just want to write a mode and need to be pushed kicked and screaming just to stop using pawno and dini. I believe the vast majority of compiler updates should be significantly geared towards the latter group. They should make average scripting simpler, not make advanced techniques simpler. There are several reasons for this:

  1. Impact. A change that makes 1000 users' lives easier is vastly better than a change that makes 5 users' lives better.

  2. Documentation. The more there is to the language, frankly the more there is to get confused by, and the higher the bar becomes for new users. Even if they don't need all these advanced new bits, they still need to know they don't need them - which they won't.

  3. Utility vs workarounds. This is sort of the same as 1. If there is a pain-point in the language, how often is it actually hit? And thus, what really is the cost-benefit analysis of new syntax to repair it? If there are only 3 people who hit this point, and they all know the pitfalls and work-arounds, that's just not a good candidate for expansion. On the other hand, if the pain point is well known even to newbies, that's bad and needs addressing.

  4. Scope. PAWN is an embedded scripting language. It isn't an assembly language or DSL language. And I say this as one of the people who has done some of the most assembly and DSL work in the language. But everything I write, all the horrible work-arounds I make, I try and design to make end-users' coding lives simpler.

  5. Longevity. Is this cool new idea you just thought of actually going to be useful for more than one line of code or library? Is it going to bloat the codebase, making future maintenance harder, for no long-term benefit? The one thing it was useful for is done, now nothing more needs to be done with it; but it is forever in the codebase, possibly buggy. Was it really better than a few extra macros?

That's what I try and think about when making proposals. Not saying that all of mine always meet this goal (in recent memory, #pragma option was probably not of great wide interest, but at least that didn't actually affect the language itself in any way).

samphunter commented 6 years ago

In this particular case:

  1. Better libraries affect a lot of people, it trickles down in my opinion.
  2. I would disagree at least in this case, these features will be documented separately from the official language guide, therefore an average user may not even know about them. Even if they find this change, the difference from normal #define can be explained in a single sentence.
  3. Overloaded functions and in extension macros are not something, that is rarely used.
  4. And I am currently in process of migrating away from YSI because I started hitting horrible bugs that I had no idea how to even diagnose and missing features even I could not implement (also speed, but yeah). I would defer to point 1, it is better to maintain (what i presume will be) 10s of lines of code here than incredible mess elsewhere.
  5. In my opinion, this is the same as 3. How often will this be used is hard to say but I would expect quite a few libraries to use this.

PS: I only started this issue now, because kasias69 contacted me using IM to explain to him a mess I had in my library using the tag hack. He needed to add a small feature and was lost in it. Just to maybe illustrate my point better.