Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Steven D'Aprano
On Fri, 07 Sep 2018 15:10:10 +0100, Paul Moore wrote:

> On Fri, 7 Sep 2018 at 14:06, Steven D'Aprano
>  wrote:
[...]

>> However I have a follow up question. Why the "let" construct in the
>> first place? Is this just a matter of principle, "put everything in its
>> own scope as a matter of precautionary code hygiene"? Because I can't
>> see any advantage to the inner function:
> 
> My impression is that this is just functional programming "good style".
> As you say, it's not needed, it's just "keep things valid in the
> smallest range possible". Probably also related to the mathematical
> style of naming sub-expressions. Also, it's probably the case that in a
> (compiled) functional language like SML, the compiler can optimise this
> to avoid any actual inner function, leaving it as nothing more than a
> temporary name.

I guessed it would be something like that.


Thanks Paul, and especially Marko for going above and beyond the call of 
duty with his multiple translations into functional-style Python, and 
everyone else who answered.



-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Marko Rauhamaa
Marko Rauhamaa :

> def f(n):
> def auxf1(sum, m, i):
> if i == n:
> return sum
> else:
> def auxf2(sum, m, i):
> if sum % m == 0:
> return auxf1(sum, m + 1, i)
> else:
> return auxf1(sum, m, i)
> return auxf2(sum + m * i, m, i + 1)
> return auxf1(0, 1, 0)
>
> cheating slightly with locally named functions.
>
> If cheating is not allowed, you will need a Y combinator construct...

... and here's the same function without cheating:

f = (lambda n:
 (lambda auxf1, auxf2: auxf1(auxf1, auxf2, 0, 1, 0))(
 lambda auxf1, auxf2, sum, m, i:
 sum
 if i == n else
 auxf2(auxf1, auxf2, sum + m * i, m, i + 1),
 lambda auxf1, auxf2, sum, m, i:
 auxf1(auxf1, auxf2, sum, m + 1, i)
 if sum % m == 0 else
 auxf1(auxf1, auxf2, sum, m, i)))

... or replacing the conditional with arrays:

f = (lambda n:
 (lambda auxf1, auxf2: auxf1(auxf1, auxf2, 0, 1, 0))(
 lambda auxf1, auxf2, sum, m, i:
 [lambda m: auxf2(auxf1, auxf2, sum + m * i, m, i + 1),
  lambda m: sum][i == n](m),
 lambda auxf1, auxf2, sum, m, i:
 [lambda m: auxf1(auxf1, auxf2, sum, m, i),
  lambda m: auxf1(auxf1, auxf2, sum, m + 1, i)][sum % m == 0](m)))

It is possible to get rid of the arrays and numbers, too. Combinatory
logic would allow us to get rid of the local variables. At the pinnacle
of functional programming is iota:

   https://en.wikipedia.org/wiki/Iota_and_Jot>

The iota programming language has only one primitive value, the
Swiss-army-knife function ι, which can express Life, Universe and
Everything:

ι = lambda f: (f(lambda x: lambda y: lambda z: (x(z))(y(z(
lambda q: lambda i: q)


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Marko Rauhamaa
Paul Moore :

> On Fri, 7 Sep 2018 at 15:10, Paul Moore  wrote:
>>
>> On Fri, 7 Sep 2018 at 14:06, Steven D'Aprano
>>  wrote:
>> > However I have a follow up question. Why the "let" construct in the
>> > first place? Is this just a matter of principle, "put everything in
>> > its own scope as a matter of precautionary code hygiene"? Because I
>> > can't see any advantage to the inner function:
>>
>> My impression is that this is just functional programming "good
>> style". [...]
>
> It's also worth noting that functional languages don't typically have
> variables or assignments (more accurately, such things aren't
> fundamental to the programming model the way they are in imperative
> languages). So although technically let introduces a new scope, in
> practical terms it's basically just "how functional programmers do
> assignments".

To put it succinctly, SML does it because there's no other way to
introduce local variables.

IOW, in many functional programming languages, the only local variables
are function arguments.

And if you want to go really functional, you can't even alter bindings.
So to implement a for loop in Python under these constraints, you would
implement:

def f(n):
sum = 0
m = 1
for i in range(n):
sum += m * i
if sum % m == 0:
m += 1
return sum

like this:

def f(n):
def auxf1(sum, m, i):
if i == n:
return sum
else:
def auxf2(sum, m, i):
if sum % m == 0:
return auxf1(sum, m + 1, i)
else:
return auxf1(sum, m, i)
return auxf2(sum + m * i, m, i + 1)
return auxf1(0, 1, 0)

cheating slightly with locally named functions.

If cheating is not allowed, you will need a Y combinator construct...


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Paul Moore
On Fri, 7 Sep 2018 at 15:10, Paul Moore  wrote:
>
> On Fri, 7 Sep 2018 at 14:06, Steven D'Aprano
>  wrote:
> >
> > On Thu, 06 Sep 2018 13:48:54 +0300, Marko Rauhamaa wrote:
> >
> > > Chris Angelico :
> > >> The request was to translate this into Python, not to slavishly imitate
> > >> every possible semantic difference even if it won't actually affect
> > >> behaviour.
> > >
> > > I trust Steven to be able to refactor the code into something more
> > > likable. His only tripping point was the meaning of the "let" construct.
> >
> > Thanks for the vote of confidence :-)
> >
> > However I have a follow up question. Why the "let" construct in the first
> > place? Is this just a matter of principle, "put everything in its own
> > scope as a matter of precautionary code hygiene"? Because I can't see any
> > advantage to the inner function:
>
> My impression is that this is just functional programming "good
> style". As you say, it's not needed, it's just "keep things valid in
> the smallest range possible". Probably also related to the
> mathematical style of naming sub-expressions. Also, it's probably the
> case that in a (compiled) functional language like SML, the compiler
> can optimise this to avoid any actual inner function, leaving it as
> nothing more than a temporary name.

It's also worth noting that functional languages don't typically have
variables or assignments (more accurately, such things aren't
fundamental to the programming model the way they are in imperative
languages). So although technically let introduces a new scope, in
practical terms it's basically just "how functional programmers do
assignments".

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Neil Cerutti
On 2018-09-07, Steven D'Aprano  wrote:
> On Thu, 06 Sep 2018 13:48:54 +0300, Marko Rauhamaa wrote:
>
>> Chris Angelico :
>>> The request was to translate this into Python, not to slavishly imitate
>>> every possible semantic difference even if it won't actually affect
>>> behaviour.
>> 
>> I trust Steven to be able to refactor the code into something more
>> likable. His only tripping point was the meaning of the "let" construct.
>
> Thanks for the vote of confidence :-) 
>
> However I have a follow up question. Why the "let" construct in
> the first place? Is this just a matter of principle, "put
> everything in its own scope as a matter of precautionary code
> hygiene"? Because I can't see any advantage to the inner
> function:

let is a convenient way for functional languages to introduce new
names for things. You'd consider it wherever you'd consider
assigning something to a new name in Python. In this case, it was
probably just to avoid writing out that square root calculation
twice. Though you could use lambda calculus directly instead,
that might be considered painful, and the first thing you'd then
do is write a let macro.

-- 
Neil Cerutti
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Paul Moore
On Fri, 7 Sep 2018 at 14:06, Steven D'Aprano
 wrote:
>
> On Thu, 06 Sep 2018 13:48:54 +0300, Marko Rauhamaa wrote:
>
> > Chris Angelico :
> >> The request was to translate this into Python, not to slavishly imitate
> >> every possible semantic difference even if it won't actually affect
> >> behaviour.
> >
> > I trust Steven to be able to refactor the code into something more
> > likable. His only tripping point was the meaning of the "let" construct.
>
> Thanks for the vote of confidence :-)
>
> However I have a follow up question. Why the "let" construct in the first
> place? Is this just a matter of principle, "put everything in its own
> scope as a matter of precautionary code hygiene"? Because I can't see any
> advantage to the inner function:

My impression is that this is just functional programming "good
style". As you say, it's not needed, it's just "keep things valid in
the smallest range possible". Probably also related to the
mathematical style of naming sub-expressions. Also, it's probably the
case that in a (compiled) functional language like SML, the compiler
can optimise this to avoid any actual inner function, leaving it as
nothing more than a temporary name.

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-07 Thread Steven D'Aprano
On Thu, 06 Sep 2018 13:48:54 +0300, Marko Rauhamaa wrote:

> Chris Angelico :
>> The request was to translate this into Python, not to slavishly imitate
>> every possible semantic difference even if it won't actually affect
>> behaviour.
> 
> I trust Steven to be able to refactor the code into something more
> likable. His only tripping point was the meaning of the "let" construct.

Thanks for the vote of confidence :-) 

However I have a follow up question. Why the "let" construct in the first 
place? Is this just a matter of principle, "put everything in its own 
scope as a matter of precautionary code hygiene"? Because I can't see any 
advantage to the inner function:

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))

Sure, it ensures that r is in its own namespace. But why is that an 
advantage in a function so small? Perhaps its a SML functional-
programming thing.

Putting aside the observation that recursion may not be the best way to 
do this in Python, I don't think that the inner function is actually 
needed. We can just write:

def isqrt(n):
if n == 0:
return 0
else:
r = isqrt(n//4)
if n < (2*r+1)**2:
return 2*r
else:
return 2*r+1


By the way I got this from this paper:

https://www.cs.uni-potsdam.de/ti/kreitz/PDF/03cucs-intsqrt.pdf





-- 
Steven D'Aprano
"Ever since I learned about confirmation bias, I've been seeing
it everywhere." -- Jon Ronson

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Marko Rauhamaa
Chris Angelico :
> The request was to translate this into Python, not to slavishly
> imitate every possible semantic difference even if it won't actually
> affect behaviour.

I trust Steven to be able to refactor the code into something more
likable. His only tripping point was the meaning of the "let" construct.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Chris Angelico
On Thu, Sep 6, 2018 at 7:22 PM, Antoon Pardon  wrote:
> On 06-09-18 10:50, Chris Angelico wrote:
>> On Thu, Sep 6, 2018 at 6:44 PM, Marko Rauhamaa  wrote:
>>> Chris Angelico :
>>>
 On Thu, Sep 6, 2018 at 2:29 PM, Marko Rauhamaa  wrote:
> Marko Rauhamaa  (Marko Rauhamaa):
>> Steven D'Aprano :
>>> 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.
>> And even more idiomatically, Python doesn't require a new scope just
>> for a new variable.
>
> You may have overlooked where Marko wrote:
> Actually, this is a more *direct* translation

That was *after* stating this:

> You must make sure "r" doesn't leak outside its syntactic context so:

Why "must"? The request was to translate this into Python, not to
slavishly imitate every possible semantic difference even if it won't
actually affect behaviour. If there were some way in which the name
actually HAD to be kept scoped in, then sure - maybe a name collision
or something - but I can't see that here. So by insisting that the
translation maintain an unnecessary inner function, Marko is
distracting from a logical and semantic translation of the behaviour
of the function.

Unless I'm missing something, and there actually IS a good reason for
the inner function, other than "well, that's how it works in the
source language".

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Antoon Pardon
On 06-09-18 10:50, Chris Angelico wrote:
> On Thu, Sep 6, 2018 at 6:44 PM, Marko Rauhamaa  wrote:
>> Chris Angelico :
>>
>>> On Thu, Sep 6, 2018 at 2:29 PM, Marko Rauhamaa  wrote:
 Marko Rauhamaa  (Marko Rauhamaa):
> Steven D'Aprano :
>> 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.
> And even more idiomatically, Python doesn't require a new scope just
> for a new variable.

You may have overlooked where Marko wrote:
Actually, this is a more *direct* translation

-- 
Antoon.



-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Marko Rauhamaa
Chris Angelico :

> On Thu, Sep 6, 2018 at 6:44 PM, Marko Rauhamaa  wrote:
> And even more idiomatically, Python doesn't require a new scope just
> for a new variable. So a much more idiomatic translation would be to
> simply ensure that the inner variable can't collide, and then ignore
> the function boundary. And I'm not sure if there even is a name
> collision. What's the issue with scoping at all here? What's the inner
> function actually achieving?

We can debate what the inner function is achieving. The main point is
that functional languages create an inner function for each "let"
statement. Steve was wondering what "let" meant, and the Python code--I
hope--helped illustrate it.

Typical Scheme code is riddled with inner functions. Local variables?
An inner function. A loop? An inner function. Exception handling? An
inner function.

Scheme can also be written procedurally through macros, but those macros
generate inner functions.


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Chris Angelico
On Thu, Sep 6, 2018 at 6:44 PM, Marko Rauhamaa  wrote:
> Chris Angelico :
>
>> On Thu, Sep 6, 2018 at 2:29 PM, Marko Rauhamaa  wrote:
>>> Marko Rauhamaa  (Marko Rauhamaa):
 Steven D'Aprano :
> 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.

And even more idiomatically, Python doesn't require a new scope just
for a new variable. So a much more idiomatic translation would be to
simply ensure that the inner variable can't collide, and then ignore
the function boundary. And I'm not sure if there even is a name
collision. What's the issue with scoping at all here? What's the inner
function actually achieving?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Marko Rauhamaa
Chris Angelico :

> On Thu, Sep 6, 2018 at 2:29 PM, Marko Rauhamaa  wrote:
>> Marko Rauhamaa  (Marko Rauhamaa):
>>> Steven D'Aprano :
 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


Re: Any SML coders able to translate this to Python?

2018-09-06 Thread Chris Angelico
On Thu, Sep 6, 2018 at 2:29 PM, Marko Rauhamaa  wrote:
> Marko Rauhamaa  (Marko Rauhamaa):
>> Steven D'Aprano :
>>> 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?

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-05 Thread Marko Rauhamaa
Marko Rauhamaa  (Marko Rauhamaa):
> Steven D'Aprano :
>> 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))


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-05 Thread Marko Rauhamaa
Steven D'Aprano :

> 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
>
>
> I've tried reading up on SML and can't make heads or tails of the
> "let...in...end" construct.
>
>
> The best I've come up with is this:
>
> def isqrt(n):
> if n == 0:
> return 0
> else:
> r = isqrt(n/4)
> if n < (2*r+1)**2:
> return 2*r
> else:
> return 2*r+1
>
> but I don't understand the let ... in part so I'm not sure if I'm doing
> it right.

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()

(Also use // instead of /: isqrt = integer square root.)


Marko

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-05 Thread Paul Moore
On Tue, 4 Sep 2018 at 13:31, Steven D'Aprano
 wrote:
>
> 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
>
>
> I've tried reading up on SML and can't make heads or tails of the
> "let...in...end" construct.
>
>
> The best I've come up with is this:
>
> def isqrt(n):
> if n == 0:
> return 0
> else:
> r = isqrt(n/4)
> if n < (2*r+1)**2:
> return 2*r
> else:
> return 2*r+1
>
> but I don't understand the let ... in part so I'm not sure if I'm doing
> it right.

I've not used SML much, but what you have looks right. let ... in is basically
a local binding "let x = 12 in x+2" is saying "the value of x+2 with x set to
12".

As I'm sure you realise (but I'll add it here for the sake of any newcomers who
 read this), the recursive approach is not natural (or efficient) in Python,
whereas it's the natural approach in functional languages like SML. In Python
an iterative solution would be better.

Paul

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-04 Thread Thomas Jollans
On 2018-09-04 14:26, Steven D'Aprano wrote:
> 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
> 
> 
> I've tried reading up on SML and can't make heads or tails of the 
> "let...in...end" construct.


I don't know SML specifically, but my guess would be that
  let X = Y in A end
means "A, evaluated in a local scope where X refers to Y". Reasoning:
often (e.g. in JavaScript), 'let' sets something in a local scope, and I
think Haskell has a construct like this? It's been a while since I
played around with Haskell though... In an as-direct-as-possible Python
translation, (lambda X=Y: A)()

So,

isqrt = (lambda n: 0 if n == 0 else
(lambda r=isqrt(n//4):
2*r if n < (2*r+1)**2 else 2*r+1)())

This is obviously the same as your multi-expression function, with the
addition of the integer division as suggested by Marko.

Cheers,
Thomas



> 
> The best I've come up with is this:
> 
> def isqrt(n):
> if n == 0:
> return 0
> else:
> r = isqrt(n/4)
> if n < (2*r+1)**2:
> return 2*r
> else:
> return 2*r+1
> 
> but I don't understand the let ... in part so I'm not sure if I'm doing 
> it right.
> 
> 


-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-04 Thread Marko Rauhamaa
Steven D'Aprano :

> 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
>
>
> I've tried reading up on SML and can't make heads or tails of the 
> "let...in...end" construct.
>
>
> The best I've come up with is this:
>
> def isqrt(n):
> if n == 0:
> return 0
> else:
> r = isqrt(n/4)
> if n < (2*r+1)**2:
> return 2*r
> else:
> return 2*r+1
>
> but I don't understand the let ... in part so I'm not sure if I'm doing 
> it right.

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()

(Also use // instead of /: isqrt = integer square root.)


Marko
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Any SML coders able to translate this to Python?

2018-09-04 Thread Paul Moore
On Tue, 4 Sep 2018 at 13:31, Steven D'Aprano
 wrote:
>
> 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
>
>
> I've tried reading up on SML and can't make heads or tails of the
> "let...in...end" construct.
>
>
> The best I've come up with is this:
>
> def isqrt(n):
> if n == 0:
> return 0
> else:
> r = isqrt(n/4)
> if n < (2*r+1)**2:
> return 2*r
> else:
> return 2*r+1
>
> but I don't understand the let ... in part so I'm not sure if I'm doing
> it right.

I've not used SML much, but what you have looks right. let ... in is
basically a local binding "let x = 12 in x+2" is saying "the value of
x+2 with x set to 12".

As I'm sure you realise (but I'll add it here for the sake of any
newcomers who read this), the recursive approach is not natural (or
efficient) in Python, whereas it's the natural approach in functional
languages like SML. In Python an iterative solution would be better.

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list