|
6macros: discussing the finer points of Perl 6 macros, Qtrees, and how to stay sane | irclog: irclog.perlgeek.de/6macros/today Set by moderator on 28 July 2015. |
|||
|
05:58
vendethiel joined
08:40
Ven joined
|
|||
| masak tries to finish up a refactor that ended up busting a few more tests than expected on the way | 09:26 | ||
| Ven | $ time ./bin/007 --help | 09:56 | |
| ... | |||
| real\t0m0.794s user\t0m0.722s sys\t0m0.064s | |||
| That's pretty insanely slow Oo | |||
| macro gah(x) { sub infix:<+>(a, b) {return 5 }; return quasi { {{{x}}} } }; gah(-> { say(2 + 2) }) am I doing something wrong? | 10:00 | ||
| masak | we don't have expression blocks anymore. | ||
| so the -> thing won't fly | |||
| we're getting expression subs | |||
| beyond that, I don't see anything ever calling your lambda thing | 10:01 | ||
| Ven | well, it just doesn't parse, so :P. | 10:02 | |
| macro gah(x) { sub infix:<+>(a, b) {return 5 }; return quasi { {{{x}}} } }; gah(say(2 + 2)) am I doing something wrong? | |||
| ^ this doesn't print anything instead :P | |||
| ok, so, "return x" is not the same as "return quasi { {{{ x }}} }" | 10:03 | ||
|
11:28
Ven joined
|
|||
| masak | should be | 11:55 | |
| modulo the stmt-expr impedance matching quasis are meant to do, but that doesn't matter here | 11:56 | ||
| I have a new idea which I'm trying out in my head right now | |||
| I started thinking about it when considering our four hard-to-make-builtin-subs-out-of operators: infix:<=>, postfix:<[]>, postfix:<()>, and postfix:<.> | 11:57 | ||
| I wonder if we want a type of macro that (a) installs a new Q node (like Q::Infix::Assignment) instead of some expanded code, and (b) runs at runtime instead of compile time, but (c) still gets Qtrees as parameter inputs, but (d) returns a runtime value as output | 11:59 | ||
| some things feel right about that idea | |||
| Ven | uhm | ||
| masak | and some things feel off | ||
| I think of them as either "persistent macros" or "semimacros" | 12:00 | ||
| we talked about some parsing modes where the macro call would be left as-is after "expansion". | |||
| this would be the opt-in version of that. | |||
| because the wasiest way to reason about and analyze an assignment in a Qtree expression is still through Q::Infix::Assignment and its properties, not through whatever low-level stuff it stands for | 12:01 | ||
| Ven | I'm not sure what you mean about "returns a runtime value" | 12:02 | |
| macro f { quasi { 5 } }; returns a "runtime value" | |||
| I get the difference you're making (not quasi at the end), but.. | 12:03 | ||
| masak | right -- something like `42` more than something like `Q::Literal::Int { value: 42 }` | 12:07 | |
| masak mulls some more | 12:14 | ||
| Ven | what's the point? | 12:20 | |
| masak | I started thinking about this because I want infix:<=>, postfix:<[]>, postfix:<()>, and postfix:<.> to be definable as userland constructs | 12:52 | |
| (with the possible exception of some function body being written in Perl 6) | |||
| there are several interesting questions here that I don't feel I have an answer to yet | 12:53 | ||
| for example, when you define an ordinary (non-macro) operator, how would you associate it with a user-defined Q node type? | 12:54 | ||
| I guess something like `sub infix:<~+*>(l, r) is qtype(Q::Infix::Glonking) {}` would work. but it feels wrongish because now we're not using the function body or the paramters. | 12:55 | ||
| which indicates maybe there should be a macro to do this. | |||
| `define-infix("~+*`, Q::Infix::Glonking);` or something | 13:23 | ||
|
13:33
Ven joined
|
|||
| masak | ok, so | 13:42 | |
| I have this mostly successful refactor where I consolidate the .interpolate logic into a single sub, instead of lots of small and mostly repetitive methods on Q types | |||
| (.interpolate helps clone a Qtree from a quasi to the thing that ends up injected in code) | 13:43 | ||
| but it's flagging up difficulties with the $.ident attribute in operators | |||
| part of the signal I'm getting from the code is that I should make $.ident be the primary determiner of what operator you're dealing with, not the Q type (e.g. Q::Infix::Assignment) | 13:46 | ||
| which kind of makes sense, because someone could create a Q::Infix with the same ident as Q::Infix::Assignment, and it'd be a Q::Infix::Assignment in everything but name | 13:47 | ||
| but it's also a bit sad -- I think people like to think of those different language-provided operators as subtypes | |||
| if there were a mechanism by which I could "lock" $.ident in the subtypes, making it impossible to set at creation, I think this might work | 13:49 | ||
| but it feels wrong from an OOD perspective, for some reason | |||
| also, the Val::Sub::Builtin value that each operator subclass needs to set is defined in Runtime::Builtins, which is less core than Q, so there's a dependency arrow going the wrong way there, too | 13:51 | ||
| hm, that's not 100% true. I don't need that actual value; only an identifier which is guaranteed to point at the built-ins. | 13:52 | ||
| that, in retrospect, was the nice thing about having $type as a role parameter -- the linking of a Q type and an operator was made on the type level, not at each object construction. | 14:17 | ||
|
15:04
Ven joined
15:07
Ven joined
15:08
Ven joined
16:23
Ven joined
21:13
vendethiel joined
|
|||