Annoying naming clashes
Hi, when writing haskell code. It is so annoying that name clashes keep happening. I have to be careful about the data constructor names, about the class names, about the class member names. I understand that we can use class to achieve some overloading effect. However, it does not help with data constructors. And, what's more important, it looks like Haskell does not allow two classes sharing methods of the same name. And that is something I deemed the most annoying. No matter how powerful type class is compared to Java interfaces, the naming problem just makes it so inconvinient. I'm a programmer who can be so easily affected by ethetics of the program. And when I have to keep worrying about "should I use this name? it may have been used in a similar class", the precious peace in mind is gone. As a novice haskell programmer, I might be missing something here though. If somebody can kindly give me some instruction of how to work with names, appreicate it a lot! Ben. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately.
Ben.Yu@combined.com wrote:
Hi, when writing haskell code. It is so annoying that name clashes keep happening.
I have to be careful about the data constructor names, about the class names, about the class member names.
[...]
As a novice haskell programmer, I might be missing something here though. If somebody can kindly give me some instruction of how to work with names, appreicate it a lot!
Hi. Try using small modules and qualified names. module Illumination where data Illumination = Dark | Light module Weight where data Weight = Heavy | Light module UseBoth where import Illumination import Weight easyToCarry = (Illumination.Light, Weight.Light) Regards, Tom
Tom, Then what will you do when naming operations in a class? Is it right that care has to be taken in order not to conflict with other classes? Say, I have a Person class where I want to define an operation "getName". Is it wise to name it "getPersonName" instead? I notice that FiniteMap always names operations and functions xxxFM, although that looks ugly to me. Is that a general good thing to do when naming operations? Ben. Tom Pledger <tpledger@ihug.co To: Ben.Yu@combined.com .nz> cc: haskell@haskell.org Sent by: Subject: Re: [Haskell] Annoying naming clashes haskell-bounces@h askell.org 06/11/2004 09:27 PM Ben.Yu@combined.com wrote:
Hi, when writing haskell code. It is so annoying that name clashes keep happening.
I have to be careful about the data constructor names, about the class names, about the class member names.
[...]
As a novice haskell programmer, I might be missing something here though. If somebody can kindly give me some instruction of how to work with names, appreicate it a lot!
Hi. Try using small modules and qualified names. module Illumination where data Illumination = Dark | Light module Weight where data Weight = Heavy | Light module UseBoth where import Illumination import Weight easyToCarry = (Illumination.Light, Weight.Light) Regards, Tom _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately.
Ben.Yu@combined.com wrote:
Tom, Then what will you do when naming operations in a class? Is it right that care has to be taken in order not to conflict with other classes?
Say, I have a Person class where I want to define an operation "getName". Is it wise to name it "getPersonName" instead?
Class method names support the small-modules-and-qualified-names approach too. module C1 where class C1 a where c :: Int -> a module C2 where class C2 a where c :: Int -> a module UseBoth where import C1 import C2 f i = (C1.c i, C2.c i) This can cause trouble if you use C1 extensively without C2, and *then* import C2: you'd have to change a lot of unqualified c to C1.c. But when you're using C1 in the first place, you can guess whether you should write C1.c in anticipation of clashes.
I notice that FiniteMap always names operations and functions xxxFM, although that looks ugly to me. Is that a general good thing to do when naming operations?
It's not my preferred approach, but opinions vary. Regards, Tom
On 12/06/2004, at 9:52 AM, Ben.Yu@combined.com wrote:
Hi, when writing haskell code. It is so annoying that name clashes keep happening.
I have to be careful about the data constructor names, about the class names, about the class member names.
I understand that we can use class to achieve some overloading effect. However, it does not help with data constructors. And, what's more important, it looks like Haskell does not allow two classes sharing methods of the same name.
The standard response to this is "use the module system to help you". Don't export your data constructors because you then expose the internals of your module, which is bad for abstraction; export function names which serve as the data constructors instead. Use qualified module names. e.g. in the case of the Data.FiniteMap module, it has function names such as "emptyFM", "unitFM", "addToFM", etc. Don't do this, instead call those functions "empty", "unit", "add", and then a user of a module can use the module by using qualified module names: module MyModule where import Data.FiniteMap as FM foo = FM.add key elt FM.empty You can 'wrap' the current Data.FiniteMap module with your own MyFiniteMap module to achieve this affect. I think this is a far from ideal solution, but it's adequate. Google for "per-type function namespaces", which was an idea I sent to the list a few months ago, for something which I think better solves the naming issue. Quite a lot of people disagreed with it, but I still think it's a good idea. (FWIW, I nearly managed to implement this with Template Haskell, but I couldn't work around the restriction that you couldn't splice in a TH function declared in the same module.) -- % Andre Pang : trust.in.love.to.save
Another problem is that people learning haskell, especially those coming from a OO background or language like java, tend to write code that needlessly exasperates the naming conflict problem. I think this is because of the initial steps one usually takes in other languages, the first thing one types when writing java or other OO languages tends to be something like 1. define the data structures you think you will need or 2. define the class/interface your data structures will have (which tend to be confabulated together in OO languages) however, neither of these is a very good way to start a haskell program, for example, a novice programmer when presented with writing a simple interpreter might write out (somewhat contrived)
data Exp = Val Int | Plus Exp Exp | ...
readExp = readInt <|> readPlus readInt = x <- do readInt ; return (Val x) readPlus = x <- do readExp; readPlus; y <- readExp ; return (Plus x y)
interpretExp (Val x) = x interpretExp (Plus x y) = (interpretExp x) + (interpretExp y)
however an experienced haskell programmer might realize the data structure is not needed and just write
readInterpretExp = readInterpretInt <|> readInterpretPlus readInt = do x <- readInt ; return x readPlus = do x <- readExp; readPlus; y <- readExp ; return ( x + y)
by getting rid of these needless intermediate data structures (something you learn to do intuitivly as you use haskell), one reduces the chances for naming conflicts. now classes are a bit trickier, the main thing is that classes in haskell are not like classes in other languages. A class in haskell is nothing more than a construct allowing you to reuse the same syntax on different types. (to hopefully do similar things) Very few actual applications require you to write a class. It is not that writing a class is particularly difficult or they are complicated, it is just that they are usually not needed unless you are specifically writing a reusable library. The key thing to remember when starting a haskell program is to NOT write your classes first. just write your program and if you notice that you are performing similar operations to different types, only then consider adding a class after the fact. classes should be used to clean up and refactor existing code, not as a basic building block like in OO languages.. Haskell is very malliable, it is a lot easier to observe how your algorithms are being used than to predict how beforehand. Hope this helps, of course, this is not generally applicable to all haskell programmers, it is just an observation of how I see new users of the language try to use it and perhaps get frustrated. John now, if anyone has some insight as to what the first thing you type should be when writing haskell code.. :) Perhaps haskells concisity obviates the need for these 'easy choices'. if it were trivial to know how to start a program then one might say the language is deficient for forcing you to make the easy decision anyway... but now I am rambling... -- John Meacham - ⑆repetae.net⑆john⑈
[snip: parser and interpreter for a little expression language]
however an experienced haskell programmer might realize the data structure is not needed and just write
[snip: combined parser/interpreter for same language]
by getting rid of these needless intermediate data structures (something you learn to do intuitivly as you use haskell), one reduces the chances for naming conflicts.
I don't think I agree with that at all. John Hughes' "Why Functional Programming Matters" makes it very clear how much power you gain from adding intermediate data structures. I personally find them extremely valuable in compilers and interpreters because they help me separate the concrete syntax from the abstract syntax. Further, if the language were to evolve a little, having a separate data structure would make it possible to add typechecking or other static semantics. [I avoid name clashes using a combination of smallish modules, qualified naming and ad hoc use of prefixes and deliberate mis-spellings. The situation in Haskell isn't especially happy.] -- Alastair Reid
On Tue, Jun 15, 2004 at 07:35:44AM +0100, Alastair Reid wrote:
I don't think I agree with that at all.
John Hughes' "Why Functional Programming Matters" makes it very clear how much power you gain from adding intermediate data structures.
I personally find them extremely valuable in compilers and interpreters because they help me separate the concrete syntax from the abstract syntax. Further, if the language were to evolve a little, having a separate data structure would make it possible to add typechecking or other static semantics.
[I avoid name clashes using a combination of smallish modules, qualified naming and ad hoc use of prefixes and deliberate mis-spellings. The situation in Haskell isn't especially happy.]
Oh, I didn't mean to say intermediate data structures are bad, or that they should be avoided, they are quite useful and a fundamental technique of haskell programming. I just meant that people coming from different backgrounds tend not to know how or even realize that they can elide them when they are not important, which leads to a perception that the naming problem is far worse than it actually is. When you are creating the intermediate data structure for a reason, you tend to come up with good unique names anyway that deal with the algorithm or technique you are trying to express so it is less of an issue. In fact, I find this to be a useful measure when programming, if I really can't think of an appropriate name for a function or data constructor, then perhaps I should rethink why I think I need it in the first place. It is the purely intermediate data structures that have no real operations on them because they need not exist that are hard to name and lead to naming conflicts. It is these structures that haskell programers learn are not needed as their skills improve. but yeah, I love intermediate structures as much as the next haskell programmer :) John -- John Meacham - ⑆repetae.net⑆john⑈
John Meacham wrote:
1. define the data structures you think you will need or 2. define the class/interface your data structures will have
if you want to take the "prototyping" route, then indeed do 1. first and then 2., but of course first 2. then 1. gives better code right from the start. I mean, you don't write a sort function for strings, another for doubles etc. only to discover later that you should use the Ord interface (erm, class). OTOH, if you do the complete sequence 1+2+1 then you can call it "refactoring" in order to be buzzword compliant.
however an experienced haskell programmer might realize the data structure is not needed and just write
as has been said already, the programmer should indeed *use* such structures, and it's the job of the *compiler* to figure out where and how they could be removed. as Eric Raymond puts it, "Smart data structures and dumb code works a lot better than the other way around." http://www.catb.org/~esr/writings/cathedral-bazaar/cathedral-bazaar/ar01s06.... best regards, -- -- Johannes Waldmann, Tel/Fax: (0341) 3076 6479 / 6480 -- ------ http://www.imn.htwk-leipzig.de/~waldmann/ ---------
Am Dienstag, 15. Juni 2004 04:05 schrieb John Meacham:
[...]
now classes are a bit trickier, the main thing is that classes in haskell are not like classes in other languages. A class in haskell is nothing more than a construct allowing you to reuse the same syntax on different types. (to hopefully do similar things)
Classes are not only for reusing the same syntax but also for polymorphism. For example, the Num class doesn't exist solely for the purpose that I can use the + operator with different types. It's also for the purpose that one can, for example, define a function which sums up the elements of a list where the element type isn't restricted to one specific numeric type. I'd say, classes in Haskell are similar to interfaces in Java.
[...]
Wolfgang
On Tue, Jun 15, 2004 at 11:30:24AM +0200, Wolfgang Jeltsch wrote:
Am Dienstag, 15. Juni 2004 04:05 schrieb John Meacham:
[...]
now classes are a bit trickier, the main thing is that classes in haskell are not like classes in other languages. A class in haskell is nothing more than a construct allowing you to reuse the same syntax on different types. (to hopefully do similar things)
Classes are not only for reusing the same syntax but also for polymorphism. For example, the Num class doesn't exist solely for the purpose that I can use the + operator with different types. It's also for the purpose that one can, for example, define a function which sums up the elements of a list where the element type isn't restricted to one specific numeric type.
yes, and that summing function is a piece of reusable syntax. Whether something is a class member or built on class members is nicely abstracted away in haskell. (at least for those not creating new instances). Yeah, polymorphism is the right term, but not always the best one when trying to explain basic haskell to my impertive minded friends. I find trying to draw analogies between haskell classes and constructs in other languages to be problematic as people then try to apply knowledge from other fields incorrectly to haskell unless you give a full explanation of haskell classes anyway.. but YMMV. John -- John Meacham - ⑆repetae.net⑆john⑈
John Meacham wrote:
[...]
I find trying to draw analogies between haskell classes and constructs in other languages to be problematic as people then try to apply knowledge from other fields incorrectly to haskell unless you give a full explanation of haskell classes anyway.. but YMMV. John
In the particular case of Haskell classes and Java interfaces, I like the analogy *provided that* the Haskell class in question doesn't have a method with two occurrences of the class variable in parameter positions. For example, class Set s where empty :: (a -> a -> Ordering) -> s a insert :: s a -> a -> s a member :: s a -> a -> Bool fits nicely (until you add a union method), but Eq does not. The classes which fit the Java interface analogy are also the classes which can be rendered as explicit dictionaries instead: module Set where data Set a = Set {insert :: a -> Set a, member :: a -> Bool} module RedBlack(empty) where import Set empty :: (a -> a -> Ordering) -> Set a empty cmp = ... Importantly (IMHO), if you use an explicit dictionary instead of a class, the 'heterogeneous list of class instances' problem goes away. Regards, Tom
At 11:30 15/06/04 +0200, Wolfgang Jeltsch wrote:
I'd say, classes in Haskell are similar to interfaces in Java.
I started my Haskell programming with that viewpoint, but got tripped up by it. A Java interface can be used as a type in its own right, but a Haskell class cannot. For example, you can't have a list of Eq's, only a list of some type that happens to be an Eq. The different list members can't be differently-typed instances of Eq. To emulate a Java interface, I have ended up creating algebraic data types whose components are functions. (I don't claim that's a good approach to Haskell programming, just what I ended up doing.) #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact
On Tue, 15 Jun 2004 12:05:46 +0100, Graham Klyne <GK@ninebynine.org> wrote:
At 11:30 15/06/04 +0200, Wolfgang Jeltsch wrote:
I'd say, classes in Haskell are similar to interfaces in Java.
I started my Haskell programming with that viewpoint, but got tripped up by it.
A Java interface can be used as a type in its own right, but a Haskell class cannot. For example, you can't have a list of Eq's, only a list of some type that happens to be an Eq. The different list members can't be differently-typed instances of Eq. Well, just with existential types.
To emulate a Java interface, I have ended up creating algebraic data types whose components are functions. (I don't claim that's a good approach to Haskell programming, just what I ended up doing.)
My approach was to create an existential types for each class and instanciate it from the class like: class FooClass f where bar :: f -> Integer setBar :: Integer -> f -> f data Foo = forall f . FooClass f => Foo f instance FooClass Foo where bar (Foo f) = bar f setBar b (Foo f) = Foo $ setBar b f I am not sure if this is the way to go, but at least it works (except for read issues). The advantage I see in this approach is that I can stick all types that are instanciated from FooClass in a list and can deal with them as there would be no exitential type constructor "in the way". Cheers, Georg
Don't export your data constructors because you then expose the internals of your module, which is bad for abstraction; export function names which serve as the data constructors instead.
Actually this is another thing that I'm wondering about. it is nice to use 'maybe', 'either' functions. However, with data types with more than 2 constructors, using such function tends to be tedious than pattern match, where, you can pick specific constructors of interest. And in order to use pattern match, I have to expose my constructors. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately.
In message <OFF88B2A02.2232ECC3-ON86256EB4.0054E974-86256EB4.00559618@combined. com>, Ben.Yu@combined.com writes:
it is nice to use 'maybe', 'either' functions. However, with data types with more than 2 constructors, using such function tends to be tedious than pattern match, where, you can pick specific constructors of interest.
And in order to use pattern match, I have to expose my constructors.
You don't necessarily need to expose the constructors even in that case. Often you can expose functions that return 'Maybe a' for some suitably chosen 'a' instead of the constructor itself. Then you can pattern match with e.g. the following syntax: f x | Just(y) <- matchZ x = y + 1 And the Maybe monad works beautifully for combining such functions into larger pattern matchers. The point with having abstraction is to actually expose only higher level operations. Of course, this doesn't negate any other reasons you might have for exposing the constructors [e.g. if the data type is used to represent an interface], but if you want to build abstract data types, those should be at higher level of abstraction than the concrete types. -- Esa Pulkkinen
Ben, BY> it is nice to use 'maybe', 'either' functions. However, with BY> data types with more than 2 constructors, using such function BY> tends to be tedious than pattern match, where, you can pick BY> specific constructors of interest. BY> And in order to use pattern match, I have to expose my BY> constructors. Well, you've just identified the well-known trade-off between abstraction and induction. A language extension involving 'views' [4, 1, 3] has been proposed [2] to deal with this issue. Regards, Stefan [1] Warren Burton and Robert Cameron. Pattern matching with abstract data types. Journal of Functional Programming, 3(2):171-190, 1993. http://citeseer.ist.psu.edu/context/176591/0/ [2] Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson, and Philip Wadler. Views: An extension to Haskell pattern matching, 1996. http://www.haskell.org/development/views.html [3] Chris Okasaki. Views for Standard ML, 1998. 1998 ACM SIGPLAN Workshop on ML. http://citeseer.ist.psu.edu/okasaki98views.html [4] Philip Wadler. Views: A way for pattern matching to cohabit with data abstraction. In Steve Munchnik, editor, Proceedings of the 14th Symposium on Principles of Programming Languages, pages 307-312. Association for Computing Machinery, 1987. http://citeseer.ist.psu.edu/wadler87views.html
Stefan Holdermans writes:
Well, you've just identified the well-known trade-off between abstraction and induction. A language extension involving 'views' [4, 1, 3] has been proposed [2] to deal with this issue.
That proposal for views is eight years old. Has there been any movement towards implementing it? Did some technical obsticle arise, or have people simply been busy elsewhere?
[2] Warren Burton, Erik Meijer, Patrick Sansom, Simon Thompson, and Philip Wadler. Views: An extension to Haskell pattern matching, 1996. http://www.haskell.org/development/views.html -- David Menendez <zednenem@psualum.com> <http://www.eyrie.org/~zednenem/>
On Thu, Jun 17, 2004 at 06:03:31PM -0400, David Menendez wrote:
Stefan Holdermans writes:
Well, you've just identified the well-known trade-off between abstraction and induction. A language extension involving 'views' [4, 1, 3] has been proposed [2] to deal with this issue.
That proposal for views is eight years old. Has there been any movement towards implementing it? Did some technical obsticle arise, or have people simply been busy elsewhere?
I think it was a couple things, Pattern guards were introduced which were conceptually a whole lot simpler and provided a way to do many of the things views did. http://research.microsoft.com/~simonpj/Haskell/guards.html The other thing is that it is unclear whether they are a good idea, I mean, they would probably be useful to some, but as extensions go, they would be a pretty radical change to the language. Many consider the simplicity and consistancy of pattern matching a virtue. Also, the views proposal is 8 years old, I don't know if anyone has thought much about how they would interact with all the other generally accepted language extensions that have happened in the meantime. I think the moral is, don't hold your breath. and learn pattern guards, they are a really really useful and universal extension to the language. John -- John Meacham - ⑆repetae.net⑆john⑈
On Thu, Jun 17, 2004 at 11:55:56PM +0100, Alastair Reid wrote:
[...] learn pattern guards, they are a really really useful and universal extension to the language.
Universal?
Ah, universally implemented in GHC!
really? for some reason I thought they were in nhc and hugs. although, I must admit, I don't spend much time with these other compilers. in that case, consider this a feature request for all other haskell implementations to retroactivly make my statement true. John -- John Meacham - ⑆repetae.net⑆john⑈
At 15:33 17/06/04 -0700, John Meacham wrote:
I think it was a couple things, Pattern guards were introduced which were conceptually a whole lot simpler and provided a way to do many of the things views did. http://research.microsoft.com/~simonpj/Haskell/guards.html
I like that proposal. In response to: [[ Is this a storm in a teacup? Much huff and puff for a seldom-occurring situation? No! It happens to me ALL THE TIME. The Glasgow Haskell Compiler is absolutely littered with definitions like clunky. I would really welcome feedback on this proposal. Have you encountered situations in which pattern guards would be useful? Can you think of ways in which they might be harmful, or in which their semantics is non-obvious? Are there ways in which the proposal could be improved? And so on. ]] I'll say that in my programming, I would find that feature really useful. For example, in my work on Network.URI, I found I had to change the underlying data type. While I don't think this proposal would deal with the legacy problem, I do think it would make it easier to define an interface that better supports future changes. I notice some similar potential issues with the XML library I'm currently working on: the algebraic data types comprise a considerable part of the package interface, which is not always satisfactory. And a small thought: a current convenience with algebraic data types is the facility to export/import the constructors with (..) notation. I think it would be useful to extend this to accessor functions that are somehow bound to the ADT definition. Hmmm... would this make any sense?: [[ data URI = URI { uriScheme :: String , uriAuthority :: Maybe URIAuth , uriPath :: String , uriQuery :: String , uriFragment :: String } deriving Eq where scheme (URI {uriScheme=""}) = Nothing scheme (URI {uriScheme=a}) = Just a : etc. ]] The idea here being that functions declared in the 'where' block would be included in any export/import of URI(..). Then, also, some way to hide the individual field labels might also be useful to hide the internal structurte from that exposed. ... The other problem I've noticed with ADTs (which I think has been discussed before) is that field labels work like functions to access fields, but there's no corresponding mechanism for selective update using the same name. I could imagine something like: scheme :: a -> b -> (a,b) scheme a' u@(URI {uriScheme=a}) = (a,u {uriScheme=a'}) with auxiliaries: get :: (a -> b -> (a,b)) -> b -> a get f = fst . f undefined update :: (a -> b -> (a,b)) -> a -> b -> b update f a = snd . f a hence s = get scheme uri and uri' = update scheme s uri ... #g ------------ Graham Klyne For email: http://www.ninebynine.org/#Contact
Google for "per-type function namespaces", which was an idea I sent to the list a few months ago, for something which I think better solves the naming issue. Quite a lot of people disagreed with it, but I still think it's a good idea. (FWIW, I nearly managed to implement this with Template Haskell, but I couldn't work around the restriction that you couldn't splice in a TH function declared in the same module.)
Andrei, I just skimmed through the "per-type namespace" thread. I'd say besides the ability to do overloading with type classes, I do like what they called ad-hoc polymorphism. And that is by no means the type classes can support. By "ad-hoc", we mean we don't know who the heck will create a function with the same name with whatever parameters and in whatever modules, classes. If you create a type class to mean "well, this name may be used by different module for god-knows different things", that feels awkward. And theoretically, any name can be duplicated. Do we create a class for every function names we create? And there's naming problems for type class operations too. When you create classes, how do you name operations? If you name your operation happily as "get", how are you sure that somebody else will not want to use this name for his own functions or class operations? Actually, to me, it is the naming clash for class operations that bothers me the most. For the alternatives people present so far, I don't see any of them satisfactory. 1. Use small modules. Yes. I can use small modules. But I will somewhere need to use more than one modules. And it is very possible that two names from two modules that I import clash. Also, even not able to use the same name within one module is sometimes annoying too. Split this module into 2 sub modules? I suppose modules are designed for seperating natural modules, not for seperating duplicate names. Creating a module just to get some synonym out sounds quite ad-hoc design. OO languages, on the other hand, even within the same class/interface, we have overloadings, we can create nested classes that brings its own namespace. Very rarely do I need to worry about name clashes. I can name functions as nicely as I can come up with. 2. Use qualified name. Well. that is a systematic solution. But, if I know I'll have to almost always write MySomeModule.add, I probably would want to name it "addMSM" to make it short, as what FiniteMap is doing. I like the code example that Oleg presented in your thread, and I love the Haskell type system that can even support overloading by returns, very powerful indeed. However, they are parametric polymorphism, even though they can to some extent simulate ad-hoc polymorphism, I just don't see they are the right tool to support ad-hoc polymorphism. In summary, names may seem a cosmetic issue. What is the fundamental semantics and functionality differnce between "add" and "MyModule.add" anyway? Just a few keystrokes, right? However, IMHO, naming is the very fundamental cosmetic issue, as in most programming languages. Not being able to name things freely is a big problem in my eyes. This message is intended only for the addressee and may contain information that is confidential or privileged. Unauthorized use is strictly prohibited and may be unlawful. If you are not the intended recipient, or the person responsible for delivering to the intended recipient, you should not read, copy, disclose or otherwise use this message, except for the purpose of delivery to the addressee. If you have received this email in error, please delete and advise us immediately.
participants (12)
-
Alastair Reid -
André Pang -
Ben.Yu@combined.com -
David Menendez -
Esa Pulkkinen -
Georg Martius -
Graham Klyne -
Johannes Waldmann -
John Meacham -
Stefan Holdermans -
Tom Pledger -
Wolfgang Jeltsch