|
Scaevolus posted:http://luke.breuer.com/time/item/MeditechCodeProcessor/318.aspx What's wrong with it? There's no way I'm going to make the mental effort to try to parse out what that regex does.
|
# ? Mar 29, 2008 22:53 |
|
|
# ? May 16, 2024 17:18 |
|
such a nice boy posted:What's wrong with it? There's no way I'm going to make the mental effort to try to parse out what that regex does.
|
# ? Mar 29, 2008 23:16 |
|
nebby posted:For example, if you are writing a method called countOfApplesInBasket() that returns a count of apples, if I see the line "result += 1;" I have to look at context to determine wtf result is. The best bit is I don't even have to think up new jokes, you're still saying the same things. Mainly because a lot of people will waste a lot of time arguing with you, here is what I see as the condensed nebby experience: Fake Nebby posted:Naming schemes are hard to get right. Thus we should use a series of cryptonyms to identify each indivudal type. The best thing to do is mmenonics for each data structure used. On a more serious note — I did give up trying to debate the merits of nebby's ideas given his inability to argue them consistently (Apps vs System being the most obvious example). (Edit: Another is that although you realise that inconsitent naming schemes are bad, you are yet to realise that a consistent naming scheme can be bad in a completely different way. You point out the trivial flaws of others (NumChild/NumChildren), hammer home ambiguitiy I've rarely seen and focus on statements at a macro level. You then take these as support for your scheme, rather than being innacurate criticisms of straw men) Really his system of naming speaks more about his command of the english language (and his comfort in using it) than it does about his ability to program. It boils down to "Hungarian Notation will free you from the Tyranny of understaning things in context". nebby posted:You're forgetting that I explicitly said in all my posts I intentionally post on subjects that are controversial in order to spice things up. A troll by any other name would smell as foul. tef fucked around with this message at 06:05 on Mar 30, 2008 |
# ? Mar 30, 2008 05:51 |
|
pokeyman posted:Found this in the PHP manual. It's like the guy knew he wanted some kind of conditional execution, but forgot about the "if" keyword. Looks more like a Lisper missing cond. code:
|
# ? Mar 30, 2008 13:09 |
|
tef posted:Now, what we are actually storing is a hash which uses student names as keys (strings) pointing to percentages (ints). This leads to the obvious naming scheme "Score" is a lovely name for pretty much anything because every time I've written code involving scores there is more than one type of score. Passing these around becomes cumbersome and confusing to follow. For example, "public score" and "private score" and "human friendly score" and "score before we've added in bonus points" and so on. Sure I can look at 'context', but its funny because this exact case came up in the past for me, and deciphering what particular type of score was being calculated required going through lots of other methods for enough context to be sure. The places where this wasn't necessary was when the name was consistent like "publicScoreBeforeBonusPoints", which is precise and helped me a lot when it was used consistently, but is a mouthful. For all but the simplest projects, this dynamic happens with many different domain objects/quantities. Now, the name mpNameSpct does encode implementation in part of the name, namely, "mp", which says it is a map (like a Hashtable or Dictionary.) You'd say this is bad, though. But look closely, because you've actually encoded that facet of implementation in your name, albeit less precisely, by making it plural. "StudentScores". By making it plural you've indicated it is some data structure that contains things. Not much beyond that. I'd argue that including the 'implementation' detail that it's a map and not a indexable list or something that's iterable at the cost of two characters at the beginning instead of one or two at the end is worth it, relevant, and not 'redundant'. The fact that English doesn't have a worthwhile suffix for describing "map vs. list" just shows how poorly English maps onto programming language variables. Now, Java interfaces get a nice mapping from English, the suffix "-able", but 'map vs. list' loses out. You again forgot the main point of my post re: System vs Apps is that you fall back on encoding native type information when there is nothing else worthwhile to encode. For example, almost all booleans have an "f" prefix, because they are generally just used as a flag to check something. They're a goddamn boolean. Just because I use "f" for my boolean flag prefix all the time doesn't mean I am using "Systems Hungarian" because the rest of my code uses tags that encode far more than implementation (and much more than "Score".) This is less because "f" is useful and more because if we didn't put *some* tag at the beginning our names would appear inconsistent. And again, the argument about context is missing the point. I have never said context isn't important, somehow you think context magically disappears if I am using Hungarian naming. Context is still just as useful and key to understanding an algorithm. But the goal is to optimize naming so you minimize the need for context. If this wasn't a worthwhile goal than we would name everything by typing random keys on the keyboard instead of trying to come up with something consistent and that makes sense. Just because my definition of "makes sense" grates against your bias towards English doesn't mean it's inferior on its own. You also claim that the information encoded is "redundant". If you say "Score" and I say "Spct" which designates a specific domain specific type of score, I don't think it's redundant, but necessary, since there is no other place to directly encode that information other than in the amorphous context or comments of the method it is being used in. I'm not a troll -- the points are subtle and your own self reflection of what you think that I am trying to get across reveals how they've flown over your head. I've read good arguments against this approach before, and yours is not one of them. Edit: FYI code:
nebby fucked around with this message at 18:24 on Mar 30, 2008 |
# ? Mar 30, 2008 18:02 |
|
nebby, what if the programmers with whom you work just suck at giving proper context? Also, you repeatedly forget to note that this is much more important for dynamic languages, as things are less clear there. Have you looked into coding for the military, using ADA? It gets fairly close to your approach, but has compiler-enforced type safety. You can only get speed if you divide distance by time (or integrate acceleration by time, etc.). Maybe I missed it, but I do not remember you ever explaining why your desire for Hungarian whatever is in the distinct minority of programmers. Does your approach really allow you to code more quickly and more accurately than other people, on average? (Take into account learning curve here!) To what extent are the problems you encounter, unique to your problem domain, or at least a very, very small fraction of programming? The more I think about this, the more you must address the above if you want to stop digging/get out of the hole you've dug. Right now, you're some weird freak in most of our minds. I'm cutting you more slack than most, because I have very little respect for experience and track record, if I cannot understand the why behind the experience and track record. However, most people do, and you, my friend, have demonstrated zero.
|
# ? Mar 30, 2008 18:58 |
|
quote:Mode #cobol +b *!*@*.hu
|
# ? Mar 30, 2008 19:44 |
|
Victor posted:nebby, what if the programmers with whom you work just suck at giving proper context? Also, you repeatedly forget to note that this is much more important for dynamic languages, as things are less clear there. Have you looked into coding for the military, using ADA? It gets fairly close to your approach, but has compiler-enforced type safety. You can only get speed if you divide distance by time (or integrate acceleration by time, etc.). quote:nebby, what if the programmers with whom you work just suck at giving proper context? However, I've also spent a lot of time digging through rails and other open source gems recently, and the problems there are patently obvious. Here's a tiny example. Yesterday I had to drill through some of Rails's template processing code. They pass variables with the name "template" around all over the place. My intuition totally fails me here -- this could contain the filename of the template, the name of the template, the HTML contents of the template, a parsed AST of the template, or a object of type Template (or something else.) The only way I can know is if I dig through all the dynamic crazy metaprogramming stuff, through methods that I have to figure out not based upon static binding but dynamic binding or method_missing calls, or get to a breakpoint in a debugger, or dig through unit tests. Wouldn't it be nicer if they just had a consistent understanding that "template" should always be a variable pointing to a Template object, and "htmlTemplate" and "astTemplate" and "fpthTemplate" and so on for the others? Of course, sometimes they'll say "template_file_name" or "template_contents" but its by no means a hard and fast rule, and it's generally not their fault because their approach in general does not encourage precision and typing those names out is just annoying. Note that this problem still happens in static programming languages, replace "template" with "score" for an int variable and consider there may be many different types of scores, and the same problem comes through. quote:Have you looked into coding for the military, using ADA? It gets fairly close to your approach, but has compiler-enforced type safety. quote:Maybe I missed it, but I do not remember you ever explaining why your desire for Hungarian whatever is in the distinct minority of programmers. I think this is just another example of the classic case of intuitivity vs. efficiency. Most people, when they first start using something, do not even think about efficiency. If the system is intuitive, they pick it up quickly and stick to it, no matter how inefficient it is to use once they are experts. If you look at CAD systems they are notoriously unintuitive, and require years to get good at. But their user interfaces are incredibly efficient. This is an example where the tradeoff was recognized and a sacrifice was made in intuitivity for efficiency. At first glance, AutoCAD is totally impenetrable and if you just put a layman in front of it he will reject it for something that is more intuitive and matches what he is used to. But the pro can't live without it. I see the push towards English naming as a consequence of this natural human desire for intuitivity. When you see a new piece of code, it is much easier for you to digest the overall algorithm if the names appear intuitive. However, if this is a body of code you need to become intimitely familiar with, in my experience, Hungarianized code is much easier to become efficient at working with, since there is less ambiguitiy once you penetrate the style of naming. Even once I became used to the overall concept of Hungarian, a new body of code with unrecognizable tags would seem menacing at first. But, provided the programmers involved were disciplined, after the initial pain of understanding what the hell was going on was passed (intuitivity was about zero) then I became a total domain expert for that body of code. Additionally, Hungairian makes it painfully obvious what you do and don't understand. This was because you are not tricked into thinking you understand something because of it 'reading nicely'. You are forced to actually step through code mentally and truly grok what was happening. If you see an unrecognized tag, it signals "oh poo poo this is a big concept I haven't seen before", vs if you see a class called "Email" you think "eh, whatever, its some kind of email". These unfounded assumptions are dangerous and cause lots of bugs. It's all to easy to look at code examples in rails and ruby and miss the subtlety, simply because its easy to read. Second, it has a bad reputation because of Systems Hungarian's prevalence in Win32 programming. Systems Hungarian is a total poison and it would be hard to think of a naming style that provides less value other than random characters. quote:Does your approach really allow you to code more quickly and more accurately than other people, on average? (Take into account learning curve here!) To what extent are the problems you encounter, unique to your problem domain, or at least a very, very small fraction of programming? First, for writing code. You no longer "think of a name" for a variable. I can't stress this enough. I know from almost everyones perspective this seems trivial, but the amount of "numApples" vs "countOfApples" vs "appleCount" vs "applesInBasket" and so on I think really contributes to a lot of unnecessary noise both in reading and writing code. When working on a team, each programmer often has their own unique style of naming. I'm sure you've all seen this. Some guy always has "retval" for the return value. Some guy always says "listOfApples" and the next guy says "apples" and the next guy says "listToReturn". Having everyone automatically agree that a list of apples is going to be "rgApple" makes it so your brain barely even registers the word, you just read it as you read this sentence and don't have to look at context to understand what I mean by the words I use. I firmly think that the majority of creativity in programming should be spent on designing system architecture, data schema optimization, user interface design and other tasks that directly impact the success or failure of a given project. In my own personal experience, in projects where we were not using Hungarian, a disproportionate amount of creative energy was spent on coming up with names that best mapped the purpose of a type onto an English real-world equivalent. All this effort, pining over if we should call something the "EmailDispatch" or the "EmailSender", and so on. Again, it seems trivial, but totally removing this creative burden once we decided a name was really not that important was very liberating. On small projects, this is no big deal. But when you start building huge class libraries you end up getting lots of "English collisions" and end up twisting the language in directions it was never meant to go. A simple reporting framework explodes into having things called ExtendedSearchSiteReportsEmailReport (a real example.) Edit: Oh, and before someone says "namespaces" here, let me remind you that namespaces are a compiler hack for binding names to classes and not meant to reduce ambiguity in the name itself. quote:To what extent are the problems you encounter, unique to your problem domain, or at least a very, very small fraction of programming? That said, I draw a lot of my conclusions not based upon the projects I've been using Hungarian with, but the contrast against the projects I've worked on without it over the years. I remember distinctly arguing over what we should call things and tracing through code trying to find enough context to understand what exactly was being stored in a quantity. Knowing the type of a variable through IntelliSense is often not enough to get at the crux of its role in an algorithm, so the applicability of this to static languages is still very useful. (Though I'll grant it's been even more profound for me in Ruby.) nebby fucked around with this message at 20:32 on Mar 30, 2008 |
# ? Mar 30, 2008 20:01 |
|
nebby posted:Yeah, I mean, I catch myself using "i" when I know better. The problem is, I see it as a bad habit when most see it as acceptable. When you are writing a loop, you can quickly get into trouble if you have nested loops and have i, j, or even k being used. Additionally, and more importantly, using "i" is ignoring an opportunity to introduce a good name into the code. You're looping over it for a reason, so you should usually opt to provide hints as to why you're doing so in the name. If you are looping over a list of apples that need to be put into another bucket, instead of "i", you could use "iAppleForBucket" and not worry about confusing it with another loop variable and potentially remove a comment saying "// We loop over the apples for the bucket" ! This is why I think you are missing the point of Intentional Programming. As I understood it from Simonyi's explanation, the mere notion that you loop over apples in a bucket has one more parameter than is necessary: you are creating an index for something that inherently has no necessary index. There is no need to create a key, because all the key does is provide base address plus offset. In other words, all it does is provide information about what is in a particular memory address. Furthermore, this is a general idea in Computer Science that was made obvious by Ted Codd: set-based programming is superior to Bachman-style navigational programming. The for loop and the nested loop patterns are artifacts from navigational programming. Some people were really stunned when Codd showed that math could be used to provide succinct code. nebby posted:I don't see how I can be misrepresenting them when the lead dev at Simonyi's company (who is a real wizard, IMHO) told me my blog put forward the best argument he had ever read for Hungarian (assumingly apart from those written by Charles.) You are using an appeal to authority to back up your point. Yet, you aren't telling me why that person thought your argument was worth hearing. I don't care if they liked it or hated it. I care that they understood it and why they would recommend I read it. I have read ISC devs' blog comments on some of Simonyi's staff on his blog, and they were always impossible to understand. It was all blah, blah, blah, THEN I HAD AN EPIPHANY, blah, blah, blah. This is how you come across, as well. By contrast, Simonyi is the only person at that company who really wows me with their comprehension about this idea of "Intentional Programming".
|
# ? Mar 30, 2008 20:25 |
|
nebby posted:
This interface doesn't make any sense. Why would you add a basket to a basket? The most important parameter to explicitly model in this problem is that you clearly care about ownership and not membership. These baskets are not the same thing as mathematical sets, so you cannot therefore model them as sets: you cannot use membership as a status. One basket must clearly own all of the apples in its basket. Forget the fact you have the "c" in there. Your model is dumb. You have bigger problems than whether to use Hungarian notation or not!
|
# ? Mar 30, 2008 20:33 |
|
Z-Bo posted:This is why I think you are missing the point of Intentional Programming. You're right, index variables are unnecessary mathematically, but in some languages (which I deemed "sane", a misnomer perhaps) we are forced to use them. When we are forced to use them, the question of naming comes into play. When the question of naming comes into play, we are forced into coming up with one that usually matches /^[A-Z][0-9A-Z]*/i that's less than some maximum length. It's this set of constraints that Hungarian is designed (again, forced) to work within. Think of it as an incredibly 'projected' view of the ideal solution to a specific subproblem onto the lovely tools and languages we have forced upon us today. quote:You are using an appeal to authority to back up your point. As far as the specifics, I mean, basically it was like "good job on that post I think you hit the points on Hungarian better than anyone has written before" or something like that? If you have any other specific things you think I am not making sense about then you have to admit I've been more than willing to try and refute them, don't go painting me like I am some question dodging illogical person.
|
# ? Mar 30, 2008 20:48 |
|
nebby's example looks like it's written in Python and there, the first argument to a method is always the instance itself. So if you havecode:
|
# ? Mar 30, 2008 20:52 |
|
Z-Bo posted:This interface doesn't make any sense. Why would you add a basket to a basket? Again, your bias towards English is making you assume something about what I mean when I say "addToBasket(basket)". In his example, he (bizarrely) passed in a reference to a basket to add one to the count. I'm assuming in this bizzaro example this fake language we are programming in those are static methods, otherwise passing in a basket would make no sense. In Hungarian, its "<returnType><verb><parameters>" so I am not returning anything, I am addingTo, and I am passing it a basket. Implicit is the fact that the verb "addTo" will increase the count of apples ("cApple") on the specified basket. If I was going to pass an apple into the basket to add to it, it would be "addApple(apple)". Oh poo poo. I just typed this reply up, and realized the reason we are both confused in the first place is because his naming sucked in the original example. In his 'unenlightened programmer' he passed in a variable called "s", which I guess he meant to be an Apple not a Basket. But then in his 'enlightened' example, he passed in something called "applebasketself" which I assumed was the basket he wanted to increment the count of apples on. He actually confused himself by his own lovely naming, unless I am missing something. Double oh poo poo. Ok, so that was a reference that is supposed to be self, and we're in Python. Now I get it. I think instead of him confusing himself, he confused Z-Bo, who thought we were passing in Apples instead of it being the self variable. With this in mind, I would have named my methods "add" and "take" since we would not include the Basket in the name since it's an implicit parameter (self). I think the important thing to take away from this is that all this confusion stems from bad and ambiguous names. If he called his first parameter "self", it would have been fine since we all understand what that means. Also, consider these three method names: "add", "addApple", "addToBasket". With Hungarian, I can tell you exactly what the inputs and outputs of these are, and while I can't tell you *exactly* what they do, I will be much less confused than if there were no rules for me to think of when I saw these methods. nebby fucked around with this message at 21:19 on Mar 30, 2008 |
# ? Mar 30, 2008 20:56 |
|
Ok, my g/f just came over and said she saw "the penis man" (my avatar) and so that means I'm slacking off and posting and I should stop. She's right, and I am, so back to your regularly scheduled programming (Z-Bo you get the last word )
|
# ? Mar 30, 2008 21:10 |
|
There's nothing wrong with Hungarian Notation used judiciously, but there's a lot wrong with using it everywhere. It suggests something going badly wrong with your code. Nebby, your examples sound like the code your working on makes poor use of scoping. The problem you think Hungarian Notation solves, I would say, is much better solved by making sure your names stay within about half a page of each other. That is, don't let your functions get so big that the entire context of the name is visible on the screen. If this is impossible, class members for example, the names should be maximally descriptive. This seems to be the point where you struggle, 'apples' is almost always going to be a collection of 'apple' objects, we don't need to tack on 'lst', 'vec' etc to the beginning to tell us this (yes this is an oblique example of Hungarian Notation, however, it's also English). If all else fails you can just go look them up (C-r in my editor). If your class gains so many members it's impossible to keep track of them all in your head then you need to refactor your class, not rename the members. This is why Hungarian everywhere is a bad sign for code, it's the wrong solution to the problem of complexity.
|
# ? Mar 30, 2008 21:24 |
|
I think I've spent more time reading nebby posts about hungarian than I've spent, total over the 12 years I've been a programmer, being confused by variable names. Nebby, do you have any kind of studies that show this to be any kind of significant problem at all? Honestly, the entire argument reeks of brace-style, tabs-vs-spaces nonsense, except everyone seems to be taking it seriously, which baffles me.
|
# ? Mar 30, 2008 22:59 |
|
rotor posted:Nebby, do you have any kind of studies that show this to be any kind of significant problem at all? Honestly, the entire argument reeks of brace-style, tabs-vs-spaces nonsense, except everyone seems to be taking it seriously, which baffles me. I mean, think about it. Many people in this forum think I'm some crazy person, a troll, a kook, a crackpot, throw personal insults and so on because of a variable naming convention I promote when I write computer programs. It's ridiculous. I certainly don't think about anyone here in that way, regardless of whatever they might post in a thread!
|
# ? Mar 30, 2008 23:31 |
|
nebby posted:No, how could I? The whole thing has been largely ignored and discarded by the programming community, who would study it? I dunno. Given the number of grad students in the world, I find it hard to believe that there's been zero studies done. quote:Honestly, it's not a huge issue to me these days, I just am often amazed at the reaction I get when it comes up and the logical fallacies otherwise smart people start throwing out there (a) you are not communicating your ideas well enough, because all these otherwise smart people are just not getting it or (b) you are in fact crazy That's just honest feedback, man. Do with it what you will. quote:I mean, think about it. Many people in this forum think I'm some crazy person, a troll, a kook, a crackpot, throw personal insults and so on because of a variable naming convention I promote when I write computer programs.
|
# ? Mar 30, 2008 23:43 |
|
rotor posted:I think I've spent more time reading nebby posts about hungarian than I've spent, total over the 12 years I've been a programmer, being confused by variable names. I'm not sure what the gently caress he's talking about either, but I think tef nailed it with his fake quote. It almost seems like nebby agrees that Hungarian is confusing line noise, but that when you parse all that useless information it all magically clicks and you enter this zen buddha mode of coding and all the code suddenly makes sense. At least that's what I've gathered from his points.
|
# ? Mar 30, 2008 23:46 |
|
Well I think sheds should be painted blue.
|
# ? Mar 30, 2008 23:51 |
|
rotor posted:If you have a bunch of 'otherwise smart people' who routinely tell you you're crazy whenever you bring this up, you should probably take a step back and consider whether: quote:Well, it's a software forum. We kind of take software seriously here. I don't really care what you're like as a human being, but so far all your opinions on writing software I've seen are ... well, they're crazy. As for the personal insults, I dunno man, welcome to SA I guess. As for SA, yeah, well, I've been here forever so I know how it goes. It's still dumb though, but I guess programmers are known for crucifying each other over editor choices and such. nebby fucked around with this message at 23:54 on Mar 30, 2008 |
# ? Mar 30, 2008 23:52 |
|
biznatchio posted:Well I think sheds should be painted blue. You would you goddamn hippie.
|
# ? Mar 31, 2008 00:01 |
|
biznatchio posted:Well I think sheds should be painted blue. A blue shed will survive a nuclear holocaust in the event the power plant nukes itself. When someone looks at the blueprints for this facility 10,000 years from now after the radioactivity has decayed, people will look at it and recognize it is a blue shed.
|
# ? Mar 31, 2008 00:13 |
|
Z-Bo posted:A blue shed will survive a nuclear holocaust in the event the power plant nukes itself. When someone looks at the blueprints for this facility 10,000 years from now after the radioactivity has decayed, people will look at it and recognize it is a blue shed. not enough namedropping in this post.
|
# ? Mar 31, 2008 00:33 |
|
Dear nebby, victor, zbo: drat kids get out my thread If you really wish to beat this dead horse go and start a new thread so we can go back to making fun of crap code.
|
# ? Mar 31, 2008 10:13 |
|
Ultimate variable naming schemecode:
|
# ? Mar 31, 2008 15:13 |
|
Bonus posted:Ultimate variable naming scheme Similarly, back when C# first came out, I couldn't resist the urge to use full Unicode in my identifier names. code:
On the one hand, I think having the ability to use Unicode identifiers is awesome and long overdue. On the other hand, it would permit sweet revenge and job security for those outsourced overseas programmers to write all their code in Hindi or Urdu character sets
|
# ? Mar 31, 2008 15:32 |
|
I don't think we should stop at making programmers manage their own type systems in symbol names. I think they should have to code in assembly. Screw that: ones and zeros. Actually, what would happen if we made programmers code mechanically, maybe via some sort of punch card system that is about as reliable as the punch cards used in the Florida election? Surely, in that case, the bug count would go way down.
|
# ? Mar 31, 2008 16:22 |
|
Victor, you are thinking too advanced. The only way to program is to create an analytical machine in the form of a difference engine to do it for you! No need for messy punch cards, only pure determination and genius. Lots of genius. I'd love to see dynamic programming on one of these babies. Also, far less writing and punching than cards.
|
# ? Mar 31, 2008 16:26 |
|
If we're going into unicode territory how about something like ∀ x ∈ l : print x; perhaps?
|
# ? Mar 31, 2008 16:36 |
|
tef posted:If we're going into unicode territory how about something like ∀ x ∈ l : print x; perhaps? Wouldn't that make the existential operator the perfect mechanism to introduce unification and backtracking into a language? ps. #define ∀(col, op) for_each(col.begin(), col.end(), op)
|
# ? Mar 31, 2008 16:48 |
|
tef posted:If we're going into unicode territory how about something like ∀ x ∈ l : print x; perhaps? We're gonna need bigger keyboards.
|
# ? Mar 31, 2008 17:03 |
|
rotor posted:We're gonna need bigger keyboards. APL was ahead of its time! It was a language without a mainstream character set large enough to hold it... but now things are different! It's ripe to make a comeback, I say!
|
# ? Mar 31, 2008 17:10 |
|
tef posted:If we're going into unicode territory how about something like ∀ x ∈ l : print x; perhaps?
|
# ? Mar 31, 2008 17:28 |
|
rotor posted:We're gonna need bigger keyboards.
|
# ? Mar 31, 2008 17:36 |
|
rotor posted:We're gonna need bigger keyboards. This do?
|
# ? Mar 31, 2008 17:55 |
|
tef posted:This do? look at the hosed-up brace and arrow key placement, I can't use that piece of poo poo. rotor fucked around with this message at 18:30 on Mar 31, 2008 |
# ? Mar 31, 2008 18:15 |
|
tef posted:This do? Is there a das keyboard version?
|
# ? Mar 31, 2008 18:28 |
|
yaoi prophet posted:Is there a das keyboard version?
|
# ? Mar 31, 2008 18:30 |
|
|
# ? May 16, 2024 17:18 |
|
These things, as Perl programmer, piss me off:code:
code:
|
# ? Mar 31, 2008 18:44 |