From: Panu Viljamaa <panu@way.com_nospams> Newsgroups: comp.lang.smalltalk,comp.lang.smalltalk.dolphin,comp.object,comp.software.extreme-programming Subject: [ANN] SRNC-ST 3.2: Generic Types Date: Mon, 26 Feb 2001 02:02:44 -0500 The latest version 3.2 of SRNC-ST (Signature Revealing Naming Convention - Smalltalk) is available at http://members.fcc.net/panu/SRNC-ST.htm. V. 3.2 adds the major new feature of Generic Types to SRNC-ST, in a simple way, without having to extend Smalltalk syntax (see below). Generic Types are a solution to the question: "How do I reuse a collection interface with different element types?". More generally it is applicable anywhere where one type serves as a parameter to another. From the release notes: " ... V. 3.2: Generic Types To define an interface such as Dictionary, you must define signatures for methods such as #at: and #at:put:. In general these methods have arbitrary Objects as arguments and return values. But what if your program depends on knowing that more specific types of objects are stored in a dictionary ? What if you want to constrain the key to be a String, and the value an Integer for instance ? In SRNC you can naturally create a subclass of Dictionary specifying such a narrower interface. But does this mean you have to rewrite all of the inherited methods that use these types as their interface ? No, if you create a 'Generic Type' according to Rule 5 of SRNC-ST. You define: Dictionary >> at: aKey put: aValue ... Dictionary class >> Key ^anObject ... Dictionary class >> Value ^anObject For a subclass (sub-interface) of Dictionary called 'StringToIntMap' you would add the following overrides: StringToIntMap class >> Key ^aString StringToIntMap class >> Value ^anInteger The method whose return type specifies the meaning of a TSV (Type Specifying Variable) is called a 'Type Realizer' (TR). Why are type realizers *class* methods ? Because if they were on the instance side, adding a TR would artificially extend the interface of the class using it. Doing the above example would require that every Dictionary implements the methods #Key and #Value, even though there is little value from them at runtime. By putting the TRs on the class-side we keep them clearly separate from 'real' methods, because they really exist for a different purpose, and keeping them together makes it easy to understand the generic aspects of your type specifications. Rule 5 allows us to specify the properties of a composite type in a single location, with only few method redefinitions. The information about the element type is specified "once and only once". Contrast this to an alternative scheme that somehow defined an explicit syntax for composite types, like 'aDictionary([String], [Integer])'. If you use this in 100 places you need to type in 100 x 32 = 3200 characters. If instead you define the generic type'StringToIntMap' you need 100 x 14 = 1400 characters, plus the few TR methods needed to define the element types. Note also that while it's easy to propose a format like 'aDictionary([String], [Integer])', it is not easy to define what this exactly would mean in terms of individual method signatures. .... " Feedbacks welcome. Thanks Panu Viljamaa