<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx</link><description>I just created a new CodePlex project: http://undo.codeplex.com What It's a simple framework to add Undo/Redo functionality to your applications, based on the classical Command design pattern . It supports merging actions, nested transactions, delayed</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9810558</link><pubDate>Wed, 01 Jul 2009 12:20:26 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9810558</guid><dc:creator>JimK</dc:creator><description>&lt;p&gt;It's useful for me,&lt;/p&gt;
&lt;p&gt;can you put a demo project to the source code?or some unit tests,just for understand how to use it&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9813553</link><pubDate>Thu, 02 Jul 2009 12:09:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9813553</guid><dc:creator>Anandarajeshwaran</dc:creator><description>&lt;p&gt;Hi,&lt;/p&gt;
&lt;p&gt;I am looking for a application framework/architecture for winforms applications. I am planning to develop very small applications like customer address management/to do list etc., mostly they will be using access as back end and single user only.the framework/architecture i see in msdn suits for enterprise level development not for an hobbyist. can u guide on this perspective&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9814808</link><pubDate>Thu, 02 Jul 2009 22:24:18 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9814808</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Hi JimK,&lt;/p&gt;
&lt;p&gt;I added a couple of demo projects:&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://blogs.msdn.com/kirillosenkov/archive/2009/07/02/samples-for-the-undo-framework.aspx"&gt;http://blogs.msdn.com/kirillosenkov/archive/2009/07/02/samples-for-the-undo-framework.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Anandarajeshwaran:&lt;/p&gt;
&lt;p&gt;to be frank, I'm unaware of a good guidance for creating small scale WinForms client applications. Use your common sense, general design guidelines, design patterns and you'll be successful.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9817136</link><pubDate>Sat, 04 Jul 2009 03:16:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9817136</guid><dc:creator>Stefan</dc:creator><description>&lt;p&gt;There is no need for undo-redo framework.&lt;/p&gt;
&lt;p&gt;All you need is purely functional&lt;/p&gt;
&lt;p&gt;data structures which provide&lt;/p&gt;
&lt;p&gt;multiple versions with efficient&lt;/p&gt;
&lt;p&gt;representation and update operatations.&lt;/p&gt;
&lt;p&gt;You history is then a list of&lt;/p&gt;
&lt;p&gt;(action-name, current-version).&lt;/p&gt;
&lt;p&gt;Design patterns are the wrong way&lt;/p&gt;
&lt;p&gt;to attack many problems.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9819148</link><pubDate>Mon, 06 Jul 2009 11:17:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9819148</guid><dc:creator>David Myers</dc:creator><description>&lt;p&gt;I agree with Stefan...I am afraid you have just suffered death by patterns.&lt;/p&gt;
&lt;p&gt;Using the command pattern is a good start but not in the way you used it. A much better approach would be to use two stacks. The first stack contains the operations to be executed, whilst the second has undo operations. When adding a command to be executed, the undo method is also specified. Initially the undo stack would be empty whilst the execution stack contains the operations to be executed.&lt;/p&gt;
&lt;p&gt;When a command is executed sucessfully the undo operation is added to the undo stack. In the event of an exception, all methods in the undo stack would be executed ensuring the undo is in the same order as the normal execution. &lt;/p&gt;
&lt;p&gt;Of course to make this work you need to ensure that you have undo operations where required and that the undo methods work in the same order as the normal execution.&lt;/p&gt;
&lt;p&gt;I have some sample code if anyone is interested.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9820422</link><pubDate>Mon, 06 Jul 2009 22:12:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9820422</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Stefan:&lt;/p&gt;
&lt;p&gt;I agree, immutability is the way to go. Undoing then is just bringing back a snapshot of your data-structure from back then.&lt;/p&gt;
&lt;p&gt;However there are a couple of points to keep in mind.&lt;/p&gt;
&lt;p&gt;1. There are existing projects out there that are not built in a functional way. A LOT of them. And they need guidance on how to implement Undo in their mutable world. I've seen applications where v1 allows undoing 1 step, and v2 is well advanced - it allows undoing 5 steps!!! Forget immutability, let's just start with not copying the whole world and being explicit about your operations.&lt;/p&gt;
&lt;p&gt;2. I believe that design patterns are something that every developer should know well. After getting to know them, one can decide for oneself - whether to use them or not, but this decision has to be conscious and weighted. I see that you probably know patterns very well and have chosen against them for &amp;quot;many problems&amp;quot;. OK. Good for you. However my point is that one can't become a good developer (in the .NET world) without having a solid knowledge of patterns. If you decide to dump them in favor of functional style, LISP, DSLs, meta-programming or anything else - you're welcome. What I don't like is when someone critisizes patterns and doesn't know a thing about them (again, I'm sure you know your patterns well).&lt;/p&gt;
&lt;p&gt;David:&lt;/p&gt;
&lt;p&gt;That very well may be the case. I didn't promise my implementation is the best one.&lt;/p&gt;
&lt;p&gt;I'm very interested in your sample code :) Go ahead and share your experience with the rest of the world. &lt;a rel="nofollow" target="_new" href="http://code.msdn.com"&gt;http://code.msdn.com&lt;/a&gt;, or &lt;a rel="nofollow" target="_new" href="http://codeplex.com"&gt;http://codeplex.com&lt;/a&gt;&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9821342</link><pubDate>Tue, 07 Jul 2009 06:30:51 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9821342</guid><dc:creator>Kevin</dc:creator><description>&lt;p&gt;David Myers: I am interested in your code. Do you have somewhere you could post it?&lt;/p&gt;
&lt;p&gt;Thanks&lt;/p&gt;
&lt;p&gt;Kevin&lt;/p&gt;
</description></item><item><title>Design Patterns</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9823181</link><pubDate>Wed, 08 Jul 2009 01:03:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9823181</guid><dc:creator>Stefan</dc:creator><description>&lt;p&gt;Its corporations and business who want you to think in design patterns, so that they can make money. In functional style a design pattern is simply a higher order function. Everything is much much much more light weight. Design patterns are not extensible&lt;/p&gt;
&lt;p&gt;and often non composable. One you choose to use one of them you are stuck, for the rest of the life of the application. Design patterns are top-down approach and therefore they &amp;quot;claim&amp;quot; they know the &amp;quot;future&amp;quot; of the application. Since no one can predict how an application will evolve, forget about top-down design and software architects. Software arichtects means incompetence. Use bottom-up and no-patterns. If you want to have persistance then simply use persistent data structures -- and you have a provable guarantee which you don't have an undo-redo framework. Persistance is composable -- undo-redo is not. You don't copy the whole structure upon update -- this is very important. Here is where algorithmics come into play. Simply google for &amp;quot;Purely functional data strucutres&amp;quot;, read it and you&lt;/p&gt;
&lt;p&gt;have learned much much more than reading any design pattern book -- and you have learned something right.&lt;/p&gt;
&lt;p&gt;Using purely functional data structures, you simply don't have to solve any problem. Its very simple, all you effort is in algorithmic thinking -- how to design such a structure. But most of the purely functional data structures are out there -- simple lists, double ended queues, hash tables, trees -- the slow down and memory usage are usually logarithmic, in the size of the data structure -- which is nothing. Simply to keep a list of n operations is O(n). If one operation does an O(1) incremental update then you pay O(log(n)) in total -- its nothing compared to O(n) to keep a list of the names of the operations. &lt;/p&gt;
&lt;p&gt;The problem is not if your or mine code is good -- here the problem is fundamental -- it is what COMPUTING is all about -- coming up with simple solutions to complicated problems.&lt;/p&gt;
&lt;p&gt;Design patterns are complicated solution to compicated problems. I'm going to show you in a minute how design patterns are subsumed by functional programming.&lt;/p&gt;
</description></item><item><title>Design Patterns vs. Func. Prog.</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9823267</link><pubDate>Wed, 08 Jul 2009 03:13:22 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9823267</guid><dc:creator>Stefan</dc:creator><description>&lt;p&gt;Design Patterns is Software Developmment Done Wrong&lt;/p&gt;
&lt;p&gt;Design Patterns arise in the Object Oriented Programming Way&lt;/p&gt;
&lt;p&gt;The problem with OO style is first&lt;/p&gt;
&lt;p&gt; &amp;nbsp;- mutability (small problem)&lt;/p&gt;
&lt;p&gt; &amp;nbsp;- objects have multiple methods, this means that they are not built from the smallest attomic pieces (functions). Sometimes it is necessesary to have something like an OO-class (e.g. monads in functional programming -- a monad needs 3 functions), but in 90% it is not. This usually creates tight couping&lt;/p&gt;
&lt;p&gt; &amp;nbsp;especially when combined with interfaces. Try changing the interface of IEnumerable for example and you have to change 90% of existing applications substantially.&lt;/p&gt;
&lt;p&gt; &amp;nbsp;- top-down design (you need to draw your diagram before you begin coding -- need to know all about your application's future, but who can predict it?)&lt;/p&gt;
&lt;p&gt; &amp;nbsp;- Object are non-composable (because of state and multiple methods and interfaces) without significant plannig -- this is the killer. A small change in the behavior of the program will imply a large change in the code)&lt;/p&gt;
&lt;p&gt; &amp;nbsp;- Tight-copling -- this is also a killer&lt;/p&gt;
&lt;p&gt; &amp;nbsp;- Non-cooperative components &lt;/p&gt;
&lt;p&gt;The biggest evil is on object-oriented thinking. Object orientedness lacks the following properties&lt;/p&gt;
&lt;p&gt;-- composability. Fix: use only simple functions. Use well-though-out and composable type-classes.&lt;/p&gt;
&lt;p&gt;-- non-intrusiveness: fix: templates (like C++) and generics, also static type classes&lt;/p&gt;
&lt;p&gt;Most design pattern solution actually propose either classes with state + multiple methods. &lt;/p&gt;
&lt;p&gt;Let's take a look at some desing patterns from wikipedia and&lt;/p&gt;
&lt;p&gt;show that those are either features of functional languages or&lt;/p&gt;
&lt;p&gt;a higher order function&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://en.wikipedia.org/wiki/Design_pattern_"&gt;http://en.wikipedia.org/wiki/Design_pattern_&lt;/a&gt;(computer_science)&lt;/p&gt;
&lt;p&gt;Encapsulation and information hiding&lt;/p&gt;
&lt;p&gt;FP Solution: a closure&lt;/p&gt;
&lt;p&gt;Inheritance or subclassing&lt;/p&gt;
&lt;p&gt;A type class&lt;/p&gt;
&lt;p&gt;Many of those patterns are basically features of OO languages. They are not really design patterns...&lt;/p&gt;
&lt;p&gt;Let's look here: &lt;a rel="nofollow" target="_new" href="http://userpages.umbc.edu/~tarr/dp/fall00/cs491.html"&gt;http://userpages.umbc.edu/~tarr/dp/fall00/cs491.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The observer pattern:&lt;/p&gt;
&lt;p&gt;Java example: a database connected to a graph view and a table view&lt;/p&gt;
&lt;p&gt;Solution: message passing Erlang-style&lt;/p&gt;
&lt;p&gt;Factory Pattern:&lt;/p&gt;
&lt;p&gt;Java Example: CreateDocument with methods open/close/save/revert&lt;/p&gt;
&lt;p&gt;Best solution is by type classes (in Haskell)&lt;/p&gt;
&lt;p&gt;However, this is not the best example for the factory pattern in func. prog. The best use case is a function returning a function&lt;/p&gt;
&lt;p&gt;Iterator Pattern:&lt;/p&gt;
&lt;p&gt;For example lists/streams with get_next()&lt;/p&gt;
&lt;p&gt;Solution: cons lists/delayed cons lists(streams)/yield (syntactic sugar)/higher order functions generating and consuming streams&lt;/p&gt;
&lt;p&gt;Facade Pattern&lt;/p&gt;
&lt;p&gt;Java Example: seal classes together&lt;/p&gt;
&lt;p&gt;Functional approach: modules&lt;/p&gt;
&lt;p&gt;The state pattern: &lt;/p&gt;
&lt;p&gt;A gui: object has a state and depending on actions and state change the state&lt;/p&gt;
&lt;p&gt;Functional approach: message passing with pattern matching. Also ability to pass closures and state, Best is to keep purely functional.&lt;/p&gt;
&lt;p&gt;Now those are the best:&lt;/p&gt;
&lt;p&gt;The Composite pattern: simply a dot in haskell and &amp;gt;&amp;gt; in F#&lt;/p&gt;
&lt;p&gt;Functors: a special type class in haskell (called Functor). &lt;/p&gt;
&lt;p&gt;Addapter patterns: a simple function, e.g. List.of_seq, Seq.of_list in (example in F#)&lt;/p&gt;
&lt;p&gt;The Decorator pattern: a function which wraps another function, e.g. read_only(takes as input a list) returns a read only list&lt;/p&gt;
&lt;p&gt;In conclusing, I would think again if I have to use OO and with it patterns. &lt;/p&gt;
&lt;p&gt;Recomendations: 1. avoid OO and especially OO design as much as possible. No big class diagrams, no UML, no type hierarchies.&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;If you have to design your program before you start coding&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;it then after a point the code will crumble against its weight. You cannot design against future/unknown requirements&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;so there is no point to try. Just make sure your code has two features: COMPOSABILITY and NON-Intrusiveness&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2. Start simple. Usually programs are simply tranformations from one representations to another. &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Use a library of higher order functions which can be composed together to make complicated transformations&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Make a library of your own transformations if you want to avoid boiler plate code&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;3. Pass state around. Try to keep mutable state within a single function. For user interfaces use message&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;passing and monads(Haskell)/computation expressions(F#)/engines(Scheme)&lt;/p&gt;
&lt;p&gt;Gui Example (not compiled, but possible to write in this style):&lt;/p&gt;
&lt;p&gt;let db = open_db(&amp;quot;...&amp;quot;) &lt;/p&gt;
&lt;p&gt;let rec mygui = gui{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;let state = get_state() &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;let t = state.num_tries&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (t &amp;gt; 0) then&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;do! mk_label &amp;quot;You tried too many times&amp;quot;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;let! usernamebox = mk_textbox &amp;quot;User name:&amp;quot;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;let! passwrdbox = mk_passwordbox &amp;quot;Password:&amp;quot;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;do! button (fun msg -&amp;gt;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;match msg with&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;| ButtonClicked -&amp;gt; let username = get_text usernamebox&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; let passwrd = get_text passwrdbox&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (lookup_db query{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;let! users = table db &amp;quot;users&amp;quot; &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;filter(users, fun (this_user,this_passwrd -&amp;gt; username = username &amp;amp;&amp;amp; &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; this_passwrd = passwrd))&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;|&amp;gt; count&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }) = 1 then&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; //continue gui simply runs the next screen&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue_gui nextgui (update_state state{user=username})&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;else &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;continue_gui mygui (update_state state{num_tries = state.num_tries + 1}) &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;} &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;//run the initial screen&lt;/p&gt;
&lt;p&gt;continue_gui mygui mk_init_state() &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9823518</link><pubDate>Wed, 08 Jul 2009 09:49:44 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9823518</guid><dc:creator>NSFW</dc:creator><description>&lt;p&gt;&amp;quot;Its corporations and business who want you to think in design patterns, so that they can make money.&amp;quot;&lt;/p&gt;
&lt;p&gt;If that's true then thank you for warning me away from this functional stuff. &amp;nbsp;I'd hate to find myself using an approach that didn't lend itself to writing software that customers actually want to pay for.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9824328</link><pubDate>Wed, 08 Jul 2009 19:52:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9824328</guid><dc:creator>Farid Zakaria</dc:creator><description>&lt;p&gt;There are two sides to this coin and the discussion seems to have diverted largely from the original intention of undo/redo.&lt;/p&gt;
&lt;p&gt;I think design patterns are a great tool such as a hammer however it is important that not everything is a nail.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9824568</link><pubDate>Wed, 08 Jul 2009 21:56:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9824568</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Farid: you NAILED it!!! :)&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9825298</link><pubDate>Thu, 09 Jul 2009 04:48:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9825298</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Stefan: this deserves a separate blog post. Do you blog?&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9826026</link><pubDate>Thu, 09 Jul 2009 11:10:35 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9826026</guid><dc:creator>Khurram</dc:creator><description>&lt;p&gt;Stefan:&lt;/p&gt;
&lt;p&gt;I completely agree with you. I had been scratching my head with patterns before I came to know about functional world. &lt;/p&gt;
&lt;p&gt;I agree that the fundamental problem isn't that your code is good or mine, what should be the ideal pattern for a problem but The problem is how we think about problems and choose an appropriate solution. Functional programming is a natural way of computing. On the other hand, oop and design patterns give you a vocabulary at very high level to communicate about the problems and there solutions. I haven't seen anything like this in functional world. There are tradeoffs in each of the world. I'm still looking for some standard ways in functional world to design large scale systems and a higher level language to model (like design patterns). &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9826947</link><pubDate>Thu, 09 Jul 2009 18:30:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9826947</guid><dc:creator>M. Wernig</dc:creator><description>&lt;p&gt;Kirill: Stefan's posts regarding design patterns really should be a separate post/discussion. I would definitely be interested in hearing some of the opinions on both sides of the issue. I tend to agree with Stefan regarding design patterns, having seen them being misused repeatedly and turning relatively simple systems into a bloated, hard-to-maintain, ones. (p.s. I also hate the term &amp;quot;software architects&amp;quot; :-) &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9827025</link><pubDate>Thu, 09 Jul 2009 19:02:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827025</guid><dc:creator>Dave</dc:creator><description>&lt;p&gt;Stefan:&lt;/p&gt;
&lt;p&gt;It looks like you apply the monolithic paradigm very well. &amp;nbsp;I'm sure the work you do has never made it beyond academia where everything is about the algorithms used in implementations, but in the real world, be it enterprise development, game development, or device driver development, the type of spaghetti code that your style of functional programming leads to never produces a complete solution that is useful or maintainable. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Even your example does not provide a solution on target with the Undo/Redo framework, instead providing a trite example of how much garbage you can shove into a function. &amp;nbsp;If you want to illustrate how much better functional programming can be, you should create a functional version of Kirill's solution so we can understand the downfall of our foolish OO ways that we somehow managed to produce maintainable software. &amp;nbsp;This means you have to create a complete, buildable solution, not just throw up some theoretical code. &amp;nbsp;I would love to see it, rather than an academic example that is missing your functional tenants of simple and composable, even for the basic task of validating a login.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9827307</link><pubDate>Thu, 09 Jul 2009 21:11:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827307</guid><dc:creator>Dave #2</dc:creator><description>&lt;p&gt;@Dave:&lt;/p&gt;
&lt;p&gt;My thoughts exactly. I want to like functional software, but everything I see about it being &amp;quot;superior&amp;quot; is theoretical.&lt;/p&gt;
&lt;p&gt;Show me an enterprise level, distributed system, and then I can take you seriously.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9827510</link><pubDate>Thu, 09 Jul 2009 22:52:34 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827510</guid><dc:creator>Bruce Pierson</dc:creator><description>&lt;p&gt;@Dave:&lt;/p&gt;
&lt;p&gt;Beautiful. Everything I've read on FP is academic, and they spend all their time trying to figure out how to make something like a Queue immutable. WTH!? Convince me of the BUSINESS VALUE of something, then I'll look at it.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9827765</link><pubDate>Fri, 10 Jul 2009 01:32:07 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9827765</guid><dc:creator>Ben</dc:creator><description>&lt;p&gt;Don't EVER listen to a compsci major / phd about anything real world.. &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9828563</link><pubDate>Fri, 10 Jul 2009 12:47:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9828563</guid><dc:creator>Christian</dc:creator><description>&lt;p&gt;@Bruce&lt;/p&gt;
&lt;p&gt;try to weigh everything with business value and you are stuck in repetition because looking outside the box is costly at first and who knows whether you are being rewarded.&lt;/p&gt;
&lt;p&gt;@Ben&lt;/p&gt;
&lt;p&gt;It is those majors/phds who add to the existing body of knowledge - or inversely without them you wouldn't even be programming using punch cards. Clearly, not every aspect of theory has a direct application in the non-academic world but as Jeff Atwood has demonstrated recently, there is even practical value in the P=NP problem (&lt;a rel="nofollow" target="_new" href="http://www.codinghorror.com/blog/archives/001270.html"&gt;http://www.codinghorror.com/blog/archives/001270.html&lt;/a&gt;). &lt;/p&gt;
&lt;p&gt;Now, I agree with that before before touting something without proof one should think carefully about the word one uses. However, I believe this form of discussion repeats itself (Assembler vs. C, C vs. C++, ...). Clearly, (at the moment) functional programming languages can be used more efficiently (lines of code per hour/$) for certain classes of problems (&amp;quot;number crunching&amp;quot; if you will, etc.). For example, banks use FP in the development of risk assessment programs, chemical companies use FP in the development of gene/molecule sequencing programs. Routing algorithms, Spam filter, Machine Learning utilizing apps, ...&lt;/p&gt;
&lt;p&gt;Now, if you consider the above type of applications as something of pure theoretical/ academic value, you are certainly right (but I believe then we might have a different interpretation of academic/theoretic).&lt;/p&gt;
&lt;p&gt;To make a long story short, if boundaries are not pushed there is no progress - and clearly I wouldn't want to be a developer in a world where the same type of applications are developed using the same old-style methods (remember before the invention of quicksort there was only linear sort).&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9828734</link><pubDate>Fri, 10 Jul 2009 17:05:45 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9828734</guid><dc:creator>Stefan</dc:creator><description>&lt;p&gt;Actually, all the possible project mentioneds:&lt;/p&gt;
&lt;p&gt;-- Kiril's live geometry project&lt;/p&gt;
&lt;p&gt;-- Distributed systems&lt;/p&gt;
&lt;p&gt;have simpler (and beatiful) solutions by Functional Programming (that are more&lt;/p&gt;
&lt;p&gt;likely to work). &lt;/p&gt;
&lt;p&gt;Let me give you challenge: implement&lt;/p&gt;
&lt;p&gt;a parallel/distributed version of&lt;/p&gt;
&lt;p&gt;K-means clustering algorithm in 10 lines&lt;/p&gt;
&lt;p&gt;of code in OOP. Then we can talk.&lt;/p&gt;
&lt;p&gt;I choose this problem because it is just&lt;/p&gt;
&lt;p&gt;10 lines (matching my implementation). Kiril's system would be more lines, that's why I propose this.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9828797</link><pubDate>Fri, 10 Jul 2009 18:16:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9828797</guid><dc:creator>Dave #2</dc:creator><description>&lt;p&gt;@Stefan,&lt;/p&gt;
&lt;p&gt;You prove my point exactly. An algorithm is the same kind of example I always see. An academic, but useless example.&lt;/p&gt;
&lt;p&gt;I issued the challenge initially:&lt;/p&gt;
&lt;p&gt;Show ME a an n-tier enterprise solution implemented with a functional language, then we can talk.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9828799</link><pubDate>Fri, 10 Jul 2009 18:22:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9828799</guid><dc:creator>Dave</dc:creator><description>&lt;p&gt;I'm not trying to pit OO against FP or C# against Lisp. &amp;nbsp;I think whatever technique and toolset makes the most sense for the solution is the best, and I'm sure there are some scenarios where FP makes great sense - I'm just not seeing it here. &amp;nbsp;Instead, I've seen a usable OO solution by Kirill for an Undo / Redo framework, followed by a diatribe by Stefan on how OO is terrible and an FP solution would be so much better. &amp;nbsp;But I don't see an FP solution, and in my C# OO mind, or even in an IronPython blend of OO and FP, I'm having trouble conceptualizing how an FP solution would be better. &amp;nbsp;&lt;/p&gt;
&lt;p&gt;Again, I'd really like to see a complete FP solution to this problem, because I'm always a fan of applying different techniques. &amp;nbsp;I really don't think Kirill posted this blog entry to discuss the merits of OOP, but rather to present an implementation of an Undo/Redo Framework using a design pattern. &amp;nbsp;The point of a design pattern isn't to show off OOP skills but rather to communicate a software design using generally understood programming techniques. &amp;nbsp;I'm willing to bet there are FP design patterns as well, right?&lt;/p&gt;
&lt;p&gt;Stephan - rather than continuing to come up with new algorithmic challenges, why don't you just take on the challenge Kirill did (staying with the topic of this blog) and create an FP version of the Undo/Redo Framework. &amp;nbsp;I'm sure if a parallel K-means clustering algorithm can be done in 10 lines of FP, then the Undo/Redo Framework is what, 3 or 4? &amp;nbsp;It sounds great! &amp;nbsp;Show me!&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9829624</link><pubDate>Sat, 11 Jul 2009 18:20:32 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9829624</guid><dc:creator>Marjan</dc:creator><description>&lt;p&gt;FP is good for trying algorithms in a quick way. If you want to build system that will be extendable and modular FP fails. &lt;/p&gt;
&lt;p&gt;Also correcting mistakes and bugs is quite harder in FP than in OO, not to say communication between scenarios, n-tier architectures.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9829743</link><pubDate>Sun, 12 Jul 2009 00:57:06 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9829743</guid><dc:creator>Rajesh</dc:creator><description>&lt;p&gt;I gone though both the aspects of OO and FP. It all depends upon the organisation and implementation along with the past experince. Approach should be to make it workable and maintainable&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9830626</link><pubDate>Mon, 13 Jul 2009 00:48:49 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9830626</guid><dc:creator>Catto</dc:creator><description>&lt;p&gt;Hey Now Kirill,&lt;/p&gt;
&lt;p&gt;That sure is a good project. &lt;/p&gt;
&lt;p&gt;Thx 4 the info,&lt;/p&gt;
&lt;p&gt;Catto&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9831439</link><pubDate>Mon, 13 Jul 2009 14:09:27 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9831439</guid><dc:creator>Danny P</dc:creator><description>&lt;p&gt;A Design Pattern is not the way you should do things, but merely the way people do things already, but formally documented. This is why they don't say you &amp;quot;invented&amp;quot; a pattern, but instead you &amp;quot;discovered&amp;quot; a pattern.&lt;/p&gt;
&lt;p&gt;I do agree there is a number of people out there trying use the wrong design pattern for their problems, or even using design patterns where none are required (just for the sake of using it). A good understanding of Design Patterns in the OOP world is crucial for good software design, for it provides you with toolset of solutions for problems you (we) oftenly bump into when building enterprise application. &lt;/p&gt;
&lt;p&gt;I believe FP has it's applicability as much as Design Patterns. It all depends on the problem you're trying to solve.&lt;/p&gt;
&lt;p&gt;I would also like to re-iterate the challange, and have the FP-defenders (that claim FP is &amp;quot;better&amp;quot; than Design Patterns), to come up with a better solution for the Undo/Redo problem. Also, please let us know on which aspects it tops the rival (performance, maintenability, testability, reusability, etc).&lt;/p&gt;
&lt;p&gt;If anyone is creating a forum discussion or a blog post based on the OOP x FP debate, please post the link here so we all can participate (and learn from it).&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9832425</link><pubDate>Tue, 14 Jul 2009 01:30:15 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9832425</guid><dc:creator>Garry McGlennon</dc:creator><description>&lt;p&gt;Kirill: &lt;/p&gt;
&lt;p&gt;Thanks for sharing your work, its truely unfortunate that people have decided to turn your work in to a debate about FP vs OOP. I know how much effort it takes to prepare your work for public consumption, and I find it objectionable that its been turned into a meaningless debate and an attack on your work. Seriously if you dont like the implementation then dont use it.&lt;/p&gt;
&lt;p&gt;Its this type of mindless debate and criticism that prevents people posting their work.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9832485</link><pubDate>Tue, 14 Jul 2009 02:16:39 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9832485</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Garry: thanks! To be frank, I totally don't mind this discussion. It's interesting to watch and it provokes thought. I might not agree with everything that has been said, but that's fine. I only regret that I haven't created a separate blog post in time to discuss FP vs. OOP - but I thought that would become just another holy war.&lt;/p&gt;
&lt;p&gt;Also I don't perceive anything here as an attack - people can write whatever they want in a common process of &amp;quot;finding the truth&amp;quot;. As long as there are a couple of people who find this framework/approach useful - I consider my job fulfilled.&lt;/p&gt;
&lt;p&gt;I'm also not afraid that Design Patterns critisism will scare people away from projects like these - one should be able to judge for oneself - if one likes it, one will use it regardless of what others say :)&lt;/p&gt;
&lt;p&gt;In any case, I might post a separate article on FP vs. OOP, but I'm not sure if it's going to be fruitful.&lt;/p&gt;
&lt;p&gt;Take care,&lt;/p&gt;
&lt;p&gt;Kirill&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9832799</link><pubDate>Tue, 14 Jul 2009 08:39:48 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9832799</guid><dc:creator>Bruce Pierson</dc:creator><description>&lt;p&gt;@Christian:&lt;/p&gt;
&lt;p&gt;What's really funny about the &amp;quot;looking outside the box is costly&amp;quot; comment is that I remember back in the 90's when managers and such were against OOP because it was costly and required more analysis, etc. This was back when I was programming configuration systems in Lisp, ironically. The pendulum truly does swing...&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9833560</link><pubDate>Wed, 15 Jul 2009 00:44:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9833560</guid><dc:creator>Christian</dc:creator><description>&lt;p&gt;@Bruce&lt;/p&gt;
&lt;p&gt;must be interesting to have this kind of experience (enables one to smile some sort of when some people jump overly excited on the train of buzzwords and almost self-fulfilling prophecies).&lt;/p&gt;
&lt;p&gt;Now, with the recent convergence of functional and object-oriented languages (F# + OO constructs &amp;lt;--&amp;gt; C# + lambdas, ...) there isn't really one one beats it all programming language. Also, since many OO languages offer nothing more than syntactic suggar to coat the simple message sender-receiver paradigm, one may implement OO atop a lot languages (clearly not as beautiful and safe). For example, if one looks at the source code of Quake 1 one finds OO concepts embedded into C code.&lt;/p&gt;
&lt;p&gt;Lastly, thanks to Kirill for providing brain-food, because this is what it should be about (as it has been mentioned) get the mind to think about something beautiful - solving a problem (in one of many ways)!&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9833740</link><pubDate>Wed, 15 Jul 2009 04:59:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9833740</guid><dc:creator>edmund yau</dc:creator><description>&lt;p&gt;very very good framework, i am using it, thank you for your great affort&lt;/p&gt;
&lt;p&gt;@@@@@@@@@@@@@@@@@@@@&lt;/p&gt;
&lt;p&gt;係IT super manager, 唔係super IT manager&lt;/p&gt;
&lt;p&gt;&lt;a rel="nofollow" target="_new" href="http://www.geocities.com/it_super_manager"&gt;http://www.geocities.com/it_super_manager&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;IT界最強技術王, 名字擬似:edmund yau&lt;/p&gt;
</description></item><item><title>re: FP vs OO</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9834271</link><pubDate>Wed, 15 Jul 2009 17:06:59 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9834271</guid><dc:creator>Matt Ellen</dc:creator><description>&lt;p&gt;Hi Stephan,&lt;/p&gt;
&lt;p&gt;I'm not entirely sure you've grasped OO programming.&lt;/p&gt;
&lt;p&gt;The whole point is to allow programmers to think like people when writing programmes, rather than having to think like a computer.&lt;/p&gt;
&lt;p&gt;OO may take more code than FP code, but it is better code in terms of readability and maintainability.&lt;/p&gt;
&lt;p&gt;Anyone can think like a person (generally speaking ;) ) but it takes a lot more restraint to think like a computer. Why restrain yourself like this when at the same time trying to be creative?&lt;/p&gt;
&lt;p&gt;Maybe you've been trying to apply OO techniques where they aren't appropriate, and have come to the conclusion that FP trump OO in all cases.&lt;/p&gt;
&lt;p&gt;That said - I'd be very interested to see a FP version of undo/redo. If you have an example please post it so we can evaluate what you say.&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Matt&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9838560</link><pubDate>Sat, 18 Jul 2009 15:08:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9838560</guid><dc:creator>MAMA Jack</dc:creator><description>&lt;p&gt;coolo, just what I might need if i was writing a professional app. A killer app, many would say it were.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9842108</link><pubDate>Mon, 20 Jul 2009 22:00:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9842108</guid><dc:creator>Brian</dc:creator><description>&lt;p&gt;Funniest quote of this whole thread:&lt;/p&gt;
&lt;p&gt;&amp;quot;Stefan:Its corporations and business who want you to think in design patterns, so that they can make money.&amp;quot;&lt;/p&gt;
&lt;p&gt;I work for a software development services company. &amp;nbsp;More often than not the companies we develop for have us maintain the apps we've written for them. &amp;nbsp;I can take a kid fresh out of college, plop him down in front of visual studio and with minimal instruction (though obviously heavy supervision for one fresh out of college) I can get him maintaining one of our customers apps.&lt;/p&gt;
&lt;p&gt;As Matt said, &amp;quot;OO may take more code than FP code, but it is better code in terms of readability and maintainability.&amp;quot; &amp;nbsp;&lt;/p&gt;
&lt;p&gt;I've said in my blog, &amp;quot;Writing code is easy. Writing code cleanly, efficiently so it’s easy to maintain, now that takes some skill.&amp;quot;&lt;/p&gt;
&lt;p&gt;From a business perspective FP doesn't make a lot of sense. &amp;nbsp;I'm not saying FP doesn't have it's applications. &amp;nbsp;I'm saying that team development of large scale applications and the maintenance of those applications become so complex that I suspect a company wouldn't make much money off of them. &amp;nbsp;With OO we can develop large scale applications and turn around a nice profit from the development and maintenance of those applications.&lt;/p&gt;
&lt;p&gt;FP might be fine for small projects with small maintenance tails and small teams. &amp;nbsp;The problem with large projects is that, though we tend to have low turn-around, turn-around happens. &amp;nbsp;With OO I can lead a team of ten engineers, lose one or two, drop one or two back in and there is minimal impact to the project.&lt;/p&gt;
&lt;p&gt;@Stefan: &amp;nbsp;What middle or large scale projects (which I would define as being developed by a team of 5 or more engineers, 100 person or more user base and a three to five year maintenance tail) are out there that are developed in FP and turning a profit for the company that developed it?&lt;/p&gt;
&lt;p&gt;I'm not opposed to the idea of FP, just this idea that is seems like you want to replace all OO with FP and that just seems like a bad application of FP.&lt;/p&gt;
&lt;p&gt;Back on topic, thanks for this code Kirill. &amp;nbsp;I've looked at both of the samples and everything seems fairly straight forward. &amp;nbsp;This will make my life easier. &amp;nbsp;Though the project I'm working on now is too far along in development to integrate your framework I'll make sure whatever architect I'm working with on our next application is aware of the framework. &amp;nbsp;Integration from the beginning design phases seems key to any core framework.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Brian&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9842253</link><pubDate>Mon, 20 Jul 2009 23:26:37 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9842253</guid><dc:creator>Randy</dc:creator><description>&lt;p&gt;Kirill, this is a nice implementation of undo/redo for mutable data structures. &amp;nbsp;I don't want to throw fuel on the language/abstraction war, but immutable data structures do provide an easier/safer way to build undo/redo. &amp;nbsp;Given the use of a garbage collected language like c#, it is fairly easy to build immutable data structures, and is a technique that can be applied independently of functional programming. &amp;nbsp;Indeed it works quite well in an object-oriented design, too.&lt;/p&gt;
&lt;p&gt;For those who haven't built large applications with undo/redo, a significant challenge is ensuring that your do/undo methods are perfect mirrors. &amp;nbsp;One helpful approach is to create a small library of &amp;quot;actions&amp;quot;, and everything else is built as a combination of these small, proven actions, and therefore undoing a larger action is simply undoing the set of sub-actions in reverse order.&lt;/p&gt;
&lt;p&gt;The final plug for immutable data structures is if you have background processes that will operate on the document in parallel with the users changes (think text editor with background compilation or something similar). &amp;nbsp;With an immutable system, this can be done easily and safely (just restart the background process periodically if the document changes). &amp;nbsp;With mutable documents, all of the foreground (user) mutations must be synchronized with the background process.&lt;/p&gt;
&lt;p&gt;-Randy&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9845051</link><pubDate>Wed, 22 Jul 2009 20:45:57 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9845051</guid><dc:creator>Spaceus</dc:creator><description>&lt;p&gt;Evolution is a bad thing or how am I to read this... A pattern well applied should as I see it hide the complexity of the problems your application handles. A way of getting to the core problem ( The part we get paid for). A pattern like the command pattern applied correctly would limit you app in anyway eventhough it evolves in ways you've never thought of..&lt;/p&gt;
&lt;p&gt;Just my 2 cents&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9868371</link><pubDate>Thu, 13 Aug 2009 18:00:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9868371</guid><dc:creator>Philips</dc:creator><description>&lt;p&gt;I made the following change in TransactionBase. The problem is that if you rollback the transaction inside a using statement then it crashes.&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public virtual void Rollback()&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (ActionManager != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ActionManager.RollBackTransaction();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Aborted = true;&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public bool Aborted { get; set; }&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;public void Dispose()&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;{&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if(!this.Aborted)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Commit();&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9870131</link><pubDate>Fri, 14 Aug 2009 17:46:10 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9870131</guid><dc:creator>Philips</dc:creator><description>&lt;p&gt;I think that inside public void RecordAction(IAction existingAction) the following two lines must be added:&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;if (this.History.CurrentState.NextAction != null)&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;this.History.Clear();&lt;/p&gt;
&lt;p&gt;i.e. if you are back to history and record a new action the history must be cleared &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9873536</link><pubDate>Tue, 18 Aug 2009 07:09:33 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9873536</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Thanks Philips, I've checked in your first change.&lt;/p&gt;
&lt;p&gt;About the second point though, if you're back in history and record a new action, the old next action will get dereferenced and will be garbage collected. So no need for this code.&lt;/p&gt;
&lt;p&gt;If you still believe that there is bug in the code around RecordAction and clearing history, please provide a repro in terms of the MinimalConsole sample.&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
&lt;p&gt;P.S. I should really add unit tests to this project.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9892776</link><pubDate>Tue, 08 Sep 2009 22:45:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9892776</guid><dc:creator>Anwar</dc:creator><description>&lt;p&gt;Hello,&lt;/p&gt;
&lt;p&gt;Can you post the Silverlight Application for this. &lt;/p&gt;
&lt;p&gt;I converted the existing winformsample application to Silverlight and the Redo functionality is not working as it working in winforms.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Anwar &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9894054</link><pubDate>Fri, 11 Sep 2009 10:03:05 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9894054</guid><dc:creator>Ramesh</dc:creator><description>&lt;p&gt;Hi Kirill,&lt;/p&gt;
&lt;p&gt;i have used your Undo framework in my Application.&lt;/p&gt;
&lt;p&gt;I have one doubt....Actually my application is Big one, whether it gives me any issue iwth memory...if Actions are more&lt;/p&gt;</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9894115</link><pubDate>Fri, 11 Sep 2009 13:02:54 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9894115</guid><dc:creator>Ramesh</dc:creator><description>&lt;p&gt;Hi Kirill,&lt;/p&gt;
&lt;p&gt;i have used your Undo framework in my Application.&lt;/p&gt;
&lt;p&gt;I have one doubt....Actually my application is Big one, whether it gives me any issue iwth memory...if Actions are more&lt;/p&gt;</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9894330</link><pubDate>Fri, 11 Sep 2009 21:47:16 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9894330</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Hi Ramesh,&lt;/p&gt;
&lt;p&gt;indeed, the Undo stack will keep references to your domain model's old state, so the Garbage Collector will not collect them. This is something to be aware of.&lt;/p&gt;
&lt;p&gt;However any other Undo framework implementation will have the same limitation. You can use the profiler to measure the impact of keeping the undo history in memory.&lt;/p&gt;
&lt;p&gt;I'm afraid that the rest is specific to your particular application and there is no general advice that I can give. Just use the profiler when in doubt.&lt;/p&gt;
&lt;p&gt;One final point is that I found that Undo buffer in two of my projects contributed only insignificantly to the memory consumption, but it's still worth checking.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Kirill&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9894942</link><pubDate>Mon, 14 Sep 2009 16:22:08 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9894942</guid><dc:creator>Vikas</dc:creator><description>&lt;p&gt;Hi Kirill,&lt;/p&gt;
&lt;p&gt; &amp;nbsp; What all I have to do if I want to limit 10 actions for Undo-Redo? &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9896074</link><pubDate>Thu, 17 Sep 2009 00:56:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896074</guid><dc:creator>Vikas</dc:creator><description>&lt;p&gt;Hi Kirill,&lt;/p&gt;
&lt;p&gt;Nevermind. &amp;nbsp;I'm not sure why I asked that. &amp;nbsp;I am not a baby. &amp;nbsp;I do not need you to hold my hand through every trivial thing. &amp;nbsp;You gave me an example and I should use my own brain to learn how to build upon that to create my own implementation.&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9896283</link><pubDate>Thu, 17 Sep 2009 13:59:23 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896283</guid><dc:creator>AliPST</dc:creator><description>&lt;p&gt;Hi Kirill&lt;/p&gt;
&lt;p&gt;Great work, thank you for sharing it and the participant in Informative discussion about it.&lt;/p&gt;
&lt;p&gt;I have some questions about details:&lt;/p&gt;
&lt;p&gt;1-In RecordAction function, the CheckNotRunningBeforeRecording(existingAction) called 2 times: first directly and second in RunActionDirectly(existingAction) function.&lt;/p&gt;
&lt;p&gt;Why?&lt;/p&gt;
&lt;p&gt;2-If I want to use this frame work in a composite application (like MS CAB+SCSF), what will be it's role? As I understand it will become a central point that all the modules and work items should pass their command/action to it! this is not good, is it? &lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9896294</link><pubDate>Thu, 17 Sep 2009 14:37:14 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896294</guid><dc:creator>AliPST</dc:creator><description>&lt;p&gt;And about memory:&lt;/p&gt;
&lt;p&gt;I run the winformsample, it start with about 18 mb &amp;nbsp;memory, and after a few changing in name &amp;amp; age field, consumed memory grow up to 21 mb! and I think it is relatively a big number, for one int and one string field!&lt;/p&gt;
&lt;p&gt;on the other hand, if you know Autodesk AutoCAD software, I run some test on it too, and I can not detect this behavior! it seems there is no growing &amp;nbsp;in memory consumption or it's very small.&lt;/p&gt;
&lt;p&gt;Can you help me on this?&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9896638</link><pubDate>Fri, 18 Sep 2009 06:32:13 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896638</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Hi Vikas,&lt;/p&gt;
&lt;p&gt;sorry for the delayed reply, I'm currently on vacation. No, the issue you mention is actually great feedback, so no worries here. I definitely need to look into adding a property to ActionManager saying MaxHistoryLength or something. BTW if you came up with a solution for this, you can send me a patch or a shelveset, if you feel like :)&lt;/p&gt;
&lt;p&gt;AliPst: this is a good find and is most likely a bug :) I'm now on vacation but once I get back I definitely will look into this. As for your second question, ActionManager should be a service that everyone consumes on an as needed basis. If you're using a dependency injection container such as MEF, wherever you need to track undo changes, import an ActionManager or make it a singleton. It's OK if a lot of things reference it. But of course, I can't tell more without looking at your particular implementation. If you use this framework in a large project, I'd be happy to hear any reports or feedback. &lt;/p&gt;
&lt;p&gt;Also a note to everyone - the project is open source and if you'd like to send in an improvement, you're welcome to do so. After one or two quality contributions I can add you as a developer to the project. &lt;/p&gt;
&lt;p&gt;AliPST, regarding your second message, it looks like a memory leak. I'll take a look sometime later.&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Kirill&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9896639</link><pubDate>Fri, 18 Sep 2009 06:36:36 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9896639</guid><dc:creator>Kirill Osenkov</dc:creator><description>&lt;p&gt;Thanks all, I've logged 3 bugs in the project bug tracker: &lt;a rel="nofollow" target="_new" href="http://undo.codeplex.com/WorkItem/List.aspx"&gt;http://undo.codeplex.com/WorkItem/List.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I'll deal with them whenever I have some time. Keep the great feedback coming!&lt;/p&gt;
&lt;p&gt;Thanks,&lt;/p&gt;
&lt;p&gt;Kirill&lt;/p&gt;
</description></item><item><title>re: New CodePlex project: a simple Undo/Redo framework</title><link>http://blogs.msdn.com/kirillosenkov/archive/2009/06/29/new-codeplex-project-a-simple-undo-redo-framework.aspx#9909685</link><pubDate>Tue, 20 Oct 2009 06:24:01 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9909685</guid><dc:creator>Sergey Arhipenko</dc:creator><description>&lt;p&gt;Hi, Kirill &lt;/p&gt;
&lt;p&gt;Thanks for referencing to my DejaVu project.&lt;/p&gt;
&lt;p&gt;It exists for a long time but not many people know about it. DejaVu uses different approach and I am happy that I did not choose Command Pattern.&lt;/p&gt;
&lt;p&gt;Actually, I would not recomend to anyone to use Command Pattern for Undo/Redo implementation.&lt;/p&gt;
&lt;p&gt;The general point is: it should not be solved on business logic level - it should be solved on data level. If you use Command Pattern, complexity will grow exponentially when number of commands/data entities increased. Solving undo/redo on data level tames complexity on the same level - no matter how many commands/data do you have. &lt;/p&gt;
</description></item></channel></rss>