Chris Angelico <[email protected]>:
> On Thu, Sep 6, 2018 at 2:29 PM, Marko Rauhamaa <[email protected]> wrote:
>> Marko Rauhamaa <[email protected]> (Marko Rauhamaa):
>>> Steven D'Aprano <[email protected]>:
>>>> I have this snippet of SML code which I'm trying to translate to Python:
>>>>
>>>> fun isqrt n = if n=0 then 0
>>>> else let val r = isqrt (n/4)
>>>> in
>>>> if n < (2*r+1)^2 then 2*r
>>>> else 2*r+1
>>>> end
>>> [...]
>>> You must make sure "r" doesn't leak outside its syntactic context so:
>>>
>>> def isqrt(n):
>>> if n == 0:
>>> return 0
>>> else:
>>> def f2398478957():
>>> r = isqrt(n//4)
>>> if n < (2*r+1)**2:
>>> return 2*r
>>> else:
>>> return 2*r+1
>>> return f2398478957()
>>
>> Actually, this is a more direct translation:
>>
>> def isqrt(n):
>> if n == 0:
>> return 0
>> else:
>> def f2398478957(r):
>> if n < (2*r+1)**2:
>> return 2*r
>> else:
>> return 2*r+1
>> return f2398478957(isqrt(n//4))
>>
>
> I don't understand why you created that nested function instead of
> something simple like renaming the variable. Is there a difference
> here?
Yes, in understanding the semantics of "let."
"let" is used to introduce local bindings in some functional programming
languages. I must admit I'm not fully versed in ML but it looks like the
analogue in Lisp variants. This is how the above function would be
written in Scheme:
(define (isqrt n)
(if (= n 0)
0
(let ((r (isqrt (quotient n 4))))
(if (< n (expt (1+ (* 2 r)) 2))
(* 2 r)
(1+ (* 2 r))))))
Now, Lisp's "let" can be implemented/defined using "lambda":
(let ((X A) (Y B) ...) . BODY)
=>
((lambda (X Y ...) . BODY) A B ...)
which gives us:
(define (isqrt n)
(if (= n 0)
0
((lambda (r)
(if (< n (expt (1+ (* 2 r)) 2))
(* 2 r)
(1+ (* 2 r))))
(isqrt (quotient n 4)))))
Python does have a limited form of "lambda" and even a conditional
expression so--as others have mentioned--this particular function could
be translated pretty directly into Python using its lambda.
More generally and idiomatically, though, Python's functions are named.
So that explains the version I give above.
Marko
--
https://mail.python.org/mailman/listinfo/python-list