Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. Friday Programming Quiz

Friday Programming Quiz

Scheduled Pinned Locked Moved The Lounge
csharpasp-netcomhelptutorial
32 Posts 14 Posters 5 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Shog9 0

    function Transact()
    {
    if ( arguments.length < 1 )
    return true;
    var op = arguments[0];
    if ( op() && Transact.apply(this, [].slice.call(arguments, 1)) )
    return true;
    eval("Reset"+op.name)();
    return false;
    }

    Transact(Step1, Step2, Step3, Step4);

    function Step1() { console.log("one - success"); return true; }
    function Step2() { console.log("two - success"); return true; }
    function Step3() { console.log("three - failure"); return false; }
    function Step4() { console.log("four - success"); return true; }

    function ResetStep1() { console.log("one - reset"); }
    function ResetStep2() { console.log("two - reset"); }
    function ResetStep3() { console.log("three - reset"); }
    function ResetStep4() { console.log("four - reset"); }

    ----

    I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

    -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

    J Offline
    J Offline
    Josh Smith
    wrote on last edited by
    #3

    Is that Javascript?

    :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

    S 1 Reply Last reply
    0
    • J Josh Smith

      Is that Javascript?

      :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

      S Offline
      S Offline
      Shog9 0
      wrote on last edited by
      #4

      Yup. :)

      ----

      I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

      -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

      J 1 Reply Last reply
      0
      • R Rama Krishna Vavilala

        A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

        if (Step1())
        {
        if (Step2())
        {
        if (Step3())
        {
        if (Step4())
        {
        //.....
        //You get the idea
        }
        else
        {
        ResetStep2();
        ResetStep1();
        }
        }
        else
        {
        ResetStep1();
        }
        }

        Co-Author ASP.NET AJAX in Action

        M Offline
        M Offline
        Miszou
        wrote on last edited by
        #5

        @echo off  set failstep=%1  set fn=  set errorlevel=0  for /L %%i in (1,1,5) do call :runit %%i  goto :eof :runit  if "%errorlevel%" == "1" goto :eof  call :func%1  set /A fn=%1-1  if "%errorlevel%" == "1" (      if /I %fn% GTR 0 call :reset%fn% )  goto :eof :func1  echo func1  if "%failstep%"=="1" set errorlevel=1  goto :eof :func2  echo func2  if "%failstep%"=="2" set errorlevel=1  goto :eof :func3  echo func3  if "%failstep%"=="3" set errorlevel=1  goto :eof :func4  echo func4  if "%failstep%"=="4" set errorlevel=1  goto :eof :func5  echo func5  if "%failstep%"=="5" set errorlevel=1  goto :eof :reset5  echo reset5 :reset4  echo reset4 :reset3  echo reset3 :reset2  echo reset2 :reset1  echo reset1  goto :eof The command line parameter is the step number at which to fail. ie:

        c:\>steps 3
        func1
        func2
        func3
        reset2
        reset1


        Sunrise Wallpaper Project | The StartPage Randomizer | The Windows Cheerleader

        1 Reply Last reply
        0
        • R Rama Krishna Vavilala

          A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

          if (Step1())
          {
          if (Step2())
          {
          if (Step3())
          {
          if (Step4())
          {
          //.....
          //You get the idea
          }
          else
          {
          ResetStep2();
          ResetStep1();
          }
          }
          else
          {
          ResetStep1();
          }
          }

          Co-Author ASP.NET AJAX in Action

          E Offline
          E Offline
          El Corazon
          wrote on last edited by
          #6

          :rolleyes: qwikSeqTasks(Step1,Step2,Step3,Step4,Step5); qwikSeqUndoTasks(ResetStep1,ResetStep2,ResetStep3,ResetStep4,ResetStep5); qwikSeqTaskRun(); as apposed to qwikScheduleTasks(Step1,Step2,Step3,Step4,Step5); which would have put them all on a round-robin scheduler.... Things were actually easier in the DOS days.... I need to rewrite that C library.... That was... oh gee.... Revision 1.0.0 : Original code written by David Gersic 11-02-92 Revision 2.0.0 : Modified code for return values 04-13-95 Revision 2.0.1 : Modified code for sequential call stack 05-14-95 Revision 2.0.2 : Modified code for variable argument lists 07-22-95 and yes, that was a variable argument list.... Step6 is legal too, as is fewer, but at least 1. (the modifications were mine, the original code for the task_kernel was public domain.)

          _________________________ Asu no koto o ieba, tenjo de nezumi ga warau. Talk about things of tomorrow and the mice in the ceiling laugh. (Japanese Proverb)

          1 Reply Last reply
          0
          • R Rama Krishna Vavilala

            A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

            if (Step1())
            {
            if (Step2())
            {
            if (Step3())
            {
            if (Step4())
            {
            //.....
            //You get the idea
            }
            else
            {
            ResetStep2();
            ResetStep1();
            }
            }
            else
            {
            ResetStep1();
            }
            }

            Co-Author ASP.NET AJAX in Action

            T Offline
            T Offline
            Tomas Petricek
            wrote on last edited by
            #7

            This time I'll abandon Visual Basic, if you won't mind :) In F# it can be solved using one recently added feature called computation expressions (similar to Haskell monads). It's not that trivial to implement, so I will not send full code, but after writing some supporting code, it could be used like this:

            // You'll probably want to keep code to perform action
            // and rollback together, so I'll write it like this..
            let operation1 () =
            Compensable
            (code { do printf "First action.."
            // .. any ordinary F# code ...
            // returns 'Some' if succeeds, otherwise 'None'
            // (so it can return some value and not just bool)
            return Some(42) })
            (fail { do printf "Reset first.." })

            // Use the 'compensable' operations here...
            let main () =
            trans
            { let! v = operation1()
            do! operation2(v+v)
            do! operation3()
            // ... some more F# code }

            If the operation2 fails, the operation3 will never be executed and the code that forms the fail part of the operation1 will be called - it is not needed to write this explicitly, because the trans block which wraps the code handles this automatically. It's just a quick sketch, but you can see the most beautiful thing - that is that once you write the code that makes this possible, you don't have to do anything special to execute it and handle compensations - just write 'primitive operations' in some way (combining function to execute the opearion with a function that does the compensation) and wrap the code in some block (I used the name trans). All the compensation handling is hidden in a few basic functions (that the code sample I posted doesn't show). PS: It's actually very interesting example :) I'm currently learning for some exams, but after that I'll write a blog post about this. Thanks for the inspiration!

            Homepage: TomasP.net | Photo of the month: Calendar | C# and LINQ, F#, Phalanger: My Blog
            Latest article: Phalanger, PHP for .NET: Introduction for .NET developers

            1 Reply Last reply
            0
            • S Shog9 0

              Yup. :)

              ----

              I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

              -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

              J Offline
              J Offline
              Josh Smith
              wrote on last edited by
              #8

              Shog9 wrote:

              Yup.

              Ok, then I have a programming question to ask you, but since this is the Lounge...oh screw it...this whole thread is a programming question. What the heck is this?

              Transact.apply(this, [].slice.call(arguments, 1))

              I assume it's the recursion point in the function, but I'll be damned if I can make heads or tails of it. I mean, Transact is a function, right? So what does .apply() mean when called on a function name? And what's the [].slice all about? :confused:

              :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

              S 1 Reply Last reply
              0
              • R Rama Krishna Vavilala

                A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

                if (Step1())
                {
                if (Step2())
                {
                if (Step3())
                {
                if (Step4())
                {
                //.....
                //You get the idea
                }
                else
                {
                ResetStep2();
                ResetStep1();
                }
                }
                else
                {
                ResetStep1();
                }
                }

                Co-Author ASP.NET AJAX in Action

                J Offline
                J Offline
                J Dunlap
                wrote on last edited by
                #9

                Step[] steps = new[]
                {
                new Step(
                ()=>Console.WriteLine("step 0"),
                ()=>Console.WriteLine("reset 0")
                ),
                new Step(
                ()=>Console.WriteLine("step 1"),
                ()=>Console.WriteLine("reset 1")
                ),
                new Step(
                ()=>Console.WriteLine("step 2"),
                ()=>Console.WriteLine("reset 2")
                ),
                new Step(
                ()=>Console.WriteLine("step 3"),
                ()=>Console.WriteLine("reset 3")
                ),
                new Step(
                ()=>Console.WriteLine("step 4"),
                ()=>Console.WriteLine("reset 4")
                ),
                };

                bool DoSteps(IEnumerable<step> steps)
                {
                Step step=steps.FirstOrDefault();
                if(step==null || (step.Action() && DoSteps(steps.TakeAfter(0)))
                return true;
                step.Reset();
                return false;
                }

                //EDIT: oops, forgot to define the step class! :o)
                public class Step
                {
                public Step(Action action, Action reset)
                {Action=action; Reset=reset;}

                public Action Action{get;set;}
                public Action Reset{get;set;}
                }
                public delegate bool Action();

                To use it:

                DoSteps(steps);

                The neat thing about TakeAfter() is that it returns an enumerator method that iterates the existing array, rather than creating a new array. This saves on performance while still allowing elegance.


                Last modified: 15mins after originally posted --

                --Justin, Microsoft MVP, C#

                C# / DHTML / VG.net / MyXaml expert available for consulting work[^] Get Quality Portraits Drawn From Your Photos[^]

                N A 2 Replies Last reply
                0
                • R Rama Krishna Vavilala

                  A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

                  if (Step1())
                  {
                  if (Step2())
                  {
                  if (Step3())
                  {
                  if (Step4())
                  {
                  //.....
                  //You get the idea
                  }
                  else
                  {
                  ResetStep2();
                  ResetStep1();
                  }
                  }
                  else
                  {
                  ResetStep1();
                  }
                  }

                  Co-Author ASP.NET AJAX in Action

                  N Offline
                  N Offline
                  Nish Nishant
                  wrote on last edited by
                  #10

                  A hopefully reusable solution in C#

                  class Program
                  {
                  static void Main(string[] args)
                  {
                  AtomicActions atomicActions = new AtomicActions();
                  atomicActions.AddActionPair(Actions.Step1, Actions.ResetStep1);
                  atomicActions.AddActionPair(Actions.Step2, Actions.ResetStep2);
                  atomicActions.AddActionPair(Actions.Step3, Actions.ResetStep3);
                  atomicActions.Run();
                  }
                  }

                  internal class AtomicActions
                  {
                  internal delegate bool Action();
                  internal delegate void ResetAction();

                  struct ActionPair
                  {
                      internal Action action;
                      internal ResetAction resetAction;
                  
                      internal ActionPair(Action action, ResetAction resetAction)
                      {
                          this.action = action;
                          this.resetAction = resetAction;
                      }            
                  }
                  
                  Stack<ResetAction> undoStack = new Stack<ResetAction>();
                  List<ActionPair> actionList = new List<ActionPair>();
                  
                  internal void AddActionPair(Action action, ResetAction resetAction)
                  {
                      actionList.Add(new ActionPair(action, resetAction));
                  }
                  
                  internal bool Run()
                  {
                      bool runSuccess = true;
                  
                      foreach (ActionPair actionPair in actionList)
                      {
                          undoStack.Push(actionPair.resetAction);
                          if (!(runSuccess = actionPair.action()))
                              break;
                      }
                  
                      if (!runSuccess)
                          while (undoStack.Count > 0)
                              undoStack.Pop()();
                  
                      return runSuccess;
                  }
                  

                  }

                  internal static class Actions
                  {
                  public static bool Step1()
                  {
                  Console.WriteLine("Step1");
                  return true;
                  }

                  public static void ResetStep1()
                  {
                      Console.WriteLine("ResetStep1");
                  }
                  
                  public static bool Step2()
                  {
                      Console.WriteLine("Step2");
                      return true;
                  }
                  
                  public static void ResetStep2()
                  {
                      Console.WriteLine("ResetStep2");
                  }
                  
                  public static bool Step3()
                  {
                      Console.WriteLine("Step3");
                      return true;
                  }
                  
                  public static void ResetStep3()
                  {
                      Console.WriteLine("ResetStep3");
                  }
                  

                  }

                  Regards, Nish


                  Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                  My latest book :

                  1 Reply Last reply
                  0
                  • J J Dunlap

                    Step[] steps = new[]
                    {
                    new Step(
                    ()=>Console.WriteLine("step 0"),
                    ()=>Console.WriteLine("reset 0")
                    ),
                    new Step(
                    ()=>Console.WriteLine("step 1"),
                    ()=>Console.WriteLine("reset 1")
                    ),
                    new Step(
                    ()=>Console.WriteLine("step 2"),
                    ()=>Console.WriteLine("reset 2")
                    ),
                    new Step(
                    ()=>Console.WriteLine("step 3"),
                    ()=>Console.WriteLine("reset 3")
                    ),
                    new Step(
                    ()=>Console.WriteLine("step 4"),
                    ()=>Console.WriteLine("reset 4")
                    ),
                    };

                    bool DoSteps(IEnumerable<step> steps)
                    {
                    Step step=steps.FirstOrDefault();
                    if(step==null || (step.Action() && DoSteps(steps.TakeAfter(0)))
                    return true;
                    step.Reset();
                    return false;
                    }

                    //EDIT: oops, forgot to define the step class! :o)
                    public class Step
                    {
                    public Step(Action action, Action reset)
                    {Action=action; Reset=reset;}

                    public Action Action{get;set;}
                    public Action Reset{get;set;}
                    }
                    public delegate bool Action();

                    To use it:

                    DoSteps(steps);

                    The neat thing about TakeAfter() is that it returns an enumerator method that iterates the existing array, rather than creating a new array. This saves on performance while still allowing elegance.


                    Last modified: 15mins after originally posted --

                    --Justin, Microsoft MVP, C#

                    C# / DHTML / VG.net / MyXaml expert available for consulting work[^] Get Quality Portraits Drawn From Your Photos[^]

                    N Offline
                    N Offline
                    Nish Nishant
                    wrote on last edited by
                    #11

                    Excellent solution :-)

                    Regards, Nish


                    Nish’s thoughts on MFC, C++/CLI and .NET (my blog)
                    My latest book : C++/CLI in Action / Amazon.com link

                    1 Reply Last reply
                    0
                    • J Josh Smith

                      Shog9 wrote:

                      Yup.

                      Ok, then I have a programming question to ask you, but since this is the Lounge...oh screw it...this whole thread is a programming question. What the heck is this?

                      Transact.apply(this, [].slice.call(arguments, 1))

                      I assume it's the recursion point in the function, but I'll be damned if I can make heads or tails of it. I mean, Transact is a function, right? So what does .apply() mean when called on a function name? And what's the [].slice all about? :confused:

                      :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

                      S Offline
                      S Offline
                      Shog9 0
                      wrote on last edited by
                      #12

                      [] is an empty array. In this case, i'm using it as shorthand for Array.prototype. Why? Because arguments isn't actually a proper array - while it does array-like things (indexed access to the current function's parameters), it's a separate type of object, one that also does other, function-specific things. So, it doesn't have a slice() method, which i wanted - slice() extracts a portion of an array (i want the second item and everything after it). call() and apply() are members of every function. call() takes at least one argument, which will become this when the function executes, while each subsequent argument becomes an argument to the function itself. In this way, i can call a function defined for Array objects on an arbitrary array-like object (arguments) and everything works just fine. apply() is very similar to call(), except that it takes two parameters, with the second being an array of arguments to the function. In this way, Transact() handles recursion with a variable (but ever-decreasing) number of arguments. A simpler definition for Transact might look like this:

                      function Transact(ops)
                      {
                      if ( ops.length < 1 )
                      return true;
                      var op = ops[0];
                      if ( op() && Transact(ops.slice(1)) )
                      return true;
                      eval("Reset"+op.name)();
                      return false;
                      }

                      Transact([Step1, Step2, Step3, Step4]);

                      ...while a slightly more confusing implementation could take this form:

                      function Transact()
                      {
                      if ( arguments.length < 1 )
                      return true;
                      var op = arguments[0];
                      if ( op() && arguments.callee.apply(this, [].slice.call(arguments, 1)) )
                      return true;
                      eval("Reset"+op.name)();
                      return false;
                      }

                      ;)

                      ----

                      I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

                      -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

                      J 2 Replies Last reply
                      0
                      • S Shog9 0

                        [] is an empty array. In this case, i'm using it as shorthand for Array.prototype. Why? Because arguments isn't actually a proper array - while it does array-like things (indexed access to the current function's parameters), it's a separate type of object, one that also does other, function-specific things. So, it doesn't have a slice() method, which i wanted - slice() extracts a portion of an array (i want the second item and everything after it). call() and apply() are members of every function. call() takes at least one argument, which will become this when the function executes, while each subsequent argument becomes an argument to the function itself. In this way, i can call a function defined for Array objects on an arbitrary array-like object (arguments) and everything works just fine. apply() is very similar to call(), except that it takes two parameters, with the second being an array of arguments to the function. In this way, Transact() handles recursion with a variable (but ever-decreasing) number of arguments. A simpler definition for Transact might look like this:

                        function Transact(ops)
                        {
                        if ( ops.length < 1 )
                        return true;
                        var op = ops[0];
                        if ( op() && Transact(ops.slice(1)) )
                        return true;
                        eval("Reset"+op.name)();
                        return false;
                        }

                        Transact([Step1, Step2, Step3, Step4]);

                        ...while a slightly more confusing implementation could take this form:

                        function Transact()
                        {
                        if ( arguments.length < 1 )
                        return true;
                        var op = arguments[0];
                        if ( op() && arguments.callee.apply(this, [].slice.call(arguments, 1)) )
                        return true;
                        eval("Reset"+op.name)();
                        return false;
                        }

                        ;)

                        ----

                        I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

                        -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

                        J Offline
                        J Offline
                        Josh Smith
                        wrote on last edited by
                        #13

                        Wow, thanks a lot for the in-depth explanations! I never realized that Javascript had so much going for it. Very cool! Too bad it's only used inside the browser, or else I'd give it a whirl.

                        :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

                        D 1 Reply Last reply
                        0
                        • R Rama Krishna Vavilala

                          A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

                          if (Step1())
                          {
                          if (Step2())
                          {
                          if (Step3())
                          {
                          if (Step4())
                          {
                          //.....
                          //You get the idea
                          }
                          else
                          {
                          ResetStep2();
                          ResetStep1();
                          }
                          }
                          else
                          {
                          ResetStep1();
                          }
                          }

                          Co-Author ASP.NET AJAX in Action

                          I Offline
                          I Offline
                          ied
                          wrote on last edited by
                          #14

                          I'm feeling nostolgic... bwa ha ha... -- Ian --------- bool Step1() {printf("Step1\n"); return true;} bool Step2() {printf("Step2\n"); return true;} bool Step3() {printf("Step3\n"); return true;} bool Step4() {printf("Step4\n"); return false;} bool Step5() {printf("Step5\n"); return true;} void ResetStep1() {printf("ResetStep1\n");} void ResetStep2() {printf("ResetStep2\n");} void ResetStep3() {printf("ResetStep3\n");} void ResetStep4() {printf("ResetStep4\n");} void ResetStep5() {printf("ResetStep5\n");} typedef bool (*steptype)(); steptype steplist[] = {Step1,Step2,Step3,Step4,Step5}; typedef void (*resetsteptype)(); resetsteptype resetsteplist[] = {ResetStep1,ResetStep2,ResetStep3,ResetStep4,ResetStep5}; int main(int argc, char* argv[]) { int i=0; while (i<5 && (*(steplist[i]))()) i++; if (i<5) while (i>0) (*(resetsteplist[--i]))(); return 0; } --------- Step1 Step2 Step3 Step4 ResetStep3 ResetStep2 ResetStep1

                          G 1 Reply Last reply
                          0
                          • J Josh Smith

                            Wow, thanks a lot for the in-depth explanations! I never realized that Javascript had so much going for it. Very cool! Too bad it's only used inside the browser, or else I'd give it a whirl.

                            :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

                            D Offline
                            D Offline
                            David Stone
                            wrote on last edited by
                            #15

                            Not so! Rhino JavaScript[^] :)

                            1 Reply Last reply
                            0
                            • J J Dunlap

                              Step[] steps = new[]
                              {
                              new Step(
                              ()=>Console.WriteLine("step 0"),
                              ()=>Console.WriteLine("reset 0")
                              ),
                              new Step(
                              ()=>Console.WriteLine("step 1"),
                              ()=>Console.WriteLine("reset 1")
                              ),
                              new Step(
                              ()=>Console.WriteLine("step 2"),
                              ()=>Console.WriteLine("reset 2")
                              ),
                              new Step(
                              ()=>Console.WriteLine("step 3"),
                              ()=>Console.WriteLine("reset 3")
                              ),
                              new Step(
                              ()=>Console.WriteLine("step 4"),
                              ()=>Console.WriteLine("reset 4")
                              ),
                              };

                              bool DoSteps(IEnumerable<step> steps)
                              {
                              Step step=steps.FirstOrDefault();
                              if(step==null || (step.Action() && DoSteps(steps.TakeAfter(0)))
                              return true;
                              step.Reset();
                              return false;
                              }

                              //EDIT: oops, forgot to define the step class! :o)
                              public class Step
                              {
                              public Step(Action action, Action reset)
                              {Action=action; Reset=reset;}

                              public Action Action{get;set;}
                              public Action Reset{get;set;}
                              }
                              public delegate bool Action();

                              To use it:

                              DoSteps(steps);

                              The neat thing about TakeAfter() is that it returns an enumerator method that iterates the existing array, rather than creating a new array. This saves on performance while still allowing elegance.


                              Last modified: 15mins after originally posted --

                              --Justin, Microsoft MVP, C#

                              C# / DHTML / VG.net / MyXaml expert available for consulting work[^] Get Quality Portraits Drawn From Your Photos[^]

                              A Offline
                              A Offline
                              Anton Afanasyev
                              wrote on last edited by
                              #16

                              bool DoSteps(IEnumerable steps)
                              {
                              Step step=steps.FirstOrDefault();
                              if(step==null || (step.Action() && DoSteps(steps.TakeAfter(0))))
                              return true;
                              step.Reset();
                              return false;
                              }

                              could be changed to:

                              bool DoSteps(IEnumerable steps)
                              {
                              Step step=steps.FirstOrDefault();
                              return (step==null || (step.Action() && DoSteps(steps.TakeAfter(0)))|| (step.Reset() && false));
                              }

                              and btw, you forget a bracket there ;)


                              :badger:

                              J 1 Reply Last reply
                              0
                              • R Rama Krishna Vavilala

                                A common problem, a simple problem of compensating transactions. There are variety of different solutions. There are 5 steps an application need to perform in sequence. Call them Step1, Step2, Step3, Step4, and Step5. Assume them to be functions that return boolean and take no arguments. bool Step() There are corresponding reset or rollback functions that undo the effects of the steps. Call them ResetStep1, ResetStep2, ResetStep3, ResetStep4, and ResetStep5. If a step fails, the Reset methods of all the previous steps should be called and none of the new steps should execute. For example, if Step3 fails (returns false), then ResetStep2() and ResetStep1() should be called (in that order). Here is a sample code written poorly so that you can get an idea. BTW There are several creatve solutions: RAII, boolean algebra etc.

                                if (Step1())
                                {
                                if (Step2())
                                {
                                if (Step3())
                                {
                                if (Step4())
                                {
                                //.....
                                //You get the idea
                                }
                                else
                                {
                                ResetStep2();
                                ResetStep1();
                                }
                                }
                                else
                                {
                                ResetStep1();
                                }
                                }

                                Co-Author ASP.NET AJAX in Action

                                G Offline
                                G Offline
                                Gary R Wheeler
                                wrote on last edited by
                                #17

                                In the K.I.S.S. tradition:

                                void (*step[])() = { Step1, Step2, Step3, Step4, Step5 };
                                void (*reset_step[])() = { ResetStep1, ResetStep2, ResetStep3, ResetStep4, ResetStep5 };

                                int index = 0;
                                int step_count = sizeof(step) / sizeof(step[0]);

                                while ((index < step_count) && step[index]()) index++;
                                if (index < step_count) {
                                while (index >= 0) reset_step[--index];
                                }


                                Software Zen: delete this;

                                Fold With Us![^]

                                S 1 Reply Last reply
                                0
                                • I ied

                                  I'm feeling nostolgic... bwa ha ha... -- Ian --------- bool Step1() {printf("Step1\n"); return true;} bool Step2() {printf("Step2\n"); return true;} bool Step3() {printf("Step3\n"); return true;} bool Step4() {printf("Step4\n"); return false;} bool Step5() {printf("Step5\n"); return true;} void ResetStep1() {printf("ResetStep1\n");} void ResetStep2() {printf("ResetStep2\n");} void ResetStep3() {printf("ResetStep3\n");} void ResetStep4() {printf("ResetStep4\n");} void ResetStep5() {printf("ResetStep5\n");} typedef bool (*steptype)(); steptype steplist[] = {Step1,Step2,Step3,Step4,Step5}; typedef void (*resetsteptype)(); resetsteptype resetsteplist[] = {ResetStep1,ResetStep2,ResetStep3,ResetStep4,ResetStep5}; int main(int argc, char* argv[]) { int i=0; while (i<5 && (*(steplist[i]))()) i++; if (i<5) while (i>0) (*(resetsteplist[--i]))(); return 0; } --------- Step1 Step2 Step3 Step4 ResetStep3 ResetStep2 ResetStep1

                                  G Offline
                                  G Offline
                                  Gary R Wheeler
                                  wrote on last edited by
                                  #18

                                  Teach me not to read the whole thread... :-O Aha! Your solution doesn't work quite correctly. It will never call ResetStep1().


                                  Software Zen: delete this;

                                  Fold With Us![^]

                                  E I 2 Replies Last reply
                                  0
                                  • G Gary R Wheeler

                                    Teach me not to read the whole thread... :-O Aha! Your solution doesn't work quite correctly. It will never call ResetStep1().


                                    Software Zen: delete this;

                                    Fold With Us![^]

                                    E Offline
                                    E Offline
                                    Eytukan
                                    wrote on last edited by
                                    #19

                                    omg! every other people here's going by the same way and much better than mine. I didn't like my code.:doh: deleted it. Feeling happy now :-O


                                    The Advantage in work-from-home is that... we can blame the dog -Mark Salsbery Best wishes to Rexx[^]

                                    1 Reply Last reply
                                    0
                                    • S Shog9 0

                                      [] is an empty array. In this case, i'm using it as shorthand for Array.prototype. Why? Because arguments isn't actually a proper array - while it does array-like things (indexed access to the current function's parameters), it's a separate type of object, one that also does other, function-specific things. So, it doesn't have a slice() method, which i wanted - slice() extracts a portion of an array (i want the second item and everything after it). call() and apply() are members of every function. call() takes at least one argument, which will become this when the function executes, while each subsequent argument becomes an argument to the function itself. In this way, i can call a function defined for Array objects on an arbitrary array-like object (arguments) and everything works just fine. apply() is very similar to call(), except that it takes two parameters, with the second being an array of arguments to the function. In this way, Transact() handles recursion with a variable (but ever-decreasing) number of arguments. A simpler definition for Transact might look like this:

                                      function Transact(ops)
                                      {
                                      if ( ops.length < 1 )
                                      return true;
                                      var op = ops[0];
                                      if ( op() && Transact(ops.slice(1)) )
                                      return true;
                                      eval("Reset"+op.name)();
                                      return false;
                                      }

                                      Transact([Step1, Step2, Step3, Step4]);

                                      ...while a slightly more confusing implementation could take this form:

                                      function Transact()
                                      {
                                      if ( arguments.length < 1 )
                                      return true;
                                      var op = arguments[0];
                                      if ( op() && arguments.callee.apply(this, [].slice.call(arguments, 1)) )
                                      return true;
                                      eval("Reset"+op.name)();
                                      return false;
                                      }

                                      ;)

                                      ----

                                      I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

                                      -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

                                      J Offline
                                      J Offline
                                      Josh Smith
                                      wrote on last edited by
                                      #20

                                      Shog9 wrote:

                                      call() and apply() are members of every function.

                                      I'm still shocked by this. In Javascript, functions have members. That is very strange to me, coming from a "classical" object-oriented background of C++ and C#. Do you commonly find a use for the members of functions, or is it an abstruse niche that you happen to be savvy about?

                                      :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

                                      S 1 Reply Last reply
                                      0
                                      • G Gary R Wheeler

                                        In the K.I.S.S. tradition:

                                        void (*step[])() = { Step1, Step2, Step3, Step4, Step5 };
                                        void (*reset_step[])() = { ResetStep1, ResetStep2, ResetStep3, ResetStep4, ResetStep5 };

                                        int index = 0;
                                        int step_count = sizeof(step) / sizeof(step[0]);

                                        while ((index < step_count) && step[index]()) index++;
                                        if (index < step_count) {
                                        while (index >= 0) reset_step[--index];
                                        }


                                        Software Zen: delete this;

                                        Fold With Us![^]

                                        S Offline
                                        S Offline
                                        Shog9 0
                                        wrote on last edited by
                                        #21

                                        Nice! (missing parens in the call to reset though)

                                        ----

                                        I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

                                        -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

                                        1 Reply Last reply
                                        0
                                        • J Josh Smith

                                          Shog9 wrote:

                                          call() and apply() are members of every function.

                                          I'm still shocked by this. In Javascript, functions have members. That is very strange to me, coming from a "classical" object-oriented background of C++ and C#. Do you commonly find a use for the members of functions, or is it an abstruse niche that you happen to be savvy about?

                                          :josh: My WPF Blog[^] Without a strive for perfection I would be terribly bored.

                                          S Offline
                                          S Offline
                                          Shog9 0
                                          wrote on last edited by
                                          #22

                                          It's just part of how Javascript works - there isn't the same distinction between functions, classes, and objects that you get with, say, C++. All functions are objects, derived from Function and inheriting whatever methods are defined for it. You can actually add methods to Function and immediately use them on any other function (this also works for other base types such as Array and Object; it's great for filling in the gaps of a sub-par (*cough*IE*cough*) JS engine). And you make your own types by - wait for it - defining a function that creates them! That said, you don't really get things like inheritance in the classical sense, although the language is flexible enough you can make it work with a bit of discipline. Honestly, it's a lot of fun. ;)

                                          ----

                                          I don't care what you consider witty, but at least I do not blather on posting nonsense like Jim Crafton.

                                          -- Stringcheese, humbled by Crafton's ability to string together multiple sentences

                                          J 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups