On Wed, Mar 12, 2003 at 03:35:58PM -0800, Dave Whipp wrote: : Larry Wall replied: : >: my Database $db = MySqlDatabase.connect(...); : >: $db.select * FROM Foo WHERE Foo.bar LIKE a%b; : : >To answer your actual question, you either need to have some keyword out : >front to start the alternate parsing, or you need to treat ".select" : >as an infix macro that has an ordinary expression on the left ($db) and : >a specially parsed argument on the right (* FROM Foo WHERE Foo.bar LIKE : >a%b) : : This feels a bit clunky. The sort of hack one makes when its too late to : fix it. : : If we define .select as an infix macro, it is then not scoped to the : invocant. This means that it would confict with any other .select method : that one might wish to call. E.g. : : $io.select(...); : : (OK, thats not a good example, but you get the gist). If sure it would : be possible to write the macro in such a way that it looks at its LHS : arg -- and ignores itself if its not a Database object ... but that : places an overly large burden on the macro writer. To avoid this burden, : I'd like to propose C<macromethod> as a counterpart to C<submethod>. A : macromethod would enable me to write an invocant-scoped macro, without : polluting the lexical namespace: : : class Database : { : ... : macromethod select ($lhs, $rhs:) is parsed /<sql.select.body>/ : { : "$lhs.do_sql('select $rhs')" : } : }
I am uncomfortable with the notion of depending on the declared type of the left argument for deciding which macro to use, because its failure mode potentially includes totally misparsing the right argument, and because the declared type of the object is not necessarily the same as the actual type, so if a derived class had its own idea of the macro, the "wrong" macro would be used according to at least one viewpoint. : Without this mechanism, then we need a way to prevent an infinite : regress on macro processing. I am assuming that, if the output of a : macro is a string, then that string will be re-parsed and any macros in : it will be expanded. How would an infix macro indicate that it didn't : want to handle the "$io.select" example? If it returns its input, : unchanged, then that would be an infinite loop. If the declaration is essentially nailing down a particular class in a non-virtual sense, then there's really nothing gained over writing IO::select $io: ... DB::select $db: ... other than the obvious obfuscational benefit of having the class selection defined elsewhere. I'm not saying that what you want is bad. I'm just uncomfortable with it. Certainly a macro could be written to pay attention to the declared type of its left argument, and we could even arrange for some kind of compile-time multimethod dispatch with whatever syntax is deemed appropriate. But mixing such compile-time semantics with a notation that supposedly mandates run-time dispatch is a recipe for a certain amount of confusion no matter how well we do it. Larry