5

I am really new to SML and I can't figure out how to get answer for the same;

It goes something like: 3^4 < 32 but 3^5 > 32 so my answer is 4 (power of 3), similarly if I have numbers 4 and 63 then 4^2<63 but 4^3>63 so my answer is 2(power of 4).

I have come up with the following code

val log (b, n) =
    let
        val counter = ref b
        val value = 0
    in
        while !counter > n do 
        ( counter := !counter*b 
          value := !value + 1)
    end;

So here value is what I need as my answer but I get a lot of errors. I know I am wrong at many places. Any help would be appreciated.

I can perhaps do this the normal ML way but I want to learnt impure ML also...

fun loghelper(x,n,b) = if x>n then 0 else (1+loghelper((x*b),n,b)); 
fun log(b,n) = loghelper(b,n,b);

ok so finally here is the correct code for the while loop and it works as well;

      fun log (b, n) =
            let
               val counter = ref b
               val value = ref 0
            in
               while (!counter <= n) do 
               (counter := !counter*b; 
                value := !value + 1);
               !value
            end;
Ritesh Ahuja
  • 77
  • 2
  • 2
  • 9

1 Answers1

5

You have several problems in your code:

Errors:

  • Instead of val log (b, n) = it should be fun log (b, n) =. fun is a convenience syntax that lets you define functions easily. If you wanted to write this with val you would write: val log = fn (b, n) => (it gets more complicated in the cases of recursive functions or functions with multiple curried arguments)
  • You need a semicolon to separate two imperative statements: ( counter := !counter*b; value := !value + 1)
  • value needs to be a ref: val value = ref 0

Logic:

  • Your function doesn't return anything. A while loop has the unit type, so your function returns () (unit). You probably want to return !value. To do this, you need to add a semicolon after the whole while loop thing, and then write !value
  • Your while loop condition doesn't really make sense. It seems reversed. You probably want while !counter <= n do
  • Your base case is not right. Either value should start at 1 (since counter starts at b, and b is b to the first power); or counter should start at 1 (since b to the zeroth power is 1). The same issue exists with your functional version.
newacct
  • 119,665
  • 29
  • 163
  • 224
  • functional version was working perfectly but the impure version needed just what you recommended. thanks a lot.. i should probably post the corrected code also. – Ritesh Ahuja Sep 26 '11 at 04:28
  • Just to be precise, `fun` is syntactic sugar for `val rec`. I'm sure you already know that @newacct, and that you just simplified it for the sake of a simple answer (with the equivalent to...). However I think it is still worth mentioning. – Jesper.Reenberg Sep 26 '11 at 23:06
  • @Jesper.Reenberg: yeah I know (I edited the answer). and also `fun` allows you to write multiple (curried) arguments whereas with `val` you have to do `fn a => fn b =>` – newacct Sep 27 '11 at 04:00
  • @newacct: Good one aswell. My point was more that it was a good fact to mention, given that he don't seem to know it. It was not necessarily that you had to update the "equivalence" you gave, as it was perfectly equivalent to just use `val` in the example you gave. – Jesper.Reenberg Sep 27 '11 at 08:34