Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Personally, I think compiler macros are far more interesting than 'regular' macros. I would love to see compiler macros even in mundane languages such as python.

Example, in pseudo code:

<code> defun regex_find(some_string, regex) return regex.compile().find(some_string)

def compilermacro regex_find(some_string, regex) if IS_STRING_LITERAL(some_string) and IS_STRING_LITERAL(regex) SUBSTITUTE exec(regex.compile().find(some_string)) elif IS_STRING_LITERAL(regex) SUBSTITUTE exec(regex.compile()).find(some_string) else DO_NOTHING return

</code>

regex_find(MYSTRING, '\w(.+)\b')

A language without compiler macros would compile the regex at runtime, even in those cases that it is a string literal, and could be compiled at compile time. And in the case that both the string and the regex are string literals, the result itself could be computed at compile time. Another alternative, used by lots of languages/libraries, is to maintain a cache of recently compiled regular expressions. Of course, this doesn't help when you have a loop that uses 15 regular expressions but it only caches the last 14, for example.

This is one reason why CL-PPCRE is faster than the C PCRE in benchmarks, it makes great use of compiler macros.

This is a very concrete real world thing, that isn't endlessly debatable, unlike regular macros, and it could be included in languages without any special macro syntax.

One example of a time I really wanted compiler macros in Python was when I was doing some parsing of binary files, using the struct module. The struct module lets you do stuff like struct.decode(data, 'UUUIUH'), where the UUUIUH is some code for Unsigned long, unsigned long, 32bit int, whatever. However, it parses the little code each time you want to use it, which ends up taking way longer than the actual decoding itself. In python 2.x, whatever I was using, they didn't have any way to make any sort of compiled decoder, you had to just use it as above, which is silly, since the code is almost always going to be a string literal and 99% of the work could be done once when the code is compiled.



> Another alternative, used by lots of languages/libraries, is to maintain a cache of recently compiled regular expressions. Of course, this doesn't help when you have a loop that uses 15 regular expressions but it only caches the last 14, for example.

Nitpick: it depends on the replacement policy whether it helps. If the cache is MRU, for example, it would work fine.


It doesn't matter if each one is used once, say in a loop.

If you have 14 slots in your cache, and you loop over 15 regular expressions, no cache policy (unless it also tracks regexes it has already lost from the cache, which effectively gives it more than 14 slots) will work, except maybe some kind of cache that just remembers the first 14 regexes it sees, and only forgets one randomly every 10 more regexes it sees. Such a cache policy would be really really stupid in most cases not specifically designed to thwomp, say, an LRU cache or a regular deque or something.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: