Talk:Y combinator: Difference between revisions

Content added Content deleted
Line 297: Line 297:
==Temporary reversion of a recent Haskell edit==
==Temporary reversion of a recent Haskell edit==
For the moment I have reverted a couple of edits made to Haskell last night – mainly because the second piece of code no longer compiled. Reversion of the first piece may not have been necessary – reading the editors note, I initially took the phrase 'correcting grammar' as a reference to Haskell grammar, and interpreted the introduction of () as a slight misunderstanding :-) Perhaps it refers, though, to the English preamble. [[User:Hout|Hout]] ([[User talk:Hout|talk]]) 13:15, 10 October 2018 (UTC)
For the moment I have reverted a couple of edits made to Haskell last night – mainly because the second piece of code no longer compiled. Reversion of the first piece may not have been necessary – reading the editors note, I initially took the phrase 'correcting grammar' as a reference to Haskell grammar, and interpreted the introduction of () as a slight misunderstanding :-) Perhaps it refers, though, to the English preamble. [[User:Hout|Hout]] ([[User talk:Hout|talk]]) 13:15, 10 October 2018 (UTC)
:I had converted the bindings to the head of the infinite facs` lists to functions to remind users of memory leaks as per [https://wiki.haskell.org/Memory_leak the Haskell wiki]: a binding to the head of an evaluated list means that none of the list can be released; it doesn't matter much here where only 20 elements are evaluated and printed before the program closes, but imagine if the last of a million elements were printed where millions of Megabytes would be tied up - the use of a function means that the head of the list can be released as the list is consumed, meaning that in this case only two elements (the first and second) need be in memory at any given time.

:As to the second part you've temporarily removed, there was a mistake that crept into the type signature for <code>simplefac</code> which should be <code>simplefac :: Integer -> Integer</code>; this prevented it from compiling.

:The reason for the second part, and its included actually third part is that this task is ambiguous as to the type of recursion that is disallowed: Although because Haskell is non-strict and doesn't have a problem with either recursive bindings (as used in the the <code>fix f = x where x = f x</code> definition) or recursive functions (as used in the <code>fix f = f (fix f)</code> definition with regard to <code>fix</code>), many non-strict languages disallow the first unless there is a function injected (<code>fix f = x() where x = \() -> f x</code>) in the interested of avoiding cyclic data, and a few don't allow recursive functions which call themselves from their own definition. In these cases, the Y-combinator may be actually useful in allowing recursion where otherwise it would be forbidden.

:I think @WillNess, who posted the second part originally, intended to show that one can avoid binding recursion but still use the "non-sharing point form" of the Y-combinator, and his Y-combinator example of <code>fibs</code> then is essentially the same version as currently used which uses the double <code>fix</code> and completely avoids even function recursion (just in a simpler, easier to understand form in not using the applicative).

:My point in modifying his <code>fibs</code> example, adding an equivalent <code>facs</code> example, and adding the "simple" non-fix/non-Y-combinator versions is that, if function recursion is to be allowed as in the definition of the non-sharing version of <code>fix</code> (with the function <code>fix</code> self referenced in its definition), then there is no need for <code>fix</code>/Y-combinator at all in these cases as they can be defined just using function recursion.--[[User:GordonBGood|GordonBGood]] ([[User talk:GordonBGood|talk]]) 22:13, 10 October 2018 (UTC)