* Factory Pattern @ 2007-07-25 18:19 shaunpatterson 2007-07-25 18:28 ` Martin ` (3 more replies) 0 siblings, 4 replies; 26+ messages in thread From: shaunpatterson @ 2007-07-25 18:19 UTC (permalink / raw) I'm just starting out learning Ada and I'm having some trouble converting some C++ code. The last hurtle I'm having trouble with is implementing a Factory in Ada I basically have a base class Message and all other messages are derived from this. I have a function call createMessage that I would like to return the appropriate subclass type. My code looks something like this: type Message is abstract tagged; type Message_Class is access all Message'Class; derived type: package MessageInteger_Pkg is -- I want this to act like a constructor -- Just fills in the value function create (i : Integer) return MessageInteger; private type MessageInteger with new Message with record value : Integer; end record; end MessageInteger_Pkg; -- create looks like this: function create (i : Integer) return MessageInteger is msg : MessageInteger; begin msg.value := i; return msg; end create; Factory method: -- I would like it to work like this... function createMessage (type : Integer) return Message_Class is begin case type is when 0 => return MessageInteger_Pkg.create (1234); when others => return MessageSomethingElse_Pkg.create ("blah"); end case end createMessage However - it doesn't like me returning the MessageInteger from a class that returns a Message_Class (obviously..) Now if I do this -- changing the constructor to take in a Message_Class.... function createMessage (type : Integer) return Message_Class is decodedMessage : Message_Class; begin case type is when 0 => decodedMessage := new MessageInteger_Pkg.MessageInteger; MessageInteger_Pkg.create (decodedMessage, 1234); -- change the decoded message this way return decodedMessage; when others => return MessageSomethingElse_Pkg.create ("blah"); end case end createMessage -- That method works... but I find the intermediary step of making a new object decodedMessage to someone unneeded? There must be another way of doing this. Perhaps I should move the "new" to the create function? And... I'm not completely sure I'm doing all this correctly in Ada. LIke I said, I'm very new to Ada. Thanks -- Shaun ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-25 18:19 Factory Pattern shaunpatterson @ 2007-07-25 18:28 ` Martin 2007-07-25 18:51 ` Dmitry A. Kazakov ` (2 subsequent siblings) 3 siblings, 0 replies; 26+ messages in thread From: Martin @ 2007-07-25 18:28 UTC (permalink / raw) On 25 Jul, 19:19, shaunpatter...@gmail.com wrote: [snip] Welcome to Ada! :-) Check out that patterns at www.adapower.com - a very useful resouce to know about anyway. The link to the patterns page is http://www.adapower.com/index.php?Command=Class&ClassID=Patterns&Title=Patterns Cheers -- Martin ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-25 18:19 Factory Pattern shaunpatterson 2007-07-25 18:28 ` Martin @ 2007-07-25 18:51 ` Dmitry A. Kazakov 2007-07-25 21:06 ` Georg Bauhaus 2007-07-25 19:27 ` Matthew Heaney 2007-07-26 0:51 ` Jeffrey R. Carter 3 siblings, 1 reply; 26+ messages in thread From: Dmitry A. Kazakov @ 2007-07-25 18:51 UTC (permalink / raw) On Wed, 25 Jul 2007 11:19:31 -0700, shaunpatterson@gmail.com wrote: > I'm just starting out learning Ada and I'm having some trouble > converting some C++ code. > > The last hurtle I'm having trouble with is implementing a Factory in > Ada > > I basically have a base class Message and all other messages are > derived from this. > I have a function call createMessage that I would like to return the > appropriate subclass type. > > My code looks something like this: > > type Message is abstract tagged; -- Abstract factory, each non-abstract derived type will be forced to -- implement this: function Create (I : Integer) return Message is abstract; > type Message_Class is access all Message'Class; > > derived type: > > package MessageInteger_Pkg is > > -- I want this to act like a constructor > -- Just fills in the value > function create (i : Integer) return MessageInteger; > > private > type MessageInteger with new Message with > record > value : Integer; > end record; > > > end MessageInteger_Pkg; > > -- create looks like this: > function create (i : Integer) return MessageInteger is > msg : MessageInteger; > begin > msg.value := i; > return msg; You could use an extension aggregate here: return (Message with I); > end create; > > Factory method: > > -- I would like it to work like this... > function createMessage (type : Integer) return Message_Class is "Type" is a reserved word. > begin > case type is > when 0 => > return MessageInteger_Pkg.create (1234); > when others => > return MessageSomethingElse_Pkg.create > ("blah"); > end case > > end createMessage function Factory (What : Integer) return Message'Class is begin case What is when 0 => return MessageInteger_Pkg.Create (1234); ... > However - it doesn't like me returning the MessageInteger from a class > that returns a Message_Class (obviously..) [...] > Perhaps I should move the "new" > to the create function? Yes, you you want to work with pointers. But what for? Ada can return polymorphic objects on the stack. No need in pointers. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-25 18:51 ` Dmitry A. Kazakov @ 2007-07-25 21:06 ` Georg Bauhaus 0 siblings, 0 replies; 26+ messages in thread From: Georg Bauhaus @ 2007-07-25 21:06 UTC (permalink / raw) Dmitry A. Kazakov wrote: > On Wed, 25 Jul 2007 11:19:31 -0700, shaunpatterson@gmail.com wrote: >> function create (i : Integer) return MessageInteger is >> msg : MessageInteger; >> begin >> msg.value := i; >> return msg; > > You could use an extension aggregate here: > > return (Message with I); Or even return (Message with value => I); >> Factory method: >> >> -- I would like it to work like this... >> function createMessage (type : Integer) return Message_Class is > > "Type" is a reserved word. > >> begin >> case type is >> when 0 => >> return MessageInteger_Pkg.create (1234); >> when others => >> return MessageSomethingElse_Pkg.create >> ("blah"); >> end case >> >> end createMessage > > function Factory (What : Integer) return Message'Class is Let me just stress that 'Class is the important part of Factory because it adds the polymophism: T'Class stands for all types that have T as a parent (including T). This roughly corresponds to the pointer use in C++ but as Dmitry has already mentioned, the Ada language takes care of polymorphic reference for you already for 'Class types. (And it isn't pointing that adds polymorphism, it is 'Class.) So you needn't return pointers to objects in the T hierarchy. You can just return objects. The returned objects will either be passed to subprograms, or assigned. Some_Message_Op(Factory(Event)); -- chosen based on what Factory returns (the return -- value's tag) declare What_is_It: Message'Class := Factory (Event); begin Some_Message_Op(What_is_It); -- chosen based on tag of What_Is_It ... end; declare What_is_It: MessageInteger := MessageInteger(Factory (Event)); -- you could do this if you know that the Factory returns an -- object that can act as one of type MessageInteger begin if What_is_It.value > 42 then ... end; > begin > case What is > when 0 => return MessageInteger_Pkg.Create (1234); > ... Another feature that I would consider when writing a factory is case coverage, like this: As your program is such that you know all *possible* types before runtime, define an enumeration that has an identifier for each of the possible types. Then in the body of Facroty, leave out "others" from the case statement. The compiler will then check that all cases are covered which makes the factory more predictable. This works for user defined numeric types, too. For example, if the What variable stands for expected average number of births per woman in one socioeconometeriological region, the Factory will create family types: type Kid_Count is range 0 .. 20; What := Births_per_Woman (Latitude => ..., GDP => ..., Wheather => ...); case What is when 0 => return Couples.Create; when 1 => if Longitude in China.West .. China.East then return China.Create(1); else return High_Tec.Create(Average => 1.27); end if; when 2 => return Saturated.Create(1.73); when 3 | 4 => return Sunnier.Create(Population => Mixed); when 5 => return Silent_Africa.Create(...); when 6 .. 8 => return Shaken_Africa.Create(...); when 9 .. 20 => return Random.Create; end case; ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-25 18:19 Factory Pattern shaunpatterson 2007-07-25 18:28 ` Martin 2007-07-25 18:51 ` Dmitry A. Kazakov @ 2007-07-25 19:27 ` Matthew Heaney 2007-07-26 0:51 ` Jeffrey R. Carter 3 siblings, 0 replies; 26+ messages in thread From: Matthew Heaney @ 2007-07-25 19:27 UTC (permalink / raw) On Jul 25, 2:19 pm, shaunpatter...@gmail.com wrote: > > My code looks something like this: > > type Message is abstract tagged; You need to say more here, but see below. > type Message_Class is access all Message'Class; In Ada05 you might not need this access type, since functions can now return an anonymous access value. Also, if you want to force clients of your abstraction to call your constructor, you should probably declare the type as limited: type Message is abstract tagged limited null record; If your root type has payload that you want to make private, then you can say: type Message is abstract tagged limited private; ... private type Message is abstract tagged limited record ... end record; > derived type: > > package MessageInteger_Pkg is You probably want to declare the partial view of your type in the public part, and with an unknown discriminant: type MessageInteger (<>) is new Message with private; > > -- I want this to act like a constructor > -- Just fills in the value > function create (i : Integer) return MessageInteger; > > private > type MessageInteger with new Message with > record > value : Integer; > end record; > > end MessageInteger_Pkg; > > -- create looks like this: > function create (i : Integer) return MessageInteger is > msg : MessageInteger; > begin > msg.value := i; > return msg; > end create; This won't work if the type is limited. You can say either: function Create (I : Integer) return MessageInteger is begin return (Value => I); end; or function Create (I : Integer) return MessageInteger is begin return Result : MessageInteger do Result.Value := I; end return; end Create; > Factory method: > > -- I would like it to work like this... > function createMessage (type : Integer) return Message_Class is > begin > case type is > when 0 => > return MessageInteger_Pkg.create (1234); > when others => > return MessageSomethingElse_Pkg.create > ("blah"); > end case > > end createMessage You can do this: function CreateMessage (T : Integer) return Message'Class is begin case T is when 0 => return MessageInteger_Pkg.Create (T); when others => return MessageSomethingElse_Pkg.Create; end case; end CreateMessage; This avoids any use of pointers. This might or might not be what you need. Another possibility is: function CreateMessage (T : Integer) return not null access Message'Class is begin case T is when 0 => return MessageInteger_Pkg.Create (T); when others => return MessageSomethingElse_Pkg.Create; end case; end CreateMessage; (You'll have to also change the ctors for each derived type to return an access value designating the specific type.) > However - it doesn't like me returning the MessageInteger from a > class > that returns a Message_Class (obviously..) Right, because (in your original example) MessageInteger_Pkg.Create returns a value of the type, while CreateMessage returns an access value. > Now if I do this -- changing the constructor to take in a > Message_Class.... > > function createMessage (type : Integer) return Message_Class is > decodedMessage : Message_Class; > begin > case type is > when 0 => > decodedMessage := new > MessageInteger_Pkg.MessageInteger; > MessageInteger_Pkg.create (decodedMessage, > 1234); -- change the decoded message this way > return decodedMessage; > when others => > return MessageSomethingElse_Pkg.create > ("blah"); > end case > > end createMessage > > -- That method works... but I find the intermediary step of making a > new object decodedMessage > to someone unneeded? There must be another way of doing this. > Perhaps I should move the "new" > to the create function? Yes, move the new to the Create function for each derived type. (There are others ways of solving this problem, but that will at least get you going.) > And... I'm not completely sure I'm doing all this correctly in Ada. > LIke I said, I'm very new to > Ada. That's OK. That's what CLA is for. Welcome! -Matt ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-25 18:19 Factory Pattern shaunpatterson ` (2 preceding siblings ...) 2007-07-25 19:27 ` Matthew Heaney @ 2007-07-26 0:51 ` Jeffrey R. Carter 2007-07-26 6:44 ` Maciej Sobczak 3 siblings, 1 reply; 26+ messages in thread From: Jeffrey R. Carter @ 2007-07-26 0:51 UTC (permalink / raw) shaunpatterson@gmail.com wrote: > > -- I would like it to work like this... > function createMessage (type : Integer) return Message_Class is > begin > case type is > when 0 => > return MessageInteger_Pkg.create (1234); > when others => > return MessageSomethingElse_Pkg.create > ("blah"); > end case > > end createMessage Obviously this won't work, since Messageinteger_Pkg.Create returns type Messageinteger, presumably a tagged record type, not Message_Class, an access type. I would think that an enumeration type would be better than Integer for selecting among a few choices. Using Integer probably reflects C/++ thinking. Like all well designed languages, Ada is not case sensitive. We tend to avoid camelCase, since the 1st thing people often do is run it through a reformatter that will convert it to the de facto Ada standard of Camelcase. Instead we separate words with underlines. Ada's features for programming by extension are somewhat different than C++'s, and you need to become familiar with the Ada concepts before trying something like this. Once you do, though, you may find you like Ada way better. You can have both static and dispatching calls to the same subprogram, for example. -- Jeff Carter "Sheriff murdered, crops burned, stores looted, people stampeded, and cattle raped." Blazing Saddles 35 ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 0:51 ` Jeffrey R. Carter @ 2007-07-26 6:44 ` Maciej Sobczak 2007-07-26 8:40 ` Georg Bauhaus 2007-07-27 10:16 ` Jeffrey R. Carter 0 siblings, 2 replies; 26+ messages in thread From: Maciej Sobczak @ 2007-07-26 6:44 UTC (permalink / raw) On 26 Lip, 02:51, "Jeffrey R. Carter" <spam.jrcarter....@acm.nospam.org> wrote: > I would think that an enumeration type would be better than Integer for > selecting among a few choices. Using Integer probably reflects C/++ > thinking. No. C and C++ have enumerations. > Like all well designed languages, Ada is not case sensitive. Careful. It is a question of interpretation of any given character set and it can be different with different tools, and there are many. The problem is that it is only the Ada compiler which can be case insensitive, but text editors or tools like diff or grep are not by default and making them such requires additioinal effort - this is a perfect place for mistakes. In addition, being case-insensitive and at the same time allowing full Unicode in identifiers is kind of schisophreny. > de facto Ada standard of > Camelcase. If there are such standards, then what's the benefit of being case- insensitive? Get any Ada program that conforms to this de facto standard and imagine that the compiler is today case-sensitive. Would you have any problem compiling this program? No. > Ada's features for programming by extension are somewhat different than > C++'s, and you need to become familiar with the Ada concepts before > trying something like this. Once you do, though, you may find you like > Ada way better. You can have both static and dispatching calls to the > same subprogram, for example. You can have it in C++ as well, so this example is not the reason to like Ada "way better". -- Maciej Sobczak http://www.msobczak.com/ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 6:44 ` Maciej Sobczak @ 2007-07-26 8:40 ` Georg Bauhaus 2007-07-26 9:53 ` Dmitry A. Kazakov 2007-07-27 10:16 ` Jeffrey R. Carter 1 sibling, 1 reply; 26+ messages in thread From: Georg Bauhaus @ 2007-07-26 8:40 UTC (permalink / raw) On Wed, 2007-07-25 at 23:44 -0700, Maciej Sobczak wrote: > On 26 Lip, 02:51, "Jeffrey R. Carter" > <spam.jrcarter....@acm.nospam.org> wrote: > > > I would think that an enumeration type would be better than Integer for > > selecting among a few choices. Using Integer probably reflects C/++ > > thinking. > > No. C and C++ have enumerations. > > > Like all well designed languages, Ada is not case sensitive. > > Careful. It is a question of interpretation of any given character set > and it can be different with different tools, and there are many. Many case sensitive tools seem to be inspired by the case sensitive 7bit tools, and the case sensitive programmers, used in creating them. > In addition, being case-insensitive and at the same time allowing full > Unicode in identifiers is kind of schisophreny. Why is being case-insensitive and allowing full Unicode in identifiers schizophrenic? ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 8:40 ` Georg Bauhaus @ 2007-07-26 9:53 ` Dmitry A. Kazakov 2007-07-26 11:01 ` Georg Bauhaus ` (2 more replies) 0 siblings, 3 replies; 26+ messages in thread From: Dmitry A. Kazakov @ 2007-07-26 9:53 UTC (permalink / raw) On Thu, 26 Jul 2007 10:40:43 +0200, Georg Bauhaus wrote: > Why is being case-insensitive and allowing full Unicode > in identifiers schizophrenic? Because the concept of "case" does not apply to all scripts. I presume that hieroglyphic scripts might possess quite outlandish ideas about arts of glyphs composition and the equivalence of the results obtained. I'm curios, if GNAT will support sources in Zapfino (:-)) http://en.wikipedia.org/wiki/Zapfino -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 9:53 ` Dmitry A. Kazakov @ 2007-07-26 11:01 ` Georg Bauhaus 2007-07-26 13:02 ` Maciej Sobczak 2007-07-26 16:58 ` Adam Beneschan 2007-07-29 11:38 ` Manuel Gomez 2 siblings, 1 reply; 26+ messages in thread From: Georg Bauhaus @ 2007-07-26 11:01 UTC (permalink / raw) On Thu, 2007-07-26 at 11:53 +0200, Dmitry A. Kazakov wrote: > On Thu, 26 Jul 2007 10:40:43 +0200, Georg Bauhaus wrote: > > > Why is being case-insensitive and allowing full Unicode > > in identifiers schizophrenic? > > Because the concept of "case" does not apply to all scripts. How does the concept of "case" apply to '-' or '8' in 7bit ASCII? The schizophrenia is elsewhere, I'd say :-) ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 11:01 ` Georg Bauhaus @ 2007-07-26 13:02 ` Maciej Sobczak 2007-07-26 13:44 ` Dmitry A. Kazakov ` (2 more replies) 0 siblings, 3 replies; 26+ messages in thread From: Maciej Sobczak @ 2007-07-26 13:02 UTC (permalink / raw) On 26 Lip, 13:01, Georg Bauhaus <rm.tsoh+bauh...@maps.futureapps.de> wrote: > > > Why is being case-insensitive and allowing full Unicode > > > in identifiers schizophrenic? > > > Because the concept of "case" does not apply to all scripts. Bingo, but not only. Some scripts do have the concept of "case", but the mapping between upper-case and lower-case is not 1:1. Or even better, the *length* of sequence changes with case. This introduces some funny effects when trying to decide whether two sequences have the same meaning. In the case-insensitive programming language I would expect that changing the "case" of one character in the identifier will not change its semantics. How Ada guarantees this for Unicode? Or maybe is Ada case-insensitive only in the ASCII subset of Unicode? Sorry, I don't call it "well-designed". > How does the concept of "case" apply to '-' or '8' in 7bit ASCII? > The schizophrenia is elsewhere, I'd say :-) Yes. It's in the motivation. We can make something case-insensitive in order to *reduce* the number of characters that are effectively different; and we can provide support for Unicode in order to *increase* the number of different characters. In my very humble opinion both are bad ideas (even separately). -- Maciej Sobczak http://www.msobczak.com/ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 13:02 ` Maciej Sobczak @ 2007-07-26 13:44 ` Dmitry A. Kazakov 2007-07-26 14:58 ` Georg Bauhaus 2007-07-26 22:31 ` Randy Brukardt 2 siblings, 0 replies; 26+ messages in thread From: Dmitry A. Kazakov @ 2007-07-26 13:44 UTC (permalink / raw) On Thu, 26 Jul 2007 06:02:38 -0700, Maciej Sobczak wrote: > We can make something case-insensitive in order to *reduce* the number > of characters that are effectively different; No, the letters are same, A and a is the same letter. Glyphs might be different, but why should that influence the program semantics? What about typefaces, colors, thickness, slant, ligatures, stamping? It is a question of alphabet. Ada 83 was based on Latin alphabet. K&R C was not. > and we can provide support for Unicode in order to *increase* the number of different > characters. Yep. I propose to introduce one Unicode code position for each correct program. That would eliminate any need in any programming languages, compilers, and programmers... (:-)) -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 13:02 ` Maciej Sobczak 2007-07-26 13:44 ` Dmitry A. Kazakov @ 2007-07-26 14:58 ` Georg Bauhaus 2007-07-26 22:31 ` Randy Brukardt 2 siblings, 0 replies; 26+ messages in thread From: Georg Bauhaus @ 2007-07-26 14:58 UTC (permalink / raw) On Thu, 2007-07-26 at 06:02 -0700, Maciej Sobczak wrote: > On 26 Lip, 13:01, Georg Bauhaus <rm.tsoh+bauh...@maps.futureapps.de> > wrote: > > > > > Why is being case-insensitive and allowing full Unicode > > > > in identifiers schizophrenic? > > > > > Because the concept of "case" does not apply to all scripts. > > Bingo, but not only. Some scripts do have the concept of "case", but > the mapping between upper-case and lower-case is not 1:1. Or even > better, the *length* of sequence changes with case. This introduces > some funny effects when trying to decide whether two sequences have > the same meaning. What is funny about the effects of a transformation function? I would expect a transformation to result in something that is not identical, but reflecting needs. Just like a calendar date has a number of literals because most of them must follow the local conventions (e.g. in legal documents). This precludes writing a canonical, technical, internal representation in source documents. Insofar as programming is a formal, human activity, I would expect the mode of expression to be somewhere between formal and prosaic. > In the case-insensitive programming language I would > expect that changing the "case" of one character in the identifier > will not change its semantics. How Ada guarantees this for Unicode? Ada guarantees this by way of defining identifiers etc. in the RM. > Or maybe is Ada case-insensitive only in the ASCII subset of Unicode? > Sorry, I don't call it "well-designed". That would indeed be strange. > We can make something case-insensitive in order to *reduce* the number > of characters that are effectively different; and we can provide > support for Unicode in order to *increase* the number of different > characters. Being able to select characters reduces it again. (Computers can help with checking the selection. They are already performing more advanced checks. :-) I think it is quite likely that the large population using ideographic characters will find it easier to use the words that they know when the alternative is to learn English. (I think the transcriptions using Latin characters have never become popular in China.) (Try having us communicate in Japanese. How long will the training take? Slavic languages are already different for those having grown up with one of the Latin-Saxon dialects. Yet at least the grammars have similar structure. Not so with Chinese.) > In my very humble opinion both are bad ideas (even separately). But why? When I saw the Fortress language documents I thought, Oh God, not that again! If my understanding is correct, "a" and "A" in the same local scope are different identifiers, and "_a" with a leading underscore adds bold face characteristics to another a! And they happily reintroduce the white space operator that is so aptly described by Bjarne Stroustrup. (Robert Dewar (Spitbol) was credited by Ralph Griswold (SNOBOL4) for having replaced the white space operator with '?'). Perhaps the Fortress guys think it is cool to be able to write something like a A /= aA Will the computer-denying academics learn that writing programs is *not*, and should not be, the same as writing a math paper? Lazy snobs! Getting them out of their universities and laboratories and have them change a handful of programs written by regular programmers might help. Enough steam for today, sorry! -- Georg ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 13:02 ` Maciej Sobczak 2007-07-26 13:44 ` Dmitry A. Kazakov 2007-07-26 14:58 ` Georg Bauhaus @ 2007-07-26 22:31 ` Randy Brukardt 2007-07-27 13:07 ` Maciej Sobczak 2 siblings, 1 reply; 26+ messages in thread From: Randy Brukardt @ 2007-07-26 22:31 UTC (permalink / raw) "Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message news:1185454958.105983.143570@l70g2000hse.googlegroups.com... ... > In the case-insensitive programming language I would > expect that changing the "case" of one character in the identifier > will not change its semantics. How Ada guarantees this for Unicode? It uses the Unicode-defined case mapping tables. And yes, this can change the length of things. So what? We used the Unicode-defined tables because that way we let the experts in these scripts make the decisions, not us language designers. If you really care how these things are defined, check out the standard clauses 2.1 and 2.3: http://www.adaic.com/standards/05rm/html/RM-2-1.html http://www.adaic.com/standards/05rm/html/RM-2-3.html 2.3(5-5.3/2) defines how identifiers are compared for equality; 2.1 defines the various character categories. The wording is more obtuse that we would have liked because we couldn't reference Unicode normatively (it is not an ISO standard). > Or maybe is Ada case-insensitive only in the ASCII subset of Unicode? No, Ada is case-insensitive across the entire range of Unicode characters. > Sorry, I don't call it "well-designed". Well, that's your choice, but it would be better informed if you understood the rules in question first. Randy. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 22:31 ` Randy Brukardt @ 2007-07-27 13:07 ` Maciej Sobczak 2007-07-27 14:23 ` shaunpatterson 2007-07-27 22:23 ` Randy Brukardt 0 siblings, 2 replies; 26+ messages in thread From: Maciej Sobczak @ 2007-07-27 13:07 UTC (permalink / raw) On 27 Lip, 00:31, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > > In the case-insensitive programming language I would > > expect that changing the "case" of one character in the identifier > > will not change its semantics. How Ada guarantees this for Unicode? > > It uses the Unicode-defined case mapping tables. > If you really care how these things are defined, check out the standard > clauses 2.1 and 2.3. Thank you for pointing this. > > Sorry, I don't call it "well-designed". > > Well, that's your choice, but it would be better informed if you understood > the rules in question first. Yes, with the rules as described in ARM no such problems should arise, at least with the use of tools that are part of the langauge implementation (compiler or interpreter or whatever). Still, I don't share the motivation for introducing such support into the language. There are two reasons for this: 1. The programming language does not exist in a vacuum and the typical software development process involves many more tools than just a compiler. Text editor might be useful as well, not mentioning countless utilities for automated text processing. They are not covered by ARM and do not have to follow its rules. This makes it more difficult to work with code that liberally uses Unicode or case- agnostic naming - and can be an additional source of mistakes. This additional burden and the risk of mistakes is against the Ada spirit (as I understant it). 2. There is no way to escape English and Latin1 character set anyway. Not only Ada is very rich in reserved words, there are also tons of names in the standard library. All these are English and Latin1. In addition, there are third-party libraries, code is moved from one project to another, projects are published, companies merge, etc. This means that a programmer wanting to use her hieroglyphs in the Ada program cannot be consistent with any convention. I, for example, find it very disturbing when I see in a single line of code two names in different languages and all the companies and projects I've been involved in prohibit(ed) such mixes without exceptions - note that I'm not a native English speaker, so such rules relate to me directly. Interestingly, using localized identifier names does not increase readability of the program! Again, not Ada spirit (as I understand it). OK, let's better write some more Latin1 code with standard naming convention... ;-) -- Maciej Sobczak http://www.msobczak.com/ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-27 13:07 ` Maciej Sobczak @ 2007-07-27 14:23 ` shaunpatterson 2007-07-27 22:23 ` Randy Brukardt 1 sibling, 0 replies; 26+ messages in thread From: shaunpatterson @ 2007-07-27 14:23 UTC (permalink / raw) Umm well in the case of simplicity in my example I used an integer to show I was switching between types. In both my C++ code and my Ada code I used enumerations... Anyway - thanks for the help ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-27 13:07 ` Maciej Sobczak 2007-07-27 14:23 ` shaunpatterson @ 2007-07-27 22:23 ` Randy Brukardt 2007-07-28 18:56 ` Maciej Sobczak 2007-07-29 7:54 ` Maciej Sobczak 1 sibling, 2 replies; 26+ messages in thread From: Randy Brukardt @ 2007-07-27 22:23 UTC (permalink / raw) "Maciej Sobczak" <see.my.homepage@gmail.com> wrote in message news:1185541668.089363.258220@q75g2000hsh.googlegroups.com... ... > Still, I don't share the motivation for introducing such support into > the language. There are two reasons for this: > > 1. The programming language does not exist in a vacuum and the typical > software development process involves many more tools than just a > compiler. Text editor might be useful as well, not mentioning > countless utilities for automated text processing. They are not > covered by ARM and do not have to follow its rules. This makes it more > difficult to work with code that liberally uses Unicode or case- > agnostic naming - and can be an additional source of mistakes. This > additional burden and the risk of mistakes is against the Ada spirit > (as I understant it). > > 2. There is no way to escape English and Latin1 character set anyway. > Not only Ada is very rich in reserved words, there are also tons of > names in the standard library. All these are English and Latin1. In > addition, there are third-party libraries, code is moved from one > project to another, projects are published, companies merge, etc. This > means that a programmer wanting to use her hieroglyphs in the Ada > program cannot be consistent with any convention. I, for example, find > it very disturbing when I see in a single line of code two names in > different languages and all the companies and projects I've been > involved in prohibit(ed) such mixes without exceptions - note that I'm > not a native English speaker, so such rules relate to me directly. > Interestingly, using localized identifier names does not increase > readability of the program! Again, not Ada spirit (as I understand > it). > > OK, let's better write some more Latin1 code with standard naming > convention... ;-) For what it's worth, I agree with you and would have preferred to leave identifiers as they were in Ada 95. However, the requirement for this support came down from above; essentially, if we wanted Ada to continue to be an ISO standard, we needed to add this sort of support. (New standards for other languages also will have to add this sort of support, or take their chances at having their standards fail.) Even so, we did consider not doing it, but there was enough interest from some countries that we felt that there was quite a bit of risk that the standard would fail if we didn't add this support. To summarize: the decision to add Unicode identifiers was political, not technical. Complaining about it on technical factors has about as much relevance as trying to decide a major national issue on merits (say health-care in the US) -- the technical factors are virtually irrelevant. Randy. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-27 22:23 ` Randy Brukardt @ 2007-07-28 18:56 ` Maciej Sobczak 2007-07-29 7:54 ` Maciej Sobczak 1 sibling, 0 replies; 26+ messages in thread From: Maciej Sobczak @ 2007-07-28 18:56 UTC (permalink / raw) On 28 Lip, 00:23, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > However, the requirement for this support came down from above; essentially, > if we wanted Ada to continue to be an ISO standard, we needed to add this > sort of support. (New standards for other languages also will have to add > this sort of support, or take their chances at having their standards fail.) > Even so, we did consider not doing it, but there was enough interest from > some countries that we felt that there was quite a bit of risk that the > standard would fail if we didn't add this support. This is a very interesting twist in this discussion. I wonder how will the next standardization iteration go for C++ - this is supposed to happen in the coming few years and no support for Unicode in the source representation was ever considered. Interesting, interesting... -- Maciej Sobczak http://www.msobczak.com/ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-27 22:23 ` Randy Brukardt 2007-07-28 18:56 ` Maciej Sobczak @ 2007-07-29 7:54 ` Maciej Sobczak 2007-07-29 8:53 ` Dmitry A. Kazakov 2007-07-29 10:53 ` Georg Bauhaus 1 sibling, 2 replies; 26+ messages in thread From: Maciej Sobczak @ 2007-07-29 7:54 UTC (permalink / raw) On 28 Lip, 00:23, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > (New standards for other languages also will have to add > this sort of support, or take their chances at having their standards fail.) When I think about it more, I cannot even believe it might be true. Consider... C. It has the ISO standard and surely will be revised. One of the things that are taken for granted in the whole industry is the fact that C names are immediately "extern" without any further tweaking. Thanks to this you can write pragma Import (C, Puts, "puts"); and gain access to the standard puts function in C. Or any other. *Every* programming language that is even remotely useful uses this fact and relies on it. Now imagine that C introduces support for Unicode in names. In order to reuse the whole existing infrastructure of binary utilities (the tradition that is hard to drop) it would be necessary to introduce name mangling that will translate Unicode identifiers into something a typical linker can understand. But that will not be standardized, leading to complete mess. The alternative would be to require that the whole world starts to understand Unicode in symbol names for linking and import/export. The implications for the industry would be disastrous. My humble opinion: there will be no Unicode allowed for C identifiers and the binary symbol names will stay Latin1 (or even a subset of it) till the end of the world as we know it. This means that ISO cannot have any reasonable mandate to enforce Unicode support on other languages without the risk of undermining its credibility by being inconsistent. Am I missing something? -- Maciej Sobczak http://www.msobczak.com/ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-29 7:54 ` Maciej Sobczak @ 2007-07-29 8:53 ` Dmitry A. Kazakov 2007-07-29 10:53 ` Georg Bauhaus 1 sibling, 0 replies; 26+ messages in thread From: Dmitry A. Kazakov @ 2007-07-29 8:53 UTC (permalink / raw) On Sun, 29 Jul 2007 00:54:34 -0700, Maciej Sobczak wrote: > On 28 Lip, 00:23, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > >> (New standards for other languages also will have to add >> this sort of support, or take their chances at having their standards fail.) > > When I think about it more, I cannot even believe it might be true. > Consider... C. It has the ISO standard and surely will be revised. > > One of the things that are taken for granted in the whole industry is > the fact that C names are immediately "extern" without any further > tweaking. Thanks to this you can write > > pragma Import (C, Puts, "puts"); > > and gain access to the standard puts function in C. Or any other. > *Every* programming language that is even remotely useful uses this > fact and relies on it. > > Now imagine that C introduces support for Unicode in names. In order > to reuse the whole existing infrastructure of binary utilities (the > tradition that is hard to drop) it would be necessary to introduce > name mangling that will translate Unicode identifiers into something a > typical linker can understand. But that will not be standardized, > leading to complete mess. The alternative would be to require that the > whole world starts to understand Unicode in symbol names for linking > and import/export. The implications for the industry would be > disastrous. > > My humble opinion: there will be no Unicode allowed for C identifiers > and the binary symbol names will stay Latin1 (or even a subset of it) > till the end of the world as we know it. This means that ISO cannot > have any reasonable mandate to enforce Unicode support on other > languages without the risk of undermining its credibility by being > inconsistent. > > Am I missing something? Hmm, AFAIK both C and C++ always mangled external names: "_puts" not "puts" in C. "??00puts@t346�$____�&G_Fsdf..." in C++. Usability is nobody's care, anyway. Just try to link Borland C++ to a MSVC import library, you'll see. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-29 7:54 ` Maciej Sobczak 2007-07-29 8:53 ` Dmitry A. Kazakov @ 2007-07-29 10:53 ` Georg Bauhaus 1 sibling, 0 replies; 26+ messages in thread From: Georg Bauhaus @ 2007-07-29 10:53 UTC (permalink / raw) On Sun, 2007-07-29 at 00:54 -0700, Maciej Sobczak wrote: > On 28 Lip, 00:23, "Randy Brukardt" <ra...@rrsoftware.com> wrote: > > > (New standards for other languages also will have to add > > this sort of support, or take their chances at having their standards fail.) > > When I think about it more, I cannot even believe it might be true. > Consider... C. It has the ISO standard and surely will be revised. > > One of the things that are taken for granted in the whole industry is > the fact that C names are immediately "extern" without any further > tweaking. Thanks to this you can write > > pragma Import (C, Puts, "puts"); > > and gain access to the standard puts function in C. This does right now depend on the combination of tools, unfortunately. However, names across languages are being considered in new language revisions and are aware of Unicode (or ISO 10646). > Now imagine that C introduces support for Unicode in names. No need to imagine things, as Unicode inclusion has already happened. There are also C compilers and C++ compilers documenting how to use Unicode identifiers, and their users report sucess (I think a D compiler with Unicode support is available, too). "WG14/N1124 Committee Draft — May 6, 2005 ISO/IEC 9899:TC2 "6.4.2 Identifiers "3 Each universal character name in an identifier shall designate a character whose encoding in ISO/IEC 10646 falls into one of the ranges specified in annex D. [60] "[60] On systems in which linkers cannot accept extended characters, an encoding of the universal character name may be used in forming valid external identifiers. For example, some otherwise unused character or sequence of characters may be used to encode the \u in a universal character name. Extended characters may produce a long external identifier. "Annex D (normative) Universal character names for identifiers 1 This clause lists the hexadecimal code values that are valid in universal character names in identifiers." Roughly the same wording is found for C++ in http://www.open-std.org/jtc1/sc22/open/n2356/ Annex E > Am I missing something? I think yes. Unicode identifiers are already allowed, though not by every compiler. Linker tools are standardizing on mangling rules. The rules are more programmer friendy in that they can use names that many systems can use, for example UTF-8 names (UTF-8 has been around in final form since 1992, see the interesting remarks by Rob Pike in http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt ) Character set representations have been differing around the globe and within one country and between machines. This isn't surprising when there are competing computers, and languages that are different between nations (thinking of EBCDIC, Sun SPARC, embedded and mobile computers in Japan, Korea, 香港 (Hong Kong) ...). ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 9:53 ` Dmitry A. Kazakov 2007-07-26 11:01 ` Georg Bauhaus @ 2007-07-26 16:58 ` Adam Beneschan 2007-07-29 11:38 ` Manuel Gomez 2 siblings, 0 replies; 26+ messages in thread From: Adam Beneschan @ 2007-07-26 16:58 UTC (permalink / raw) On Jul 26, 2:53 am, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > On Thu, 26 Jul 2007 10:40:43 +0200, Georg Bauhaus wrote: > > Why is being case-insensitive and allowing full Unicode > > in identifiers schizophrenic? > > Because the concept of "case" does not apply to all scripts. I presume that > hieroglyphic scripts might possess quite outlandish ideas about arts of > glyphs composition and the equivalence of the results obtained. I agree, that's an area where C++ beats Ada. Ada programmers who wish to use hieroglyphics in identifiers could run into trouble figuring out where case-equivalence applies, while C++ programs tend to look like hieroglyphics anyway so there would be a lot less adjustment. -- Adam ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 9:53 ` Dmitry A. Kazakov 2007-07-26 11:01 ` Georg Bauhaus 2007-07-26 16:58 ` Adam Beneschan @ 2007-07-29 11:38 ` Manuel Gomez 2 siblings, 0 replies; 26+ messages in thread From: Manuel Gomez @ 2007-07-29 11:38 UTC (permalink / raw) On 26 jul, 11:53, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de> wrote: > I'm curios, if GNAT will support sources in Zapfino (:-)) > > http://en.wikipedia.org/wiki/Zapfino > Zapfino seems a complicated typeface with glyphs depending on context, but it doesn't use a particular encoding, as far as I have read. So GNAT is not involved in whether you select Zapfino for display, but our spartan programming editors will probably reject this font, at least if you don't use Mac OS X. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-26 6:44 ` Maciej Sobczak 2007-07-26 8:40 ` Georg Bauhaus @ 2007-07-27 10:16 ` Jeffrey R. Carter 2007-07-27 12:47 ` Maciej Sobczak 1 sibling, 1 reply; 26+ messages in thread From: Jeffrey R. Carter @ 2007-07-27 10:16 UTC (permalink / raw) Maciej Sobczak wrote: > On 26 Lip, 02:51, "Jeffrey R. Carter" > <spam.jrcarter....@acm.nospam.org> wrote: > >> I would think that an enumeration type would be better than Integer for >> selecting among a few choices. Using Integer probably reflects C/++ >> thinking. > > No. C and C++ have enumerations. Which are just names for integer values, last time I looked. The type of a function parameter would be int. And even if that's not the case, experienced users are accustomed to doing it this way from the days before it had them. And even newer users are accustomed to seeing it done this way in the code they've been exposed to. And even if that's not the case, C/++, emphasizing ease of writing over ease of reading, induces a mindset in the user of "why bother typing this enumeration definition and using it when I can just say int?" All of these are symptoms of "C/++ thinking". -- Jeff Carter "Beyond 100,000 lines of code you should probably be coding in Ada." P. J. Plauger 26 ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-27 10:16 ` Jeffrey R. Carter @ 2007-07-27 12:47 ` Maciej Sobczak 2007-08-26 7:18 ` David Thompson 0 siblings, 1 reply; 26+ messages in thread From: Maciej Sobczak @ 2007-07-27 12:47 UTC (permalink / raw) On 27 Lip, 12:16, "Jeffrey R. Carter" <spam.jrcarter....@acm.nospam.org> wrote: > > No. C and C++ have enumerations. > > Which are just names for integer values, last time I looked. No. There are implicit conversions to int, but enums are separate types. > The type of > a function parameter would be int. No. Each enum is a separate type: #include <iostream> enum E1 {a, b, c}; enum E2 {x, y, z}; void foo(E1 e) { std::cout << ": foo(E1)\n"; } void foo(E2 e) { std::cout << ": foo(E2)\n"; } void foo(int e) { std::cout << ": foo(int)\n"; } int main() { std::cout << static_cast<int>(a); foo(a); std::cout << static_cast<int>(x); foo(x); int i = 0; std::cout << i; foo(i); } This program prints: 0: foo(E1) 0: foo(E2) 0: foo(int) which means that even though a and x have the same value when converted to int, they are distinct from int and between each other and can be properly picked by separately overloaded functions. > And even if that's not the case, > experienced users are accustomed to doing it this way from the days > before it had them. I consider myself to be an experienced user of C++ and I don't seem to remember it working the way you describe. I'm not a dinosaur though, so I might have missed a thing or two as well... > And even newer users are accustomed to seeing it > done this way in the code they've been exposed to. >From what you write it appears that you have been looking at C++ quite a while ago - in which case I wonder where you get the knowledge of what newer users are exposed to. > And even if that's > not the case, C/++, emphasizing ease of writing over ease of reading, > induces a mindset in the user of "why bother typing this enumeration > definition and using it when I can just say int?" I agree with this. C++ allows the programmer to be explicit about many things, but does not require it. Many programmers, especially those that have been exposed to poorly written C (this is unfortunately unavoidable) or some scripting languages of the Perl league are tempted to reduce the dictionary of their designs and end up with numbers everywhere. In most cases not even named. > All of these are > symptoms of "C/++ thinking". These are symptoms of hacking. Note that we are discussing it not in the context of C++, but in the context of some Ada program that was shown few posts earlier - this shows that hacking is possible in every language and since there are about 2500 of them, there is no reason to distinguish any single one of them as the supposed originator. C++ is not even old enough to be the source of such practices. It just allows them. Like Ada (which is actually older and allowed such bad practices earlier ;-) ). -- Maciej Sobczak http://www.msobczak.com/ ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: Factory Pattern 2007-07-27 12:47 ` Maciej Sobczak @ 2007-08-26 7:18 ` David Thompson 0 siblings, 0 replies; 26+ messages in thread From: David Thompson @ 2007-08-26 7:18 UTC (permalink / raw) On Fri, 27 Jul 2007 05:47:34 -0700, Maciej Sobczak <see.my.homepage@gmail.com> wrote: > On 27 Lip, 12:16, "Jeffrey R. Carter" > <spam.jrcarter....@acm.nospam.org> wrote: > > > > No. C and C++ have enumerations. > > > > Which are just names for integer values, last time I looked. > > No. There are implicit conversions to int, but enums are separate > types. > > > The type of > > a function parameter would be int. > > No. Each enum is a separate type: > <snip rest> Actually this is an area of difference between C and C++, and as such called out in Annex C of the C++ standard. In C enum values are just 'int' values, and enum types are just aliases for integer types -- commonly just one integer type, 'int', although the C standard did and does allow each enum type to be any integer type that covers the specified range. You can directly assign (or pass or return) to an enum from an integer or different enum type. In C++, each enum type is a distinct type, and its values are of its type; as you go on to detail, they can disambiguate overloads, and also an enum can be silently converted to integer (int or possibly long, since C++ unlike C allows enum values outside the range of int), but not to another enum or from integer to enum without a cast or in some (stronger) contexts a user-defined conversion operator. - formerly david.thompson1 || achar(64) || worldnet.att.net ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2007-08-26 7:18 UTC | newest] Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-07-25 18:19 Factory Pattern shaunpatterson 2007-07-25 18:28 ` Martin 2007-07-25 18:51 ` Dmitry A. Kazakov 2007-07-25 21:06 ` Georg Bauhaus 2007-07-25 19:27 ` Matthew Heaney 2007-07-26 0:51 ` Jeffrey R. Carter 2007-07-26 6:44 ` Maciej Sobczak 2007-07-26 8:40 ` Georg Bauhaus 2007-07-26 9:53 ` Dmitry A. Kazakov 2007-07-26 11:01 ` Georg Bauhaus 2007-07-26 13:02 ` Maciej Sobczak 2007-07-26 13:44 ` Dmitry A. Kazakov 2007-07-26 14:58 ` Georg Bauhaus 2007-07-26 22:31 ` Randy Brukardt 2007-07-27 13:07 ` Maciej Sobczak 2007-07-27 14:23 ` shaunpatterson 2007-07-27 22:23 ` Randy Brukardt 2007-07-28 18:56 ` Maciej Sobczak 2007-07-29 7:54 ` Maciej Sobczak 2007-07-29 8:53 ` Dmitry A. Kazakov 2007-07-29 10:53 ` Georg Bauhaus 2007-07-26 16:58 ` Adam Beneschan 2007-07-29 11:38 ` Manuel Gomez 2007-07-27 10:16 ` Jeffrey R. Carter 2007-07-27 12:47 ` Maciej Sobczak 2007-08-26 7:18 ` David Thompson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox