<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Colin-adams</id>
		<title>EiffelStudio: an EiffelSoftware project - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Colin-adams"/>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/Special:Contributions/Colin-adams"/>
		<updated>2026-05-06T04:44:43Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Colin-adams&amp;diff=14686</id>
		<title>User:Colin-adams</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Colin-adams&amp;diff=14686"/>
				<updated>2013-03-22T07:08:13Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Removing all content from page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Agents_in_SCOOP&amp;diff=14685</id>
		<title>Talk:Agents in SCOOP</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Agents_in_SCOOP&amp;diff=14685"/>
				<updated>2013-03-22T07:02:53Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I use the first parameter in ROUTINE as a documentation hint, to specify the contract an agent is expected to fulfill.&lt;br /&gt;
&lt;br /&gt;
That is, I declare the callback agent as having type ROUTINE [MY_CLASS, TUPLE [....]]&lt;br /&gt;
&lt;br /&gt;
Then in MY_CLASS I declare a single deferred routine that conforms to the expected signature of the callback.&lt;br /&gt;
This routine is then equipped with contracts.&lt;br /&gt;
&lt;br /&gt;
This serves as a hint to the user as to what the requirements of the callback actually are. If the user follows the hint by inheriting from MY_CLASS to implement the call back, then the contract is actually checked at runtime, and so provides an early warning of what the bug is.&lt;br /&gt;
&lt;br /&gt;
So I find it usefull.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:37, 21 March 2013 (UTC)&lt;br /&gt;
&lt;br /&gt;
''[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 07:45, 21 March 2013 (UTC):'' Could you provide an example? Isn't it too restrictive to require an agent to be based on a specific target?&lt;br /&gt;
&lt;br /&gt;
It isn't restrictive, because a deferred class with a single deferred routine can be inherited as many times as you need, renaming the routine.&lt;br /&gt;
&lt;br /&gt;
I don't have an example that I can post publicly, but I'll send one by email.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:02, 22 March 2013 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Agents_in_SCOOP&amp;diff=14678</id>
		<title>Talk:Agents in SCOOP</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Agents_in_SCOOP&amp;diff=14678"/>
				<updated>2013-03-21T07:43:39Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I use the first parameter in ROUTINE as a documentation hint, to specify the contract an agent is expected to fulfill.&lt;br /&gt;
&lt;br /&gt;
That is, I declare the callback agent as having type ROUTINE [MY_CLASS, TUPLE [....]]&lt;br /&gt;
&lt;br /&gt;
Then in MY_CLASS I declare a single deferred routine that conforms to the expected signature of the callback.&lt;br /&gt;
This routine is then equipped with contracts.&lt;br /&gt;
&lt;br /&gt;
This serves as a hint to the user as to what the requirements of the callback actually are. If the user follows the hint by inheriting from MY_CLASS to implement the call back, then the contract is actually checked at runtime, and so provides an early warning of what the bug is.&lt;br /&gt;
&lt;br /&gt;
So I find it usefull.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:37, 21 March 2013 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Agents_in_SCOOP&amp;diff=14677</id>
		<title>Talk:Agents in SCOOP</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Agents_in_SCOOP&amp;diff=14677"/>
				<updated>2013-03-21T07:37:28Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: New page: I use the first parameter in ROUTINE as a documentation hint in deferred classes with a single routine.  --~~~~&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I use the first parameter in ROUTINE as a documentation hint in deferred classes with a single routine.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:37, 21 March 2013 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelBase2&amp;diff=14592</id>
		<title>Talk:EiffelBase2</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelBase2&amp;diff=14592"/>
				<updated>2012-10-20T11:13:14Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* {PREDICATE}.precondition */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 17:51, 23 April 2010 (UTC):'''&lt;br /&gt;
Changing indexable structures to use 1 everywhere for lower index looks like a good idea. The summary mentions the corresponding modification to the class &amp;lt;e&amp;gt;ARRAY&amp;lt;/e&amp;gt;. There is one more class that does not fit &amp;quot;start at 1&amp;quot; rule: &amp;lt;e&amp;gt;SPECIAL&amp;lt;/e&amp;gt;. Is it planned to change it to start at 1 as well?&lt;br /&gt;
&lt;br /&gt;
'''[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 14:01, 5 April 2012 (UTC):'''&lt;br /&gt;
An iterator is usually seen as a passive handle that can be operated by some other code to access elements in turn. On the other hand it can naturally provide &amp;lt;e&amp;gt;do_all&amp;lt;/e&amp;gt; and similar iteration features. Such features are quite similar to the previous case, but the loop structure is reused and the code to process elements is wrapped in agents. The third variation covers the case when no external handling is required. Everything is performed by the redefined feature &amp;lt;e&amp;gt;forth&amp;lt;/e&amp;gt;. In this case the iterator becomes an active rather than a passive object, because it exhibits some meaningful behaviour itself, without any additional code. In both the second and the third cases the associated loop can be abstrated by some higher-level iterator-like class. Are there any provisions for such abstractions in the proposed class hierarchy?&lt;br /&gt;
&lt;br /&gt;
== Style guidelines for creation procedure names ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 11:09, 12 April 2012 (UTC) with_object_equality doesn't sound like the name of a command, as recommended in the OOSC2 style guidelines. Make_with_object_equality is what I would expect to see.&lt;br /&gt;
&lt;br /&gt;
== {PREDICATE}.precondition ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 11:13, 20 October 2012 (UTC) Features such as {V_CONTAINER}.for_all have preconditions which make use of {PREDICATE}.precondition. In ES 7.1 this is still implemented as always True. Are there plans for a more accurate implementation?&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Main_Page&amp;diff=14561</id>
		<title>Talk:Main Page</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Main_Page&amp;diff=14561"/>
				<updated>2012-10-06T13:41:09Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* Browse source link doesn't work */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Juliant|Juliant]] 23:22, 28 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
Just that it doesn't get forgotten and since someone of the admins has to change navigation I post this here again (From [[Talk:New Main Page]]):&lt;br /&gt;
&lt;br /&gt;
Also a new page logo (at least withouth the white border) and a new navigation would look better. I would split the navigation to a 'normal navigation' part and a 'developers' part (see below).&lt;br /&gt;
&lt;br /&gt;
Navigation proposal:&lt;br /&gt;
&lt;br /&gt;
* Navigation&lt;br /&gt;
** Home      (not sure if this is needed because the logo alredy points to the main page)&lt;br /&gt;
** Categories&lt;br /&gt;
** Downloads&lt;br /&gt;
** Version history&lt;br /&gt;
** FAQ&lt;br /&gt;
** Mailing lists&lt;br /&gt;
** Eiffel links&lt;br /&gt;
&lt;br /&gt;
* Developement&lt;br /&gt;
** Recent changes&lt;br /&gt;
** Changelog of 6.x&lt;br /&gt;
** SVN repository&lt;br /&gt;
** Compiling&lt;br /&gt;
** How to contribute&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Seilerm|Seilerm]] 18:35, 4 December 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
I think this wiki, as this is the home of EiffelStudio, should be customized.&lt;br /&gt;
How others do it:&lt;br /&gt;
http://www.mono-project.com&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Manus|manus]] 22:47, 4 December 2006 (CET)'''&lt;br /&gt;
I agree with Martin. Does anyone have the experience for doing the customization?&lt;br /&gt;
&lt;br /&gt;
== Browse source link doesn't work ==&lt;br /&gt;
&lt;br /&gt;
It's pointing to origo.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 13:41, 6 October 2012 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Migration_to_Unicode&amp;diff=14548</id>
		<title>Talk:Migration to Unicode</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Migration_to_Unicode&amp;diff=14548"/>
				<updated>2012-09-26T08:45:40Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* Where is UTF_CONVERTER? */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''[[User:Peter gummer|Peter gummer]] 22:25, 25 September 2012 (UTC)''' These are interesting guidelines. Is this recommended already in EiffelStudio 7.1?&lt;br /&gt;
&lt;br /&gt;
Our code currently uses &amp;lt;e&amp;gt;STRING&amp;lt;/e&amp;gt; almost everywhere; the ECF maps &amp;lt;e&amp;gt;STRING&amp;lt;/e&amp;gt; to &amp;lt;e&amp;gt;STRING_8&amp;lt;/e&amp;gt;. Do the guidelines mean that we can change the ECF mapping from &amp;lt;e&amp;gt;STRING&amp;lt;/e&amp;gt; to &amp;lt;e&amp;gt;STRING_32&amp;lt;/e&amp;gt;? This would be much faster than editing every class individually.&lt;br /&gt;
&lt;br /&gt;
The guidelines recommend using some &amp;lt;e&amp;gt;*_FILE_32&amp;lt;/e&amp;gt; classes. Most of our files are UTF-8, not UTF-32. Will using the &amp;lt;e&amp;gt;*_FILE_32&amp;lt;/e&amp;gt; classes work?&lt;br /&gt;
&lt;br /&gt;
'''[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 04:07, 26 September 2012 (UTC)'''&lt;br /&gt;
This is a work in progress. Specifying mapping for the strings in an ECF might not work if application classes redefine features from the library classes.&lt;br /&gt;
&lt;br /&gt;
As to using &amp;lt;e&amp;gt;*_FILE_32&amp;lt;/e&amp;gt; classes, the only difference is the support of file names that use non-ASCII characters. Reading and writing the files is not affected.&lt;br /&gt;
&lt;br /&gt;
== Where is UTF_CONVERTER? ==&lt;br /&gt;
&lt;br /&gt;
In which library is this class to be found? Is it available in 7.0?&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:45, 26 September 2012 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelBase2&amp;diff=14406</id>
		<title>Talk:EiffelBase2</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelBase2&amp;diff=14406"/>
				<updated>2012-04-12T11:09:22Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* Style guidelines for creation procedure names */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 17:51, 23 April 2010 (UTC):'''&lt;br /&gt;
Changing indexable structures to use 1 everywhere for lower index looks like a good idea. The summary mentions the corresponding modification to the class &amp;lt;e&amp;gt;ARRAY&amp;lt;/e&amp;gt;. There is one more class that does not fit &amp;quot;start at 1&amp;quot; rule: &amp;lt;e&amp;gt;SPECIAL&amp;lt;/e&amp;gt;. Is it planned to change it to start at 1 as well?&lt;br /&gt;
&lt;br /&gt;
'''[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 14:01, 5 April 2012 (UTC):'''&lt;br /&gt;
An iterator is usually seen as a passive handle that can be operated by some other code to access elements in turn. On the other hand it can naturally provide &amp;lt;e&amp;gt;do_all&amp;lt;/e&amp;gt; and similar iteration features. Such features are quite similar to the previous case, but the loop structure is reused and the code to process elements is wrapped in agents. The third variation covers the case when no external handling is required. Everything is performed by the redefined feature &amp;lt;e&amp;gt;forth&amp;lt;/e&amp;gt;. In this case the iterator becomes an active rather than a passive object, because it exhibits some meaningful behaviour itself, without any additional code. In both the second and the third cases the associated loop can be abstrated by some higher-level iterator-like class. Are there any provisions for such abstractions in the proposed class hierarchy?&lt;br /&gt;
&lt;br /&gt;
== Style guidelines for creation procedure names ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 11:09, 12 April 2012 (UTC) with_object_equality doesn't sound like the name of a command, as recommended in the OOSC2 style guidelines. Make_with_object_equality is what I would expect to see.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Stateless_and_pure&amp;diff=14172</id>
		<title>Talk:Stateless and pure</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Stateless_and_pure&amp;diff=14172"/>
				<updated>2011-07-01T07:36:28Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: New page: I think the way to have stateless routines is simply to put them in classes with no attributes.  Then the class should be marked as stateless in some syntactic way (something more obvious ...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I think the way to have stateless routines is simply to put them in classes with no attributes.&lt;br /&gt;
&lt;br /&gt;
Then the class should be marked as stateless in some syntactic way (something more obvious than an = sign - stateless class, perhaps).&lt;br /&gt;
Tools can then indicate to a programmer that an individual routine happens to be stateless.&lt;br /&gt;
&lt;br /&gt;
Then a (sufficient, but not necessary) validity rule would be that a statefull class inheriting from such a stateless class may not redefine the routine.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:36, 1 July 2011 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Unicode/Encoding_Utility_Wish_List&amp;diff=14048</id>
		<title>Talk:Unicode/Encoding Utility Wish List</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Unicode/Encoding_Utility_Wish_List&amp;diff=14048"/>
				<updated>2011-01-24T14:05:20Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: New page: Unicode normalization is supported in Gobo.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Unicode normalization is supported in Gobo.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Not_a_Number&amp;diff=13698</id>
		<title>Talk:Not a Number</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Not_a_Number&amp;diff=13698"/>
				<updated>2010-02-23T14:27:44Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Manus|manus]] 19:37, 8 May 2007 (CEST)''': Have a look at [[Real_numbers| Real Numbers]] page where we already started a similar discussion but currently only for the specification of REAL_64, not its usage.&lt;br /&gt;
&lt;br /&gt;
== One possibility for working with NaN ==&lt;br /&gt;
&lt;br /&gt;
I was working on a project to represent complex numbers and used the following `is_equal' to accomodate the use of NaNs:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
	is_equal (other: like Current): BOOLEAN&lt;br /&gt;
			-- Is `other' attached to an object considered&lt;br /&gt;
			-- equal to current object?&lt;br /&gt;
			-- If current object is not a number (NaN) and&lt;br /&gt;
			-- `other' is as well `True' will be returned.&lt;br /&gt;
		do&lt;br /&gt;
			if is_nan then&lt;br /&gt;
				if real /~ real and then imaginary ~ imaginary then&lt;br /&gt;
					Result := real /~ other.real and then imaginary ~ other.imaginary&lt;br /&gt;
				elseif real ~ real and then imaginary /~ imaginary then&lt;br /&gt;
					Result := real ~ other.real and then imaginary /~ other.imaginary&lt;br /&gt;
				elseif real /~ real and then imaginary /~ imaginary then&lt;br /&gt;
					Result := real /~ other.real and then imaginary /~ other.imaginary&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				Result := real ~ other.real and then imaginary ~ other.imaginary&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 10:17, 22 February 2010 (UTC) Can you format that code? I can't follow it at all as it stands.&lt;br /&gt;
&lt;br /&gt;
---[[User:Peter gummer|Peter gummer]] 14:44, 22 February 2010 (UTC): Whoever pasted the code there had formatted it, but without suitable mark-up it came out on one line. I've added the mark-up ... how's that look now?&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 14:27, 23 February 2010 (UTC)So that is pretending that two NaNs compare equal. Which is unsound. you are saying that the complex numbers (0/0, 1) and (0/0, 1) are equal. The whole problem arises because they are not comparable.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Not_a_Number&amp;diff=13696</id>
		<title>Talk:Not a Number</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Not_a_Number&amp;diff=13696"/>
				<updated>2010-02-22T10:17:45Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Manus|manus]] 19:37, 8 May 2007 (CEST)''': Have a look at [[Real_numbers| Real Numbers]] page where we already started a similar discussion but currently only for the specification of REAL_64, not its usage.&lt;br /&gt;
&lt;br /&gt;
== One possibility for working with NaN ==&lt;br /&gt;
&lt;br /&gt;
I was working on a project to represent complex numbers and used the following `is_equal' to accomodate the use of NaNs:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	is_equal (other: like Current): BOOLEAN&lt;br /&gt;
			-- Is `other' attached to an object considered&lt;br /&gt;
			-- equal to current object?&lt;br /&gt;
			-- If current object is not a number (NaN) and&lt;br /&gt;
			-- `other' is as well `True' will be returned.&lt;br /&gt;
		do&lt;br /&gt;
			if is_nan then&lt;br /&gt;
				if real /~ real and then imaginary ~ imaginary then&lt;br /&gt;
					Result := real /~ other.real and then imaginary ~ other.imaginary&lt;br /&gt;
				elseif real ~ real and then imaginary /~ imaginary then&lt;br /&gt;
					Result := real ~ other.real and then imaginary /~ other.imaginary&lt;br /&gt;
				elseif real /~ real and then imaginary /~ imaginary then&lt;br /&gt;
					Result := real /~ other.real and then imaginary /~ other.imaginary&lt;br /&gt;
				end&lt;br /&gt;
			else&lt;br /&gt;
				Result := real ~ other.real and then imaginary ~ other.imaginary&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 10:17, 22 February 2010 (UTC) Can you format that code? I can't follow it at all as it stands.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13660</id>
		<title>Talk:Ieee arithmetic</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13660"/>
				<updated>2010-02-05T07:41:28Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 3 February 2010 (UTC)'''&lt;br /&gt;
Most probably C compilers inline functions, but just to be sure, I'd convert them into the macros:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define to_raw_bits(d) *((EIF_NATURAL_64*)&amp;amp;(d))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan_bits(value) ((value &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan(v) ((*((EIF_NATURAL_64 *)&amp;amp;(v)) &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Does it affect the benchmarks?&lt;br /&gt;
:'''--[[User:Manus|manus]] 17:59, 3 February 2010 (UTC)''' Actually it does not on Windows for sure, I've verified that it was inlined. But you are right that those could be simply defined as macros.&lt;br /&gt;
::'''--[[User:Manus|manus]] 20:25, 3 February 2010 (UTC)''' I've done again some of the benchmarks and on windows at least, some of them are slower when I use a macro. I'm no sure why as I haven't looked at the generated assembly code.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Colin-adams|Colin-adams]] 14:48, 3 February 2010 (UTC)'''&lt;br /&gt;
'''Not IEEE arithmetic, nor maths''', NaN = NaN is never true. And placing NaNs in a sort order isn't write either - REAL_32/64 are not totally ordered types.&lt;br /&gt;
&lt;br /&gt;
:'''--[[User:Manus|manus]] 17:57, 3 February 2010 (UTC)''' How do you solve the problem of assertions then in ARRAY.put for example?&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 20:01, 3 February 2010 (UTC)'''&lt;br /&gt;
* Does it mean that &amp;lt;e&amp;gt;REAL_GENERAL&amp;lt;/e&amp;gt; should inherit &amp;lt;e&amp;gt;PART_COMPARABLE&amp;lt;/e&amp;gt; rather than &amp;lt;e&amp;gt;COMPARABLE&amp;lt;/e&amp;gt;?&lt;br /&gt;
* Do we need 2 equality queries: one that tells two objects represent the same value (it is used to ensure &amp;lt;e&amp;gt;copy&amp;lt;/e&amp;gt; does what is expected, and it is used to implement &amp;lt;e&amp;gt;~&amp;lt;/e&amp;gt;) and the other one that tells that the numbers are equal in terms of ordering relation of &amp;lt;e&amp;gt;(PART_)COMPARABLE&amp;lt;/e&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Colin-adams|Colin-adams]] 12:37, 4 February 2010 (UTC)''': '''Postcondition for {ARRAY}.put''' should read:&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
inserted: v = v  implies (item (i) = v)&lt;br /&gt;
undefined_case: v /= V implies (item (i) /= item (1))&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:'''--[[User:Manus|manus]] 19:50, 4 February 2010 (UTC)''': I'm sure you realize that this is not feasible as there are so many of those assertions in actual Eiffel code.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Colin-adams|Colin-adams]] 12:42, 4 February 2010 (UTC)''': I have previously suggested separating the notion of numerical equality and object equality. Eric said that we use = for three different notions, i think, but I don't remember what these were. Certainly PART_COMPARABLE is better than COMPARABLE for IEEE math types. I'm not sure if that is sufficient or not.&lt;br /&gt;
&lt;br /&gt;
:'''--[[User:Manus|manus]] 19:50, 4 February 2010 (UTC)''': The question is not whether or not we adhere to a standard. The question is if that standard makes sense in Eiffel. And clearly it does not. It breaks too much of the good assumption we have been making about equality. In absence of conversion which is pure syntactic sugare, the following is a fundamental aspect of Eiffel: x := y implies x = y.&lt;br /&gt;
&lt;br /&gt;
I advocate changing all postconditions to that form where necessary. it is perfectly reasonable thing to do.&lt;br /&gt;
The current situation means it is not possible to turn postcondition checking on routinely. This is very bad for Design by Contract in practice. I suffer from this every day at work.&lt;br /&gt;
&lt;br /&gt;
You '''have''' to abide by the standard, as that is what the hardware implements. You can't pretend NaNs don't exist. &lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:41, 5 February 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13654</id>
		<title>Talk:Ieee arithmetic</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13654"/>
				<updated>2010-02-04T12:42:29Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* Numeric equality */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Most probably C compilers inline functions, but just to be sure, I'd convert them into the macros:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define to_raw_bits(d) *((EIF_NATURAL_64*)&amp;amp;(d))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan_bits(value) ((value &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan(v) ((*((EIF_NATURAL_64 *)&amp;amp;(v)) &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Does it affect the benchmarks?&lt;br /&gt;
:'''--[[User:Manus|manus]] 17:59, 3 February 2010 (UTC)''' Actually it does not on Windows for sure, I've verified that it was inlined. But you are right that those could be simply defined as macros.&lt;br /&gt;
::'''--[[User:Manus|manus]] 20:25, 3 February 2010 (UTC)''' I've done again some of the benchmarks and on windows at least, some of them are slower when I use a macro. I'm no sure why I haven't looked at the generated assembly code.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Colin-adams|Colin-adams]] 14:48, 3 February 2010 (UTC)'''&lt;br /&gt;
'''Not IEEE arithmetic, nor maths''', NaN = NaN is never true. And placing NaNs in a sort order isn't write either - REAL_32/64 are not totally ordered types.&lt;br /&gt;
&lt;br /&gt;
:'''--[[User:Manus|manus]] 17:57, 3 February 2010 (UTC)''' How do you solve the problem of assertions then in ARRAY.put for example?&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 20:01, 3 February 2010 (UTC)'''&lt;br /&gt;
* Does it mean that &amp;lt;e&amp;gt;REAL_GENERAL&amp;lt;/e&amp;gt; should inherit &amp;lt;e&amp;gt;PART_COMPARABLE&amp;lt;/e&amp;gt; rather than &amp;lt;e&amp;gt;COMPARABLE&amp;lt;/e&amp;gt;?&lt;br /&gt;
* Do we need 2 equality queries: one that tells two objects represent the same value (it is used to ensure &amp;lt;e&amp;gt;copy&amp;lt;/e&amp;gt; does what is expected, and it is used to implement &amp;lt;e&amp;gt;~&amp;lt;/e&amp;gt;) and the other one that tells that the numbers are equal in terms of ordering relation of &amp;lt;e&amp;gt;(PART_)COMPARABLE&amp;lt;/e&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
== Postcondition for put ==&lt;br /&gt;
&lt;br /&gt;
the postcondition for {ARRAY}.put should read:&lt;br /&gt;
&lt;br /&gt;
inserted: v = v  implies (item (i) = v)&lt;br /&gt;
undefined_case: v /= V implies (item (i) /= item (1))&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 12:37, 4 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Numeric equality ==&lt;br /&gt;
&lt;br /&gt;
I have previously suggested separating the notion of numerical equality and object equality. Eric said that we use = for three different notions, i think, but I don't remember what these were.&lt;br /&gt;
&lt;br /&gt;
Certainly PART_COMPARABLE is better than COMPARABLE for IEEE math types. I'm not sure if that is sufficient or not.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 12:42, 4 February 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13653</id>
		<title>Talk:Ieee arithmetic</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13653"/>
				<updated>2010-02-04T12:37:55Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* Postcondition for put */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Most probably C compilers inline functions, but just to be sure, I'd convert them into the macros:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define to_raw_bits(d) *((EIF_NATURAL_64*)&amp;amp;(d))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan_bits(value) ((value &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan(v) ((*((EIF_NATURAL_64 *)&amp;amp;(v)) &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Does it affect the benchmarks?&lt;br /&gt;
:'''--[[User:Manus|manus]] 17:59, 3 February 2010 (UTC)''' Actually it does not on Windows for sure, I've verified that it was inlined. But you are right that those could be simply defined as macros.&lt;br /&gt;
::'''--[[User:Manus|manus]] 20:25, 3 February 2010 (UTC)''' I've done again some of the benchmarks and on windows at least, some of them are slower when I use a macro. I'm no sure why I haven't looked at the generated assembly code.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Colin-adams|Colin-adams]] 14:48, 3 February 2010 (UTC)'''&lt;br /&gt;
'''Not IEEE arithmetic, nor maths''', NaN = NaN is never true. And placing NaNs in a sort order isn't write either - REAL_32/64 are not totally ordered types.&lt;br /&gt;
&lt;br /&gt;
:'''--[[User:Manus|manus]] 17:57, 3 February 2010 (UTC)''' How do you solve the problem of assertions then in ARRAY.put for example?&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 20:01, 3 February 2010 (UTC)'''&lt;br /&gt;
* Does it mean that &amp;lt;e&amp;gt;REAL_GENERAL&amp;lt;/e&amp;gt; should inherit &amp;lt;e&amp;gt;PART_COMPARABLE&amp;lt;/e&amp;gt; rather than &amp;lt;e&amp;gt;COMPARABLE&amp;lt;/e&amp;gt;?&lt;br /&gt;
* Do we need 2 equality queries: one that tells two objects represent the same value (it is used to ensure &amp;lt;e&amp;gt;copy&amp;lt;/e&amp;gt; does what is expected, and it is used to implement &amp;lt;e&amp;gt;~&amp;lt;/e&amp;gt;) and the other one that tells that the numbers are equal in terms of ordering relation of &amp;lt;e&amp;gt;(PART_)COMPARABLE&amp;lt;/e&amp;gt;?&lt;br /&gt;
&lt;br /&gt;
== Postcondition for put ==&lt;br /&gt;
&lt;br /&gt;
the postcondition for {ARRAY}.put should read:&lt;br /&gt;
&lt;br /&gt;
inserted: v = v  implies (item (i) = v)&lt;br /&gt;
undefined_case: v /= V implies (item (i) /= item (1))&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 12:37, 4 February 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13647</id>
		<title>Talk:Ieee arithmetic</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Ieee_arithmetic&amp;diff=13647"/>
				<updated>2010-02-03T14:48:16Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: /* Not IEEE arithmetic, nor maths */ new section&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Most probably C compilers inline functions, but just to be sure, I'd convert them into the macros:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define to_raw_bits(d) *((EIF_NATURAL_64*)&amp;amp;(d))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan_bits(value) ((value &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
 &lt;br /&gt;
#define eif_is_nan(v) ((*((EIF_NATURAL_64 *)&amp;amp;(v)) &amp;amp; ~RTU64C(0x8000000000000000)) &amp;gt; RTU64C(0x7ff0000000000000))&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Does it affect the benchmarks?&lt;br /&gt;
&lt;br /&gt;
== Not IEEE arithmetic, nor maths ==&lt;br /&gt;
&lt;br /&gt;
NaN = NaN is never true. &lt;br /&gt;
&lt;br /&gt;
And placing NaNs in a sort order isn't write either - REAL_32/64 are not totally ordered types.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 14:48, 3 February 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Debug_generated_C_code&amp;diff=12578</id>
		<title>Talk:Debug generated C code</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Debug_generated_C_code&amp;diff=12578"/>
				<updated>2009-06-08T15:41:59Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Please, not just MS-Windows&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is for MS-Windows only.&lt;br /&gt;
&lt;br /&gt;
It would be nice to have the instructions for Linux, and Mac OSX.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 15:41, 8 June 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Using_CDD&amp;diff=12211</id>
		<title>Talk:Using CDD</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Using_CDD&amp;diff=12211"/>
				<updated>2009-03-09T15:15:21Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: New page: Is the CDD branch integrated into the regular EiffelStudio delivery yet?  Where are test cases extracted to? Do you define a directory in the ECF or something? --~~~~&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Is the CDD branch integrated into the regular EiffelStudio delivery yet?&lt;br /&gt;
&lt;br /&gt;
Where are test cases extracted to? Do you define a directory in the ECF or something?&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 15:15, 9 March 2009 (UTC)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=11284</id>
		<title>Talk:EiffelStudio Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=11284"/>
				<updated>2008-07-07T06:20:15Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Patrickr|Patrickr]] 17:31, 9 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
The location for the mo files should be setup in the environment library, on Unix those files go under&lt;br /&gt;
 /usr/share/locale&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 /usr/share/locale/en/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de_CH/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Juliant|Juliant]] 19:53, 10 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
Is it really necessary that the language can be changed while running EiffelStudio? I would say this is set once (even during installation). It wouldn't be a problem to just restart EiffelStudio.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Ted|Ted]] 03:20, 13 November 2006 (CET)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
What are the advantages of putting mo files under /usr/share/locale? mo files are not shared between applications and normally users do not need to change mo files.&lt;br /&gt;
All mo files are put in ES installation directory, we only need to store the locale id as a preference.&lt;br /&gt;
More over, mo files are implemented to be accepted by the library only with names of locale id.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
We need to decide whether the language can be switched at runtime. Of course, not doing this as most applications definitely reduces a lot of time.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Patrickr|Patrickr]] 17:13, 13 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
On Unix there are rules where which part of an application belongs to. Standardising this locations makes various things easier.&lt;br /&gt;
I also think changing the language during runtime is not necessary.&lt;br /&gt;
&lt;br /&gt;
== Dont use UTF-16 ==&lt;br /&gt;
&lt;br /&gt;
UTF-16 is an abomination - it should never be used.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:03, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
I agree. -- [[User:Ted|Ted]] 08:04, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Auto-encoding detection ==&lt;br /&gt;
&lt;br /&gt;
Do you have a scheme in mind?&lt;br /&gt;
&lt;br /&gt;
This is, in general, impossible, but special circumstances can make it tractable. The starting possibilities&lt;br /&gt;
for an Eiffel source text are quite limited, so at first glance it looks possible.&lt;br /&gt;
&lt;br /&gt;
However, I note that if an Eiffel source text uses ASCII characters for everything except the contents of STRING_8 literals, and no STRING_32 or CHARACTER_32 literals are present, then it will be impossible to distinguish between ISO-8859-1 (or most other subsets of ISO-8859) and UTF-8, unless the UTF-8 file starts with a BOM. But the latter practise is reprehensible, and many editors do not support it.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:09, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Yes, one can not tell the encoding accurately. I thought this could be possible done by combination of means. I knew firefox and IE has encoding detection library, but they seem only give the most possible results, not accurate ones.&lt;br /&gt;
This part maybe implemented as just &amp;quot;encoding detection&amp;quot; in the end.&lt;br /&gt;
--[[User:Ted|Ted]] 08:13, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Notes term ==&lt;br /&gt;
&lt;br /&gt;
The problem becomes much simpler if you add the following restriction:&lt;br /&gt;
&lt;br /&gt;
Source codings other than ISO-646 (US-ASCII) and ISO-8859-1 (Latin-1) are only allowed if the class contains an encoding term in the notes (indexing, in pre-ECMA) clause whose value names the encoding.&lt;br /&gt;
&lt;br /&gt;
So a UTF-8 source file would start something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;eiffel&amp;gt;&lt;br /&gt;
indexing&lt;br /&gt;
&lt;br /&gt;
 description: &amp;quot;My latest class writen in Unicode&amp;quot;&lt;br /&gt;
 encoding: &amp;quot;UTF-8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MY_LATEST&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/eiffel&amp;gt;&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:17, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
This is one way we are thinking of. But ideally this needs parsing. Maybe specifying encoding as compiler argument is good enough, or make it into .ecf files.&lt;br /&gt;
--[[User:Ted|Ted]] 08:18, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== All XML files support all of Unicode ==&lt;br /&gt;
&lt;br /&gt;
The line that says ECF files, etc., will need a Unicode encoding is not true. All XML files, no matter what their encoding, support the entire Unicode character set.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 22:41, 1 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
What I mean is specific to EiffelStudio in which we only put iso-8859-1 as encoding of ecfs. This char set is not sufficient, since users will be able to put any Unicode chars in project settings, for example, descriptions. And other internal implementations using XML, like diagram storage, metrics storage may not even take encoding into account. These parts need to be adapted. --[[User:Ted|Ted]] 08:25, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
One thing I am not so sure is whether Gobo XML parser has supported encodings rather than Unicode ones. For example, GB2312. (This implies ability to convert between GB2312 and UTF8 etc.) --[[User:Ted|Ted]] 08:29, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
It IS sufficient.&lt;br /&gt;
No matter what the encoding, all Unicode characters (within the limits of the XML version - which means 1.0 for Gobo) can be represented. That is what character references are for. E.g. &amp;amp;#331; is outside the range of Latin-1, but you can still specify it in an XML file with encoding=&amp;quot;ISO8859-1&amp;quot;.&lt;br /&gt;
And no, Gobo does not support GB2312, but it does support UTF-8 (all XML parsers must support UTF-8 and UTF-16). But this is not very relevant.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:13, 3 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
I see what you mean. It is good to know Gobo takes them as what they are (no information lose). But I am a little surprised that knowing the encoding Gobo doesn't return meaningful strings (in UTF8), but simply the stream taken directly from byte sequence. (Correct me if I am wrong.) So EiffelStudio still needs to handle conversions manually because UTF-32 is used internally and only with known encoding strings can be correctly rendered.&lt;br /&gt;
This means we need to convert strings into an encoding the XML file specifies (none implies UTF8). Then converting most Unicode chars to iso-8859-1 is not correct anymore. And can only be safe converting the byte sequence read from XML from the encoding it specifies to UTF32. In any case, I prefer to use UTF8 for all XML files as default.&lt;br /&gt;
I am also afraid that using &amp;quot;iso-8859-1&amp;quot; to carry strings in other encoding would make some XML editors incorrectly render them.&lt;br /&gt;
--[[User:Ted|Ted]] 09:13, 3 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
Why do you think Gobo doesn't return meaningful strings? Of course it does.&lt;br /&gt;
You don't have to worry about any of this. The XML specification, written oer 10 years ago, sorted all this out.&lt;br /&gt;
&lt;br /&gt;
And it is quite safe to serialize as ISO-8859-1 if you wish. No XML editor can render it incorrectly.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 23:20, 6 July 2008 (PDT)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=11279</id>
		<title>Talk:EiffelStudio Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=11279"/>
				<updated>2008-07-03T14:13:31Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Patrickr|Patrickr]] 17:31, 9 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
The location for the mo files should be setup in the environment library, on Unix those files go under&lt;br /&gt;
 /usr/share/locale&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 /usr/share/locale/en/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de_CH/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Juliant|Juliant]] 19:53, 10 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
Is it really necessary that the language can be changed while running EiffelStudio? I would say this is set once (even during installation). It wouldn't be a problem to just restart EiffelStudio.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Ted|Ted]] 03:20, 13 November 2006 (CET)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
What are the advantages of putting mo files under /usr/share/locale? mo files are not shared between applications and normally users do not need to change mo files.&lt;br /&gt;
All mo files are put in ES installation directory, we only need to store the locale id as a preference.&lt;br /&gt;
More over, mo files are implemented to be accepted by the library only with names of locale id.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
We need to decide whether the language can be switched at runtime. Of course, not doing this as most applications definitely reduces a lot of time.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Patrickr|Patrickr]] 17:13, 13 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
On Unix there are rules where which part of an application belongs to. Standardising this locations makes various things easier.&lt;br /&gt;
I also think changing the language during runtime is not necessary.&lt;br /&gt;
&lt;br /&gt;
== Dont use UTF-16 ==&lt;br /&gt;
&lt;br /&gt;
UTF-16 is an abomination - it should never be used.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:03, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
I agree. -- [[User:Ted|Ted]] 08:04, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Auto-encoding detection ==&lt;br /&gt;
&lt;br /&gt;
Do you have a scheme in mind?&lt;br /&gt;
&lt;br /&gt;
This is, in general, impossible, but special circumstances can make it tractable. The starting possibilities&lt;br /&gt;
for an Eiffel source text are quite limited, so at first glance it looks possible.&lt;br /&gt;
&lt;br /&gt;
However, I note that if an Eiffel source text uses ASCII characters for everything except the contents of STRING_8 literals, and no STRING_32 or CHARACTER_32 literals are present, then it will be impossible to distinguish between ISO-8859-1 (or most other subsets of ISO-8859) and UTF-8, unless the UTF-8 file starts with a BOM. But the latter practise is reprehensible, and many editors do not support it.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:09, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
Yes, one can not tell the encoding accurately. I thought this could be possible done by combination of means. I knew firefox and IE has encoding detection library, but they seem only give the most possible results, not accurate ones.&lt;br /&gt;
This part maybe implemented as just &amp;quot;encoding detection&amp;quot; in the end.&lt;br /&gt;
--[[User:Ted|Ted]] 08:13, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Notes term ==&lt;br /&gt;
&lt;br /&gt;
The problem becomes much simpler if you add the following restriction:&lt;br /&gt;
&lt;br /&gt;
Source codings other than ISO-646 (US-ASCII) and ISO-8859-1 (Latin-1) are only allowed if the class contains an encoding term in the notes (indexing, in pre-ECMA) clause whose value names the encoding.&lt;br /&gt;
&lt;br /&gt;
So a UTF-8 source file would start something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;eiffel&amp;gt;&lt;br /&gt;
indexing&lt;br /&gt;
&lt;br /&gt;
 description: &amp;quot;My latest class writen in Unicode&amp;quot;&lt;br /&gt;
 encoding: &amp;quot;UTF-8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MY_LATEST&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/eiffel&amp;gt;&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:17, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
This is one way we are thinking of. But ideally this needs parsing. Maybe specifying encoding as compiler argument is good enough, or make it into .ecf files.&lt;br /&gt;
--[[User:Ted|Ted]] 08:18, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== All XML files support all of Unicode ==&lt;br /&gt;
&lt;br /&gt;
The line that says ECF files, etc., will need a Unicode encoding is not true. All XML files, no matter what their encoding, support the entire Unicode character set.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 22:41, 1 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
What I mean is specific to EiffelStudio in which we only put iso-8859-1 as encoding of ecfs. This char set is not sufficient, since users will be able to put any Unicode chars in project settings, for example, descriptions. And other internal implementations using XML, like diagram storage, metrics storage may not even take encoding into account. These parts need to be adapted. --[[User:Ted|Ted]] 08:25, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
One thing I am not so sure is whether Gobo XML parser has supported encodings rather than Unicode ones. For example, GB2312. (This implies ability to convert between GB2312 and UTF8 etc.) --[[User:Ted|Ted]] 08:29, 2 July 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
It IS sufficient.&lt;br /&gt;
No matter what the encoding, all Unicode characters (within the limits of the XML version - which means 1.0 for Gobo) can be represented. That is what character references are for. E.g. &amp;amp;#331; is outside the range of Latin-1, but you can still specify it in an XML file with encoding=&amp;quot;ISO8859-1&amp;quot;.&lt;br /&gt;
And no, Gobo does not support GB2312, but it does support UTF-8 (all XML parsers must support UTF-8 and UTF-16). But this is not very relevant.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 07:13, 3 July 2008 (PDT)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=11273</id>
		<title>Talk:EiffelStudio Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=11273"/>
				<updated>2008-07-02T05:41:42Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: All XML files support all of Unicode&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Patrickr|Patrickr]] 17:31, 9 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
The location for the mo files should be setup in the environment library, on Unix those files go under&lt;br /&gt;
 /usr/share/locale&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 /usr/share/locale/en/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de_CH/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Juliant|Juliant]] 19:53, 10 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
Is it really necessary that the language can be changed while running EiffelStudio? I would say this is set once (even during installation). It wouldn't be a problem to just restart EiffelStudio.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Ted|Ted]] 03:20, 13 November 2006 (CET)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
What are the advantages of putting mo files under /usr/share/locale? mo files are not shared between applications and normally users do not need to change mo files.&lt;br /&gt;
All mo files are put in ES installation directory, we only need to store the locale id as a preference.&lt;br /&gt;
More over, mo files are implemented to be accepted by the library only with names of locale id.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
We need to decide whether the language can be switched at runtime. Of course, not doing this as most applications definitely reduces a lot of time.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Patrickr|Patrickr]] 17:13, 13 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
On Unix there are rules where which part of an application belongs to. Standardising this locations makes various things easier.&lt;br /&gt;
I also think changing the language during runtime is not necessary.&lt;br /&gt;
&lt;br /&gt;
== Dont use UTF-16 ==&lt;br /&gt;
&lt;br /&gt;
UTF-16 is an abomination - it should never be used.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:03, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Auto-encoding detection ==&lt;br /&gt;
&lt;br /&gt;
Do you have a scheme in mind?&lt;br /&gt;
&lt;br /&gt;
This is, in general, impossible, but special circumstances can make it tractable. The starting possibilities&lt;br /&gt;
for an Eiffel source text are quite limited, so at first glance it looks possible.&lt;br /&gt;
&lt;br /&gt;
However, I note that if an Eiffel source text uses ASCII characters for everything except the contents of STRING_8 literals, and no STRING_32 or CHARACTER_32 literals are present, then it will be impossible to distinguish between ISO-8859-1 (or most other subsets of ISO-8859) and UTF-8, unless the UTF-8 file starts with a BOM. But the latter practise is reprehensible, and many editors do not support it.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:09, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Notes term ==&lt;br /&gt;
&lt;br /&gt;
The problem becomes much simpler if you add the following restriction:&lt;br /&gt;
&lt;br /&gt;
Source codings other than ISO-646 (US-ASCII) and ISO-8859-1 (Latin-1) are only allowed if the class contains an encoding term in the notes (indexing, in pre-ECMA) clause whose value names the encoding.&lt;br /&gt;
&lt;br /&gt;
So a UTF-8 source file would start something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;eiffel&amp;gt;&lt;br /&gt;
indexing&lt;br /&gt;
&lt;br /&gt;
 description: &amp;quot;My latest class writen in Unicode&amp;quot;&lt;br /&gt;
 encoding: &amp;quot;UTF-8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MY_LATEST&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/eiffel&amp;gt;&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:17, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== All XML files support all of Unicode ==&lt;br /&gt;
&lt;br /&gt;
The line that says ECF files, etc., will need a Unicode encoding is not true. All XML files, no matter what their encoding, support the entire Unicode character set.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 22:41, 1 July 2008 (PDT)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Collaborative_Documentation_Solutions&amp;diff=11190</id>
		<title>Talk:Collaborative Documentation Solutions</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Collaborative_Documentation_Solutions&amp;diff=11190"/>
				<updated>2008-06-11T13:53:33Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Using a wiki (or anything that requires to use a web-browser) is a real pain for writing documentation. The web browser is an extremely hostile environment for text editing, and I for one would never attempt to write an substantial text using it.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 06:53, 11 June 2008 (PDT)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Downloads&amp;diff=11187</id>
		<title>Talk:Downloads</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Downloads&amp;diff=11187"/>
				<updated>2008-06-11T12:52:53Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Mac OS X 64-bit  binary for 6.2?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hmm - is the command line compiler really at production level? With all the changes in the interface (move from .ace via .acex to .ecf). I know it is good and stable, but still ... (Bernd)&lt;br /&gt;
&lt;br /&gt;
== Mac OS X 64-bit  binary for 6.2? ==&lt;br /&gt;
&lt;br /&gt;
I see in the Origo downloads area, that one of the latest downloads is labelled as platform Mac OS X x86_64. However the file name includes solaris, so I assume it is really an x86_64 solaris build.&lt;br /&gt;
&lt;br /&gt;
When will we get a Mac OS X x86_64 build?&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 05:52, 11 June 2008 (PDT)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Eiffel_Code_Comments&amp;diff=10975</id>
		<title>Talk:Eiffel Code Comments</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Eiffel_Code_Comments&amp;diff=10975"/>
				<updated>2008-04-22T07:59:58Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I think that in the case of multiple inheritance, &lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
-- &amp;lt;Precursor&amp;gt; &lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
should be sufficient. The tool just selects the same version that the compiler would select.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 00:59, 22 April 2008 (PDT)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Catcall_Test_Proposal&amp;diff=9988</id>
		<title>Talk:Catcall Test Proposal</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Catcall_Test_Proposal&amp;diff=9988"/>
				<updated>2007-11-07T07:41:08Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: What is the example supposed to mean?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Colin-adams|Colin-adams]] 00:09, 6 November 2007 (PST)''': Can you give an example of when using the &amp;lt;e&amp;gt;variant&amp;lt;/e&amp;gt; keyword makes sense?&lt;br /&gt;
&lt;br /&gt;
As for the &amp;lt;e&amp;gt;frozen&amp;lt;/e&amp;gt; keyword, doesn't this break the open/closed principle yet again (I know the example shows an attribute, but the wording suggests a routine could also be marked with a frozen type - does this limit redeclaration)?&lt;br /&gt;
&lt;br /&gt;
What is supposed to happen in the multiple constraint case (if the compiler didn't have a limitation)?&lt;br /&gt;
&lt;br /&gt;
: '''--[[User:Schoelle|Schoelle]] 03:26, 6 November 2007 (PST)''': The &amp;lt;e&amp;gt;variant&amp;lt;/e&amp;gt; keyword is nearly the same as the wildcard types introduced in Java. The only difference is the use of a global analysis (i.e. non-modular) to check certain corner cases that are valid although generics are used in the arguments.&lt;br /&gt;
&lt;br /&gt;
: '''--[[User:Manus|manus]] 11:53, 6 November 2007 (PST)''': &lt;br /&gt;
:* The &amp;lt;e&amp;gt;variant&amp;lt;/e&amp;gt; keyword has to be used whenever you want to preserve today's generic conformance rules. For example assigning a &amp;lt;e&amp;gt;LIST [STRING]&amp;lt;/e&amp;gt; to a &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; is possible today, but with the new rule, only if you declare it as &amp;lt;e&amp;gt;LIST [variant ANY]&amp;lt;/e&amp;gt;.&lt;br /&gt;
:* The &amp;lt;e&amp;gt;frozen&amp;lt;/e&amp;gt; keyword is not preventing you from redefining a feature, just its signature. So if it breaks the open/closed prinicple, then it just does it very slightly. I would say it is a small price to pay for not having catcalls.&lt;br /&gt;
:* For the multiple constraint case, if the descendant type base class is &amp;lt;e&amp;gt;class A [G -&amp;gt; {B,C}]&amp;lt;/e&amp;gt; I need to define a type that matches the constraint and being a descendant type. If there are no classes in the universe that inherits from both B and C, such a type cannot be constructed and thus the compiler limitation which will report a potential catcall. Possibly, we could find all the classes that are matching the constraint and use them as base types. For the moment we haven't done it, because it is still experimental and there is little code with multiple constraint.&lt;br /&gt;
&lt;br /&gt;
--[[User:Clemahieu|Clemahieu]] 21:51, 6 November 2007 (PST)&lt;br /&gt;
I forgot where it was stated but it was something to the effect of &amp;quot;If a language isn't type safe in all instances, it's not really type safe&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Maybe we can eventually solve all catcall issues but covariant redefinition seems like it's taking a lot of resources to try and make work safely.&lt;br /&gt;
&lt;br /&gt;
Didn't someone state that most covariant problems can be solved type safely with generics?  Honestly that's what I use instead of covariance.&lt;br /&gt;
&lt;br /&gt;
== What is the example supposed to mean? ==&lt;br /&gt;
&lt;br /&gt;
What is the example supposed to mean? I can't see that the G in class B comes into anything.&lt;br /&gt;
&lt;br /&gt;
Bernd, I haven't follow Java developments since I last did any Java programming, several years ago, so I am none the wiser.&lt;br /&gt;
Can we have an example showing how this is supposed to work (for both situations, with and without the variant keyword). I am completely unable to follow the article at the moment.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 23:41, 6 November 2007 (PST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Catcall_Test_Proposal&amp;diff=9978</id>
		<title>Talk:Catcall Test Proposal</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Catcall_Test_Proposal&amp;diff=9978"/>
				<updated>2007-11-06T08:09:00Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Can you give an example of when using the variant keyword makes sense?&lt;br /&gt;
&lt;br /&gt;
As for the frozen keyword, doesn't this break the open/closed principle yet again (I know the example shows an attribute, but the wording suggests a routine could also be marked with a frozen type - does this limit redeclaration)?&lt;br /&gt;
&lt;br /&gt;
What is supposed to happen in the multiple constraint case (if the compiler didn't have a limitation)?&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 00:09, 6 November 2007 (PST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9842</id>
		<title>Talk:Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9842"/>
				<updated>2007-10-04T16:44:35Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Class for serialization&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:21, 3 October 2007 (CEST)&lt;br /&gt;
It would be nice to extend the example to see where the &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; attribute is serialized (given that the attribute &amp;lt;e&amp;gt;gadget&amp;lt;/e&amp;gt; is not serialized at all).&lt;br /&gt;
&lt;br /&gt;
== Transformation at store time ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:49, 3 October 2007 (CEST)&lt;br /&gt;
The proposed scheme assumes that some attributes need to be stored and some - not. However, it's possible that the object model is changed over time, but backward compatibility as well as interoperability with other applications is still required. For example, the original program used the RGB color model with the attributes corresponding to the main colors. Over time it turned out that another model, say, HSV one, is more approriate for the associated algorithms and the attributes were replaced by the new ones. Both models cover the same range of spectrum but use different attribute sets.&lt;br /&gt;
&lt;br /&gt;
For example, the systems A and B use the original RGB coding scheme and the new system A' uses new HSV scheme. For interoperability between all these products (given that they are used on multiple machines and cannot be immediately updated, or even worse, the system B is no longer maintained), it's essential to stick to the original storable format. It means that there should be a way to store new attributes of HSV model using the old RGB style.&lt;br /&gt;
&lt;br /&gt;
: On the other hand, the new development can go on and new systems are designed to use HSV model from the beginning. There is no need to use the old format anymore, given that the new systems A' are able to store the data in a new format as well. As far as I can see, this can be achieved by the predicate on the corresponding attributes that tell whether they need to be stored &amp;quot;as is&amp;quot; or not. This behaviour is easily achieved using the proposed technique with predicates if there is also a way to store data in the old format.&lt;br /&gt;
&lt;br /&gt;
The incompleteness of the example is why the page is still marked as under construction.&lt;br /&gt;
&lt;br /&gt;
As for the long-term issue, I explicitly said I was not addressing this in the article. Using storables for a short-to-medium term cache is good. For longer term persistence, a proper database schema is needed, I think (I shall be interested to see what comes out of the persistence project).&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:31, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Agent keyword was missing ==&lt;br /&gt;
&lt;br /&gt;
I just noticed your point about &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; - I had missed out the keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; following the &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt; tag.&lt;br /&gt;
This produces a closed agent (and therefore incorporates the id value). The idea was that somehow the closed agent gets stored in the storable. But maybe this is not possible and/or desirable (if the code for the agent has changed in the meantime, then it is must be better to use the updated code). In which case the storing mechanism can &amp;lt;em&amp;gt;infer&amp;lt;/em&amp;gt; the need to store &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt;, but only for the purpose of closing the agent built at restore time. Does that make sense?&lt;br /&gt;
&lt;br /&gt;
Anyway, I still have to provide a more comprehensive example.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:05, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Examples added ==&lt;br /&gt;
&lt;br /&gt;
I have now filled out a more complete example, and so I have removed the &amp;quot;under construction&amp;quot; label.&lt;br /&gt;
&lt;br /&gt;
Alexander, your RGB -&amp;gt; HSV example is quite interesting, now I think about it a bit more.&lt;br /&gt;
&lt;br /&gt;
I suppose the scenario goes a bit like this:&lt;br /&gt;
&lt;br /&gt;
1) There are three attributes, red, green and blue, which are persistent.&lt;br /&gt;
&lt;br /&gt;
2) New variables, hue, saturation and value are added. To initialize these from an old-format storable, a restoration routine would be needed. &lt;br /&gt;
I'm not sure how the routine is supposed to know whether or not restoration must be performed, given that default values would be reasonable. Perhaps restoration routines must be restricted to having detachable reference arguments.&lt;br /&gt;
&lt;br /&gt;
If red, green and blue were re-defined as routines in terms of hue, saturation and value, then a mis-match would occur, so this is no better than the current situation with mismatch-correctors. So they have to still be (redundant) attributes, and must still be persistent so that new storables can be used on the old system.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 11:26, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Necessity ==&lt;br /&gt;
Is this type of functionality needed?  If a serialized object of a class A contains more information than what is needed to be serialized, wouldn't it be easier to create a class B that has a creation feature that accepts a parameter of type A, copies the needed information out of A and then serialized the new object of B?  When deserializing, A has a creation procedure accepting a parameter of type B and the process is reversed and caches are recreated?&lt;br /&gt;
&lt;br /&gt;
This would seem a lot easier in my opinion.&lt;br /&gt;
--[[User:Clemahieu|Clemahieu]] 17:59, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Class for serialization ==&lt;br /&gt;
&lt;br /&gt;
Creating a separate class for serialization was my first thought too when I encountered the problem.&lt;br /&gt;
&lt;br /&gt;
That is fine if you only face the problem once. It becomes very tedious as soon as you reached the second or third class, never mind the rest.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 18:44, 4 October 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9839</id>
		<title>Talk:Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9839"/>
				<updated>2007-10-04T09:26:49Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Examples added&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:21, 3 October 2007 (CEST)&lt;br /&gt;
It would be nice to extend the example to see where the &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; attribute is serialized (given that the attribute &amp;lt;e&amp;gt;gadget&amp;lt;/e&amp;gt; is not serialized at all).&lt;br /&gt;
&lt;br /&gt;
== Transformation at store time ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:49, 3 October 2007 (CEST)&lt;br /&gt;
The proposed scheme assumes that some attributes need to be stored and some - not. However, it's possible that the object model is changed over time, but backward compatibility as well as interoperability with other applications is still required. For example, the original program used the RGB color model with the attributes corresponding to the main colors. Over time it turned out that another model, say, HSV one, is more approriate for the associated algorithms and the attributes were replaced by the new ones. Both models cover the same range of spectrum but use different attribute sets.&lt;br /&gt;
&lt;br /&gt;
For example, the systems A and B use the original RGB coding scheme and the new system A' uses new HSV scheme. For interoperability between all these products (given that they are used on multiple machines and cannot be immediately updated, or even worse, the system B is no longer maintained), it's essential to stick to the original storable format. It means that there should be a way to store new attributes of HSV model using the old RGB style.&lt;br /&gt;
&lt;br /&gt;
: On the other hand, the new development can go on and new systems are designed to use HSV model from the beginning. There is no need to use the old format anymore, given that the new systems A' are able to store the data in a new format as well. As far as I can see, this can be achieved by the predicate on the corresponding attributes that tell whether they need to be stored &amp;quot;as is&amp;quot; or not. This behaviour is easily achieved using the proposed technique with predicates if there is also a way to store data in the old format.&lt;br /&gt;
&lt;br /&gt;
The incompleteness of the example is why the page is still marked as under construction.&lt;br /&gt;
&lt;br /&gt;
As for the long-term issue, I explicitly said I was not addressing this in the article. Using storables for a short-to-medium term cache is good. For longer term persistence, a proper database schema is needed, I think (I shall be interested to see what comes out of the persistence project).&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:31, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Agent keyword was missing ==&lt;br /&gt;
&lt;br /&gt;
I just noticed your point about &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; - I had missed out the keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; following the &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt; tag.&lt;br /&gt;
This produces a closed agent (and therefore incorporates the id value). The idea was that somehow the closed agent gets stored in the storable. But maybe this is not possible and/or desirable (if the code for the agent has changed in the meantime, then it is must be better to use the updated code). In which case the storing mechanism can &amp;lt;em&amp;gt;infer&amp;lt;/em&amp;gt; the need to store &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt;, but only for the purpose of closing the agent built at restore time. Does that make sense?&lt;br /&gt;
&lt;br /&gt;
Anyway, I still have to provide a more comprehensive example.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:05, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Examples added ==&lt;br /&gt;
&lt;br /&gt;
I have now filled out a more complete example, and so I have removed the &amp;quot;under construction&amp;quot; label.&lt;br /&gt;
&lt;br /&gt;
Alexander, your RGB -&amp;gt; HSV example is quite interesting, now I think about it a bit more.&lt;br /&gt;
&lt;br /&gt;
I suppose the scenario goes a bit like this:&lt;br /&gt;
&lt;br /&gt;
1) There are three attributes, red, green and blue, which are persistent.&lt;br /&gt;
&lt;br /&gt;
2) New variables, hue, saturation and value are added. To initialize these from an old-format storable, a restoration routine would be needed. &lt;br /&gt;
I'm not sure how the routine is supposed to know whether or not restoration must be performed, given that default values would be reasonable. Perhaps restoration routines must be restricted to having detachable reference arguments.&lt;br /&gt;
&lt;br /&gt;
If red, green and blue were re-defined as routines in terms of hue, saturation and value, then a mis-match would occur, so this is no better than the current situation with mismatch-correctors. So they have to still be (redundant) attributes, and must still be persistent so that new storables can be used on the old system.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 11:26, 4 October 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9838</id>
		<title>Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9838"/>
				<updated>2007-10-04T07:58:44Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Spelling correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Persistence]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s in an application has at least two significant disadvantages. &lt;br /&gt;
&lt;br /&gt;
One is that using them for long-term persistence is vulnerable to changes in the class. &lt;br /&gt;
&lt;br /&gt;
Another is that too much data may be stored, resulting in large files (or database occupancy, or whatever) and slow reload times. Some data, such as internal caches, are probably best not serialized at all. For other data, it may be better just to store a shorthand identifier to enable the data to be rebuilt (maybe on demand) at retrieval time.&lt;br /&gt;
&lt;br /&gt;
This article explores ways to address the second problem. The first problem is best tackled by only using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s as a medium-term caching mechanism.&lt;br /&gt;
&lt;br /&gt;
==Transient data==&lt;br /&gt;
&lt;br /&gt;
Java tackles this problem with the keyword &amp;lt;java&amp;gt;transient&amp;lt;/java&amp;gt;. An attribute so marked is not stored at serialization time. When the object is retrieved the attribute will be void.&lt;br /&gt;
&lt;br /&gt;
This seems rather limited to me. It can't be used if the class invariant constrains the attribute to be non-void. And I don't think there is a way for a descendant class to override this behaviour (it's a long time since I've written any Java, so I could be very wrong here).&lt;br /&gt;
&lt;br /&gt;
My thinking is that there should be a way to specify whether or not a particular attribute should be stored on any given occaision, and a way to specify what to do at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Persistence predicates===&lt;br /&gt;
&lt;br /&gt;
A persistence predicate is a routine of type &amp;lt;e&amp;gt;PREDICATE [ANY, TUPLE [!&amp;lt;attribute_type&amp;gt;]]&amp;lt;/e&amp;gt; associated with an attribute of type &amp;lt;attribute_type&amp;gt;.&lt;br /&gt;
At storage time, the predicate will be called with the instance of the attribute as its argument (if the attribute is non-Void). If it returns &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; then the attribute is stored. If it returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; then the attribute is not stored, but it may be re-created at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Restoration routines===&lt;br /&gt;
&lt;br /&gt;
If a persistence predicate returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt;, it may be that the programmer does not need this data at all (such as the case of an internal cache). But in some cases the programmer will want the data to be recreated at restoration time (this may be necessary to restore the class invariant), rather than retrieved from the persistence mechanism. &lt;br /&gt;
&lt;br /&gt;
Take an example of a class which has an attribute named &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; having an attribute named &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;INTEGER&amp;lt;/e&amp;gt;. The class invariant requires that&amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is not &amp;lt;e&amp;gt;Void&amp;lt;/e&amp;gt;, but the size required to store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is very large. The class also has a secret routine &amp;lt;e&amp;gt;`create_gadget_from_identifier (a_id: INTEGER)&amp;lt;/e&amp;gt; which can be used to create a &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; given its &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value. In such a case, rather than store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; it is probably better to just store the &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value, and then call &amp;lt;e&amp;gt;`create_gadget_from_identifier'&amp;lt;/e&amp;gt; at retrieval time.&lt;br /&gt;
&lt;br /&gt;
A restoration routine is similar to a creation procedure, in as much as it cannot reply on the class invariant holding. It can rely on attributes for which the persistence predicate evaluates to &amp;lt;e&amp;gt;True &amp;lt;/e&amp;gt; as having been restored, though.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
One new keyword &amp;lt;e&amp;gt;restore&amp;lt;/e&amp;gt; will be required. This can occur in several places:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; clause in the class prolog. What follows is a list of restoration routines, just like the list of creation procedures. Typically this will occur in the form:&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
 recreate_attributes&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword and optional body. What follows is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;1. The tag &amp;lt;e&amp;gt;persistence_predicate:&amp;lt;/e&amp;gt; followed by one of:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;p&amp;gt;a) &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; meaning always persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;b) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; meaning never persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;c) The keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; followed by a declaration of a &amp;lt;e&amp;gt;PREDICATE&amp;lt;/e&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;2. An optional body (introduced by the tag &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt;) like the attribute body, and this is code that is executed only if the attribute was not persisted. These routines run after all persisted attributes have been restored, but before the restoration procedure is run. It is only used for initialization of attributes that do not depend &lt;br /&gt;
upon other restoration attribute bodies having been run.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Within a restoration routine as an instruction. Here it is used analagously to a &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; instruction, to run one of the named restoration routines specified in the class of one of the attributes that was not persisted.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class A&lt;br /&gt;
&lt;br /&gt;
create&lt;br /&gt;
 make, make_from_db&lt;br /&gt;
&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
 initialize_attributes, recreate_attributes&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Initialization&lt;br /&gt;
&lt;br /&gt;
 make is&lt;br /&gt;
   -- Initialize `Current' with a new gadget.&lt;br /&gt;
  do&lt;br /&gt;
   initialize_attributes&lt;br /&gt;
   gadget.save_to_database&lt;br /&gt;
   -- other stuff ...&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 make_from_db (a_gadget_id: INTEGER; ...) is&lt;br /&gt;
   -- Initialize `Current' using `a_gadget_id' to create `gadget' from database.&lt;br /&gt;
  do&lt;br /&gt;
    recreate_attributes (a_gadget_id, ...)&lt;br /&gt;
    -- other stuff&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 initialize_attributes is&lt;br /&gt;
   -- Initialize `gadget' and ...&lt;br /&gt;
  do&lt;br /&gt;
   create gadget.make_new&lt;br /&gt;
   -- other stuff ...&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 recreate_attributes (a_gadget_id: INTEGER; ...) is&lt;br /&gt;
   -- Recreate certain attributes.&lt;br /&gt;
  do&lt;br /&gt;
   create_gadget_from_identifier (a_gadget_id)&lt;br /&gt;
   -- other stuff&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
feature -- Access&lt;br /&gt;
&lt;br /&gt;
 gadget: GADGET&lt;br /&gt;
   -- Gadget retrieved from DB via its `id' attribute&lt;br /&gt;
  attribute&lt;br /&gt;
  restore&lt;br /&gt;
   persistance_predicate: agent is_gadget_persisted (attribute.id) -- `True' and `False' would also be acceptable values, &lt;br /&gt;
                                                                   --  with `True' being the default&lt;br /&gt;
   body: agent create_gadget_from_identifier (attribute.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
class B&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
 A&lt;br /&gt;
  redefine&lt;br /&gt;
   make&lt;br /&gt;
  rename&lt;br /&gt;
   gadget as gadget_from_a&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
create&lt;br /&gt;
&lt;br /&gt;
 make&lt;br /&gt;
&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
&lt;br /&gt;
 restore_gadgets&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Initialization&lt;br /&gt;
&lt;br /&gt;
 make is&lt;br /&gt;
   -- Initialize `Current' with a new gadget.&lt;br /&gt;
  do&lt;br /&gt;
   Precursor&lt;br /&gt;
   create gadget.make_new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 restore_gadgets (a_id, a_other_id: INTEGER; ...is&lt;br /&gt;
   -- Restore `gadget' and `gadget_from_a' from database.&lt;br /&gt;
  do&lt;br /&gt;
   restore recreate_attributes (a_other_id, ...)&lt;br /&gt;
   create gadget.make_from_databse (a_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
feature -- Access&lt;br /&gt;
&lt;br /&gt;
 gadget: MY_GADGET&lt;br /&gt;
   -- Gadget createable from database.&lt;br /&gt;
  attribute&lt;br /&gt;
  restore&lt;br /&gt;
   persistance_predicate: False&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the ECMA &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword is reused to denote the instance of `gadget'. This is only available within the attribute restore clause, not in a restoration routine.&lt;br /&gt;
&lt;br /&gt;
Now here are some scenarios in which objects of classes A and B are stored:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
 a: A&lt;br /&gt;
 b: B&lt;br /&gt;
do&lt;br /&gt;
 create a.make&lt;br /&gt;
 create b.make&lt;br /&gt;
&lt;br /&gt;
 -- Save a to a storable, using defaults for retrieval&lt;br /&gt;
 a.independent_store (a_medium)&lt;br /&gt;
 &lt;br /&gt;
 -- Assuming `a.is_gadget_persisted (a.gadget.id)' returns `False', `a.gadget' will not be saved, but `a.gadget.id' will be saved&lt;br /&gt;
 --  for use in the local (attribute-specified) restoration routine `create_gadget_from_identifier.&lt;br /&gt;
&lt;br /&gt;
 -- Save b to a storable specifying a restoration routine&lt;br /&gt;
 b.independent_store (a_medium, agent b.restore_gadgets (b.gadget.id, b.gadget_from_a.id, ...))&lt;br /&gt;
&lt;br /&gt;
 -- Assuming `b.is_gadget_persisted (b.gadget_from_a.id)' returns `False', then neither gadget will be stored, but their identifiers&lt;br /&gt;
 --  will be recorded so they can be passed to `restore_gadgets' at retrieval time.&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redefinition==&lt;br /&gt;
&lt;br /&gt;
The open/closed principle is honoured (I think). The author of the class can determine that an attribute must always be stored (this is the default, and is the current situation), or that it is never stored (for a pure cache attribute), or provide flexibility by specifying an agent.&lt;br /&gt;
&lt;br /&gt;
The agent's routine could be deferred, frozen (yuk!) or just a normal routine, in which case descendant classes can redefine it.&lt;br /&gt;
&lt;br /&gt;
The actual instance data that is passed to the persistance_predicate and the restoration_routine could be specified via an agent, which allows for further flexibility. For restoration, it might even involve an &amp;lt;e&amp;gt;EV_DIALOG&amp;lt;/e&amp;gt; (heaven forfend)!&lt;br /&gt;
&lt;br /&gt;
==Class correctness conditions==&lt;br /&gt;
&lt;br /&gt;
The possibility of the persistance_predicate evaluating to (or statically specified as) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; on an attribute that is required to be non-Void (or non-default for an expanded attribute) implies that either inline restoration code must be supplied, or the restoration routine has an appropriate postcondition clause.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9837</id>
		<title>Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9837"/>
				<updated>2007-10-04T07:56:25Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Completed examples&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Persistence]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s in an application has at least two significant disadvantages. &lt;br /&gt;
&lt;br /&gt;
One is that using them for long-term persistence is vulnerable to changes in the class. &lt;br /&gt;
&lt;br /&gt;
Another is that too much data may be stored, resulting in large files (or database occupancy, or whatever) and slow reload times. Some data, such as internal caches, are probably best not serialized at all. For other data, it may be better just to store a shorthand identifier to enable the data to be rebuilt (maybe on demand) at retrieval time.&lt;br /&gt;
&lt;br /&gt;
This article explores ways to address the second problem. The first problem is best tackled by only using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s as a medium-term caching mechanism.&lt;br /&gt;
&lt;br /&gt;
==Transient data==&lt;br /&gt;
&lt;br /&gt;
Java tackles this problem with the keyword &amp;lt;java&amp;gt;transient&amp;lt;/java&amp;gt;. An attribute so marked is not stored at serialization time. When the object is retrieved the attribute will be void.&lt;br /&gt;
&lt;br /&gt;
This seems rather limited to me. It can't be used if the class invariant constrains the attribute to be non-void. And I don't think there is a way for a descendant class to override this behaviour (it's a long time since I've written any Java, so I could be very wrong here).&lt;br /&gt;
&lt;br /&gt;
My thinking is that there should be a way to specify whether or not a particular attribute should be stored on any given occaision, and a way to specify what to do at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Persistence predicates===&lt;br /&gt;
&lt;br /&gt;
A persistence predicate is a routine of type &amp;lt;e&amp;gt;PREDICATE [ANY, TUPLE [!&amp;lt;attribute_type&amp;gt;]]&amp;lt;/e&amp;gt; associated with an attribute of type &amp;lt;attribute_type&amp;gt;.&lt;br /&gt;
At storage time, the predicate will be called with the instance of the attribute as its argument (if the attribute is non-Void). If it returns &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; then the attribute is stored. If it returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; then the attribute is not stored, but it may be re-created at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Restoration routines===&lt;br /&gt;
&lt;br /&gt;
If a persistence predicate returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt;, it may be that the programmer does not need this data at all (such as the case of an internal cache). But in some cases the programmer will want the data to be recreated at restoration time (this may be necessary to restore the class invariant), rather than retrieved from the persistence mechanism. &lt;br /&gt;
&lt;br /&gt;
Take an example of a class which has an attribute named &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; having an attribute named &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;INTEGER&amp;lt;/e&amp;gt;. The class invariant requires that&amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is not &amp;lt;e&amp;gt;Void&amp;lt;/e&amp;gt;, but the size required to store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is very large. The class also has a secret routine &amp;lt;e&amp;gt;`create_gadget_from_identifier (a_id: INTEGER)&amp;lt;/e&amp;gt; which can be used to create a &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; given its &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value. In such a case, rather than store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; it is probably better to just store the &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value, and then call &amp;lt;e&amp;gt;`create_gadget_from_identifier'&amp;lt;/e&amp;gt; at retrieval time.&lt;br /&gt;
&lt;br /&gt;
A restoration routine is similar to a creation procedure, in as much as it cannot reply on the class invariant holding. It can rely on attributes for which the persistence predicate evaluates to &amp;lt;e&amp;gt;True &amp;lt;/e&amp;gt; as having been restored, though.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
One new keyword &amp;lt;e&amp;gt;restore&amp;lt;/e&amp;gt; will be required. This can occur in several places:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; clause in the class prolog. What follows is a list of restoration routines, just like the list of creation procedures. Typically this will occur in the form:&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
 recreate_attributes&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword and optional body. What follows is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;1. The tag &amp;lt;e&amp;gt;persistence_predicate:&amp;lt;/e&amp;gt; followed by one of:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;p&amp;gt;a) &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; meaning always persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;b) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; meaning never persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;c) The keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; followed by a declaration of a &amp;lt;e&amp;gt;PREDICATE&amp;lt;/e&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;2. An optional body (introduced by the tag &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt;) like the attribute body, and this is code that is executed only if the attribute was not persisted. These routines run after all persisted attributes have been restored, but before the restoration procedure is run. It is only used for initialization of attributes that do not depend &lt;br /&gt;
upon other restoration attribute bodies having been run.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Within a restoration routine as an instruction. Here it is used analagously to a &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; instruction, to run one of the named restoration routines specified in the class of one of the attributes that was not persisted.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class A&lt;br /&gt;
&lt;br /&gt;
create&lt;br /&gt;
 make, make_from_db&lt;br /&gt;
&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
 initialize_attributes, recreate_attributes&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Initialization&lt;br /&gt;
&lt;br /&gt;
 make is&lt;br /&gt;
   -- Initialize `Current' with a new gadget.&lt;br /&gt;
  do&lt;br /&gt;
   initialize_attributes&lt;br /&gt;
   gadget.save_to_database&lt;br /&gt;
   -- other stuff ...&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 make_from_db (a_gadget_id: INTEGER; ...) is&lt;br /&gt;
   -- Initialize `Current' using `a_gadget_id' to create `gadget' from database.&lt;br /&gt;
  do&lt;br /&gt;
    recreate_attributes (a_gadget_id, ...)&lt;br /&gt;
    -- other stuff&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 initialize_attributes is&lt;br /&gt;
   -- Initialize `gadget' and ...&lt;br /&gt;
  do&lt;br /&gt;
   create gadget.make_new&lt;br /&gt;
   -- other stuff ...&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 recreate_attributes (a_gadget_id: INTEGER; ...) is&lt;br /&gt;
   -- Recreate certain attributes.&lt;br /&gt;
  do&lt;br /&gt;
   create_gadget_from_identifier (a_gadget_id)&lt;br /&gt;
   -- other stuff&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
feature -- Access&lt;br /&gt;
&lt;br /&gt;
 gadget: GADGET&lt;br /&gt;
   -- Gadget retrieved from DB via its `id' attribute&lt;br /&gt;
  attribute&lt;br /&gt;
  restore&lt;br /&gt;
   persistance_predicate: agent is_gadget_persisted (attribute.id) -- `True' and `False' would also be acceptable values, &lt;br /&gt;
                                                                   --  with `True' being the default&lt;br /&gt;
   body: agent create_gadget_from_identifier (attribute.id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
class B&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
 A&lt;br /&gt;
  redefine&lt;br /&gt;
   make&lt;br /&gt;
  rename&lt;br /&gt;
   gadget as gadget_from_a&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
create&lt;br /&gt;
&lt;br /&gt;
 make&lt;br /&gt;
&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
&lt;br /&gt;
 restore_gadgets&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Initialization&lt;br /&gt;
&lt;br /&gt;
 make is&lt;br /&gt;
   -- Initialize `Current' with a new gadget.&lt;br /&gt;
  do&lt;br /&gt;
   Precursor&lt;br /&gt;
   create gadget.make_new&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
 restore_gadgets (a_id, a_other_id: INTEGER; ...is&lt;br /&gt;
   -- Restore `gadget' and `gadget_from_a' from database.&lt;br /&gt;
  do&lt;br /&gt;
   restore recreate_attributes (a_other_id, ...)&lt;br /&gt;
   create gadget.make_from_databse (a_id)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
feature -- Access&lt;br /&gt;
&lt;br /&gt;
 gadget: MY_GADGET&lt;br /&gt;
   -- Gadget createable from database.&lt;br /&gt;
  attribute&lt;br /&gt;
  restore&lt;br /&gt;
   presistence_predicate: False&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the ECMA &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword is reused to denote the instance of `gadget'. This is only available within the attribute restore clause, not in a restoration routine.&lt;br /&gt;
&lt;br /&gt;
Now here are some scenarios in which objects of classes A and B are stored:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
 a: A&lt;br /&gt;
 b: B&lt;br /&gt;
do&lt;br /&gt;
 create a.make&lt;br /&gt;
 create b.make&lt;br /&gt;
&lt;br /&gt;
 -- Save a to a storable, using defaults for retrieval&lt;br /&gt;
 a.independent_store (a_medium)&lt;br /&gt;
 &lt;br /&gt;
 -- Assuming `a.is_gadget_persisted (a.gadget.id)' returns `False', `a.gadget' will not be saved, but `a.gadget.id' will be saved&lt;br /&gt;
 --  for use in the local (attribute-specified) restoration routine `create_gadget_from_identifier.&lt;br /&gt;
&lt;br /&gt;
 -- Save b to a storable specifying a restoration routine&lt;br /&gt;
 b.independent_store (a_medium, agent b.restore_gadgets (b.gadget.id, b.gadget_from_a.id, ...))&lt;br /&gt;
&lt;br /&gt;
 -- Assuming `b.is_gadget_persisted (b.gadget_from_a.id)' returns `False', then neither gadget will be stored, but their identifiers&lt;br /&gt;
 --  will be recorded so they can be passed to `restore_gadgets' at retrieval time.&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Redefinition==&lt;br /&gt;
&lt;br /&gt;
The open/closed principle is honoured (I think). The author of the class can determine that an attribute must always be stored (this is the default, and is the current situation), or that it is never stored (for a pure cache attribute), or provide flexibility by specifying an agent.&lt;br /&gt;
&lt;br /&gt;
The agent's routine could be deferred, frozen (yuk!) or just a normal routine, in which case descendant classes can redefine it.&lt;br /&gt;
&lt;br /&gt;
The actual instance data that is passed to the persistance_predicate and the restoration_routine could be specified via an agent, which allows for further flexibility. For restoration, it might even involve an &amp;lt;e&amp;gt;EV_DIALOG&amp;lt;/e&amp;gt; (heaven forfend)!&lt;br /&gt;
&lt;br /&gt;
==Class correctness conditions==&lt;br /&gt;
&lt;br /&gt;
The possibility of the persistance_predicate evaluating to (or statically specified as) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; on an attribute that is required to be non-Void (or non-default for an expanded attribute) implies that either inline restoration code must be supplied, or the restoration routine has an appropriate postcondition clause.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9836</id>
		<title>Talk:Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9836"/>
				<updated>2007-10-04T07:05:58Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Agent keyword was missing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:21, 3 October 2007 (CEST)&lt;br /&gt;
It would be nice to extend the example to see where the &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; attribute is serialized (given that the attribute &amp;lt;e&amp;gt;gadget&amp;lt;/e&amp;gt; is not serialized at all).&lt;br /&gt;
&lt;br /&gt;
== Transformation at store time ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:49, 3 October 2007 (CEST)&lt;br /&gt;
The proposed scheme assumes that some attributes need to be stored and some - not. However, it's possible that the object model is changed over time, but backward compatibility as well as interoperability with other applications is still required. For example, the original program used the RGB color model with the attributes corresponding to the main colors. Over time it turned out that another model, say, HSV one, is more approriate for the associated algorithms and the attributes were replaced by the new ones. Both models cover the same range of spectrum but use different attribute sets.&lt;br /&gt;
&lt;br /&gt;
For example, the systems A and B use the original RGB coding scheme and the new system A' uses new HSV scheme. For interoperability between all these products (given that they are used on multiple machines and cannot be immediately updated, or even worse, the system B is no longer maintained), it's essential to stick to the original storable format. It means that there should be a way to store new attributes of HSV model using the old RGB style.&lt;br /&gt;
&lt;br /&gt;
: On the other hand, the new development can go on and new systems are designed to use HSV model from the beginning. There is no need to use the old format anymore, given that the new systems A' are able to store the data in a new format as well. As far as I can see, this can be achieved by the predicate on the corresponding attributes that tell whether they need to be stored &amp;quot;as is&amp;quot; or not. This behaviour is easily achieved using the proposed technique with predicates if there is also a way to store data in the old format.&lt;br /&gt;
&lt;br /&gt;
The incompleteness of the example is why the page is still marked as under construction.&lt;br /&gt;
&lt;br /&gt;
As for the long-term issue, I explicitly said I was not addressing this in the article. Using storables for a short-to-medium term cache is good. For longer term persistence, a proper database schema is needed, I think (I shall be interested to see what comes out of the persistence project).&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:31, 4 October 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Agent keyword was missing ==&lt;br /&gt;
&lt;br /&gt;
I just noticed your point about &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; - I had missed out the keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; following the &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt; tag.&lt;br /&gt;
This produces a closed agent (and therefore incorporates the id value). The idea was that somehow the closed agent gets stored in the storable. But maybe this is not possible and/or desirable (if the code for the agent has changed in the meantime, then it is must be better to use the updated code). In which case the storing mechanism can &amp;lt;em&amp;gt;infer&amp;lt;/em&amp;gt; the need to store &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt;, but only for the purpose of closing the agent built at restore time. Does that make sense?&lt;br /&gt;
&lt;br /&gt;
Anyway, I still have to provide a more comprehensive example.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:05, 4 October 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9835</id>
		<title>Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9835"/>
				<updated>2007-10-04T06:58:10Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Added missing agent keyword&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Persistence]]&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
{{Research}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s in an application has at least two significant disadvantages. &lt;br /&gt;
&lt;br /&gt;
One is that using them for long-term persistence is vulnerable to changes in the class. &lt;br /&gt;
&lt;br /&gt;
Another is that too much data may be stored, resulting in large files (or database occupancy, or whatever) and slow reload times. Some data, such as internal caches, are probably best not serialized at all. For other data, it may be better just to store a shorthand identifier to enable the data to be rebuilt (maybe on demand) at retrieval time.&lt;br /&gt;
&lt;br /&gt;
This article explores ways to address the second problem. The first problem is best tackled by only using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s as a medium-term caching mechanism.&lt;br /&gt;
&lt;br /&gt;
==Transient data==&lt;br /&gt;
&lt;br /&gt;
Java tackles this problem with the keyword &amp;lt;java&amp;gt;transient&amp;lt;/java&amp;gt;. An attribute so marked is not stored at serialization time. When the object is retrieved the attribute will be void.&lt;br /&gt;
&lt;br /&gt;
This seems rather limited to me. It can't be used if the class invariant constrains the attribute to be non-void. And I don't think there is a way for a descendant class to override this behaviour (it's a long time since I've written any Java, so I could be very wrong here).&lt;br /&gt;
&lt;br /&gt;
My thinking is that there should be a way to specify whether or not a particular attribute should be stored on any given occaision, and a way to specify what to do at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Persistence predicates===&lt;br /&gt;
&lt;br /&gt;
A persistence predicate is a routine of type &amp;lt;e&amp;gt;PREDICATE [ANY, TUPLE [!&amp;lt;attribute_type&amp;gt;]]&amp;lt;/e&amp;gt; associated with an attribute of type &amp;lt;attribute_type&amp;gt;.&lt;br /&gt;
At storage time, the predicate will be called with the instance of the attribute as its argument (if the attribute is non-Void). If it returns &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; then the attribute is stored. If it returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; then the attribute is not stored, but it may be re-created at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Restoration routines===&lt;br /&gt;
&lt;br /&gt;
If a persistence predicate returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt;, it may be that the programmer does not need this data at all (such as the case of an internal cache). But in some cases the programmer will want the data to be recreated at restoration time (this may be necessary to restore the class invariant), rather than retrieved from the persistence mechanism. &lt;br /&gt;
&lt;br /&gt;
Take an example of a class which has an attribute named &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; having an attribute named &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;INTEGER&amp;lt;/e&amp;gt;. The class invariant requires that&amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is not &amp;lt;e&amp;gt;Void&amp;lt;/e&amp;gt;, but the size required to store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is very large. The class also has a secret routine &amp;lt;e&amp;gt;`create_gadget_from_identifier (a_id: INTEGER)&amp;lt;/e&amp;gt; which can be used to create a &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; given its &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value. In such a case, rather than store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; it is probably better to just store the &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value, and then call &amp;lt;e&amp;gt;`create_gadget_from_identifier'&amp;lt;/e&amp;gt; at retrieval time.&lt;br /&gt;
&lt;br /&gt;
A restoration routine is similar to a creation procedure, in as much as it cannot reply on the class invariant holding. It can rely on attributes for which the persistence predicate evaluates to &amp;lt;e&amp;gt;True &amp;lt;/e&amp;gt; as having been restored, though.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
One new keyword &amp;lt;e&amp;gt;restore&amp;lt;/e&amp;gt; will be required. This can occur in several places:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; clause in the class prolog. What follows is a list of restoration routines, just like the list of creation procedures. Typically this will occur in the form:&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
 recreate_attributes&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword and optional body. What follows is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;1. The tag &amp;lt;e&amp;gt;persistence_predicate:&amp;lt;/e&amp;gt; followed by one of:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;p&amp;gt;a) &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; meaning always persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;b) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; meaning never persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;c) The keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; followed by a declaration of a &amp;lt;e&amp;gt;PREDICATE&amp;lt;/e&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;2. An optional body (introduced by the tag &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt;) like the attribute body, and this is code that is executed only if the attribute was not persisted. These routines run after all persisted attributes have been restored, but before the restoration procedure is run. It is only used for initialization of attributes that do not depend &lt;br /&gt;
upon other restoration attribute bodies having been run.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Within a restoration routine as an instruction. Here it is used analagously to a &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; instruction, to run one of the named restoration routines specified in the class of one of the attributes that was not persisted.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
 gadget: GADGET_FROM_DATABASE&lt;br /&gt;
   -- Gadget retrieved from DB via its `id' attribute&lt;br /&gt;
  attribute&lt;br /&gt;
   ...&lt;br /&gt;
  restore&lt;br /&gt;
   persistance_predicate: agent is_gadget_persisted (attribute.id) -- `True' and `False' would also be acceptable values, &lt;br /&gt;
                                                                   --  with `True' being the default&lt;br /&gt;
   body: agent create_gadget_from_identifier (attribute.id)&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the ECMA &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword is reused to denote the instance of `gadget'. This is only available within the attribute restore clause, not in a restoration routine.&lt;br /&gt;
&lt;br /&gt;
==Redefinition==&lt;br /&gt;
&lt;br /&gt;
The open/closed principle is honoured (I think). The author of the class can determine that an attribute must always be stored (this is the default, and is the current situation), or that it is never stored (for a pure cache attribute), or provide flexibility by specifying an agent.&lt;br /&gt;
&lt;br /&gt;
The agent's routine could be deferred, frozen (yuk!) or just a normal routine, in which case descendant classes can redefine it.&lt;br /&gt;
&lt;br /&gt;
The actual instance data that is passed to the persistance_predicate and the restoration_routine could be specified via an agent, which allows for further flexibility. For restoration, it might even involve an &amp;lt;e&amp;gt;EV_DIALOG&amp;lt;/e&amp;gt; (heaven forfend)!&lt;br /&gt;
&lt;br /&gt;
==Class correctness conditions==&lt;br /&gt;
&lt;br /&gt;
The possibility of the persistance_predicate evaluating to (or statically specified as) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; on an attribute that is required to be non-Void (or non-default for an expanded attribute) implies that either inline restoration code must be supplied, or the restoration routine has an appropriate postcondition clause.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9834</id>
		<title>Talk:Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Persistence_predicates&amp;diff=9834"/>
				<updated>2007-10-04T06:31:01Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:21, 3 October 2007 (CEST)&lt;br /&gt;
It would be nice to extend the example to see where the &amp;lt;e&amp;gt;gadget.id&amp;lt;/e&amp;gt; attribute is serialized (given that the attribute &amp;lt;e&amp;gt;gadget&amp;lt;/e&amp;gt; is not serialized at all).&lt;br /&gt;
&lt;br /&gt;
== Transformation at store time ==&lt;br /&gt;
&lt;br /&gt;
--[[User:Alexander Kogtenkov|Alexander Kogtenkov]] 21:49, 3 October 2007 (CEST)&lt;br /&gt;
The proposed scheme assumes that some attributes need to be stored and some - not. However, it's possible that the object model is changed over time, but backward compatibility as well as interoperability with other applications is still required. For example, the original program used the RGB color model with the attributes corresponding to the main colors. Over time it turned out that another model, say, HSV one, is more approriate for the associated algorithms and the attributes were replaced by the new ones. Both models cover the same range of spectrum but use different attribute sets.&lt;br /&gt;
&lt;br /&gt;
For example, the systems A and B use the original RGB coding scheme and the new system A' uses new HSV scheme. For interoperability between all these products (given that they are used on multiple machines and cannot be immediately updated, or even worse, the system B is no longer maintained), it's essential to stick to the original storable format. It means that there should be a way to store new attributes of HSV model using the old RGB style.&lt;br /&gt;
&lt;br /&gt;
: On the other hand, the new development can go on and new systems are designed to use HSV model from the beginning. There is no need to use the old format anymore, given that the new systems A' are able to store the data in a new format as well. As far as I can see, this can be achieved by the predicate on the corresponding attributes that tell whether they need to be stored &amp;quot;as is&amp;quot; or not. This behaviour is easily achieved using the proposed technique with predicates if there is also a way to store data in the old format.&lt;br /&gt;
&lt;br /&gt;
The incompleteness of the example is why the page is still marked as under construction.&lt;br /&gt;
&lt;br /&gt;
As for the long-term issue, I explicitly said I was not addressing this in the article. Using storables for a short-to-medium term cache is good. For longer term persistence, a proper database schema is needed, I think (I shall be interested to see what comes out of the persistence project).&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:31, 4 October 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Implicit_class&amp;diff=9828</id>
		<title>Talk:Implicit class</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Implicit_class&amp;diff=9828"/>
				<updated>2007-10-03T08:03:43Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;When you say downcast, presumably you mean an object test (as assignment attempt has been dropped from ECMA)?&lt;br /&gt;
&lt;br /&gt;
So your second case is equivalent to saying that an object test for a STRING_EXTRA always succeeds if the actual object is a STRING.&lt;br /&gt;
&lt;br /&gt;
Your example only makes use of the feature &amp;lt;e&amp;gt;`count'&amp;lt;/e&amp;gt; from &amp;lt;e&amp;gt;STRING&amp;lt;/e&amp;gt;, and so all that is actually needed is that the object concerned has a feature &amp;lt;e&amp;gt;count: INTEGER&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
So perhaps rather than inheriting from &amp;lt;e&amp;gt;STRING&amp;lt;/e&amp;gt;, you provide a deferred feature definition, and the object test passes if the tested object posseses a feature that matches the name, signature an contract.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 10:03, 3 October 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Environment_Roadmap&amp;diff=9815</id>
		<title>Talk:Environment Roadmap</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Environment_Roadmap&amp;diff=9815"/>
				<updated>2007-09-29T06:50:44Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: SCOOP?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I don't see any mention of SCOOP. I understood that it was to be incorporated into the compiler soon. Any plans?&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:50, 29 September 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9783</id>
		<title>Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9783"/>
				<updated>2007-09-28T07:08:32Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Restore keyword added. persistence keyword removed.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Persistence]]&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
{{Research}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s in an application has at least two significant disadvantages. &lt;br /&gt;
&lt;br /&gt;
One is that using them for long-term persistence is vulnerable to changes in the class. &lt;br /&gt;
&lt;br /&gt;
Another is that too much data may be stored, resulting in large files (or database occupancy, or whatever) and slow reload times. Some data, such as internal caches, are probably best not serialized at all. For other data, it may be better just to store a shorthand identifier to enable the data to be rebuilt (maybe on demand) at retrieval time.&lt;br /&gt;
&lt;br /&gt;
This article explores ways to address the second problem. The first problem is best tackled by only using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s as a medium-term caching mechanism.&lt;br /&gt;
&lt;br /&gt;
==Transient data==&lt;br /&gt;
&lt;br /&gt;
Java tackles this problem with the keyword &amp;lt;java&amp;gt;transient&amp;lt;/java&amp;gt;. An attribute so marked is not stored at serialization time. When the object is retrieved the attribute will be void.&lt;br /&gt;
&lt;br /&gt;
This seems rather limited to me. It can't be used if the class invariant constrains the attribute to be non-void. And I don't think there is a way for a descendant class to override this behaviour (it's a long time since I've written any Java, so I could be very wrong here).&lt;br /&gt;
&lt;br /&gt;
My thinking is that there should be a way to specify whether or not a particular attribute should be stored on any given occaision, and a way to specify what to do at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Persistence predicates===&lt;br /&gt;
&lt;br /&gt;
A persistence predicate is a routine of type &amp;lt;e&amp;gt;PREDICATE [ANY, TUPLE [!&amp;lt;attribute_type&amp;gt;]]&amp;lt;/e&amp;gt; associated with an attribute of type &amp;lt;attribute_type&amp;gt;.&lt;br /&gt;
At storage time, the predicate will be called with the instance of the attribute as its argument (if the attribute is non-Void). If it returns &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; then the attribute is stored. If it returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; then the attribute is not stored, but it may be re-created at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Restoration routines===&lt;br /&gt;
&lt;br /&gt;
If a persistence predicate returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt;, it may be that the programmer does not need this data at all (such as the case of an internal cache). But in some cases the programmer will want the data to be recreated at restoration time (this may be necessary to restore the class invariant), rather than retrieved from the persistence mechanism. &lt;br /&gt;
&lt;br /&gt;
Take an example of a class which has an attribute named &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; having an attribute named &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;INTEGER&amp;lt;/e&amp;gt;. The class invariant requires that&amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is not &amp;lt;e&amp;gt;Void&amp;lt;/e&amp;gt;, but the size required to store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is very large. The class also has a secret routine &amp;lt;e&amp;gt;`create_gadget_from_identifier (a_id: INTEGER)&amp;lt;/e&amp;gt; which can be used to create a &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; given its &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value. In such a case, rather than store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; it is probably better to just store the &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value, and then call &amp;lt;e&amp;gt;`create_gadget_from_identifier'&amp;lt;/e&amp;gt; at retrieval time.&lt;br /&gt;
&lt;br /&gt;
A restoration routine is similar to a creation procedure, in as much as it cannot reply on the class invariant holding. It can rely on attributes for which the persistence predicate evaluates to &amp;lt;e&amp;gt;True &amp;lt;/e&amp;gt; as having been restored, though.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
One new keyword &amp;lt;e&amp;gt;restore&amp;lt;/e&amp;gt; will be required. This can occur in several places:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; clause in the class prolog. What follows is a list of restoration routines, just like the list of creation procedures. Typically this will occur in the form:&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
restore {STORABLE}&lt;br /&gt;
 recreate_attributes&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;After the &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword and optional body. What follows is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;1. The tag &amp;lt;e&amp;gt;persistence_predicate:&amp;lt;/e&amp;gt; followed by one of:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;p&amp;gt;a) &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; meaning always persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;b) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; meaning never persist.&amp;lt;/p&amp;gt;&lt;br /&gt;
 &amp;lt;p&amp;gt;c) The keyword &amp;lt;e&amp;gt;agent&amp;lt;/e&amp;gt; followed by a declaration of a &amp;lt;e&amp;gt;PREDICATE&amp;lt;/e&amp;gt;.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;2. An optional body (introduced by the tag &amp;lt;e&amp;gt;body:&amp;lt;/e&amp;gt;) like the attribute body, and this is code that is executed only if the attribute was not persisted. These routines run after all persisted attributes have been restored, but before the restoration procedure is run. It is only used for initialization of attributes that do not depend &lt;br /&gt;
upon other restoration attribute bodies having been run.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
Within a restoration routine as an instruction. Here it is used analagously to a &amp;lt;e&amp;gt;create&amp;lt;/e&amp;gt; instruction, to run one of the named restoration routines specified in the class of one of the attributes that was not persisted.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
 gadget: GADGET_FROM_DATABASE&lt;br /&gt;
   -- Gadget retrieved from DB via its `id' attribute&lt;br /&gt;
  attribute&lt;br /&gt;
   ...&lt;br /&gt;
  restore&lt;br /&gt;
   persistance_predicate: agent is_gadget_persisted (attribute.id) -- `True' and `False' would also be acceptable values, &lt;br /&gt;
                                                                   --  with `True' being the default&lt;br /&gt;
   body: create_gadget_from_identifier (attribute.id)&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the ECMA &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword is reused to denote the instance of `gadget'. This is only available within the attribute restore clause, not in a restoration routine.&lt;br /&gt;
&lt;br /&gt;
==Redefinition==&lt;br /&gt;
&lt;br /&gt;
The open/closed principle is honoured (I think). The author of the class can determine that an attribute must always be stored (this is the default, and is the current situation), or that it is never stored (for a pure cache attribute), or provide flexibility by specifying an agent.&lt;br /&gt;
&lt;br /&gt;
The agent's routine could be deferred, frozen (yuk!) or just a normal routine, in which case descendant classes can redefine it.&lt;br /&gt;
&lt;br /&gt;
The actual instance data that is passed to the persistance_predicate and the restoration_routine could be specified via an agent, which allows for further flexibility. For restoration, it might even involve an &amp;lt;e&amp;gt;EV_DIALOG&amp;lt;/e&amp;gt; (heaven forfend)!&lt;br /&gt;
&lt;br /&gt;
==Class correctness conditions==&lt;br /&gt;
&lt;br /&gt;
The possibility of the persistance_predicate evaluating to (or statically specified as) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; on an attribute that is required to be non-Void (or non-default for an expanded attribute) implies that either inline restoration code must be supplied, or the restoration routine has an appropriate postcondition clause.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9782</id>
		<title>Persistence predicates</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Persistence_predicates&amp;diff=9782"/>
				<updated>2007-09-27T09:15:42Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Persistence]]&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
{{Research}}&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
Using &amp;lt;e&amp;gt;STORABLE&amp;lt;/e&amp;gt;s in an application has at least two significant disadvantages. &lt;br /&gt;
&lt;br /&gt;
One is that using them for long-term persistence is vulnerable to changes in the class. &lt;br /&gt;
&lt;br /&gt;
Another is that too much data may be stored, resulting in large files (or database occupancy, or whatever) and slow reload times. Some data, such as internal caches, are probably best not serialized at all. For other data, it may be better just to store a shorthand identifier to enable the data to be rebuilt (maybe on demand) at retrieval time.&lt;br /&gt;
&lt;br /&gt;
This article explores ways to address the second problem.&lt;br /&gt;
&lt;br /&gt;
==Transient data==&lt;br /&gt;
&lt;br /&gt;
Java tackles this problem with the keyword &amp;lt;java&amp;gt;transient&amp;lt;/java&amp;gt;. An attribute so marked is not stored at serialization time. When the object is retrieved the attribute will be void.&lt;br /&gt;
&lt;br /&gt;
This seems rather limited to me. It can't be used if the class invariant constrains the attribute to be non-void. And I don't think there is a way for a descendant class to override this behaviour (it's a long time since I've written any Java, so I could be very wrong here).&lt;br /&gt;
&lt;br /&gt;
My thinking is that there should be a way to specify whether or not a particular attribute should be stored on any given occaision, and a way to specify what to do at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Persistence predicates===&lt;br /&gt;
&lt;br /&gt;
A persistence predicate is a routine of type &amp;lt;e&amp;gt;PREDICATE [ANY, TUPLE [!&amp;lt;attribute_type&amp;gt;]]&amp;lt;/e&amp;gt; associated with an attribute of type &amp;lt;attribute_type&amp;gt;.&lt;br /&gt;
At storage time, the predicate will be called with the instance of the attribute as its argument (if the attribute is non-Void). If it returns &amp;lt;e&amp;gt;True&amp;lt;/e&amp;gt; then the attribute is stored. If it returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; then the attribute is not stored, but it may be re-created at retrieval time.&lt;br /&gt;
&lt;br /&gt;
===Restoration routines===&lt;br /&gt;
&lt;br /&gt;
If a persistence predicate returns &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt;, it may be that the programmer does not need this data at all (such as the case of an internal cache). But in some cases the programmer will want the data to be recreated at restoration time (this may be necessary to restore the class invariant), rather than retrieved from the persistence mechanism. &lt;br /&gt;
&lt;br /&gt;
Take an example of a class which has an attribute named &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; having an attribute named &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; of type &amp;lt;e&amp;gt;INTEGER&amp;lt;/e&amp;gt;. The class invariant requires that&amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is not &amp;lt;e&amp;gt;Void&amp;lt;/e&amp;gt;, but the size required to store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; is very large. The class also has a secret routine &amp;lt;e&amp;gt;`gadget_from_identifier (a_id: INTEGER): GADGET_FROM_DATABASE'&amp;lt;/e&amp;gt; which can be used to create a &amp;lt;e&amp;gt;GADGET_FROM_DATABASE&amp;lt;/e&amp;gt; given its &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value. In such a case, rather than store &amp;lt;e&amp;gt;`gadget'&amp;lt;/e&amp;gt; it is probably better to just store the &amp;lt;e&amp;gt;`id'&amp;lt;/e&amp;gt; value, and then call &amp;lt;e&amp;gt;`gadget_from_identifier'&amp;lt;/e&amp;gt; at retrieval time.&lt;br /&gt;
&lt;br /&gt;
A restoration routine is a routine of type &amp;lt;e&amp;gt;FUNCTION [ANY, TUPLE, {?|!}&amp;lt;attribute_type&amp;gt;]&amp;lt;/e&amp;gt; associated with an attribute of type &amp;lt;attribute_type&amp;gt; which is called at retrieval time to restore the attribute.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&lt;br /&gt;
Very hazy thoughts here. I did think about using indexing terms, but I'm not sure if they are appropriate. &lt;br /&gt;
&lt;br /&gt;
Maybe one new keyword &amp;lt;e&amp;gt;persistence&amp;lt;/e&amp;gt; will be required. Perhaps after the keyword &amp;lt;e&amp;gt;persistence&amp;lt;/e&amp;gt; we will see something looking like indexing terms:&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
 gadget: GADGET_FROM_DATABASE&lt;br /&gt;
   -- Gadget retrieved from DB via its `id' attribute&lt;br /&gt;
  attribute&lt;br /&gt;
   ...&lt;br /&gt;
  persistence&lt;br /&gt;
   persistance_predicate: agent is_gadget_persisted (attribute.id) -- `True' and `False' would also be acceptable values, &lt;br /&gt;
                                                                   --  with `True' being the default&lt;br /&gt;
   restoration_routine: agent gadget_from_identifier (attribute.id) -- Default is not to restore&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the ECMA &amp;lt;e&amp;gt;attribute&amp;lt;/e&amp;gt; keyword is reused to denote the instance of `gadget'.&lt;br /&gt;
&lt;br /&gt;
==Redefinition==&lt;br /&gt;
&lt;br /&gt;
The open/closed principle is honoured (I think). The author of the class can determine that an attribute must always be stored (this is the default, and is the current situation), or that it is never stored (for a pure cache attribute), or provide flexibility by specifying an agent.&lt;br /&gt;
&lt;br /&gt;
The agent's routine could be deferred, frozen (yuk!) or just a normal routine, in which case descendant classes can redefine it.&lt;br /&gt;
&lt;br /&gt;
The actual instance data that is passed to the persistance_predicate and the restoration_routine could be specified via an agent, which allows for further flexibility. For restoration, it might even involve an &amp;lt;e&amp;gt;EV_DIALOG&amp;lt;/e&amp;gt; (heaven forfend)!&lt;br /&gt;
&lt;br /&gt;
==Class correctness conditions==&lt;br /&gt;
&lt;br /&gt;
The possibility of the persistance_predicate evaluating to (or statically specified as) &amp;lt;e&amp;gt;False&amp;lt;/e&amp;gt; on an attribute that is required to be non-Void (or non-default for an expanded attribute) implies that the restoration routine must be specified in such cases. The use of an attached type as the return value of the restoration routine will be necessary to ensure class correctness in the case of invariant clauses which specify a non-Void attribute.&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Restrict&amp;diff=9777</id>
		<title>Talk:Restrict</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Restrict&amp;diff=9777"/>
				<updated>2007-09-20T17:26:40Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;--[[User:Clemahieu|Clemahieu]] 18:04, 20 September 2007 (CEST)I would have to disagree with the elegance of this solution.&lt;br /&gt;
&lt;br /&gt;
If we have a virtual restricted form of ANIMAL that CAT conforms to, let's say ANIMAL1, but ANIMAL1 does not conform to ANIMAL, what is the point of defining ANIMAL1?  In the future when there are new virtual covariant forms of ANIMAL, ANIMAL2, ANIMAL3, that have different combinations of restrictions but none of which conform to ANIMAL or each other, what is the point of having them?  Why not just use CAT, or DOG instead of CAT -&amp;gt; ANIMAL1 or DOG -&amp;gt; ANIMAL2.  If features of ANIMAL don't make sense for a specific subclass, ANIMAL is not an abstraction of this subclass by the very definition.&lt;br /&gt;
&lt;br /&gt;
In this case, sleep should not be in the definition of ANIMAL, but instead in a class ANIMALS_THAT_SLEEP to which cat does not conform.&lt;br /&gt;
&lt;br /&gt;
The same thing with an animal eating food.  If a specific animal cannot eat the definition of food that is defined in ANIMAL, then it is not an ANIMAL because it can't eat that food.&lt;br /&gt;
&lt;br /&gt;
I may be biased, I prefer using generics with generic constraints as opposed to covariant redefinition.&lt;br /&gt;
&lt;br /&gt;
ANIMAL is an abstraction of things that conform to it.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:41, 20 September 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:Ericb|Ericb]] 16:53, 20 September 2007 (CEST):&lt;br /&gt;
What I don't like with this kind of solution, and I already expressed that feeling at ECMA meetings, is that it will make the declaration of the type of the entities too verbose to my taste. But perhaps I'm wrong.&lt;br /&gt;
Another thing that I don't like is that it gives me the impression that now the signature of features will have to expose what covariantly redefined features they call or not in their implementation. If this is the really the case, then do we really want implementation details to be visible from the interface in the such a way?&lt;br /&gt;
&lt;br /&gt;
--[[User:Clemahieu|Clemahieu]] 19:05, 20 September 2007 (CEST)&lt;br /&gt;
Do two different classes with identical restrict clauses conform to each other?  If so we've basically created an anonymous class.  If not, what's the point of creating a virtual class if one and only one class conforms to it and it's a one to one mapping of class definition?&lt;br /&gt;
&lt;br /&gt;
Two different classes that inherit from the same class with the same restriction clause are both conform to the same virtual class. Whether or not they conform to each other, depends on what other features they might add.&lt;br /&gt;
&lt;br /&gt;
As for the verbosity of the declarations, in cases where this is great, an anchor can be used.&lt;br /&gt;
&lt;br /&gt;
I don't understand about exposing which covariant features they call in their implementation - can you expand on this?&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 19:26, 20 September 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:Restrict&amp;diff=9773</id>
		<title>Talk:Restrict</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:Restrict&amp;diff=9773"/>
				<updated>2007-09-20T06:41:40Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I would have to disagree with the elegance of this solution.&lt;br /&gt;
&lt;br /&gt;
If we have a virtual restricted form of ANIMAL that CAT conforms to, let's say ANIMAL1, but ANIMAL1 does not conform to ANIMAL, what is the point of defining ANIMAL1?  In the future when there are new virtual covariant forms of ANIMAL, ANIMAL2, ANIMAL3, that have different combinations of restrictions but none of which conform to ANIMAL or each other, what is the point of having them?  Why not just use CAT, or DOG instead of CAT -&amp;gt; ANIMAL1 or DOG -&amp;gt; ANIMAL2.  If ANIMAL is not an abstraction of things that conform to it, it's not an abstraction by the very definition.&lt;br /&gt;
&lt;br /&gt;
In this case, sleep should not be in the definition of ANIMAL, but instead in a class ANIMALS_THAT_SLEEP to which cat does not conform.&lt;br /&gt;
&lt;br /&gt;
The same thing with an animal eating food.  If a specific animal cannot eat the definition of food that is defined in animal, then it is not an animal because it can't eat that food.&lt;br /&gt;
&lt;br /&gt;
I may be biased, I prefer using generics with generic constraints as opposed to covariant redefinition.&lt;br /&gt;
&lt;br /&gt;
ANIMAL is an abstraction of things that conform to it.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:41, 20 September 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9763</id>
		<title>Without /except</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9763"/>
				<updated>2007-09-18T15:10:34Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Replaced by [[restrict]]&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Restrict&amp;diff=9762</id>
		<title>Restrict</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Restrict&amp;diff=9762"/>
				<updated>2007-09-18T15:09:11Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: ECMA]]&lt;br /&gt;
[[Category:Catcall]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
By allowing covariant feature redefinition and hiding of features, the Eiffel language introduces the problem of cat-calls (Changed Availability or Type). The restrict mechanism prevents this by introducing new derived types whenever a feature is covariantly redefined or the export status is restricted. These derived types are then used to prevent cat-calls through the conformance rules to the original types.&lt;br /&gt;
&lt;br /&gt;
This mechanism is a variant on forget/keep as originally envisaged by Mark Howard. This variant was worked out by us when he explained to me his ideas about forget/keep.&lt;br /&gt;
&lt;br /&gt;
===Example classes===&lt;br /&gt;
&lt;br /&gt;
The following classes will be used for illustration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class ANIMAL&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: FOOD)&lt;br /&gt;
&lt;br /&gt;
  sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    redefine&lt;br /&gt;
      eat&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CAT_FOOD&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class LIST [G]&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  has (g: G): BOOLEAN&lt;br /&gt;
&lt;br /&gt;
  put (g: G)&lt;br /&gt;
&lt;br /&gt;
  item: G&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The problem===&lt;br /&gt;
&lt;br /&gt;
The problem of cat-calls has two variants, one because a feature is covariantly redefined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- illegal since `eat' for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And one because the visibility of features change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- `sleep' is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The idea===&lt;br /&gt;
&lt;br /&gt;
To solve the problem of cat-calls, the idea is that whenever you covariantly redefine a feature of a parent type, your new classes conforms to  a virtual class of the same type as the parent type except that it lacks the covariant feature. The same goes for changing the export status of a feature.&lt;br /&gt;
&lt;br /&gt;
For instance, if the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; inherits from the type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; but covariantly redefines the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt; then the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; does not conform to &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; anymore, but only to a type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; without the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Restrict mechanism==&lt;br /&gt;
&lt;br /&gt;
The restrict mechanism introduces a new keyword &amp;lt;e&amp;gt;restrict&amp;lt;/e&amp;gt; which can be used to covariantly redefine features. By removing features from the class interface, a new type is introduced. The new type has all the features that the original type had, except those listed in the restrict clause - these latter features are present in the class, but are not part of the conforming type. If &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; is used, all features in the original will be removed from the new conforming type. This produces a conforming type with no features at all. We also introduce another new keyword &amp;lt;e&amp;gt;except&amp;lt;/e&amp;gt; which can only follow &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; (therefore it does not need to be a completely reserved word).&lt;br /&gt;
&lt;br /&gt;
===Default behavior===&lt;br /&gt;
&lt;br /&gt;
In the restrict mechanism the normal declaration of a type will have all the features of a type from which it inherits (that is, it conforms to the type). This implies that all subtypes which reduce an export status or covariantly redefine a feature don't conform to this type anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- normal declaration means we have all the features in the conforming type&lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
  cat: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
    -- legal since the feature `eat' is in the normal type&lt;br /&gt;
  animal.eat (food)&lt;br /&gt;
  &lt;br /&gt;
    -- legal since the feature `sleep' is in the normal type&lt;br /&gt;
  animal.sleep&lt;br /&gt;
&lt;br /&gt;
    -- illegal since CAT does not conform to ANIMAL anymore.&lt;br /&gt;
    -- N.B. The declaration of CAT given above is illegal under this proposal. &lt;br /&gt;
    -- Adding the restrict keyword will make it legal again, and emphasizes the lack of conformance.&lt;br /&gt;
  animal := cat&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
  -- normal declaration is an object with all features and no&lt;br /&gt;
  -- subtype which has a covariantly redefined feature conforms to this type&lt;br /&gt;
a1: ANIMAL&lt;br /&gt;
&lt;br /&gt;
  -- a type which lacks any conforming features, thus all &lt;br /&gt;
  -- subtypes conform to this type.&lt;br /&gt;
a2: ANIMAL restrict all end&lt;br /&gt;
&lt;br /&gt;
  -- a type which only restricts the features `eat' and `sleep'. All subtypes which only redefine (but not restrict) `eat' or change the export status &lt;br /&gt;
  -- of `sleep' will conform to this type.&lt;br /&gt;
a3: ANIMAL restrict eat export {NONE} sleep end&lt;br /&gt;
&lt;br /&gt;
 -- subtypes of the following type conform to it provided they do not restrict (that is, covariantly redefine) `eat' (or restrict its export status).&lt;br /&gt;
a4: ANIMAL restrict all except eat end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Covariant feature redefinition==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
With covariant feature redefinition you run into cat-call problems as this example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- eat for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the restrict mechanism the default behavior for a type is to conform to its parent with respect to all features. Types which want to have covariant redefined features will not  conform to the original type. You do not mention these features in a redefine clause, but in a restrict clause.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    restrict eat end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
feature -- Covariant redefinitions&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD) is&lt;br /&gt;
   do&lt;br /&gt;
    ...&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example with the new restrict types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: CAT_FOOD&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
    -- since CAT inherits from (and therefore conforms to) ANIMAL restrict eat&lt;br /&gt;
  a := c&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Feature hiding==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
By restricting the export status of features, a cat-call problem is introduced:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- sleep is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restricting the export status===&lt;br /&gt;
&lt;br /&gt;
Types which reduce the export status of features will not conform to the original type. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
   a := c&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL export {NONE} sleep end&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal, CAT conforms to ANIMAL export {NONE} sleep&lt;br /&gt;
  a := c&lt;br /&gt;
&lt;br /&gt;
    -- illegal, ANIMAL export {NONE} sleep doesn't export feature sleep&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the declaration of a. It is desirable that any sort of inheritance restriction (such as listing creation procedures) be allowed on declarations.&lt;br /&gt;
&lt;br /&gt;
==Generics==&lt;br /&gt;
&lt;br /&gt;
Conformance of generic classes (two generic classes conform if their base classes conform and their generic parameters conform) introduces another kind of covariantly redefined features. Every feature which has a generic argument, e.g. &amp;lt;e&amp;gt;put (g: G)&amp;lt;/e&amp;gt; in class &amp;lt;e&amp;gt;LIST [G]&amp;lt;/e&amp;gt; can be regarded as covariantly redefined since &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANY&amp;lt;/e&amp;gt; and &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt;. But &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; conforms to &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt;, thus the feature &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; is actually covariantly redefined in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
The conformance rules of generics also introduce cat-call problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- feature `put' has argument type ANY&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
    -- feature `put' has argument type ANIMAL&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- animal_list conforms to any_list, but arguments of the feature&lt;br /&gt;
    -- `put' are different&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- since any type can be put into any_list this will add&lt;br /&gt;
    -- an integer to the animal_list&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Conformance===&lt;br /&gt;
&lt;br /&gt;
A generic class X [G] conforms to another generic class X [H] if G and H are the same class, or if G conforms to H and H's conforming type does not include any features taking generic arguments, or any features that in turn (recursively) make use of features taking generic arguments.&lt;br /&gt;
 &lt;br /&gt;
===Using restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- illegal since animal_list does not conform to any_list anymore&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local&lt;br /&gt;
  any_list: like readable_list&lt;br /&gt;
  animal_list: LIST [ANIMAL] &lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
do&lt;br /&gt;
  -- legal since LIST [ANIMAL] has `put'&lt;br /&gt;
  animal_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- legal since animal_list conforms to `readable_list'&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- illegal since `readable_list' does not have `put'&lt;br /&gt;
  any_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- illegal, since `readable_list' does not have `has'&lt;br /&gt;
  any_list.has (animal)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Anchors&lt;br /&gt;
&lt;br /&gt;
  readable_list: LIST [ANY] restrict put, has end&lt;br /&gt;
      -- Anchor - in practice this anchor is defined in a class which is imported using non-conforming inheritance&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--Colin Adams and Mark Howard&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9761</id>
		<title>Without /except</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9761"/>
				<updated>2007-09-18T14:45:40Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: added local food variable&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: ECMA]]&lt;br /&gt;
[[Category:Catcall]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
By allowing covariant feature redefinition and hiding of features, the Eiffel language introduces the problem of cat-calls (Changed Availability or Type). The restrict mechanism prevents this by introducing new derived types whenever a feature is covariantly redefined or the export status is restricted. These derived types are then used to prevent cat-calls through the conformance rules to the original types.&lt;br /&gt;
&lt;br /&gt;
This mechanism is a variant on forget/keep as originally envisaged by Mark Howard. This variant was worked out by us when he explained to me his ideas about forget/keep.&lt;br /&gt;
&lt;br /&gt;
===Example classes===&lt;br /&gt;
&lt;br /&gt;
The following classes will be used for illustration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class ANIMAL&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: FOOD)&lt;br /&gt;
&lt;br /&gt;
  sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    redefine&lt;br /&gt;
      eat&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CAT_FOOD&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class LIST [G]&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  has (g: G): BOOLEAN&lt;br /&gt;
&lt;br /&gt;
  put (g: G)&lt;br /&gt;
&lt;br /&gt;
  item: G&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The problem===&lt;br /&gt;
&lt;br /&gt;
The problem of cat-calls has two variants, one because a feature is covariantly redefined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- illegal since `eat' for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And one because the visibility of features change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- `sleep' is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The idea===&lt;br /&gt;
&lt;br /&gt;
To solve the problem of cat-calls, the idea is that whenever you covariantly redefine a feature of a parent type, your new classes conforms to  a virtual class of the same type as the parent type except that it lacks the covariant feature. The same goes for changing the export status of a feature.&lt;br /&gt;
&lt;br /&gt;
For instance, if the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; inherits from the type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; but covariantly redefines the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt; then the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; does not conform to &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; anymore, but only to a type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; without the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Restrict mechanism==&lt;br /&gt;
&lt;br /&gt;
The restrict mechanism introduces a new keyword &amp;lt;e&amp;gt;restrict&amp;lt;/e&amp;gt; which can be used to covariantly redefine features. By removing features from the class interface, a new type is introduced. The new type has all the features that the original type had, except those listed in the restrict clause - these latter features are present in the class, but are not part of the conforming type. If &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; is used, all features in the original will be removed from the new conforming type. This produces a conforming type with no features at all. We also introduce another new keyword &amp;lt;e&amp;gt;except&amp;lt;/e&amp;gt; which can only follow &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; (therefore it does not need to be a completely reserved word).&lt;br /&gt;
&lt;br /&gt;
===Default behavior===&lt;br /&gt;
&lt;br /&gt;
In the restrict mechanism the normal declaration of a type will have all the features of a type from which it inherits (that is, it conforms to the type). This implies that all subtypes which reduce an export status or covariantly redefine a feature don't conform to this type anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- normal declaration means we have all the features in the conforming type&lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
  cat: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
    -- legal since the feature `eat' is in the normal type&lt;br /&gt;
  animal.eat (food)&lt;br /&gt;
  &lt;br /&gt;
    -- legal since the feature `sleep' is in the normal type&lt;br /&gt;
  animal.sleep&lt;br /&gt;
&lt;br /&gt;
    -- illegal since CAT does not conform to ANIMAL anymore.&lt;br /&gt;
    -- N.B. The declaration of CAT given above is illegal under this proposal. &lt;br /&gt;
    -- Adding the restrict keyword will make it legal again, and emphasizes the lack of conformance.&lt;br /&gt;
  animal := cat&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
  -- normal declaration is an object with all features and no&lt;br /&gt;
  -- subtype which has a covariantly redefined feature conforms to this type&lt;br /&gt;
a1: ANIMAL&lt;br /&gt;
&lt;br /&gt;
  -- a type which lacks any conforming features, thus all &lt;br /&gt;
  -- subtypes conform to this type.&lt;br /&gt;
a2: ANIMAL restrict all end&lt;br /&gt;
&lt;br /&gt;
  -- a type which only restricts the features `eat' and `sleep'. All subtypes which only redefine (but not restrict) `eat' or change the export status &lt;br /&gt;
  -- of `sleep' will conform to this type.&lt;br /&gt;
a3: ANIMAL restrict eat export {NONE} sleep end&lt;br /&gt;
&lt;br /&gt;
 -- subtypes of the following type conform to it provided they do not restrict (that is, covariantly redefine) `eat' (or restrict its export status).&lt;br /&gt;
a4: ANIMAL restrict all except eat end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Covariant feature redefinition==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
With covariant feature redefinition you run into cat-call problems as this example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- eat for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the restrict mechanism the default behavior for a type is to conform to its parent with respect to all features. Types which want to have covariant redefined features will not  conform to the original type. You do not mention these features in a redefine clause, but in a restrict clause.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    restrict eat end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
feature -- Covariant redefinitions&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD) is&lt;br /&gt;
   do&lt;br /&gt;
    ...&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example with the new restrict types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: CAT_FOOD&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
    -- since CAT inherits from (and therefore conforms to) ANIMAL restrict eat&lt;br /&gt;
  a := c&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Feature hiding==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
By restricting the export status of features, a cat-call problem is introduced:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- sleep is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restricting the export status===&lt;br /&gt;
&lt;br /&gt;
Types which reduce the export status of features will not conform to the original type. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
   a := c&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL export {NONE} sleep end&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal, CAT conforms to ANIMAL export {NONE} sleep&lt;br /&gt;
  a := c&lt;br /&gt;
&lt;br /&gt;
    -- illegal, ANIMAL export {NONE} sleep doesn't export feature sleep&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the declaration of a. It is desirable that any sort of inheritance restriction (such as listing creation procedures) be allowed on declarations.&lt;br /&gt;
&lt;br /&gt;
==Generics==&lt;br /&gt;
&lt;br /&gt;
Conformance of generic classes (two generic classes conform if their base classes conform and their generic parameters conform) introduces another kind of covariantly redefined features. Every feature which has a generic argument, e.g. &amp;lt;e&amp;gt;put (g: G)&amp;lt;/e&amp;gt; in class &amp;lt;e&amp;gt;LIST [G]&amp;lt;/e&amp;gt; can be regarded as covariantly redefined since &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANY&amp;lt;/e&amp;gt; and &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt;. But &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; conforms to &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt;, thus the feature &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; is actually covariantly redefined in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
The conformance rules of generics also introduce cat-call problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- feature `put' has argument type ANY&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
    -- feature `put' has argument type ANIMAL&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- animal_list conforms to any_list, but arguments of the feature&lt;br /&gt;
    -- `put' are different&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- since any type can be put into any_list this will add&lt;br /&gt;
    -- an integer to the animal_list&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Conformance===&lt;br /&gt;
&lt;br /&gt;
A generic class X [G] conforms to another generic class X [H] if G and H are the same class, or if G conforms to H and H's conforming type does not include any features taking generic arguments, or any features that in turn (recursively) make use of features taking generic arguments.&lt;br /&gt;
 &lt;br /&gt;
===Using restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- illegal since animal_list does not conform to any_list anymore&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local&lt;br /&gt;
  any_list: like readable_list&lt;br /&gt;
  animal_list: LIST [ANIMAL] &lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
do&lt;br /&gt;
  -- legal since LIST [ANIMAL] has `put'&lt;br /&gt;
  animal_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- legal since animal_list conforms to `readable_list'&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- illegal since `readable_list' does not have `put'&lt;br /&gt;
  any_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- illegal, since `readable_list' does not have `has'&lt;br /&gt;
  any_list.has (animal)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Anchors&lt;br /&gt;
&lt;br /&gt;
  readable_list: LIST [ANY] restrict put, has end&lt;br /&gt;
      -- Anchor - in practice this anchor is defined in a class which is imported using non-conforming inheritance&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--Colin Adams and Mark Howard&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9760</id>
		<title>Without /except</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9760"/>
				<updated>2007-09-18T14:21:03Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Renamed usable_list to readable_list and removed item from its restrict clause.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: ECMA]]&lt;br /&gt;
[[Category:Catcall]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
By allowing covariant feature redefinition and hiding of features, the Eiffel language introduces the problem of cat-calls (Changed Availability or Type). The restrict mechanism prevents this by introducing new derived types whenever a feature is covariantly redefined or the export status is restricted. These derived types are then used to prevent cat-calls through the conformance rules to the original types.&lt;br /&gt;
&lt;br /&gt;
This mechanism is a variant on forget/keep as originally envisaged by Mark Howard. This variant was worked out by us when he explained to me his ideas about forget/keep.&lt;br /&gt;
&lt;br /&gt;
===Example classes===&lt;br /&gt;
&lt;br /&gt;
The following classes will be used for illustration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class ANIMAL&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: FOOD)&lt;br /&gt;
&lt;br /&gt;
  sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    redefine&lt;br /&gt;
      eat&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CAT_FOOD&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class LIST [G]&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  has (g: G): BOOLEAN&lt;br /&gt;
&lt;br /&gt;
  put (g: G)&lt;br /&gt;
&lt;br /&gt;
  item: G&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The problem===&lt;br /&gt;
&lt;br /&gt;
The problem of cat-calls has two variants, one because a feature is covariantly redefined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- illegal since `eat' for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And one because the visibility of features change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- `sleep' is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The idea===&lt;br /&gt;
&lt;br /&gt;
To solve the problem of cat-calls, the idea is that whenever you covariantly redefine a feature of a parent type, your new classes conforms to  a virtual class of the same type as the parent type except that it lacks the covariant feature. The same goes for changing the export status of a feature.&lt;br /&gt;
&lt;br /&gt;
For instance, if the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; inherits from the type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; but covariantly redefines the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt; then the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; does not conform to &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; anymore, but only to a type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; without the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Restrict mechanism==&lt;br /&gt;
&lt;br /&gt;
The restrict mechanism introduces a new keyword &amp;lt;e&amp;gt;restrict&amp;lt;/e&amp;gt; which can be used to covariantly redefine features. By removing features from the class interface, a new type is introduced. The new type has all the features that the original type had, except those listed in the restrict clause - these latter features are present in the class, but are not part of the conforming type. If &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; is used, all features in the original will be removed from the new conforming type. This produces a conforming type with no features at all. We also introduce another new keyword &amp;lt;e&amp;gt;except&amp;lt;/e&amp;gt; which can only follow &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; (therefore it does not need to be a completely reserved word).&lt;br /&gt;
&lt;br /&gt;
===Default behavior===&lt;br /&gt;
&lt;br /&gt;
In the restrict mechanism the normal declaration of a type will have all the features of a type from which it inherits (that is, it conforms to the type). This implies that all subtypes which reduce an export status or covariantly redefine a feature don't conform to this type anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- normal declaration means we have all the features in the conforming type&lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
  cat: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal since the feature `eat' is in the normal type&lt;br /&gt;
  animal.eat (food)&lt;br /&gt;
  &lt;br /&gt;
    -- legal since the feature `sleep' is in the normal type&lt;br /&gt;
  animal.sleep&lt;br /&gt;
&lt;br /&gt;
    -- illegal since CAT does not conform to ANIMAL anymore.&lt;br /&gt;
    -- N.B. The declaration of CAT given above is illegal under this proposal. &lt;br /&gt;
    -- Adding the restrict keyword will make it legal again, and emphasizes the lack of conformance.&lt;br /&gt;
  animal := cat&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
  -- normal declaration is an object with all features and no&lt;br /&gt;
  -- subtype which has a covariantly redefined feature conforms to this type&lt;br /&gt;
a1: ANIMAL&lt;br /&gt;
&lt;br /&gt;
  -- a type which lacks any conforming features, thus all &lt;br /&gt;
  -- subtypes conform to this type.&lt;br /&gt;
a2: ANIMAL restrict all end&lt;br /&gt;
&lt;br /&gt;
  -- a type which only restricts the features `eat' and `sleep'. All subtypes which only redefine (but not restrict) `eat' or change the export status &lt;br /&gt;
  -- of `sleep' will conform to this type.&lt;br /&gt;
a3: ANIMAL restrict eat export {NONE} sleep end&lt;br /&gt;
&lt;br /&gt;
 -- subtypes of the following type conform to it provided they do not restrict (that is, covariantly redefine) `eat' (or restrict its export status).&lt;br /&gt;
a4: ANIMAL restrict all except eat end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Covariant feature redefinition==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
With covariant feature redefinition you run into cat-call problems as this example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- eat for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the restrict mechanism the default behavior for a type is to conform to its parent with respect to all features. Types which want to have covariant redefined features will not  conform to the original type. You do not mention these features in a redefine clause, but in a restrict clause.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    restrict eat end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
feature -- Covariant redefinitions&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD) is&lt;br /&gt;
   do&lt;br /&gt;
    ...&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example with the new restrict types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
    -- since CAT inherits from (and therefore conforms to) ANIMAL restrict eat&lt;br /&gt;
  a := c&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Feature hiding==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
By restricting the export status of features, a cat-call problem is introduced:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- sleep is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restricting the export status===&lt;br /&gt;
&lt;br /&gt;
Types which reduce the export status of features will not conform to the original type. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
   a := c&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL export {NONE} sleep end&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal, CAT conforms to ANIMAL export {NONE} sleep&lt;br /&gt;
  a := c&lt;br /&gt;
&lt;br /&gt;
    -- illegal, ANIMAL export {NONE} sleep doesn't export feature sleep&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the declaration of a. It is desirable that any sort of inheritance restriction (such as listing creation procedures) be allowed on declarations.&lt;br /&gt;
&lt;br /&gt;
==Generics==&lt;br /&gt;
&lt;br /&gt;
Conformance of generic classes (two generic classes conform if their base classes conform and their generic parameters conform) introduces another kind of covariantly redefined features. Every feature which has a generic argument, e.g. &amp;lt;e&amp;gt;put (g: G)&amp;lt;/e&amp;gt; in class &amp;lt;e&amp;gt;LIST [G]&amp;lt;/e&amp;gt; can be regarded as covariantly redefined since &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANY&amp;lt;/e&amp;gt; and &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt;. But &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; conforms to &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt;, thus the feature &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; is actually covariantly redefined in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
The conformance rules of generics also introduce cat-call problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- feature `put' has argument type ANY&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
    -- feature `put' has argument type ANIMAL&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- animal_list conforms to any_list, but arguments of the feature&lt;br /&gt;
    -- `put' are different&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- since any type can be put into any_list this will add&lt;br /&gt;
    -- an integer to the animal_list&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Conformance===&lt;br /&gt;
&lt;br /&gt;
A generic class X [G] conforms to another generic class X [H] if G and H are the same class, or if G conforms to H and H's conforming type does not include any features taking generic arguments, or any features that in turn (recursively) make use of features taking generic arguments.&lt;br /&gt;
 &lt;br /&gt;
===Using restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- illegal since animal_list does not conform to any_list anymore&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local&lt;br /&gt;
  any_list: like readable_list&lt;br /&gt;
  animal_list: LIST [ANIMAL] &lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
do&lt;br /&gt;
  -- legal since LIST [ANIMAL] has `put'&lt;br /&gt;
  animal_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- legal since animal_list conforms to `readable_list'&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- illegal since `readable_list' does not have `put'&lt;br /&gt;
  any_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- illegal, since `readable_list' does not have `has'&lt;br /&gt;
  any_list.has (animal)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Anchors&lt;br /&gt;
&lt;br /&gt;
  readable_list: LIST [ANY] restrict put, has end&lt;br /&gt;
      -- Anchor - in practice this anchor is defined in a class which is imported using non-conforming inheritance&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--Colin Adams and Mark Howard&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9759</id>
		<title>Without /except</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9759"/>
				<updated>2007-09-18T13:59:23Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Reworked to talk about conforming types.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: ECMA]]&lt;br /&gt;
[[Category:Catcall]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
By allowing covariant feature redefinition and hiding of features, the Eiffel language introduces the problem of cat-calls (Changed Availability or Type). The restrict mechanism prevents this by introducing new derived types whenever a feature is covariantly redefined or the export status is restricted. These derived types are then used to prevent cat-calls through the conformance rules to the original types.&lt;br /&gt;
&lt;br /&gt;
This mechanism is a variant on forget/keep as originally envisaged by Mark Howard. This variant was worked out by us when he explained to me his ideas about forget/keep.&lt;br /&gt;
&lt;br /&gt;
===Example classes===&lt;br /&gt;
&lt;br /&gt;
The following classes will be used for illustration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class ANIMAL&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: FOOD)&lt;br /&gt;
&lt;br /&gt;
  sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    redefine&lt;br /&gt;
      eat&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CAT_FOOD&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class LIST [G]&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  has (g: G): BOOLEAN&lt;br /&gt;
&lt;br /&gt;
  put (g: G)&lt;br /&gt;
&lt;br /&gt;
  item: G&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The problem===&lt;br /&gt;
&lt;br /&gt;
The problem of cat-calls has two variants, one because a feature is covariantly redefined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- illegal since `eat' for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And one because the visibility of features change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- `sleep' is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The idea===&lt;br /&gt;
&lt;br /&gt;
To solve the problem of cat-calls, the idea is that whenever you covariantly redefine a feature of a parent type, your new classes conforms to  a virtual class of the same type as the parent type except that it lacks the covariant feature. The same goes for changing the export status of a feature.&lt;br /&gt;
&lt;br /&gt;
For instance, if the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; inherits from the type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; but covariantly redefines the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt; then the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; does not conform to &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; anymore, but only to a type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; without the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Restrict mechanism==&lt;br /&gt;
&lt;br /&gt;
The restrict mechanism introduces a new keyword &amp;lt;e&amp;gt;restrict&amp;lt;/e&amp;gt; which can be used to covariantly redefine features. By removing features from the class interface, a new type is introduced. The new type has all the features that the original type had, except those listed in the restrict clause - these latter features are present in the class, but are not part of the conforming type. If &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; is used, all features in the original will be removed from the new conforming type. This produces a conforming type with no features at all. We also introduce another new keyword &amp;lt;e&amp;gt;except&amp;lt;/e&amp;gt; which can only follow &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; (therefore it does not need to be a completely reserved word).&lt;br /&gt;
&lt;br /&gt;
===Default behavior===&lt;br /&gt;
&lt;br /&gt;
In the restrict mechanism the normal declaration of a type will have all the features of a type from which it inherits (that is, it conforms to the type). This implies that all subtypes which reduce an export status or covariantly redefine a feature don't conform to this type anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- normal declaration means we have all the features in the conforming type&lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
  cat: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal since the feature `eat' is in the normal type&lt;br /&gt;
  animal.eat (food)&lt;br /&gt;
  &lt;br /&gt;
    -- legal since the feature `sleep' is in the normal type&lt;br /&gt;
  animal.sleep&lt;br /&gt;
&lt;br /&gt;
    -- illegal since CAT does not conform to ANIMAL anymore.&lt;br /&gt;
    -- N.B. The declaration of CAT given above is illegal under this proposal. &lt;br /&gt;
    -- Adding the restrict keyword will make it legal again, and emphasizes the lack of conformance.&lt;br /&gt;
  animal := cat&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
  -- normal declaration is an object with all features and no&lt;br /&gt;
  -- subtype which has a covariantly redefined feature conforms to this type&lt;br /&gt;
a1: ANIMAL&lt;br /&gt;
&lt;br /&gt;
  -- a type which lacks any conforming features, thus all &lt;br /&gt;
  -- subtypes conform to this type.&lt;br /&gt;
a2: ANIMAL restrict all end&lt;br /&gt;
&lt;br /&gt;
  -- a type which only restricts the features `eat' and `sleep'. All subtypes which only redefine (but not restrict) `eat' or change the export status &lt;br /&gt;
  -- of `sleep' will conform to this type.&lt;br /&gt;
a3: ANIMAL restrict eat export {NONE} sleep end&lt;br /&gt;
&lt;br /&gt;
 -- subtypes of the following type conform to it provided they do not restrict (that is, covariantly redefine) `eat' (or restrict its export status).&lt;br /&gt;
a4: ANIMAL restrict all except eat end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Covariant feature redefinition==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
With covariant feature redefinition you run into cat-call problems as this example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- eat for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the restrict mechanism the default behavior for a type is to conform to its parent with respect to all features. Types which want to have covariant redefined features will not  conform to the original type. You do not mention these features in a redefine clause, but in a restrict clause.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    restrict eat end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
feature -- Covariant redefinitions&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD) is&lt;br /&gt;
   do&lt;br /&gt;
    ...&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example with the new restrict types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
    -- since CAT inherits from (and therefore conforms to) ANIMAL restrict eat&lt;br /&gt;
  a := c&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Feature hiding==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
By restricting the export status of features, a cat-call problem is introduced:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- sleep is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restricting the export status===&lt;br /&gt;
&lt;br /&gt;
Types which reduce the export status of features will not conform to the original type. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
   a := c&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL export {NONE} sleep end&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal, CAT conforms to ANIMAL export {NONE} sleep&lt;br /&gt;
  a := c&lt;br /&gt;
&lt;br /&gt;
    -- illegal, ANIMAL export {NONE} sleep doesn't export feature sleep&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the declaration of a. It is desirable that any sort of inheritance restriction (such as listing creation procedures) be allowed on declarations.&lt;br /&gt;
&lt;br /&gt;
==Generics==&lt;br /&gt;
&lt;br /&gt;
Conformance of generic classes (two generic classes conform if their base classes conform and their generic parameters conform) introduces another kind of covariantly redefined features. Every feature which has a generic argument, e.g. &amp;lt;e&amp;gt;put (g: G)&amp;lt;/e&amp;gt; in class &amp;lt;e&amp;gt;LIST [G]&amp;lt;/e&amp;gt; can be regarded as covariantly redefined since &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANY&amp;lt;/e&amp;gt; and &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt;. But &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; conforms to &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt;, thus the feature &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; is actually covariantly redefined in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
The conformance rules of generics also introduce cat-call problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- feature `put' has argument type ANY&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
    -- feature `put' has argument type ANIMAL&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- animal_list conforms to any_list, but arguments of the feature&lt;br /&gt;
    -- `put' are different&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- since any type can be put into any_list this will add&lt;br /&gt;
    -- an integer to the animal_list&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Conformance===&lt;br /&gt;
&lt;br /&gt;
A generic class X [G] conforms to another generic class X [H] if G and H are the same class, or if G conforms to H and H's conforming type does not include any features taking generic arguments, or any features that in turn (recursively) make use of features taking generic arguments.&lt;br /&gt;
 &lt;br /&gt;
===Using restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- illegal since animal_list does not conform to any_list anymore&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local&lt;br /&gt;
  any_list: like usable_list&lt;br /&gt;
  animal_list: LIST [ANIMAL] &lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
do&lt;br /&gt;
  -- legal since LIST [ANIMAL] has `put'&lt;br /&gt;
  animal_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- legal since animal_list conforms to `usable_list'&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- illegal since `usable_list' does not have `put'&lt;br /&gt;
  any_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- illegal, since `usable_list' does not have `has'&lt;br /&gt;
  any_list.has (animal)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Anchors&lt;br /&gt;
&lt;br /&gt;
  usable_list: LIST [ANY] restrict put, has, item end&lt;br /&gt;
      -- Anchor - in practice this anchor is defined in a class which is imported using non-conforming inheritance&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--Colin Adams and Mark Howard&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9758</id>
		<title>Without /except</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9758"/>
				<updated>2007-09-18T10:54:08Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Changed without to restrict, and a few other minor changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: ECMA]]&lt;br /&gt;
[[Category:Catcall]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
By allowing covariant feature redefinition and hiding of features, the Eiffel language introduces the problem of cat-calls (Changed Availability or Type). The restrict mechanism prevents this by introducing new derived types whenever a feature is covariantly redefined or the export status is restricted. These derived types are then used to prevent cat-calls through the conformance rules to the original types.&lt;br /&gt;
&lt;br /&gt;
This mechanism is a variant on forget/keep as originally envisaged by Mark Howard. This variant was worked out by us when he explained to me his ideas about forget/keep.&lt;br /&gt;
&lt;br /&gt;
===Example classes===&lt;br /&gt;
&lt;br /&gt;
The following classes will be used for illustration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class ANIMAL&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: FOOD)&lt;br /&gt;
&lt;br /&gt;
  sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    redefine&lt;br /&gt;
      eat&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CAT_FOOD&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class LIST [G]&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  has (g: G): BOOLEAN&lt;br /&gt;
&lt;br /&gt;
  put (g: G)&lt;br /&gt;
&lt;br /&gt;
  item: G&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The problem===&lt;br /&gt;
&lt;br /&gt;
The problem of cat-calls has two variants, one because a feature is covariantly redefined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- illegal since `eat' for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And one because the visibility of features change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- `sleep' is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The idea===&lt;br /&gt;
&lt;br /&gt;
To solve the problem of cat-calls, the idea is that whenever you covariantly redefine a feature of a parent type, you actually inherit from a (virtual) parent type which does not have this feature at all, but you then re-introduce the feature to the new class (with restricted export status). The same goes for changing the export status.&lt;br /&gt;
&lt;br /&gt;
As a consequence of this, the types as we know them don't necessarily conform to each other. If the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; inherits from the type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; but covariantly redefines the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt; then the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; does not conform to &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; anymore, but only to a type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; without the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Restrict mechanism==&lt;br /&gt;
&lt;br /&gt;
The restrict mechanism introduces a new keyword &amp;lt;e&amp;gt;restrict&amp;lt;/e&amp;gt; which can be used to covariantly redefine features. By removing features from the class interface, a new type is introduced. The new type has all the features that the original type had, except those listed in the restrict clause - these latter features are present in the class, but exported to {NONE}. If &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; is used, all features in the original will be removed from the new type. This produces a type with no features at all, which isn't very useful on its own. But it is useful if you want to lose all except a few of the features. We introduce another new keyword &amp;lt;e&amp;gt;except&amp;lt;/e&amp;gt; which can only follow &amp;lt;e&amp;gt;restrict all&amp;lt;/e&amp;gt; (therefore it does not need to be a completely reserved word).&lt;br /&gt;
&lt;br /&gt;
===Default behavior===&lt;br /&gt;
&lt;br /&gt;
In the restrict mechanism the normal declaration of a type will have all the features of a type from which it inherits. This implies that all subtypes which reduce an export status or covariantly redefine a feature don't conform to this type anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- normal declaration means we have all the features&lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
  cat: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal since the feature `eat' is in the normal type&lt;br /&gt;
  animal.eat (food)&lt;br /&gt;
  &lt;br /&gt;
    -- legal since the feature `sleep' is in the normal type&lt;br /&gt;
  animal.sleep&lt;br /&gt;
&lt;br /&gt;
    -- illegal since CAT does not conform to ANIMAL anymore.&lt;br /&gt;
    -- N.B. The declaration of CAT given above is illegal under this proposal. &lt;br /&gt;
    -- Adding the restrict keyword will make it legal again, and emphasize the lack of conformance.&lt;br /&gt;
  animal := cat&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
  -- normal declaration is an object with all features and no&lt;br /&gt;
  -- subtype which has a covariantly redefined feature conforms to this type&lt;br /&gt;
a1: ANIMAL&lt;br /&gt;
&lt;br /&gt;
  -- a type which lacks any exported features, thus all &lt;br /&gt;
  -- subtypes conform to this type. It is not a very useful type.&lt;br /&gt;
a2: ANIMAL restrict all end&lt;br /&gt;
&lt;br /&gt;
  -- a type which only restricts the features `eat' and `sleep'. All subtypes which only redefine or change export status &lt;br /&gt;
  -- of `eat' or `sleep' will conform to this type&lt;br /&gt;
a3: ANIMAL restrict eat export {NONE} sleep end&lt;br /&gt;
&lt;br /&gt;
 -- a type which lacks any exported features other than eat.&lt;br /&gt;
a4: ANIMAL restrict all except eat end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Covariant feature redefinition==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
With covariant feature redefinition you run into cat-call problems as this example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- eat for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the restrict mechanism the default behavior for a type is to keep all features. Types which want to have covariant redefined features will not  conform to the original type. You do not mention these features in a redefine clause.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    restrict eat end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Covariant redefinitions&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD) is&lt;br /&gt;
     -- Note that the feature must be exported to NONE - otherwise the compiler will complain.&lt;br /&gt;
   do&lt;br /&gt;
    ...&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example with the new restrict types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
    -- since CAT inherits from ANIMAL restrict eat&lt;br /&gt;
  a := c&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Feature hiding==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
By restricting the export status of features, a cat-call problem is introduced:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- sleep is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Restricting the export status===&lt;br /&gt;
&lt;br /&gt;
Types which reduce the export status of features will not conform to the original type. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
   a := c&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL export {NONE} sleep end&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal, CAT conforms to ANIMAL export {NONE} sleep&lt;br /&gt;
  a := c&lt;br /&gt;
&lt;br /&gt;
    -- illegal, ANIMAL export {NONE} sleep doesn't export feature sleep&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the declaration of a. It is desirable that any sort of inheritance restriction (such as listing creation procedures) be allowed on declarations.&lt;br /&gt;
&lt;br /&gt;
==Generics==&lt;br /&gt;
&lt;br /&gt;
Conformance of generic classes (two generic classes conform if their base classes conform and their generic parameters conform) introduces another kind of covariantly redefined features. Every feature which has a generic argument, e.g. &amp;lt;e&amp;gt;put (g: G)&amp;lt;/e&amp;gt; in class &amp;lt;e&amp;gt;LIST [G]&amp;lt;/e&amp;gt; can be regarded as covariantly redefined since &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANY&amp;lt;/e&amp;gt; and &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt;. But &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; conforms to &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt;, thus the feature &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; is actually covariantly redefined in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
The conformance rules of generics also introduce cat-call problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- feature `put' has argument type ANY&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
    -- feature `put' has argument type ANIMAL&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- animal_list conforms to any_list, but arguments of the feature&lt;br /&gt;
    -- `put' are different&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- since any type can be put into any_list this will add&lt;br /&gt;
    -- an integer to the animal_list&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Conformance===&lt;br /&gt;
&lt;br /&gt;
A generic class X [G] conforms to another generic class X [H] if G and H are the same class, or if G conforms to H and H does not export any features taking generic arguments, or any features that in turn (recursively) make use of features taking generic arguments.&lt;br /&gt;
 &lt;br /&gt;
===Using restrict mechanism===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- illegal since animal_list does not conform to any_list anymore&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local&lt;br /&gt;
  any_list: like usable_list&lt;br /&gt;
  animal_list: LIST [ANIMAL] &lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
do&lt;br /&gt;
  -- legal since LIST [ANIMAL] has `put'&lt;br /&gt;
  animal_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- legal since animal_list conforms to `usable_list'&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- illegal since `usable_list' does not have `put'&lt;br /&gt;
  any_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- illegal, since `usable_list' does not have `has'&lt;br /&gt;
  any_list.has (animal)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Anchors&lt;br /&gt;
&lt;br /&gt;
  usable_list: LIST [ANY] restrict put, has, append, etc. etc. end&lt;br /&gt;
      -- Anchor - in practice this anchor is defined in a class which is imported using non-conforming inheritance&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--Colin Adams and Mark Howard&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9757</id>
		<title>Without /except</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Without_/except&amp;diff=9757"/>
				<updated>2007-09-18T09:38:48Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category: ECMA]]&lt;br /&gt;
[[Category:Catcall]]&lt;br /&gt;
{{Research}}&lt;br /&gt;
{{UnderConstruction}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
By allowing covariant feature redefinition and hiding of features, the Eiffel language introduces the problem of cat-calls (Changed Availability or Type). The forget / keep mechanism prevents this by introducing new derived types whenever a feature is covariantly redefined or the export status is restricted. These derived types are then used to prevent cat-calls through the conformance rules to the original types.&lt;br /&gt;
&lt;br /&gt;
This mechanism is a variant on forget/keep as originally envisaged by Mark Howard. This variant was worked out by us when he explained to me his ideas about forget/keep.&lt;br /&gt;
&lt;br /&gt;
===Example classes===&lt;br /&gt;
&lt;br /&gt;
The following classes will be used for illustration:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class ANIMAL&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: FOOD)&lt;br /&gt;
&lt;br /&gt;
  sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    redefine&lt;br /&gt;
      eat&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class CAT_FOOD&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  FOOD&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class LIST [G]&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  has (g: G): BOOLEAN&lt;br /&gt;
&lt;br /&gt;
  put (g: G)&lt;br /&gt;
&lt;br /&gt;
  item: G&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===The problem===&lt;br /&gt;
&lt;br /&gt;
The problem of cat-calls has two variants, one because a feature is covariantly redefined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- illegal since `eat' for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And one because the visibility of features change:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- `sleep' is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===The idea===&lt;br /&gt;
&lt;br /&gt;
To solve the problem of cat-calls, the idea is that whenever you covariantly redefine a feature of a parent type, you don't actually inherit this feature and redefine it, but you inherit from a (virtual) parent type which does not have this feature at all. The same goes for changing the export status. When you restrict the export status of a feature, you don't inherit this feature from the parent but introduce it in the current type and inherit from a parent which does not know this feature at all.&lt;br /&gt;
&lt;br /&gt;
As a consequence of this, the types as we know them don't necessarily conform to each other. If the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; inherits from the type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; but covariantly redefines the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt; than the type &amp;lt;e&amp;gt;CAT&amp;lt;/e&amp;gt; does not conform to &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; anymore, but only to a type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt; without the feature &amp;lt;e&amp;gt;eat&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Without mechanism==&lt;br /&gt;
&lt;br /&gt;
The without mechanism introduces a new keyword &amp;lt;e&amp;gt;without&amp;lt;/e&amp;gt; which can be used to remove covariantly redefined features and features which change the export status from a base type. By removing features, a new type is introduced. The new type has all the features that the original type had, except those listed in the without clause. If &amp;lt;e&amp;gt;without all&amp;lt;/e&amp;gt; is used, all features in the original will be removed from the new type. This produces a type with no features at all, which isn't very useful on its own. But it is useful if you want to lose all except a few of the features. We intoduce another new keyword &amp;lt;e&amp;gt;except&amp;lt;/e&amp;gt; which can only follow &amp;lt;e&amp;gt;without all&amp;lt;/e&amp;gt; (therefore it does not need to be a compeletly reserved word).&lt;br /&gt;
&lt;br /&gt;
===Default behavior===&lt;br /&gt;
&lt;br /&gt;
In the without mechanism the normal declaration of a type will have all the features of a type from which it inherits. This implies that all subtypes which change an export status or covariantly redefine a feature don't conform to this type anymore.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- normal declaration means we have all the features&lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
  cat: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal since the feature `eat' is in the normal type&lt;br /&gt;
  animal.eat (food)&lt;br /&gt;
  &lt;br /&gt;
    -- legal since the feature `sleep' is in the normal type&lt;br /&gt;
  animal.sleep&lt;br /&gt;
&lt;br /&gt;
    -- illegal since CAT does not conform to ANIMAL anymore.&lt;br /&gt;
    -- N.B. The declaration of CAT given above is illegal under this proposal. &lt;br /&gt;
    -- Adding the without keyword will make it legal again, and emphasize the lack of conformance.&lt;br /&gt;
  animal := cat&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Syntax===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
  -- normal declaration is an object with all features and no&lt;br /&gt;
  -- subtype which has a covariantly redefined feature conforms to this type&lt;br /&gt;
a1: ANIMAL&lt;br /&gt;
&lt;br /&gt;
  -- a type which lacks all features, thus all &lt;br /&gt;
  -- subtypes conform to this type. It is not a useful type.&lt;br /&gt;
a2: ANIMAL without all end&lt;br /&gt;
&lt;br /&gt;
  -- a type which only lacks the features `eat' and `sleep'. All subtypes which only redefine or change export status &lt;br /&gt;
  -- of `eat' or `sleep' will conform to this type&lt;br /&gt;
a3: ANIMAL without eat, sleep end&lt;br /&gt;
&lt;br /&gt;
 -- a type which lacks all features other than eat.&lt;br /&gt;
a4: ANIMAL without all except eat end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Covariant feature redefinition==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
With covariant feature redefinition you run into cat-call problems as this example shows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
  food: FOOD&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- eat for type CAT takes arguments only of type CAT_FOOD&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Without mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the without mechanism the default behavior for a type is to keep all features. Types which want to have covariant redefined features will not  conform to the original type. In fact, under this scheme, you do not &amp;quot;redefine&amp;quot; features covariantly at all. As you are not inheriting them from the original type (specified by the without keyword), you simply introduce them in the class text. You do not mention them in a redefine clause.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    without eat end&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
  eat (f: CAT_FOOD)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example with the new without types:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
    -- since CAT inherits from ANIMAL without eat&lt;br /&gt;
  a := c&lt;br /&gt;
  a.eat (food)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Feature hiding==&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
By restricting the export status of features, a cat-call problem is introduced:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
&lt;br /&gt;
  a := c&lt;br /&gt;
    -- sleep is hidden for type CAT and should not be called&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using without mechanism===&lt;br /&gt;
&lt;br /&gt;
Using the without mechanism the default behavior for a type is to keep all features. Types which change the export status of features will not conform to the original type. This is not allowed. Instead you use the without mechanism to remove these features from the type you are creating, then introduce them afresh in an export {NONE} feature clause, like any other new feature.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;top-aligned&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! the old way&lt;br /&gt;
! the new way&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL&lt;br /&gt;
    export&lt;br /&gt;
      {NONE} sleep&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
class CAT&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
&lt;br /&gt;
  ANIMAL &lt;br /&gt;
    without sleep end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Implementation&lt;br /&gt;
    &lt;br /&gt;
  sleep is&lt;br /&gt;
    -- ...&lt;br /&gt;
   do&lt;br /&gt;
     ...&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Now the cat-call example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- illegal assignment, ANIMAL and CAT don't conform&lt;br /&gt;
   a := c&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  a: ANIMAL without all except eat end&lt;br /&gt;
  c: CAT&lt;br /&gt;
do&lt;br /&gt;
    -- legal, CAT conforms to ANIMAL without all except eat&lt;br /&gt;
  a := c&lt;br /&gt;
&lt;br /&gt;
    -- illegal, ANIMAL without all except eat doesn't have a feature sleep&lt;br /&gt;
  a.sleep&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Generics==&lt;br /&gt;
&lt;br /&gt;
Conformance of generic classes (two generic classes conform if their base classes conform and their generic parameters conform) introduces another kind of covariantly redefined features. Every feature which has a generic argument, e.g. &amp;lt;e&amp;gt;put (g: G)&amp;lt;/e&amp;gt; in class &amp;lt;e&amp;gt;LIST [G]&amp;lt;/e&amp;gt; can be regarded as covariantly redefined since &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANY&amp;lt;/e&amp;gt; and &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; takes an argument of type &amp;lt;e&amp;gt;ANIMAL&amp;lt;/e&amp;gt;. But &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt; conforms to &amp;lt;e&amp;gt;LIST [ANY]&amp;lt;/e&amp;gt;, thus the feature &amp;lt;e&amp;gt;put&amp;lt;/e&amp;gt; is actually covariantly redefined in &amp;lt;e&amp;gt;LIST [ANIMAL]&amp;lt;/e&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Cat-call problem===&lt;br /&gt;
&lt;br /&gt;
The conformance rules of generics also introduce cat-call problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
    -- feature `put' has argument type ANY&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
    -- feature `put' has argument type ANIMAL&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- animal_list conforms to any_list, but arguments of the feature&lt;br /&gt;
    -- `put' are different&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- since any type can be put into any_list this will add&lt;br /&gt;
    -- an integer to the animal_list&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Conformance===&lt;br /&gt;
&lt;br /&gt;
A generic class X [G] conforms to another generic class X [H] if G and H are the same class, or if G conforms to H and H lacks any features taking generic arguments.&lt;br /&gt;
 &lt;br /&gt;
===Using without mechanism===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
local&lt;br /&gt;
  any_list: LIST [ANY]&lt;br /&gt;
  animal_list: LIST [ANIMAL]&lt;br /&gt;
do&lt;br /&gt;
    -- illegal since animal_list does not conform to any_list anymore&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
  any_list.put (5)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local&lt;br /&gt;
  any_list: like usable_list&lt;br /&gt;
  animal_list: LIST [ANIMAL] &lt;br /&gt;
  animal: ANIMAL&lt;br /&gt;
do&lt;br /&gt;
  -- legal since LIST [ANIMAL] has `put'&lt;br /&gt;
  animal_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- legal since animal_list conforms to `usable_list'&lt;br /&gt;
  any_list := animal_list&lt;br /&gt;
&lt;br /&gt;
    -- illegal since `usable_list' does not have `put'&lt;br /&gt;
  any_list.put (animal)&lt;br /&gt;
&lt;br /&gt;
    -- illegal, since `usable_list' does not have `has'&lt;br /&gt;
  any_list.has (animal)&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
feature {NONE} -- Anchors&lt;br /&gt;
&lt;br /&gt;
  usable_list: LIST [ANY] without put, has, append, etc. etc. end&lt;br /&gt;
      -- Anchor - in practice this anchor is defined in a class which is imported using non-conforming inheritance&lt;br /&gt;
&amp;lt;/e&amp;gt;&lt;br /&gt;
&lt;br /&gt;
--Colin Adams and Mark Howard&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=REAL_64_(issues)&amp;diff=9756</id>
		<title>REAL 64 (issues)</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=REAL_64_(issues)&amp;diff=9756"/>
				<updated>2007-09-18T06:55:02Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Mark Howard's proposal for dealing with NaNs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ELKS]]&lt;br /&gt;
This page describes issues with the current implementation of REAL_64 in comparison to the [[REAL_64 (interface)|interface description]] or desired output when nothing is specified.&lt;br /&gt;
&lt;br /&gt;
===is_equal and NaN===&lt;br /&gt;
&lt;br /&gt;
The floating point standard says that 'NaN = NaN' is false. But in order to uphold the postcondition of 'NaN.twin' which says that 'Result.is_equal (Current)' the comparison with 'is_equal' should yield true. &lt;br /&gt;
&lt;br /&gt;
At the moment 'is_equal' for reals is optimized in the compiler and is replaced by '=' and thus the postcondition of 'twin' is violated.&lt;br /&gt;
&lt;br /&gt;
===floor, ceiling, rounded and truncated_to_integer===&lt;br /&gt;
&lt;br /&gt;
Currently when doing a 'floor', 'ceiling', 'rounded' or 'truncate_to_integer' with a number which is too large (e.g. 2^31) the result is {INTEGER}.min_value. &lt;br /&gt;
&lt;br /&gt;
The change in the sign is a not expected behavior and violates informal contracts (see comments in EiffelBase REAL_64_REF.truncated_to_integer).&lt;br /&gt;
&lt;br /&gt;
===divisible===&lt;br /&gt;
&lt;br /&gt;
By providing NaN and INF every real value can be divided by every other real value. Thus a call of 'divisible' should always return true or the precondition of the division should be changed. This arises again in INTEGER.infix &amp;quot;/&amp;quot;. A call to 12 / 0 is not allowed by the current contract but should just return INF.&lt;br /&gt;
&lt;br /&gt;
===inherited invariants===&lt;br /&gt;
&lt;br /&gt;
Some of the invariants which are inherited from NUMERIC are not applicable if the REAL is eithern NaN or INF. To circumvent this problem we could introduce a 'is_special_case' feature into NUMERIC and change the invariants form NUMERIC to be only true if the object is not a special case.&lt;br /&gt;
&lt;br /&gt;
===three_way_comparison===&lt;br /&gt;
&lt;br /&gt;
The postcondition of ''three_way_comparison'' is violated in the case where one object is infinity and the other object is NaN:&lt;br /&gt;
&lt;br /&gt;
The postcondition lists the three cases of ''three_way_comparison''. In the case where one of the two comparables is NaN, all three cases are violated. Thus the returning value should neither be -1, 0 or 1. Currently in this case 0 is returned which then violates the contract since NaN is not equal to any other real value (including itself). What return value should be used is yet unclear.&lt;br /&gt;
To uphold the contract it would be sufficent to return any number not equal to -1, 0 or 1. But this is more of a hack than a solution.&lt;br /&gt;
&lt;br /&gt;
In the C# implementation the return value of a three way comparison involving NaN returns always that NaN is smaller compared to any other real value except with NaN itself where it is equal. But when using the comparison operators, NaN compared to any other value is false. Thus this solution cannot be used to uphold the current contract from COMPARABLE.&lt;br /&gt;
&lt;br /&gt;
The cleanest solution would be to introduce an 'is_special_case' feature in COMPARABLE like the one in NUMERIC. That way we could make the contract conditional on this feature. The downside is that you introduce COMPARABLE objects which are not comparable! (Although NaN is already an object which is a COMPARABLE but cannot be compared...)&lt;br /&gt;
&lt;br /&gt;
===A suggestion from Mark Howard===&lt;br /&gt;
&lt;br /&gt;
Mark Howard has told me that his idea to solve the NaN problem is to prefix assertions with &amp;quot;x=x implies ...&amp;quot;. This works regardless of the type of object involved, so it is particularly useful in postconditions of routines such as extend.&lt;br /&gt;
This does not help for infinities, but I would have thought that this should be tackled by an is_infinite query in NUMERIC.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 08:55, 18 September 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=EiffelStudio_Wish_List&amp;diff=9754</id>
		<title>EiffelStudio Wish List</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=EiffelStudio_Wish_List&amp;diff=9754"/>
				<updated>2007-09-12T14:01:30Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Added request for demand-loading of notebook tabs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projects]]&lt;br /&gt;
Welcome to the Eiffel/EiffelStudio Wish List. This is the place where you, the community, get a chance to tell us what you think is important to include in the future versions of the Eiffel compiler and EiffelStudio IDE.&lt;br /&gt;
&lt;br /&gt;
Please use this list responsibly and try to correctly categorize your wishes. A brief description may help us evaluate your requirements but please be brief.&lt;br /&gt;
&lt;br /&gt;
Our stock pile of genie snared, dusty gold lamps is running low for our next release ([[EiffelStudio Releases]]) but we'll be sure to scour the lands for more.&lt;br /&gt;
&lt;br /&gt;
== Compiler ==&lt;br /&gt;
&lt;br /&gt;
=== General ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ID !! Short Summary !! Pros !! Cons !! More info&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Source &amp;amp; Generated Files in an RDBMS and (optionally) Compile directly from database &lt;br /&gt;
| Use an RDBMS to store all sources,libraries and generated files instead of a filesystem.  Optionally directly compile from the database. Repository can be shared amongst multiple users &lt;br /&gt;
|| Pro's:&lt;br /&gt;
* Easy queriable&lt;br /&gt;
* Much more appropriate to use a database to store relations (dependencies) between objects.&lt;br /&gt;
* Easier for using a shared repository amongst multiple users&lt;br /&gt;
||&lt;br /&gt;
* Sophisticated collaboration tools already exist for sharing project source e.g. SVN, CVS&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Shared EIFGEN&lt;br /&gt;
| Allow sharing of EIFGENs (in read-only mode)|| || ||]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! On-demand tab loading&lt;br /&gt;
| Allow creation of an EV_NOTEBOOK tab with an agent to be called to fill the tab when it is first loaded|| || ||&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Enum&lt;br /&gt;
| A way to author Enum-like class for typed options or flags. Currently using INTEGER and a bag of analogous constants doesn't make Eiffel &amp;quot;elegant&amp;quot;. || ||&lt;br /&gt;
* The best practice way to get a value that only needs to be defined once is by using the &amp;quot;once&amp;quot; keyword in combination with a feature.&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Decimal&lt;br /&gt;
|Addition of a decimal type / REAL_128 for 28 digit precision -  || MA_DECIMAL is not efficient || MA_DECIMAL already covers this||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!User types&lt;br /&gt;
|I want to be able to define types .e.g. a decimal type as mentioned above. I know all built in types can be defined from scratch, except I a way to initialise from literals. So we need a way to define them as well. Suggest a new defered class with create methods from_literal( s:STRING), and queries is_interger_ok:BOOLIAN, is_real_ok:BOOLIAN, is_arbitary_string_ok:BOOLIAN, is_type_string_ok:BOOLIAN (we would define a new type of string just for this). The compiler when generating optimised code will have to compile the new types and dynamicaly bind to them to create an object that can be embeded into the code. I beleave this would let us write code like: x:DECIMAL; x=1.23 (without a conversion from REAL (float base2)) || || ||   &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! CHARACTER_16&lt;br /&gt;
| CHARACTER_16 type || Smaller footprint than CHARACTER_32, UTF-16 is the default internal text representation for Windows/.Net/OS X/Java so conversion from CHARACTER_32 is costly, particular when dealing with large amounts of text || Please No! CHARACTER_32 covers this already. And UTF-8 is more space-efficient than UTF-16, which is an abomination. What will happen if you have a character from above the BMP? You will then have two CHARACTER_16s in the string for one real character - neither of which is a valid character - then `count' and `item' are all wrong. If you must have UTF-16 STRINGs, then let item return a CHARACTER_32. But note that having a UTF_16 STRING in itself won't eliminate all conversion costs - there is still the endian problem - this could be tackled by each individual UTF-16 STRING knowing whether it is UTF-16BE or UTF-16LE, but you may still need to convert. Comparing two such strings with different endianness would then have to be done using the codes - in what way is that going to be more efficient than using UTF-32? See [[Wish_CHARACTER_16]] for more details on why it is not ok.||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! 7-bit ASCII&lt;br /&gt;
| 7-bit (US) ASCII_CHARACTER and ASCII_STRING which extends upon an ARRAY [ASCII_CHARACTER] with values of 0-127, removing the need for UTF8 conversion/checking when passing basic char values to C (gtk interfacing for example when connecting to signals) || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! MUTEX&lt;br /&gt;
| Make MUTEX recursive on non-windows platforms or at least provide a mutex and separate recursive mutex for all platforms. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Multiple Precompiled.&lt;br /&gt;
| Ability for multiple precompiles in a system. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability to compile/debug for both 32/64 bit systems via project settings || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability for for a fully optimal finalization for systems marked as 'client only', so that unused variables will not get generated in the finalized C Code. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability for Eiffel Studio to cross compile || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability to be able to control all user settable options in studio without having to resort to manually editing files, this is mainly for C compilation options || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Have a smarter C code generation system that can launch a C compilation of any module as soon as the C code is generated, this way we can also be smarter when monitoring C compilation progress || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability for ANY to generate a unique id for each object for referencing and hashability || ||&lt;br /&gt;
Objects that are hashable should implement HASHABLE&lt;br /&gt;
||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| With hashable ability of ANY, change object graph traversal for serialization so that multiple threads can serialize at the same time without having to wait linearly (lock_marking/unlock_marking). This may also require a reworking of the mismatch corrector facility as this does not appear to be thread-safe when magically called by the run-time|| || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability for Studio to work and compile with Cygwin || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Ability to get a list of file dependencies in the form of a file listing to stdout. This list would contain a) all .e files used in the system, b) all .lib/.so files explicitly listed in the ECF/Ace file and c) all .h files referenced in external features (ideally that have not been subjected to dead code removal). Preferably, this feature should be able to be used without performing a full compilation (level 4?). || || ||&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== .NET ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ID !! Short Summary !! Pros !! Cons !! More info&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Consume .NET generics. Not being able to use them is becoming harder.&amp;lt;br/&amp;gt;We cannot write Atlas (AJAX) based web applications because of it. The Visual Studio SDK, used by EiffelEnvision, is increasing it's use of generics and preventing use from supporting some features. The people who want to use the .NET framework classes instead of the Eiffel ones cannot use generics and have to resort to using the non-generic versions of list, which bulks implementation and leads ambiguity. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Emit .NET generics types for Eiffel generic classes. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Allow direct access to member of TYPED_POINTER [xxx] item out/ref routine arguments. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Allow direct setting of TYPED_POINTER [xxx] item for out/ref routine arguments. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Optimized ''call.do_nothing'' as a IL pop instruction to removed returned value. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Custom attributes on routine arguments and Result. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| An ability to call a parent .NET constructor from an Eiffel creation routine. || || ||&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== IDE ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ID !! Short Summary !! Pros !! Cons !! More info&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Give the user control over which classes will be compiled over the GUI (say: click on grey class and it becomes yellow and will be compiled always from now on, even though it may not be used at all. This is good for development of classes which are not added over GUI in ES.) || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| While searching for word or after a double click on a word, it would be nice if all words would be highlighted in pastel color style. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Allow arguments and locals of a routine to be pickable so that they can be renamed via the refactoring tool. || || || In the case of arguments it might be interesting to allow&lt;br /&gt;
renaming in ancestor and descendant versions of the feature.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| It's a pain to pick`n`drop huge features source code into the context window for setting break point. What about the following: Pick on the right side of the class text picks the feature as well? (Pick on the left side of the class text picks already the feature call). || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Make editor and grid more theme compliant in terms of color and font || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Remove all use of EV_TREE and EV_MULTI_COLUMN_LIST from studio so that all list widgets are drawn by vision2, this will make porting easier, we can also use the grid items to be able to change names of clusters, classes and features inline via the tree items. || || To which other platform would it make porting easier? For the Mac OS port that's completely unnecessary I think. Also it would make the tree view look uglier (not as other tree views etc on the same platform) and inline editing can be made accessible in other ways (at least in OS X that's quite easy) ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Extended Static Checking&lt;br /&gt;
| Extended static checking integrated into the IDE. || Provides more immediate feedback on potential contract violations. || ||See, for example, [http://secure.ucd.ie/products/opensource/ESCJava2/ ESC/Java2] and the associated Eclipse plugin, or Spec# integration into VisualStudio [http://download.microsoft.com/download/9/4/1/94138e2a-d9dc-435a-9240-bcd985bf5bd7/MikeBarnett-SpecSharp.wmv]. Eiffel has most of the necessary language constructs already and doesn't require annotations. See also [http://fm06.mcmaster.ca/es-verify.pdf ES-Verify]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Rearrange widgets of ''search tool'' so that they use free space on the right. Currently it uses too much vertical space. || || I don't see free space on the right. Has this already been done? ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Add an option to show the target name before the current edited class in the application title bar. When multiple projects are open, it's not possible to identify an EStudio session based on the title that appears on the tray bar|| || |||&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
!Step-by-step debugging&lt;br /&gt;
| It would be useful in step-by-step debugging to be able to follow the execution cursor when checking the invariants as it is done for the preconditions and postconditions of a routine.  This way, it would be easy to step into the right features and skip some (or all) of those present in the invariant. || || |||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!Integrated Designer&lt;br /&gt;
| It would be nice to have an integrated visual designer so that building business applications where visual design is very import can be created more easily. || || || &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Drag-n-Drop&lt;br /&gt;
| Allow the alternative of using drag and drop everywhere instead of pick and drop. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Code annotation tags support&lt;br /&gt;
| Log the tags contained in comments.  For example, when using Eclipse, it is useful to leave TODO comments behind to ensure that a part that is not implemented will be eventually.  When the time comes to clean up the TODO tags, a tool can list them all along with the descriptions and the locations of the comments.  || || || Similar approach can be applied to indexing/note tags.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Token locations in flat-view&lt;br /&gt;
| When debugging, I always look at flat view of a feature, then I found something that I want to change, so I have to go back to basic view. Buf often, I need to search the basic view to relocate the code. It would be nice if I can somehow pick a location in flat view and drop it into the right location in basic view. &lt;br /&gt;
|| || ||&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! External commands in context menu&lt;br /&gt;
| Suppose there is an external command &amp;quot;tortoisediff $file_name&amp;quot; to show diff of a file from its working base, then when a context menu for a class is displayed, this command will be in it, and before launch this command, the  $file_name placeholder will be replaced by the actual file name. Also, some special placeholders starting with # will be recognized. They represent open arguments. So before launching the command, a dialog will prompt out asking for those values. &lt;br /&gt;
|Easy to use, no need to go to Console tool anymore. || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Outline&lt;br /&gt;
| When a mouse pointer is over a class name, a feature name, etc., it would be nice to see in a pop-up tooltip some basic information about it like description, header comment, signature, etc. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Current value of a variable&lt;br /&gt;
| When a mouse pointer is over a variable in debug mode if would be nice to see in a pop-up tooltip its value. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Immediate syntax checks&lt;br /&gt;
| It would be nice if editor can detect syntax errors and warnings and highlight them inline as well as outline (using a vertical bar, an icon of a particular color, etc.). || || || Syntax warnings include obsolete language constructs as well as unused code (such as unused local variables). For them it should be possible to suggest a replacement, so that manual editing is not required.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Refactoring: unused inheritance&lt;br /&gt;
| A new tool can be introduced to check if a given inheritance path is actually used in a project and if not, would suggest to remove it. || || || It would be great to be able to run such tools in background, so that the checks are invisible to the user that only gets a warning and a suggestion to remove the unused parent clause. This way some other similar tools can be added.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Refactoring: unused arguments&lt;br /&gt;
| A new tool can be introduced to check if all arguments of a feature are used (including all versions of the feature) and would suggest to remove those that are never used. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Refactoring: more interactive renaming&lt;br /&gt;
| Renaming tool can be changed to prompt for renaming in comments and strings (one by one) rather than to apply renaming for all of them silently. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Improve search tool&lt;br /&gt;
| Progress of search operation could be shown when performing search on a project and would ensure that the IDE remains responsible at that time. It should be also possible for a user to break the search operation. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Automatic source format&lt;br /&gt;
| There could be an option to tell the editor to reformat the code according to user preference settings.  Those can address the multi-line expression format and the exceptions to the comb format (like for a class' name), for example.  The reformat feature can be made to affect only the display so that different project members can view the source as it pleases them in an uniform way. || || ||&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Language ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ID !! Short Summary !! Pros !! Cons !! More info&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Allow to use '''?''' in assigner declaration For instance &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 foo: STRING assign set_key_value (&amp;quot;foo&amp;quot;, ?) is&lt;br /&gt;
     do&lt;br /&gt;
         Result := values.item (&amp;quot;foo&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
 &lt;br /&gt;
 values: HASH_TABLE [STRING, STRING]&lt;br /&gt;
 &lt;br /&gt;
 set_key_value (k: STRING; v: STRING) is&lt;br /&gt;
     do&lt;br /&gt;
         values.force (v,k)&lt;br /&gt;
     end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Convenient Number Syntax&lt;br /&gt;
|| Adalike syntax for numbers, e.g. 2#101010 = 10#42 = 2#10_10_10 and 100_000_000 = 100000000. || effectively reduces silly bugs when reading and writing numbers || Eiffel allows underscores within numbers to allow digit grouping e.g. 8_961_226||see annotated ada reference manual   ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Exceptions mentioned in method interface&lt;br /&gt;
|| syntax for telling developers about exceptions thrown by a method. e.g.:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
foo( a : B) : C is&lt;br /&gt;
     require&lt;br /&gt;
         a /= Void&lt;br /&gt;
     exceptions&lt;br /&gt;
         Net_Unreachable, Net_Timeout&lt;br /&gt;
     do&lt;br /&gt;
         Result := values.item (&amp;quot;foo&amp;quot;)&lt;br /&gt;
     end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
|| Clear and elegant syntax, no more looking into the implementation to find out which exceptions might occur and which of them might be handled at which level.&lt;br /&gt;
|| 1) new keyword. 2) new compiler option necessary (using this interface extension is fully useful only if enforced by the compiler which would break older code). 3) Does not scale well with sub classing and redefining features.  Redefined versions may have fewer exceptions, in which some stated exceptions won't occur anymore, or more exceptions, where the feature would no longer conform to the signature and a hack would need to be made or redefining the base class in which case you have a fragile base class problem.  The Eiffel way of handling exceptions with the paradigm &amp;quot;a feature either satisfies its contract or an exception is thrown&amp;quot; is really an elegant way of handling the unknown, although it takes some getting used to when coming from Java.  ECMA exceptions as objects and the type multibranch instructions will help with non-trivial exception handling.&lt;br /&gt;
|| &lt;br /&gt;
||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Other ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!ID !! Short Summary !! Pros !! Cons !! More info&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Make every effective EiffelBase class implement default_create so that it can be used to instantiate any class with default values. || || ||&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Provide a WEAK_REFERENCE [G] class to abstract away the implementation details currently provided by IDENTIFIED for implementing weak references. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Locale support to determine what the default charset is (or whether it is UTF-8 or not) || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Build an object storing database with built-in record locking so that multiple systems can have access to the same 'objects' || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Make base.ecf rely on smaller ecf's (kernel.ecf, structures.ecf, support.ecf) so that these smaller dependancies can be compiled in only if needs be.  It would be good if ANY could be optimized so that it doesn't have any references to io (or print) or mismatch information (only needed when storable is employed) as these bring in a lot of overhead when compiling a simple system.  The smaller ecf could also link in with the object files of the runtime to avoid linking against a monolithic runtime (cecil, storable, etc) when you only want to print (&amp;quot;Hello World&amp;quot;) || ||&lt;br /&gt;
* Unused features are already eliminated in the dead code removal step when finalizing a system.&lt;br /&gt;
 ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! XXX&lt;br /&gt;
| Put more of the run-time code in to inline C code reducing the size of the executable if you are not using certain features, ideally the linked against runtime should only contain the core functionality needed to create objects, perform simple operations and garbage collect, any other features can be brought in on a class/library/configuration level. || || ||&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Additional Classes&lt;br /&gt;
| It would be nice to have classes in the basic eiffel libraries for handling serial port communication, zip compression, encryption, smtp, pop3, ftp, http, TCP/IP, usb, pdf generation, print engine for report writing.  I am sure their are others but the basic idea is that it would be nice to have a complete multi-OS tool for developing business applications with quick access to classes needed.  Presently you have to search the internet to find some of these classes.  It would be nicer to have a more complete library available from within the IDE. || || ||&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=9102</id>
		<title>Talk:EiffelStudio Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=9102"/>
				<updated>2007-08-01T07:17:42Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Notes term&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Patrickr|Patrickr]] 17:31, 9 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
The location for the mo files should be setup in the environment library, on Unix those files go under&lt;br /&gt;
 /usr/share/locale&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 /usr/share/locale/en/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de_CH/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Juliant|Juliant]] 19:53, 10 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
Is it really necessary that the language can be changed while running EiffelStudio? I would say this is set once (even during installation). It wouldn't be a problem to just restart EiffelStudio.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Ted|Ted]] 03:20, 13 November 2006 (CET)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
What are the advantages of putting mo files under /usr/share/locale? mo files are not shared between applications and normally users do not need to change mo files.&lt;br /&gt;
All mo files are put in ES installation directory, we only need to store the locale id as a preference.&lt;br /&gt;
More over, mo files are implemented to be accepted by the library only with names of locale id.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
We need to decide whether the language can be switched at runtime. Of course, not doing this as most applications definitely reduces a lot of time.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Patrickr|Patrickr]] 17:13, 13 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
On Unix there are rules where which part of an application belongs to. Standardising this locations makes various things easier.&lt;br /&gt;
I also think changing the language during runtime is not necessary.&lt;br /&gt;
&lt;br /&gt;
== Dont use UTF-16 ==&lt;br /&gt;
&lt;br /&gt;
UTF-16 is an abomination - it should never be used.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:03, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Auto-encoding detection ==&lt;br /&gt;
&lt;br /&gt;
Do you have a scheme in mind?&lt;br /&gt;
&lt;br /&gt;
This is, in general, impossible, but special circumstances can make it tractable. The starting possibilities&lt;br /&gt;
for an Eiffel source text are quite limited, so at first glance it looks possible.&lt;br /&gt;
&lt;br /&gt;
However, I note that if an Eiffel source text uses ASCII characters for everything except the contents of STRING_8 literals, and no STRING_32 or CHARACTER_32 literals are present, then it will be impossible to distinguish between ISO-8859-1 (or most other subsets of ISO-8859) and UTF-8, unless the UTF-8 file starts with a BOM. But the latter practise is reprehensible, and many editors do not support it.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:09, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Notes term ==&lt;br /&gt;
&lt;br /&gt;
The problem becomes much simpler if you add the following restriction:&lt;br /&gt;
&lt;br /&gt;
Source codings other than ISO-646 (US-ASCII) and ISO-8859-1 (Latin-1) are only allowed if the class contains an encoding term in the notes (indexing, in pre-ECMA) clause whose value names the encoding.&lt;br /&gt;
&lt;br /&gt;
So a UTF-8 source file would start something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;eiffel&amp;gt;&lt;br /&gt;
indexing&lt;br /&gt;
&lt;br /&gt;
 description: &amp;quot;My latest class writen in Unicode&amp;quot;&lt;br /&gt;
 encoding: &amp;quot;UTF-8&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class MY_LATEST&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/eiffel&amp;gt;&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:17, 1 August 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=9101</id>
		<title>Talk:EiffelStudio Internationalization</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Talk:EiffelStudio_Internationalization&amp;diff=9101"/>
				<updated>2007-08-01T07:09:35Z</updated>
		
		<summary type="html">&lt;p&gt;Colin-adams: Auto-encoding detection&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''--[[User:Patrickr|Patrickr]] 17:31, 9 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
The location for the mo files should be setup in the environment library, on Unix those files go under&lt;br /&gt;
 /usr/share/locale&lt;br /&gt;
&lt;br /&gt;
e.g.&lt;br /&gt;
 /usr/share/locale/en/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
 /usr/share/locale/de_CH/LC_MESSAGES/eiffelstudio.mo&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Juliant|Juliant]] 19:53, 10 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
Is it really necessary that the language can be changed while running EiffelStudio? I would say this is set once (even during installation). It wouldn't be a problem to just restart EiffelStudio.&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Ted|Ted]] 03:20, 13 November 2006 (CET)'''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
What are the advantages of putting mo files under /usr/share/locale? mo files are not shared between applications and normally users do not need to change mo files.&lt;br /&gt;
All mo files are put in ES installation directory, we only need to store the locale id as a preference.&lt;br /&gt;
More over, mo files are implemented to be accepted by the library only with names of locale id.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
We need to decide whether the language can be switched at runtime. Of course, not doing this as most applications definitely reduces a lot of time.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''--[[User:Patrickr|Patrickr]] 17:13, 13 November 2006 (CET)'''&lt;br /&gt;
&lt;br /&gt;
On Unix there are rules where which part of an application belongs to. Standardising this locations makes various things easier.&lt;br /&gt;
I also think changing the language during runtime is not necessary.&lt;br /&gt;
&lt;br /&gt;
== Dont use UTF-16 ==&lt;br /&gt;
&lt;br /&gt;
UTF-16 is an abomination - it should never be used.&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:03, 1 August 2007 (CEST)&lt;br /&gt;
&lt;br /&gt;
== Auto-encoding detection ==&lt;br /&gt;
&lt;br /&gt;
Do you have a scheme in mind?&lt;br /&gt;
&lt;br /&gt;
This is, in general, impossible, but special circumstances can make it tractable. The starting possibilities&lt;br /&gt;
for an Eiffel source text are quite limited, so at first glance it looks possible.&lt;br /&gt;
&lt;br /&gt;
However, I note that if an Eiffel source text uses ASCII characters for everything except the contents of STRING_8 literals, and no STRING_32 or CHARACTER_32 literals are present, then it will be impossible to distinguish between ISO-8859-1 (or most other subsets of ISO-8859) and UTF-8, unless the UTF-8 file starts with a BOM. But the latter practise is reprehensible, and many editors do not support it.&lt;br /&gt;
&lt;br /&gt;
--[[User:Colin-adams|Colin-adams]] 09:09, 1 August 2007 (CEST)&lt;/div&gt;</summary>
		<author><name>Colin-adams</name></author>	</entry>

	</feed>