From: Mathieu Bouchard Date: 2005-05-30T03:59:16+09:00 Subject: Re: [ ruby-Patches-1939 ] Pathname, totally revamped ---1077017559-1213755736-1117391523=:29957 Content-Type: MULTIPART/MIXED; BOUNDARY="-1077017559-1213755736-1117391523=:29957" This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---1077017559-1213755736-1117391523=:29957 Content-Type: TEXT/PLAIN; CHARSET=ISO-8859-1; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE Content-ID: On Sun, 29 May 2005, Sam Roberts wrote: >> So, in short, Liskov's substitution principle can be written: >> (SubPre -> SubPost) -> (SuperPre -> SuperPost) >> Does that sound accurate? > Uhm, well, IMHO, thats so abstract its hard to know if its accurate, > maybe it could be argued both ways. :-) Well, if you skip understanding what it is, and instead start making=20 suppositions about what it might be, then it can be argued both ways. > If you have a program using an X, and Y is-a X, then you can use Y > instead of X and it will "work", for some definition of work... Is it mine which is more abstract, or is it yours? How is it less=20 abstract to not even say what the word "work" means, compared to defining= =20 it as I did? > you can use them in an API that expects a String, and it works, then > they are Liskov substituteable for a String. Yes, but that's not all there is to Liskov's principle. For example,=20 consider that Array is a subtype of Enumerable and a subtype of Object and= =20 also a subtype of whatever is the common portion of the String type and=20 Array type (e.g. both support #clear and #reverse, neither of which are in= =20 Object and Enumerable). All of those subtyping patterns can be applied to= =20 the practice of Ruby, and are being applied, so I think it is important to= =20 consider them in relation to Liskov Substitution / Duck Typing. > Pragmatically, its likely that any particular implementation may work in > some cases, but not in others... If it's a read-only file, any attempt > at doing a desctructive operation is going to fail, and code that > assumes that a String that is not frozen is modifiable will find that > this hypothetical file-as-String class is not Liskov substitutable for a > String. You may think about more types than what the class structure say there=20 are. Any property of an Object may be considered a type, as long as=20 someone thinks it's a useful way of looking at things. The IO type can be= =20 seen as a subtype of ReadableIO, WritableIO, SeekableIO, and others, or=20 any combination of some of them, despite those latter labels not being in= =20 use in the Ruby environment itself. You can also think of types on several levels, sometimes considering types= =20 that are "eternal" (e.g. a given object will always stay a String) or=20 types that are assumed "transient" (e.g. a file could be reopened=20 differently, or a string could get frozen, ...) > Design is still partially a matter of taste, not exact rules, isn't it? Please do make a distinction between prescriptive rules ("you should...")= =20 and descriptive rules ("we give the name Fooable to the an object that can= =20 be fooed with") I'm not telling how to design things. I'm just proposing a mental tool for= =20 thinking about substitution rules of the Liskov/Ducktype flavour. More formalism and logic is a way to give personal tastes a shape and a=20 skeleton and an awareness. It's not the purpose of formalism and logic to= =20 dictate how things should be: that is in the dictatorship department. ,-o--------o--------o--------o-. ,---. irc.freenode.net #dataflow | | The Diagram is the Program tm| | ,-o-------------o--------------o-. `-o------------o-------------o-' | | Mathieu Bouchard (Montr=E9al QC) | | t=E9l=E9phone:+1.514.383.3801`---' `-o-- http://artengine.ca/matju -' ---1077017559-1213755736-1117391523=:29957-- ---1077017559-1213755736-1117391523=:29957--