November 29, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Horne | Steve Horne wrote: > On Wed, 29 Nov 2006 14:11:01 -0500, Brad Anderson <brad@dsource.org> wrote: > >> Steve Horne wrote: >>> On Wed, 29 Nov 2006 11:47:10 -0500, Brad Anderson <brad@dsource.org> wrote: >>> >>>> I don't think this is the primary reason. As mentioned before, syntax is a part of it, but so is the total power given to the programmer. This power leads to a lack of standard or cohesive libs, b/c it's so easy to make it exactly the way you want it. I imagine that if some of the D power users wrapped themselves in Lisp for a while, they'd be able to do for themselves what they beg Walter to do for them in D. >>> Not really. >>> >>> There are things you just can't do with Scheme macros. Associativity and precedence, for instance. This means that if you want to do these things, you have to go the Von Neumann route - treat code as data and manipulate it at compile time using Scheme functions. >> I'm not following. Do you have definitions or examples of these? I did find this... > > Sorry, I'm being stupid. On reflection, you're asking for examples of things you can't do with Scheme macros. > > Well, it's hard to provide examples of things that can't be done beyond listing them. Disproof by example is much stronger than proof by example. If your link gives examples of precedence and associativity using macros, well, that just makes me twice stupid. > > The claim about associativity and precedence, though, just fell out of my reading of the Scheme manual. At the time, I could see no way to do it. > > I'm aware that it is possible to build them in by creating an unambiguous set of BNF rules for a grammar (as opposed to the more normal approach of using disambiguating rules) but I couldn't see a way to do either. I had the distinct impression that the matching is always from left to right. > > Based on that, you can write (1 + 2 * 3) if you want, but the result > will be 9, not 7. > in a Lisp-like language, using prefix notation, this is: (+ 1 (* 2 3)) => 7 or (* (+ 1 2) 3) => 9 > On a quick scan through that, there doesn't seem to be anything to say that Scheme macros can do associativity and precedence. That's fine by me, as I don't feel quite as stupid as I did a minute ago ;-) There's no need for precedence, because it's always explicit. This thing is a dead horse. I suspect we are confusing each other, as you say. You should look at Common Lisp a bit, esp. the link I posted to Peter Seibel's book. Even a brief read may help you understand a bit of what I'm saying about metaprogramming. BA |
November 29, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Anderson | Brad Anderson wrote: > Steve Horne wrote: >> On Wed, 29 Nov 2006 14:11:01 -0500, Brad Anderson <brad@dsource.org> wrote: >> >>> Steve Horne wrote: >>>> On Wed, 29 Nov 2006 11:47:10 -0500, Brad Anderson <brad@dsource.org> wrote: >>>> >>>>> I don't think this is the primary reason. As mentioned before, syntax is a part of it, but so is the total power given to the programmer. This power leads to a lack of standard or cohesive libs, b/c it's so easy to make it exactly the way you want it. I imagine that if some of the D power users wrapped themselves in Lisp for a while, they'd be able to do for themselves what they beg Walter to do for them in D. >>>> Not really. >>>> >>>> There are things you just can't do with Scheme macros. Associativity and precedence, for instance. This means that if you want to do these things, you have to go the Von Neumann route - treat code as data and manipulate it at compile time using Scheme functions. >>> I'm not following. Do you have definitions or examples of these? I did find this... >> Sorry, I'm being stupid. On reflection, you're asking for examples of things you can't do with Scheme macros. >> >> Well, it's hard to provide examples of things that can't be done beyond listing them. Disproof by example is much stronger than proof by example. If your link gives examples of precedence and associativity using macros, well, that just makes me twice stupid. >> >> The claim about associativity and precedence, though, just fell out of my reading of the Scheme manual. At the time, I could see no way to do it. >> >> I'm aware that it is possible to build them in by creating an unambiguous set of BNF rules for a grammar (as opposed to the more normal approach of using disambiguating rules) but I couldn't see a way to do either. I had the distinct impression that the matching is always from left to right. >> >> Based on that, you can write (1 + 2 * 3) if you want, but the result >> will be 9, not 7. >> > > in a Lisp-like language, using prefix notation, this is: > > (+ 1 (* 2 3)) => 7 > > or > > (* (+ 1 2) 3) => 9 > >> On a quick scan through that, there doesn't seem to be anything to say that Scheme macros can do associativity and precedence. That's fine by me, as I don't feel quite as stupid as I did a minute ago ;-) > > There's no need for precedence, because it's always explicit. > > This thing is a dead horse. I suspect we are confusing each other, as you say. You should look at Common Lisp a bit, esp. the link I posted to Peter Seibel's book. Even a brief read may help you understand a bit of what I'm saying about metaprogramming. > > BA Sorry, gotta kick the horse one more time. http://plaza.ufl.edu/lavigne/infix.lisp BA |
November 29, 2006 OT: Lisp (Was: Re: Is metaprogramming useful?) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lutger | Lutger wrote: > Georg Wrede wrote: >> Brad Anderson wrote: >> >>> Greenspun's 10th Rule of Programming: Any sufficiently complicated C or >>> Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp. >> >> It's not a coincidence that I installed Allegro Common Lisp (from Franz Inc, a demo version of an excellent commercial implementation) on my Fedora last week. And dLISP for comparison. > > Sorry to ask it here, but how do you evaluate dLISP? Is it complete enough? Well, it's a toy, almost like a proof of concept. It's not robust at all, so a lot of errors, especially in the input, simply crash it. And no documentation to brag with. And the version on dsource is broken, it doesn't even compile. I've fixed mine, with hints from the discussion forum (thread heading "Ping") and some additional fixes. Anyway, I wouldn't recommend it for learning, since I believe that one should always learn with good tools. Get Allegro instead. It's free for private use! There exists a complete package for anybody who really wants to learn Common Lisp, called Lispbox. (http://www.gigamonkeys.com/lispbox/) It's an all-in-one package that's ready to use right "off the box". While the download is big (80Megs), it runs fine on my 800MHz 256MB Linux laptop. There are downloads for Linux, OS-X, and Windows. > I'm learning lisp atm, it sounds attractive to embed a lisp interpreter in D programs and use them together. This should be very easy with dLISP I think. dLISP is a good choice if one wants to embed Lisp in one's own application. It's got the basics, and whatever you need more you can write in D or Lisp. (I said earlier that it's not robust. But the code is clear, logical, and it looks final. The lack of robustness has more to do with not having error checking than bugs, probably because this may have been a proof of concept type effort.) It's little and lightweight, and the source code is small enough to let you study and comprehend it "in full", which always leads to a better and more robust end result for your embedding project. dLISP is easily capable of handling what you'd need, say, as the macro language in your own text editor, game logic, smarter user interfaces to your existing programs, and such. |
November 29, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Horne | Steve Horne wrote: > Brad Anderson <brad@dsource.org> wrote: > >> P.S. Please no ignorant replies about Lisp is interpreted or Lisp >> is slower than the imperative languages. > > No - I already did that a few years ago on comp.lang.python. I'm less > ignorant these days. > > I have tried to learn Scheme on many occasions, though, and only ever > got so far. Sure, it has that key mechanism there, but learning to > use the language is a bit like learning C++ by first learning how to > write asm blocks, and finding no teacher who is ever willing to teach > you the high level tools you need for real everyday work. Fine, you > can do anything, but why do you always have to reinvent all those > wheels? I took a university class in Scheme some 15 years ago. It was rewarding, but like you, I felt it was pretty hard. And it's true, recursion may not be the answer to everything under the sun. > The thing is that in the real world, most programmers need a > standard, familiar dialect which has all the everyday high level > tools available from the start. If OOP is an immediately useful > concept, programmers should be using OOP from day one, not learning > how to reinvent OOP from the basic building blocks. So, has anyone > created widely-used standard librarys for high level programming? The very point of Common Lisp is *precicely* what you wrote here! CL tries to be a practical language for people doing real-world programming. (Sound familiar?) And they explcitly take distance to Scheme, which they consider more Purist, Academic, and for theoreticians. (The latter of course disagree, as usual.) |
November 29, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Anderson | OK - I think I get the source of this confusion, and surprise surprise, it's my fault. So... On Wed, 29 Nov 2006 16:28:29 -0500, Brad Anderson <brad@dsource.org> wrote: >> Based on that, you can write (1 + 2 * 3) if you want, but the result >> will be 9, not 7. >> > >in a Lisp-like language, using prefix notation, this is: > >(+ 1 (* 2 3)) => 7 Yes, but if you say that Lisp is evil because you have to use prefix notation, you get people jumping up to say 'no you don't - just define your own syntax as a library'. That's basically where my point starts, in a wider sense that starts outside this thread, which I obviously didn't make clear. Hence the confusion - my key point is about syntax, not semantics. Getting back to what you said... : I imagine that if some of the D power users : wrapped themselves in Lisp for a while, they'd be able to do for themselves : what they beg Walter to do for them in D. In semantic terms that's true, but in syntax terms it's not - at least not without going to the extreme compiler building stuff I mentioned earlier. Lisp may provide the ability to set up whatever semantics you want, but if you have to access that through a syntax that you just can't get on with, that's a serious handicap. And the 'what they beg Walter to do for them' is probably as much about syntax as semantics. >This thing is a dead horse. I suspect we are confusing each other, as you say. You should look at Common Lisp a bit, esp. the link I posted to Peter Seibel's book. Even a brief read may help you understand a bit of what I'm saying about metaprogramming. I think I already know what you were saying to start with, and agree with the Greenspun's 10th Rule bit. And your lack of coherence bit is similar to a point I already made somewhere about the lack of standard implementations of high level concepts in Scheme (or at least of ones I can find). It's the just-use-Lisp tone of what you said that I object to. Learn from Lisp, yes, absolutely. Using it, though... -- Remove 'wants' and 'nospam' from e-mail. |
November 29, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to renoX | renoX wrote:
> Back on the subject of metaprogamming, one thing which makes me cautious about
> metaprogramming is debugging: when there is a problem debugging generated code is
> a nightmare usually..
It's not metaprogramming itself, it's the bad implementations that make it hard.
If we had Perfect Metaprogramming(TM) in D, then I could do the following:
I'm coding some stuff and I notice that what I'd really want
is a new keyword, "unless", that would make it so much easier
for me to write this application clearly. I decide to create it.
I want to use it like this
unless (fullMoonTonight) { doRegularStuff() }
So, to create such a thing in D, I'd write something like
define("unless", "(", BooleanExpression, ")", BlockStatement)
{
if(!BooleanExpression) BlockSTatement;
}
Now, if I'd made errors in writing the meta code, then the compiler would error me, of course. No biggie. And since the D compiler would understand what's going on (as opposed to the C preprosessor or compiler), the error messages would be what we're used to in D.
Later, when I actually use the "unless" construct, again the error messages would be normal because D now understands what "unless" is all about.
---
People say GC has to be slow, but that is mostly because it used to only exist in languages that were slow to begin with (and badly implemented).
The same thing with metaprogramming. C++ has given it such a bad rep, it'll take years before folks learn away from their fears.
|
November 29, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steve Horne | Steve Horne wrote: > : I imagine that if some of the D power users > : wrapped themselves in Lisp for a while, they'd be able to do for themselves > : what they beg Walter to do for them in D. > > In semantic terms that's true, but in syntax terms it's not - at least not without going to the extreme compiler building stuff I mentioned earlier. Lisp may provide the ability to set up whatever semantics you want, but if you have to access that through a syntax that you just can't get on with, that's a serious handicap. And the 'what they beg Walter to do for them' is probably as much about syntax as semantics. I agree. Good point. I have to admit - Lisp in the most powerful language I'm aware of. But it doesn't have much syntax sugar for common operations. And everything looks the same. Take this chunk from spectralnorm program from the shootout for example: --------------------------------------------------- (dotimes (i n) (incf vBv (* (aref u i) (aref v i))) (incf vv (* (aref v i) (aref v i)))) --------------------------------------------------- I think D is a bit more readable and concise: --------------------------------------------------- foreach(i, vi; v) { vBv += u[i] * vi; vv += vi * vi; } --------------------------------------------------- -- AKhropov |
November 30, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Georg Wrede | Georg Wrede wrote: > It's not metaprogramming itself, it's the bad implementations that make it hard. > > If we had Perfect Metaprogramming(TM) in D, then I could do the following: > > I'm coding some stuff and I notice that what I'd really want > is a new keyword, "unless", that would make it so much easier > for me to write this application clearly. I decide to create it. > > I want to use it like this > > unless (fullMoonTonight) { doRegularStuff() } > > So, to create such a thing in D, I'd write something like > > define("unless", "(", BooleanExpression, ")", BlockStatement) > { > if(!BooleanExpression) BlockSTatement; > } > > Now, if I'd made errors in writing the meta code, then the compiler would error me, of course. No biggie. And since the D compiler would understand what's going on (as opposed to the C preprosessor or compiler), the error messages would be what we're used to in D. > > Later, when I actually use the "unless" construct, again the error messages would be normal because D now understands what "unless" is all about. Well, I'm sorry I'm saying that again but it's almost exactly the way Nemerle does it. And it actually has that unless macro :-) Here's the actual code from the compiler svn: ------------------------------------------------------------------- macro @unless (cond, body) syntax ("unless", "(", cond, ")", body) { <[ match ($cond) { | false => $body : void | _ => () } ]> } ------------------------------------------------------------------- but it's defined using pattern matching. anyway it can be defined your way: ------------------------------------------------------------------- macro @unless (cond, body) syntax ("unless", "(", cond, ")", body) { <[ when( !($cond) ) $body ]> } ------------------------------------------------------------------- ('when' is used in Nemerle for 'if without else') > --- > > People say GC has to be slow, but that is mostly because it used to only exist in languages that were slow to begin with (and badly implemented). Sad to say, but GC in D is still conservative and hence slow :-( -- AKhropov |
November 30, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Brad Anderson | On Wed, 29 Nov 2006 16:30:28 -0500, Brad Anderson <brad@dsource.org> wrote: >Sorry, gotta kick the horse one more time. > >http://plaza.ufl.edu/lavigne/infix.lisp Well... Of course that macro is actually using quoted expressions and a 'compiler' in its implementation - using a macro to hide the 'compiler' is cheating a bit, really. And it's neither trivial nor, AFAICS, a standard library - just one persons how-to-do-it example. I confess it's certainly shorter than I expected, but that's partly because it is just a precedence parser - it only handles precedence and associativity. But then that's probably no bad thing - concepts should be kept separate rather than being bundled, which is probably a major failing in how I was looking at this (the idea of a huge extensible dialect library, rather than a small concept library). And given the point Georg made about Common Lisp vs. Scheme, which certainly suggests that some of my resistance is misplaced... I don't think you've quite proven me wrong (yet), but clearly my position is a lot weaker than I thought and probably unsustainable. And since my only remaining defence is actually a point you appear to agree with (your link isn't a standard, which relates back to the coherence thing you mentioned) I have no choice but to withdraw what I said. The worrying thing is that I think I'm still on probation from a certain Lisp-related-ignorance incident on comp.lang.python a few years back - please don't tell on me! -- Remove 'wants' and 'nospam' from e-mail. |
November 30, 2006 Re: Is metaprogramming useful? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrey Khropov | Andrey Khropov wrote: > Georg Wrede wrote: > > >>It's not metaprogramming itself, it's the bad implementations that make it >>hard. >> >>If we had Perfect Metaprogramming(TM) in D, then I could do the following: >> >> I'm coding some stuff and I notice that what I'd really want >> is a new keyword, "unless", that would make it so much easier >> for me to write this application clearly. I decide to create it. >> >> I want to use it like this >> >> unless (fullMoonTonight) { doRegularStuff() } >> >> So, to create such a thing in D, I'd write something like >> >> define("unless", "(", BooleanExpression, ")", BlockStatement) >> { >> if(!BooleanExpression) BlockSTatement; >> } >> >>Now, if I'd made errors in writing the meta code, then the compiler would >>error me, of course. No biggie. And since the D compiler would understand >>what's going on (as opposed to the C preprosessor or compiler), the error >>messages would be what we're used to in D. >> >>Later, when I actually use the "unless" construct, again the error messages >>would be normal because D now understands what "unless" is all about. > > > Well, I'm sorry I'm saying that again but it's almost exactly the way Nemerle > does it. Hmm. I'n not sorry at all! :-) There's confluence in the air.... > And it actually has that unless macro :-) Here's the actual code from the compiler svn: > > ------------------------------------------------------------------- > macro @unless (cond, body) > syntax ("unless", "(", cond, ")", body) { > <[ match ($cond) { | false => $body : void | _ => () } ]> > } > ------------------------------------------------------------------- > > but it's defined using pattern matching. > > anyway it can be defined your way: > > ------------------------------------------------------------------- > macro @unless (cond, body) > syntax ("unless", "(", cond, ")", body) { > <[ when( !($cond) ) $body ]> > } > ------------------------------------------------------------------- > > ('when' is used in Nemerle for 'if without else') > > >>--- >> >>People say GC has to be slow, but that is mostly because it used to only >>exist in languages that were slow to begin with (and badly implemented). > > > Sad to say, but GC in D is still conservative and hence slow :-( > |
Copyright © 1999-2021 by the D Language Foundation