[Prev][Next][Index][Thread]

Re: Dynamic typing confuses me!



On Sat, 8 Sep 2001 01:17:37 +0200, Bertrand Augereau <baugereau@ifrance.kom>
wrote:
>
> Hello, I'm coming from a traditional strongly-typed background (C++
> & Ada95) and I'm trying to get a grasp on modern functional objects.
> Why does this code give a run-time error?
>
> ...if I give it all the typing info, it works but it seems to me it
> can infer it in theory. Am I completly misunderstanding?
>
> define method fact (x) => ()
>   if (x = 1)
>     1;
>   else
>     fact(x - 1) * x;
>   end;
> end method fact;

Your problem is right here:

  define method fact (x) => ()
                            ^^
                           here

When you write () as the return type, you are telling Dylan to ignore
the return value of the function. So, when you call fact(1), then the
value 1 is ignored and no value is returned, leaving a value of #f to
get interpolated by the runtime.

So here's what the execution trace of your function would look like, with
the currently active expression in brackets:

 -> [fact(5)]
 -> [fact(4)] * 5
 -> [fact(3)] * 4 * 5
 -> [fact(2)] * 3 * 4 * 5
 -> [fact(1)] * 2 * 3 * 4 * 5
 -> [#f * 2]  * 3 * 4 * 5
    ^^^^^^^^
      BOOM!

Since there's no method on the \* function for <boolean> and <integer>,
you get a method lookup error. In Gwydion, the error message will be:

  No applicable methods in call of {the <generic-function> *} when given
  arguments: #[2, #f]

I'm sure Fun-Dev gives you some very similar error message.

To fix your problem, what you want to do is to let the function return a
value:

  define method fact (x)
    if (x = 1)
      1;
    else
      fact(x - 1) * x;
    end;
  end method fact;

or, if you want to make clear that only one value is returned, 

  define method fact-2 (x) => (x!)
    if (x = 1)
      1;
    else
      fact(x - 1) * x;
    end;
  end method fact-2;

Hope this helps!


Neel



References: