Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (517)
Games in Android Showcase (123)
games submitted by our members
Games in WIP (578)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: 1 2 [3] 4 5
  ignore  |  Print  
  Another language feature I'd like  (Read 16330 times)
0 Members and 1 Guest are viewing this topic.
Offline bienator

Senior Duke




OutOfCoffeeException


« Reply #60 - Posted 2009-07-07 13:33:15 »

here is the up2date list of all "realistic" proposals
http://blogs.sun.com/darcy/entry/project_coin_consideration_round_2

note: AFAIK only 5 or 6 will make it into jdk7 at the end of the process

Related, has anyone seen the list of proposed additions in Java7? Null safe handling looks like a practical piece of syntaxtic sugar (through the awesomely named "elvis operator"), and annotations on java types looks like giving us the handy-dandy @NotNull that's been kicking around in Nice for ages.

In fact that's a pretty big list - does anyone know of similar ones for java5 and 6 for comparison? (and I'm wondering if I missed anything cool that got drowned out in all the generics and annotations hype).

Offline Mr_Light

Senior Duke


Medals: 1


shiny.


« Reply #61 - Posted 2009-07-07 14:39:46 »

I'm going to reply in the reversed order since the answers make more sense that way..

Your sourcecode repository will choke on it.
Since the view doesn't exist as an actual file it's impossible to check that in. Have you ever tried checking in a piece of source with code folded?

You can't copy and paste code around anymore.
Sure you can the java code that backs the shorthand is simply copied to the clipboard.

Yeah, right. Changing the view of the source, while the real files are different... Suddenly you find yourself only being able to program in a specific IDE.
It's DSL like so you are going to need additional stuff here it's a plug-in somewhere else it's a interpreter or a compiler. A decent implementation stands or falls with how well the java source code that backs the shorthand syntax can be read. Since esp in the beginning very few will have the plug-in and the rest simply looks at the java source code backing it, so if that is crap to look at..

I'm not married to this at btw, regardless of how it looks.



It's harder to read code than to write it. - it's even harder to write readable code.

The gospel of brother Riven: "The guarantee that all bugs are in *your* code is worth gold." Amen brother a-m-e-n.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #62 - Posted 2009-07-07 16:00:05 »

This is what you said earlier:
You miss the point where it doesn't need to be a java sourcefile.

This is what you say now:
Since esp in the beginning very few will have the plug-in and the rest simply looks at the java source code backing it, so if that is crap to look at..

Those are two very different things. I definitely agree with the 2nd version.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Mr_Light

Senior Duke


Medals: 1


shiny.


« Reply #63 - Posted 2009-07-07 18:12:57 »

This is what you said earlier:
This is what you say now:
yeah my bad (as usual)

I type up words explaining stuff and then reading it back I realise that it doesn't relay the message as I though it would so I end up modifying it a lot as I go through that cycle a couple of times.

I suppose it had to be something alike "You miss the point where it doesn't need to be a java sourcefile. ".... your looking at or something. Anyway I hope I have been able to relay it better/clarified it my other messages.

There's a reason why I usually dictate stuff and let others freely put it into writing. Blessed are those who are able to put their thought clearly into words.

It's harder to read code than to write it. - it's even harder to write readable code.

The gospel of brother Riven: "The guarantee that all bugs are in *your* code is worth gold." Amen brother a-m-e-n.
Offline thiagosc

Senior Newbie





« Reply #64 - Posted 2009-07-08 18:08:17 »

Set operations are just such a fundamental way of dealing with data I wonder why they haven't been integrated into proper languages much sooner.

Cas Smiley

Some people have been doing whatever they want in programming languages using a feature called "macros" present in Lisp languages since the 60s. Everything would be much easier, not just this example, if Java had macros.

I wonder why people insist in creating special syntax for whatever little BS they can think of if they could just write macros! And I wonder why in 40 years nobody ever thought about copying such a valuable feature from Lisp.

I mean, in the 70s and 80s you would have some justification for using languages lacking in features and that look and write like vomit, like C for example, but for God's sake, we have gigabytes of RAM and multicore processors now. There's no excuse. It is simply idiotic.

It is not just Java, it is most languages out there. C# is a mess and LINQ is just a workaround for the sheer stupidity of programming language designers.
Offline thiagosc

Senior Newbie





« Reply #65 - Posted 2009-07-08 18:12:49 »

I'm kind of shocked that nobody has come out against the crowd and agreed with you yet, Cas - your example requires far fewer keystrokes, is more understandable, and omits all the crap boilerplate that makes maintaining and extending most Java code a nightmare.  I don't see what's not to like, except that it's different from the way things are done now.

We don't need more crappy syntax to complicate things even further. We need macros. A much more intelligent way of dealing with such problems.
Online princec

JGO Kernel


Medals: 409
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #66 - Posted 2009-07-08 18:21:17 »

I submit that "macros" might just be another way of saying "compiler plugins". I also suspect compiler plugins would be more flexible, delegating as they would the compilation of particular bits of text to a completely separate compiler. Possibly.

Cas Smiley

Offline thiagosc

Senior Newbie





« Reply #67 - Posted 2009-07-08 18:21:49 »

You language ****s never change! Which is why Java's stuck in the mid-90s still, where it started. I'm fed up of how much boilerplate crap I have to do to get simple things done, and I'd love a way forward to add to Java that had sod all effect on anyone who didn't care. So a plugin architecture for javac would be brilliant, because Orangytang wouldn't have to care about maintaining Java code - because it won't be Java code, it'll be base Java + SQL-over-collections-plugin code, and if that becomes some sort of standard plugin, then he'll learn it.

I wish Java would be stuck in the 50s, right when Lisp came to be. And I wish were a Lisp dialect. Then all the problems cited by you and others wouldn't exist.

Java doesn't need to copy C#, Java needs to go back in time and learn how to do it right.
Offline thiagosc

Senior Newbie





« Reply #68 - Posted 2009-07-08 18:28:00 »

I submit that "macros" might just be another way of saying "compiler plugins". I also suspect compiler plugins would be more flexible, delegating as they would the compilation of particular bits of text to a completely separate compiler. Possibly.

Cas Smiley

No, macros are a language feature, just like functions, where you can generate different code sequences based on parameters received from the macro call. With the option of nesting parameter lists, so you can have entire trees of data to play with and generate the correct code.

This way you would be able to create a "select" call yourself and it would be compiled into the usual JDBC calls you always need to do. It wouldn't be a function invocation, it would be just that you would write the code the way you want to do it, like a shortcut syntax, and the language would handle the generation of the code for that.
Offline ewjordan

Junior Duke





« Reply #69 - Posted 2009-07-08 19:20:10 »

I submit that "macros" might just be another way of saying "compiler plugins".
Perhaps, in a sense, but I'd probably put true Lisp-style macros a step or two above what a compiler plugin system would realistically enable.  The essence of the macro (a real macro, not the C++ #ifdef crap that people think of when they hear the word) is that if you're working in language X, you can write code in language X that acts on code trees in that same language, and you can do so right next to the code that you need to transform.  So you can redefine your syntax as you need to without so much as a context switch.

The main weakness of plugins compared to true macros is that there's a lot of burden involved in changing a compiler plugin to do what you need and then installing it, i.e. the context switch is pretty painful.  It's not exactly the type of thing that you can do for a one-off code transformation or as part of your day-to-day coding, to say the least, even in (say) Scala where the compiler plugin system is fairly good.  Contrast that with Lisp, where a real good Lisper will write maybe 20% macros, 80% other code.

But macros in Java?  Never going to happen.  Might be nice (I'd probably even vote for the proposal), but macros are the ultimate power-user (read: dangerous for nubz/large teams) feature, and even languages with a lot more balls than Java usually decide against allowing them.  That's not even to mention the technical difficulties that would need to be overcome to wedge a useful macro system in to such a syntactically rich language...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Online princec

JGO Kernel


Medals: 409
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #70 - Posted 2009-07-08 21:32:33 »

Ahem. My esteemed forumers cannot see the wood for the trees.
Missing macros? Simple. Add a compiler plugin that does them. Job done.

Cas Smiley

Offline Mr_Light

Senior Duke


Medals: 1


shiny.


« Reply #71 - Posted 2009-07-08 22:17:00 »

//edited

Software that gets used has source that gets read by more then one person.

It's harder to read code than to write it. - it's even harder to write readable code.

The gospel of brother Riven: "The guarantee that all bugs are in *your* code is worth gold." Amen brother a-m-e-n.
Offline Riven
« League of Dukes »

JGO Overlord


Medals: 823
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #72 - Posted 2009-07-08 22:24:38 »

It's obvious what point you're trying to make, but you fail miserably.

It's both insulting and it makes no sense at all.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline Mr_Light

Senior Duke


Medals: 1


shiny.


« Reply #73 - Posted 2009-07-08 23:29:11 »

It's obvious what point you're trying to make, but you fail miserably.
pff, though if you got it why didn't you help out by explaining it better? (no smear there, I'm be honest and certainly not below asking for help)
Also if the point that I'm making is obvious how did I fail miserably at relaying it? Perhaps the packaging could be better, but I already pointed out that I lack the finesse to 'wrap it right'.

It's both insulting and it makes no sense at all.
Some how I figured, that if I didn't made a stark comment that people would not read into the subtlety of it all.

if it was about poking fun at Cas, then explain me through pm why that was so bad?

It's harder to read code than to write it. - it's even harder to write readable code.

The gospel of brother Riven: "The guarantee that all bugs are in *your* code is worth gold." Amen brother a-m-e-n.
Online princec

JGO Kernel


Medals: 409
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #74 - Posted 2009-07-08 23:58:11 »

I don't mind being poked fun at. I am immune.

So I think the chief argument might have been there - I don't know coz it was edited out before I got to see it - is that the very thought of some different syntax appearing in some source code gives some programmers the willies?

And yet here I am, coping with the addition of generics and enhanced for loops, and writing SQL on a daily basis albeit inconveniently in different files.

I think all it takes is for people to vote the best features to the top of the pile, and the nasty ones will never make it into serious production. Nobody will take a plugin seriously that allows you to write in Brainf**k but you *will* be allowed to write one. But the rest of us who need a few DSL-like features in our source code will pick the best and most productive ones. So I'll take SQL-syntax-for-collections for starters. And I bet closures would become popular. If I didn't understand the source code, well, that's really my fault for not learning it. But then I don't understand Lisp and you don't see me whinging at the Lisp programmers that I can't understand their source.

Cas Smiley

Offline ewjordan

Junior Duke





« Reply #75 - Posted 2009-07-09 01:08:21 »

Cas, do you have thoughts on the specifics of a compiler plug-in proposal that we could discuss or comment on (read: argue about Tongue)?  Is that what this thread is meandering towards, or is this "for fun"?  Also, are there any similar proposals already on the table (or that have been rejected right off of it)?

I still think getting something like this in is a bit of a long shot, but I think you're right that it could quiet a lot of the bitching about language changes without stepping on anyone's toes or forcing the masses to learn something new.

This thread has brought up a couple important objections, which are worth thinking about in more detail, since they'd come up a lot in any discussion about this:

1) Isn't bytecode instrumentation enough?
2) If we can screw with syntax through plugins, what about our precious IDEs?

Other objections?  Solutions?  Comments?  Bueller?
Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #76 - Posted 2009-07-09 01:52:34 »

I wish Java would be stuck in the 50s, right when Lisp came to be. And I wish were a Lisp dialect. Then all the problems cited by you and others wouldn't exist.

Java doesn't need to copy C#, Java needs to go back in time and learn how to do it right.

Of course... all the most successful game companies are using LISP.  In fact most of the software you see on the shelves in any store is written in LISP.  That's what makes it such a dominant language today.  Why, I can name at least one whole program done in LISP! The rest use SmallTalk of course.  Beat that you Java and C lovers!

Offline cylab

JGO Ninja


Medals: 52



« Reply #77 - Posted 2009-07-09 06:28:25 »

LOL

Mathias - I Know What [you] Did Last Summer!
Offline Spasi
« Reply #78 - Posted 2009-07-09 10:49:37 »

Not exactly what Cas is looking for, but you may want to check out Jetbrains MPS (Meta Programming System) and mpssql.
Online princec

JGO Kernel


Medals: 409
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #79 - Posted 2009-07-09 11:33:46 »

'fraid it's just fun. I'll be happy with structs. I'm otherwise too busy writing games and earning no money.

Cas Smiley

Online Roquen
« Reply #80 - Posted 2009-07-09 12:15:08 »

WRT: Lisp - Its real power comes from being a metacircular language (like smalltalk, javascript, lua et al.) and you eval expressions (trees) not sequences.  Comparing two language so far apart in paradigm doesn't really make sense.  Things easy in one are hard in the other and vice-versa.  Attempts to push too many paradigms into a single language (have to date been) failures.
Offline ewjordan

Junior Duke





« Reply #81 - Posted 2009-07-09 19:50:42 »

Not exactly what Cas is looking for, but you may want to check out Jetbrains MPS (Meta Programming System) and mpssql.
The Jetbrains MPS thing looks very cool.  It seems to do a good job at incorporating (unsurprisingly, coming from Jetbrains - they seem to do really good work as a rule) the idea that any DSL should almost be forced to give the IDE enough information to allow its effective use, something that most languages and IDEs have sadly ignored.

It's too bad that this is so tightly tied to IntelliJ, as a concept (language-oriented programming) I'd love to see it spread much further, but that's unlikely if there's only one IDE that has any support for it!
Offline lithos
« Reply #82 - Posted 2009-07-11 19:43:16 »

Hmmm on second thought this really doesn't sound too bad.   I mean if you look at how verbose properly using all the collection classes are and can be for some simpler effects.

Granted you're also going to want to find a way to drastically limit new keywords.   I mean you would be talking about 30 some new keywords.   
________

I would recomend adding a new feature to the for each loop, a conditional.

for(PowerUps powerlist : activePowerUps : powerList.isActive)
   validPowerUp.add(activePowerUps);

Then again that isn't the best solution.

There are no such things as bugs...  Only happy accidents.
Offline zingbat

Senior Duke




Java games rock!


« Reply #83 - Posted 2009-07-12 12:56:23 »

WRT: Lisp - Its real power comes from being a metacircular language (like smalltalk, javascript, lua et al.) and you eval expressions (trees) not sequences.  Comparing two language so far apart in paradigm doesn't really make sense.  Things easy in one are hard in the other and vice-versa.  Attempts to push too many paradigms into a single language (have to date been) failures.

Thats not the real problem here. LISP and it's cousins are used in applications that would be impossible or very hard to work with Java or C++. To be used with Java games we would need a very efficient LISP to bytecode compiler. The simple way the Java VM handles call frames makes it difficult to do an efficient LISP compiler.

The Java language isn't very bad. What pisses me mostly is the mess of mixing primitives with real objects and the half-assed implementation of generics without real-time type checking RTT. The compiler should be smart enough to know when to use primitives internally and use RTT automatically. This is why we use an high level language, so that we don't need to bother with small optimizations.
Offline ewjordan

Junior Duke





« Reply #84 - Posted 2009-07-14 13:47:28 »

This old essay/rant from Steve Yegge expresses far more eloquently the gist of I've been trying to get at in this thread, even if it's not directly related to inline SQL syntax: http://steve.yegge.googlepages.com/next-big-thing

Don't be too quick to write off Yegge as just another Java-hater that wishes the whole world coded Lisp - Yegge wrote and maintained a large Java roguelike (Wyvern - http://www.cabochon.com/) as a hobby for quite some time, which apparently grew upwards of half a million lines of Java code, which I'd imagine is a more substantial game codebase than most people here have ever encountered, and he must be a pretty good Java coder, because he's been at Google a while now.

Not that an appeal to authority means much, but it might at least make you (everyone) re-think whether you're really content with the language as it is, or if you've perhaps grown too comfortable with its flaws and limitations to consider how much easier it could make your life with some small but powerful tweaks here and there...
Online princec

JGO Kernel


Medals: 409
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #85 - Posted 2009-07-14 15:14:03 »

That's a lovely rant, and absolutely spot on until he goes on about Ruby, which I really don't like at all Smiley

Cas Smiley

Offline swpalmer

JGO Coder


Exp: 12 years


Where's the Kaboom?


« Reply #86 - Posted 2009-07-15 01:30:07 »

There's some nice stuff in there, but also a lot of ignorant crap.. Like this (referring to generics), "...It may be more 'statically' type-safe, whatever that means, but my program does actually have to run someday, and then, when it really matters, it doesn't help me at all."

Bullshit it doesn't help you at all.  He apparently doesn't even know what he's talking about, but feels he can criticize it anyway.

Look at it this way:  For many programs, if static type checks were perfect, runtime type checks would be useless because you could prove that they are impossible before ever running the code.

Generics are complicated - I don't understand the wildcards... but I use the bits I do understand all the time, and it make my code clearer and coding less error-prone.


Anyway.. I'm all for evolving the language.. but I would like it to happen in ways that seem to fit naturally... the problem I guess is that I'm already biased as to what  seems natural... Undecided
I think JavaFX has done some neat things.  If you could write mixed Java and JavaFX in the same source file and deal with the whole array thing then you would have something.

Offline Mr_Light

Senior Duke


Medals: 1


shiny.


« Reply #87 - Posted 2009-07-15 02:55:56 »

other suggestions that he makes totally break some fundamental goals of java and the list goes on.

but its a rant so it's quite forgiveable that some stuff hasn't been tough through.. Where there is smoke there's usually fire though.

It's harder to read code than to write it. - it's even harder to write readable code.

The gospel of brother Riven: "The guarantee that all bugs are in *your* code is worth gold." Amen brother a-m-e-n.
Online princec

JGO Kernel


Medals: 409
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #88 - Posted 2009-07-15 10:29:04 »

Hm I've got a phone interview with Google in a few days and Yegge is listed as some pre-interview reading. Have a look at this rant by him about phone-screening programming candidates for Google. Now, I've been around for a while, programming for just under 30 years, and commercially for 15. I've made quite a few people very rich (even myself, relatively speaking, for a while). I've got a games production company with several award winning if not necessarily successful titles, and I'm a shareholder in the market leader in Local Government Performance Management, a company whose flagship product I architected. People generally come to me for advice rather than the other way around. And yet I'd flunk his phone screen at the drop of a hat. I have no idea what the O-complexity is of any of the basic datastructures. I've never needed to know but if I did need to know I'd find out on the spot.

So though I agree with some of what he says about the Java language (he was, of course, totally wrong about the Next Big Thing Smiley), I also suspect that he is one of those slightly-above-normal-cleverness programmers who likes to lord it over anyone not as brilliant as himself, a trait far too common in engineers which effectively amounts to an intellectual's revenge for being bullied in the playground for being physically meek. The arrogance in the phone interview article shines through the generics rant like the words in a stick of Blackpool rock.

Maybe I'm reading a bit too much into it Smiley

Knowing my luck he'll follow the incoming web links to his rant and be the guy who interviews me on Monday. I will dazzle him with my ignorance and incompetence.

Cas Smiley

Offline ewjordan

Junior Duke





« Reply #89 - Posted 2009-07-15 13:44:22 »

And yet I'd flunk his phone screen at the drop of a hat. I have no idea what the O-complexity is of any of the basic datastructures. I've never needed to know but if I did need to know I'd find out on the spot.
I doubt that's true - you may not have been forced to actually prove your intuitions are right, but I all but guarantee you know enough about it (probably more than you even realize) to figure out time estimates for most of the examples he gave there, even if you can't rattle them off the top of your head.

I think the point with these types of questions is to a) make sure that you have some sense what the data structures are (don't forget trees!) and why you'd use them, and b) see if you understand how the structures are implemented, and why.  Not to see if you've memorized the stuff.

The only non-obvious trick to big-O estimates: if divide and conquer is involved, that probably leads to a log N factor somewhere.  Binary search?  O(log N), because you cut the search space in half each iteration.  Binary search over a linked list?  Well, a random access lookup takes O(N) time (gotta walk the list!), and the "binary search" bit takes O(log N) lookups, -> O(N * log N) operations total (but nobody does that since a linear search (O(N)) is faster on a linked list).  Balanced tree lookup?  A binary tree cuts out half the possibilities each time you choose a branch, which means good old O(log N).  Worst case (unbalanced) tree lookup?  A heavily unbalanced tree is just a linked list, so O(N).  Etc and so on.

In any case, it's probably a decent idea to brush up on some of this stuff before the phone screen - it would probably take an hour or two max to go through all the basic structures and see what the performance characteristics are, just coming up with the barest of "stories" to tell yourself as to why.  And it might save you a missed question or two.

Brush up on your trees, if there's one data structure that's going to be important at Google and fairly underexercised in most Java code, it's the tree!

Quote
Knowing my luck he'll follow the incoming web links to his rant and be the guy who interviews me on Monday. I will dazzle him with my ignorance and incompetence.
BTW, in other stuff I've read by Yegge on the interview process he's mentioned several times that what he really looks for is a complete fail in each of these areas, not just a bit of thinking, unfamiliarity, or struggling.  Can't find the specific essay where he says that at the moment, but he's got some other advice at his newer blog, see http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html that might be worth looking through as well.  Anyone doing screening at Google has almost certainly read his stuff and taken it to heart, so be prepared...

Good luck with the interview, I hope it goes well!  I'm sure you'll do just fine.

On the topic of the Next Big Language, Yegge appears to have shifted, some of his later blog entries indicate that he's putting his money on Javascript lately, not Ruby.  Which in some ways I'm lot happier about (years ago I used to do some of my lighter analysis in Javascript for convenience, and as long as you focus on the language and not the browser integration, it's surprisingly clean and easy to get pretty sophisticated stuff done in).
Pages: 1 2 [3] 4 5
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

DarkCart (14 views)
2014-10-31 21:44:48

DarkCart (18 views)
2014-10-31 21:43:57

TehJavaDev (40 views)
2014-10-27 03:28:38

TehJavaDev (30 views)
2014-10-27 03:27:51

DarkCart (44 views)
2014-10-26 19:37:11

Luminem (26 views)
2014-10-26 10:17:50

Luminem (30 views)
2014-10-26 10:14:04

theagentd (36 views)
2014-10-25 15:46:29

Longarmx (64 views)
2014-10-17 03:59:02

Norakomi (62 views)
2014-10-16 15:22:06
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!