let rec for values and let rec for functions in ocaml












5















What is the best intuition for why the first definition would be refused, while the second one would be accepted ?



let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x

let rec a x = b x (* oki doki *)
and b x = a x


Is it linked to the 2 reduction approaches : one rule for every function substitution (and a Rec delimiter) VS one rule per function definition (and lambda lifting) ?










share|improve this question























  • I think this is caused by the value restriction and explicitly passing the argument is called eta expansion. I have no idea how to explain this in any way that is intuitive though.

    – glennsl
    Nov 16 '18 at 11:13











  • me neither. it's a tad annoying compared to haskell, although I am sure there are very good reason for that..

    – nicolas
    Nov 16 '18 at 14:24
















5















What is the best intuition for why the first definition would be refused, while the second one would be accepted ?



let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x

let rec a x = b x (* oki doki *)
and b x = a x


Is it linked to the 2 reduction approaches : one rule for every function substitution (and a Rec delimiter) VS one rule per function definition (and lambda lifting) ?










share|improve this question























  • I think this is caused by the value restriction and explicitly passing the argument is called eta expansion. I have no idea how to explain this in any way that is intuitive though.

    – glennsl
    Nov 16 '18 at 11:13











  • me neither. it's a tad annoying compared to haskell, although I am sure there are very good reason for that..

    – nicolas
    Nov 16 '18 at 14:24














5












5








5








What is the best intuition for why the first definition would be refused, while the second one would be accepted ?



let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x

let rec a x = b x (* oki doki *)
and b x = a x


Is it linked to the 2 reduction approaches : one rule for every function substitution (and a Rec delimiter) VS one rule per function definition (and lambda lifting) ?










share|improve this question














What is the best intuition for why the first definition would be refused, while the second one would be accepted ?



let rec a = b (* This kind of expression is not allowed as right-hand side of `let rec' *)
and b x = a x

let rec a x = b x (* oki doki *)
and b x = a x


Is it linked to the 2 reduction approaches : one rule for every function substitution (and a Rec delimiter) VS one rule per function definition (and lambda lifting) ?







ocaml






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 16 '18 at 10:52









nicolasnicolas

4,07622660




4,07622660













  • I think this is caused by the value restriction and explicitly passing the argument is called eta expansion. I have no idea how to explain this in any way that is intuitive though.

    – glennsl
    Nov 16 '18 at 11:13











  • me neither. it's a tad annoying compared to haskell, although I am sure there are very good reason for that..

    – nicolas
    Nov 16 '18 at 14:24



















  • I think this is caused by the value restriction and explicitly passing the argument is called eta expansion. I have no idea how to explain this in any way that is intuitive though.

    – glennsl
    Nov 16 '18 at 11:13











  • me neither. it's a tad annoying compared to haskell, although I am sure there are very good reason for that..

    – nicolas
    Nov 16 '18 at 14:24

















I think this is caused by the value restriction and explicitly passing the argument is called eta expansion. I have no idea how to explain this in any way that is intuitive though.

– glennsl
Nov 16 '18 at 11:13





I think this is caused by the value restriction and explicitly passing the argument is called eta expansion. I have no idea how to explain this in any way that is intuitive though.

– glennsl
Nov 16 '18 at 11:13













me neither. it's a tad annoying compared to haskell, although I am sure there are very good reason for that..

– nicolas
Nov 16 '18 at 14:24





me neither. it's a tad annoying compared to haskell, although I am sure there are very good reason for that..

– nicolas
Nov 16 '18 at 14:24












1 Answer
1






active

oldest

votes


















5














Verifying that recursive definitions are valid is a very hard thing to do.



Basically, you want to avoid patterns in this kind of form:



let rec x = x


In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.



Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.



You can have an outlook of the rules here. Here is an excerpt (emphasis mine):




It will be accepted if each one of expr1exprn is statically constructive with respect to name1namen, is not immediately linked to any of name1namen, and is not an array constructor whose arguments have abstract type.




As you can see, direct recursive variable binding is not permitted.



This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53336382%2flet-rec-for-values-and-let-rec-for-functions-in-ocaml%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    5














    Verifying that recursive definitions are valid is a very hard thing to do.



    Basically, you want to avoid patterns in this kind of form:



    let rec x = x


    In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.



    Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.



    You can have an outlook of the rules here. Here is an excerpt (emphasis mine):




    It will be accepted if each one of expr1exprn is statically constructive with respect to name1namen, is not immediately linked to any of name1namen, and is not an array constructor whose arguments have abstract type.




    As you can see, direct recursive variable binding is not permitted.



    This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.






    share|improve this answer




























      5














      Verifying that recursive definitions are valid is a very hard thing to do.



      Basically, you want to avoid patterns in this kind of form:



      let rec x = x


      In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.



      Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.



      You can have an outlook of the rules here. Here is an excerpt (emphasis mine):




      It will be accepted if each one of expr1exprn is statically constructive with respect to name1namen, is not immediately linked to any of name1namen, and is not an array constructor whose arguments have abstract type.




      As you can see, direct recursive variable binding is not permitted.



      This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.






      share|improve this answer


























        5












        5








        5







        Verifying that recursive definitions are valid is a very hard thing to do.



        Basically, you want to avoid patterns in this kind of form:



        let rec x = x


        In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.



        Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.



        You can have an outlook of the rules here. Here is an excerpt (emphasis mine):




        It will be accepted if each one of expr1exprn is statically constructive with respect to name1namen, is not immediately linked to any of name1namen, and is not an array constructor whose arguments have abstract type.




        As you can see, direct recursive variable binding is not permitted.



        This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.






        share|improve this answer













        Verifying that recursive definitions are valid is a very hard thing to do.



        Basically, you want to avoid patterns in this kind of form:



        let rec x = x


        In the case where every left-hand side of the definitions are function declarations, you know it is going to be fine. At worst, you are creating an infinite loop, but at least you are creating a value. But the x = x case does not produce anything and has no semantic altogether.



        Now, in your specific case, you are indeed creating functions (that loop indefinitely), but checking that you are is actually harder. To avoid writing a code that would attempt exhaustive checking, the OCaml developers decided to go with a much easier algorithm.



        You can have an outlook of the rules here. Here is an excerpt (emphasis mine):




        It will be accepted if each one of expr1exprn is statically constructive with respect to name1namen, is not immediately linked to any of name1namen, and is not an array constructor whose arguments have abstract type.




        As you can see, direct recursive variable binding is not permitted.



        This is not a final rule though, as there are improvements to that part of the compiler pending release. I haven't tested if your example passes with it, but some day your code might be accepted.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 16 '18 at 15:13









        PatJPatJ

        4,45812231




        4,45812231
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53336382%2flet-rec-for-values-and-let-rec-for-functions-in-ocaml%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Xamarin.iOS Cant Deploy on Iphone

            Glorious Revolution

            Dulmage-Mendelsohn matrix decomposition in Python