|
|||||||
This is a discussion on "Which is preferred?" in the Top Mud Sites MUD Coding forum : Originally Posted by (Yui Unifex @ foo) What? Given that almost all projects spend most of their lifetime in the maintenance stage, I obviously wouldn't know how to take advantage of Perl's features if I couldn't read or modify it. Originally Posted by (angelbob @ foo) As you say, most projects spend the vast majority of their time and effort in the maintenance stages. Features that are hard to read are a fine example of wasting effort -- how many times do you read code compared to how often you write it? With that said: sure, whatever. Originally Posted by (... |
|
You are currently viewing our boards as a guest which gives you limited access to view most discussions and access our other features. By joining our free community you will have access to post topics, communicate privately with other members (PM), respond to polls, upload content and access many other special features. Registration is fast, simple and absolutely free so please, join our MUD community today! If you have any problems with the registration process or your account login, please contact us. If you are a registered member of the old TMS forums, please click here
|
![]() |
|
|
LinkBack | Thread Tools |
|
|
#31 | ||||||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
||||||||||||||
|
|
|
|
|
#32 | |
|
Senior Member
|
Almost forgot this gem:
Quote:
|
|
|
|
|
|
|
#33 | ||
|
New Member
Join Date: Feb 2003
Location: California, US
Posts: 5
![]() |
Quote:
|
||
|
|
|
|
|
#34 | |||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
"We made sure that murder was optional, so we figure it won't cause any problems. Our laws aren't responsible for your neighbor's maliciousness. Move to a better neighborhood." Quote:
Quote:
Quote:
To make this explicit: you've taken my position, extended it to its most ridiculous extreme, and thrown it back at me as though I'd said it. "All those liberals should just move to Iraq". |
|||||||||
|
|
|
|
|
#35 | ||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
Besides, they've made it difficult, and they've made it easy to recognize when somebody's doing that. C and C++ don't go so far as that, alas. C-but-with-references would make a quite nice little language. LPC is a bit like that, which is one reason I'm using it. And DGD lives up to my silly standards surprisingly nicely since I don't use any nonstandard driver extensions. And from Lindahl (hello! Quote:
|
||
|
|
|
|
|
#36 | |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
These combinations obviously give a combined language with more expressivity than either one individually. French and English are both legendary for their ability to express uncommon and subtle shades of meaning, when used by an excellent speaker. So English-plus-Spanish must beat the #### out of Spanish, and French-plus-German must beat the #### out of German. There are academic treatises that occasionally intersperse specific phrases in other languages ("Gestalt" being used as a psychiatric term, for instance). They almost universally go to the trouble of defining those terms, or make them entirely optional to understanding the text rather than using them fully (as with books containing random quotes in Latin at the start of chapters). That seems odd given your contention that more features always makes a language better, and given the obviously greater expressivity of those combined languages. Where are all the books written in French-plus-German? |
|
|
|
|
|
|
#37 | |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
If I thought English was the right language to use, I wouldn't recommend English-plus-Swahili, even if everybody involved spoke both English and Swahili. Why not? Because some day, God forbid, somebody new might show up on the project, and making sure they're fluent in English-plus-Swahili is a lot harder than making sure they're fluent in English. As a culture Imperialist (yup, guilty as charged) I believe that English © is better than Swahili (single-dispatch OO done on top of pointers) so I feel that an unholy hybrid of the languages gains very little on top of English, and causes more problems than it solves. I'm not saying people shouldn't speak whatever unholy hybrid they like in the privacy of their own homes. But if somebody asks me "C/English or a hybrid?" I'll immediately answer "C/English" without a qualm and without batting an eyebrow. I *do* like OO for some things. It's just that what I think of as OO is very poorly represented by C++. LPC isn't all that much better but it cleans up most of the worst nastiness. Java does too, though less so. Dylan's awfully nice. I'll never write a MUD in it, though, since there'd never be a second developer on the project. C++? Nope. Too many of its "benefits" over C are things that I would never use personally, and that I've usually seen used badly by other people. Since I would never want to debug another developer's C++ code submissions, I say "C" not "C++". Is the context clearer now? |
|
|
|
|
|
|
#38 | ||||||||||||||
|
Senior Member
|
Quote:
It is plainly obvious why this is not a bug, however: Class A and class B simply can not share the same memory address. When assigning a pointer to one of the parents here, you have to grab the part of C where B starts. So you should get an address like sizeof(overlapping parent)+sizeof(object overhead)+address. So what exactly is the problem here? The only way to fix this would be to make A and B both share the same address, and that's impossible. Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
I don't think you understood me here. Restricting people from working in both ceramics and glass is radically different than allowing people to choose a specialty of their own accord. In one case, people are forced into what they do. In the other, they still have the choice to make some sort of ceramic-glass hybrid (It'll take the world by storm!) if they felt like it. As you can see, they are plainly not the same thing. Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Furthermore, unfettered access to a class' memory is very useful for those languages which lack functional properties like closures. It is useful for serialization and optimizations that scrunch classes together to avoid overhead, like a memory pool. There are thousands of C libraries which C++ was designed to interoperate with, that require a void or char pointer and a size, and then provide an operation on that memory. C++ wouldn't be operating as designed if it did not provide this functionality, and provide it easily. Quote:
References come with their own problems. They aren't re-assignable, so you are forced to encapsulate changes to them which causes problems with iteration constructs. They're always "valid", so you can't have a find operation return NULL. And for languages that pass them by value (like Java and Ruby), you have to implement silly workarounds (like encapsulating them in another object) to assign to the base value. |
||||||||||||||
|
|
|
|
|
#39 | |
|
Senior Member
|
Quote:
|
|
|
|
|
|
|
#40 | |
|
Senior Member
|
Quote:
Our principles are fundamentally different. I believe in free choice of language features, even if it's possible that someone may not choose wisely. I say this because ultimately your language is more powerful. I approach this from the standpoint of an individual: I don't want anybody restricting what I can do with a language, and if I want write a large project in it, the responsibility for enforcement of my practices falls on my own shoulders. You believe that we should specifically tailor languages so that the general quality of code that the lowest-common-denominator (I think?) writes will be as high as possible. This means either restricting common pitfalls or making it impossible to be caught in them. I agree that C++ does a rather poor job as the latter, but I think this is mainly because it was designed to be backwards-compatible with C, As you can see, excepting where certain pitfalls be made harder to fall into, these principles do not overlap. In fact, they are mutually exclusive if there are any features that the second school wishes to restrict. |
|
|
|
|
|
|
#41 | |||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
Quote:
Quote:
So yes, you *do* know where I came up with that. We've been having this same argument in minor variations for awhile now. But you told me what I needed to know to lose interest. More on that in a second. Quote:
Quote:
But yes, if you'd stated some assumptions and the principle you were extending, it would be similar. Done crudely, as you did there, it's just mockery. You're welcome to do it, but calling it logic is pretty silly. Quote:
Quote:
And references aren't always valid, at least in LPC, CommonLISP, Dylan, Perl and (I think) Java, all of which have a NULL value or the equivalent. Quote:
Quote:
Quote:
Quote:
Okay. Unless we raise a new topic (or you'd like some very specific question addressed), I think I'm done with this thread. |
|||||||||||
|
|
|
|
|
#42 | ||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
||||||||||
|
|
|
|
|
#43 | ||||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
I was only able to do it because I've played with ugly bitwise manipulation of several other C++ constructs. Knowing the behavior is required to debug the problem, and it's not behavior that I've ever seen documented (with the exception of email/posts written by me). Quote:
Quote:
Quote:
Quote:
But yes, I feel that a language that is fully known is easier to debug than a language that you only partially know. You're welcome to say Google is a full reference to everything, and I'll reply that some things are very hard to find. Again, take my typecasting and multiple inheritance problem above. What would you do a search for to figure out what's wrong with that? Would you know to search for that without already knowing what the problem is? Quote:
Quote:
Quote:
Presumably the logic you used goes, "bad features are bad, C++ contains bad features, C contains bad features, VB contains fewer bad features, so VB must be where his argument goes". But then, that sounds pretty illogical, at the very least the part that says "VB contains fewer bad features" given that we haven't talked about VB. So you apparently got there some other way. If you'd stated how, or even given a serious hint, I could have taken that as a logical utterance. You didn't, so you were simply using a challenging tone and using a statement you were pretty sure I'd disagree with, but attributing it to me. Again, that's fine, but calling it "logic" is still a stretch. I have, incidentally, taken classes in logic. That's one reason I'm calling you on this. If I hadn't, I wouldn't bother calling you on it. Nor would I bother taking classes in logic if I hadn't already since your examples make 'em look pretty useless :-) Quote:
So yes, they look a lot like pointers, and yet they're much safer to use. Quote:
And I actually make a point of using a dialect of LPC that can't do C callout. The fact that it doesn't means that it can make several other guarantees in the language, which lets it do cute tricks like atomic functions and the rlimits() construct safely. Unfortunately, neither of those things is compatible with C, nor is there any easy way to do the equivalent. |
||||||||||
|
|
|
|
|
#44 | ||||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
||||||||||
|
|
|
|
|
#45 | |||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
The way this came up was that I had a function taking a pointer, and I was passing in the pointer in question. I was using void pointers for intermediate storage, mainly because this was autogenerated code and looking up the type name for the pointer being passed was a massive pain and involved parsing an entire extra file. But typecasting to (void*) and then to what was needed turned out to give garbage results, and cause crashes. I had no clue why. Eventually, on one of those "Oh God, that would be so evil" hunches you get in debugging, I did a straight-up assertion -- assert((B*)var == (B*)(void*)var) -- and discovered that C++ was changing the value on me, but only sometimes. There was no obvious way to find the problem, though I did manage to figure the rest out once I figured out that the typecast was changing the pointer's value. But as you say, there's nothing obvious to google for there. Inheritance? Typecasting? Actually, I was disagreeing with the idea that the bald statement, the one starting with "so we should all use VB", was using the logical principle in question. You never stated how you got there, it certainly wasn't obvious, and you never gave most of your other assumptions. Quote:
Quote:
Now, back to the point you want to debate, the C vs VB thing and what the actual difference is. While I think the understanding thing is important -- I've never worked with somebody who even claimed to fully understand C++, let alone somebody who actually does -- it's not the main point. Let me introduce a pretty exact concept and then a very small number of very inexact data points. One could imagine rating every construct one sees in code for cleanliness, effectiveness and brevity. One could then look at various language features and based on the constructs that they had contributed to, decide whether they contributed to good or bad code, on average. One could then look at multiple possible language subsets (or designs or whatever) and decide on that basis whether the features included were good, and whether in concert they tended to produce good or bad code. By beginning with a language that is very clean but very simple (something like SCHEME, for instance, but even simpler), you could guarantee that the language had a baseline minimum of expressiveness and then add features from there, bearing in mind one's tolerance for ugliness in code. Adding "goto" would bring the total up a lot, so you'd much rather add loop constructs, perhaps with labelled loops (Perl's usual answer to goto). You could add exceptions, but only if, as in Java, it's easy to be sure of the full range of exceptions a given function can throw. You could add something to do template-like work, but instead you might choose procedural macros to make the results less syntactic and more semantic in the way they work. Or you might just skip them entirely if you have runtime compilation already, since then you could construct whatever you like in the language itself, very much like how LISP handles its procedural macros. If one had a very low tolerance for syntactic ugliness (or were trying to irritate Yui specifically) one could wind up with a very simple language with very few features, a lot like SCHEME. If one had a very high tolerance for syntactic ugliness, one could bolt on features 'til the cows come home, and wind up with something a lot like Perl. With a sufficiently high tolerance for semantic ugliness, you could come up with something like TCL. And each of these languages has an associated power in various domains. C has massive ability at systems programming, Perl can manipulate strings astoundingly well, TCL can be compiled very quickly, and Scheme does none of these things (being simple) but it embeds like the dickens (being simple) and compiles lightning-fast (being simple). So that's a fine abstraction, but it tells us very little about C versus VB. What's the difference? C has a higher tolerance than VB for syntactic ugliness, though not nearly as much so as C++ or Perl. Yes, this is subjective, but it's accepted in the vast majority of programming forums that more kinds of punctuation in more random places in the code is generally a bad thing -- Perl's regular expression syntax, much as I love it, is just not a pretty thing. It's also hard to read because density of expression leads to poor reading comprehension, especially if you don't know if there are bugs. Similarly, code that has bits that don't label their functions well is hard to comprehend, and usually ugly. Dylan's structure-definition stuff is a joy to behold, especially if you don't know the language very well. Since it's been awhile for me, don't take this syntax as gospel, but it's reasonbly close: class <MyClass> inherit <MyOtherClass>; field data-one, type: <integer>, setter: data-setter; end class <MyClass>; In C++, you have: class MyClass : public MyOtherClass { int data_one; public: void data_setter(int new_val) { data_one = new_val; } } Note how in this class it's less obvious what the individual bits do? You can get away with less keystrokes, at the cost of reading comprehension. And yes, yes, you're welcome to say that somebody that knows the language well will understand what the class declaration does, and you'd be right. But there's a difference between the possible and the pleasant, and if you make it more pleasant, it's usually more maintainable. So what about C versus VB? Neither looks like Dylan. VB doesn't even usually use classes, at least the way I've seen it done. C is substantially more powerful than VB for most uses (note: "most uses" here means "stuff I do" -- VB is actually more common than C in the real world, and probably rightly so). Far more powerful. Hands down. It's also uglier, at least the parts I've used. And faster, though that's effectively part of "more powerful". Thus, VB is to C as C is to C++ -- one is more powerful, and uglier. So rather than saying "why don't we all use VB?", you might have extended the point to "why don't we all use 'Hello World' in Scheme?". It does nothing and is very pretty, so it's the logical conclusion of going for a less-powerful, prettier choice of language. Of course, if I was saying, "y'know, the Honda Insight is a lot less economical than an Accord considering what the two do", you could equally validly say "well then just walk, cheapskate." This would be why I don't consider it logical. I'm considering a tradeoff, so you assume that if I prefer a trade toward cheapness and lower performance that obviously something that costs nothing and does nothing is perfect. No. It's a tradeoff. In the same way that I assume you wouldn't want a language with every possible feature, I prefer you not assume that I want a language with no features. I'm considering the cost and the value of using one thing versus another, which is different from taking a single principle and applying it to the absolute utmost. Maybe I'm wrong. Maybe if there were something with more features than C++, you'd just automatically use that, no matter how ugly and no matter how hard to debug. I don't think so, though. |
|||
|
|
|
|
|
#46 | ||
|
Member
|
Quote:
Quote:
I came across an aspect involving the width of an enum when having an int constructed from it just last week. Oh wait, that exists in C, too. And then there's the returning static thing from that poster on TMC. Except that's also the rule in C. Let's ban C, it's too easy to make silly mistakes. Kas. |
||
|
|
|
|
|
#47 | ||||||
|
Senior Member
|
Quote:
Quote:
Quote:
These other considerations particularly shine in the mud community. Because of the backwards compatibility with C, a coder can port their source over to take advantage of certain features (like strings, linked list objects that are decoupled from the object they store, and constructors/destructors to initialize memory and subsequently free it) while still maintaining the large body of code that they have already written. Quote:
Quote:
Quote:
|
||||||
|
|
|
|
|
#48 | ||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
If 10% of your problems take 10 times as long to debug as the other 90% (which is about right for me and C++ in my experience), you wind up spending half of your time on that 10%. That's fine if that's where the meat of your problem is, and in that case it's fully justified. But I've found that in C++ I wind up spending way too much time on trivial problems caused by nasty syntax or questionably-designed language features. In C, I still spend half my time on 10% of my problems. But they're the 10% that occur in places with genuinely weird logic where the hard part is figuring out the algorithm. That'd be the right 10% to my mind. Quote:
And as far as figuring out what size an enum is, granted, that should be standardized. But it has the same problem C has always had -- too many platforms. C is old enough that it can't even be sure that its integer types are multiples of eight bits. Scary but true. I haven't seen the returning static thing. I'll take your word for it. And yes, it *is* too easy to make silly mistakes in C. I'll run the risk of irritating Yui by blaming some of that on the language designers :-) |
||
|
|
|
|
|
#49 | |||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
Quote:
Quote:
Quote:
I consider popularity concerns ("if it doesn't look like C, nobody will use it") and time-to-market concerns ("but we don't have time to make a real VM language for Java! Use the language directly") pretty irrelevant to whether I should use the language, and what I should use it for. Instead I'll judge it based on its actual merits ("gee, that's a lot uglier than C" and "gee, that's really slow", respectively, in the two examples above). Quote:
You can say "but you can refactor". The codebase has to be *very* clean and *very* OO already for that to work well, though, especially at the talent level of most current MUD coders. |
|||||
|
|
|
|
|
#50 | |
|
Senior Member
|
Quote:
|
|
|
|
|
|
|
#51 | |||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
[code] /* C version */ char *build_magic_string (...) { static char magic[256]; ... return magic; }[/quote] As opposed to: [code] // C++ version string build_magic_string (...) { string magic; ... return magic; }[/quote] And all that reduced range of debugging tools, like the exact same debugger and tools they were using before? Yeah. You got me there. The lack of forced object-oriented design is an incredible plus when you simply want to take advantage of one or two features but also want your codebase to use the same idioms and design as before. Many C++ codebases use procedural C code, and this is a very good thing for programmers, because they have to do a minimal amount of porting. If you're suggesting that to take advantage of a few useful features, a programmer should have to refactor and redesign his codebase, you're crazier than I thought you were. |
|||||
|
|
|
|
|
#52 | ||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
The problem with giving the programmer "a few useful features" and letting him run with it is that he'll either hate them, in which case nothing will happen, or he'll like them and use them everywhere. It's that second scenario, the one where you bastardize the codebase by adding a second paradigm on top of the first one, that gets folks into trouble. Do I think that people should redesign their whole codebase to add a few useful features? No. But I find that adding a few useful *language* features after the fact is usually a major inviation to trouble. I've seen it work, mostly, by adding callout to another language. Usually that means that most developers on the project only know one language or the other. There are at least well-documented interfaces between the two, but debugging anything cross-language remains a pain. You can add features after the fact with an extra preprocessor, too, the way C++ used to work. SGI apparently does their arcane template-like data structure stuff that way. By and large, though, nobody does. Why do you think that is? My vote would be: adding features to the language, especially when you have a large existing codebase, is usually an invitation to trouble. By contrast, switching languages entirely guarantees that you do *not* have a large existing codebase, one way or the other. Am I in favor of switching languages instead? Not usually. Usually I'm in favor of keeping your large existing codebase in the language in which it was written, or rewriting it pretty much entirely. |
||||||
|
|
|
|
|
#53 | ||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
||||||||
|
|
|
|
|
#54 | ||||||||
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
Quote:
But yes, you did in fact offer a major feature. I still choose not to weight the history itself in my consideration of the language. I weight the feature in my consideration of the language, and I in fact debate precisely that feature later in the same message. I'm not ignoring that feature, no matter how many time you repeat that I am. Happy? Quote:
I haven't used the new Rational revision with gcc/g++ on a Unix system, only the older Pure Software version. It also has serious bugs that make it hard to use, but the new (far more expensive) version might fix that. Quote:
Quote:
Quote:
I believe that by and large, simple clean languages are a very good idea. I believe that languages like C++ and Perl (which I would put near the far opposite end of the current spectrum from "simple, clean languages") have very specific uses, but primarily those uses boil down to "prototyping". I believe that a hybrid prototyping/systems language (like C++) encourages people to build on those prototypes to turn them into the finished product, which creates lousy finished products (see "The Mythical Man-Month" for more on this phenomenon -- I know you've read it, you recommend it on your site). Quote:
Quote:
I've never seen this done well, though I've seen it done badly many times. I'm referring specifically to C-to-C++ transitions when I say that. Here, let me ask you a question as a thought exercise, and because I need to know how crazy *I* should consider *you*. Say there was a tool which advertised a particular service, but didn't usefully perform. Using that tool was always worse than not using that tool for the advertised purposes. There were conceivable uses for the tool, but the common and advertised ones weren't really among them. Should the tool exist? Quote:
If Qt is preprocessing C++ to add features then I'll remember to avoid it. "Meta-object compiler" is certainly a lovely euphemism for that, though. |
||||||||
|
|
|
|
|
#55 | |||||||||
|
Senior Member
|
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
Quote:
|
|||||||||
|
|
|
|
|
#56 |
|
Member
Join Date: Feb 2003
Location: Bay Area, CA, USA
Posts: 39
![]() |
<i>"From what I hear about C99 and the C++0x standardization process, designing a language is very, very difficult and time-consuming."</i>
Yup. Though it's amusing how many people manage to randomly do it on-line without nearly as much time or effort. The big difference between them and what standards bodies are trying to do is that most people spell out what their implementation does, but not what the language guarantees. You're probably familiar with the same distinction from designing libraries -- "if you do this, the behavior is undefined", even though your library may always do the same thing in response to that. You just don't want to guarantee it forever, or in all circumstances. Plus, of course, the standards bodies are dealing with established languages and so they have to deal with implementation issues a lot more carefully than most, and they usually need to do so without taking the time to actually implement the changes they mention. A difficult job, that. Particularly in C++ where different compilers still do genuinely different things to implement certain features, so it can be hard to tell if you're breaking something that somebody's doing. A decent C++ ABI (Application Binary Interface) would solve a lot of that problem, but that's been "just about to happen" for ten years and counting so I'm not holding my breath. |
|
|
|
|
|
#57 |
|
Member
|
Hey there,
I've been watching this thread for a while now, and I've actually recommended it to a few programmers I know who like to rant on and on about this very topic. Having very little programming experience total to draw from, and none in the area of C++, I've had to take what I could from the thread, mainly looking at the philosophies of each person and deciding which made more sense to me. In the end, I have no opinion on which is a "better" language. However: Yui, go work for M$. Their PR department would worship you. -Visko |
|
|
|
|
|
#58 | |
|
Senior Member
|
Quote:
I think that MS' style of C++ is one of the best, most prominent examples of how you can go wrong with the language =). |
|
|
|
|
|
|
#59 |
|
Posts: n/a
|
10 PRINT "I code my MUD in BASIC!"
20 GOTO 10 |
|
|
|
#60 | |
|
Member
|
Quote:
Kas. (Edit: Ack! that came out bad first time around) |
|
|
|
|
![]() |
| Thread Tools | |
Which is preferred? - Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Preferred Role Playing Level | enigma@zebedee | Advertising for Players | 27 | 04-23-2003 08:01 AM |
|
|