Setting default values in clojure defn












0















I'm super new to clojure and I am trying to set fault values for args in a clojure function. This is what I have so far:



(defn get-user-projects-by-user-id
([db-conn userid] (get-user-projects-by-user-id db-conn userid (str "asc") nil 10 10))
([db-conn userid sort filters offset size]
;;rest of the function


What I am trying to accomplish is whenever the function doesn't receive sort, filters, offset, or size, or as nil/false, they get the default values of "asc", nil, 10, and 10, respectively.



However, whenever I don't send any of those arguments to get-user-projects-by-user-id, (println sort filters offset size) is nil nil nil nil.



How can I set them to the default valuses I want?










share|improve this question



























    0















    I'm super new to clojure and I am trying to set fault values for args in a clojure function. This is what I have so far:



    (defn get-user-projects-by-user-id
    ([db-conn userid] (get-user-projects-by-user-id db-conn userid (str "asc") nil 10 10))
    ([db-conn userid sort filters offset size]
    ;;rest of the function


    What I am trying to accomplish is whenever the function doesn't receive sort, filters, offset, or size, or as nil/false, they get the default values of "asc", nil, 10, and 10, respectively.



    However, whenever I don't send any of those arguments to get-user-projects-by-user-id, (println sort filters offset size) is nil nil nil nil.



    How can I set them to the default valuses I want?










    share|improve this question

























      0












      0








      0


      1






      I'm super new to clojure and I am trying to set fault values for args in a clojure function. This is what I have so far:



      (defn get-user-projects-by-user-id
      ([db-conn userid] (get-user-projects-by-user-id db-conn userid (str "asc") nil 10 10))
      ([db-conn userid sort filters offset size]
      ;;rest of the function


      What I am trying to accomplish is whenever the function doesn't receive sort, filters, offset, or size, or as nil/false, they get the default values of "asc", nil, 10, and 10, respectively.



      However, whenever I don't send any of those arguments to get-user-projects-by-user-id, (println sort filters offset size) is nil nil nil nil.



      How can I set them to the default valuses I want?










      share|improve this question














      I'm super new to clojure and I am trying to set fault values for args in a clojure function. This is what I have so far:



      (defn get-user-projects-by-user-id
      ([db-conn userid] (get-user-projects-by-user-id db-conn userid (str "asc") nil 10 10))
      ([db-conn userid sort filters offset size]
      ;;rest of the function


      What I am trying to accomplish is whenever the function doesn't receive sort, filters, offset, or size, or as nil/false, they get the default values of "asc", nil, 10, and 10, respectively.



      However, whenever I don't send any of those arguments to get-user-projects-by-user-id, (println sort filters offset size) is nil nil nil nil.



      How can I set them to the default valuses I want?







      clojure functional-programming






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 24 '18 at 6:41









      Kaisin LiKaisin Li

      8911




      8911
























          2 Answers
          2






          active

          oldest

          votes


















          2














          Here there are 3 ways I can think of:



          Your version:



          (defn get-user-projects-by-user-id
          ([db-conn userid] (get-user-projects-by-user-id db-conn userid "asc" nil 10 10))
          ([db-conn userid sort filters offset size]
          (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

          ;; (get-user-projects-by-user-id 'db 'userid)
          ;; => arguments: sort asc , filters nil , offset 10 , size 10


          Another style would be to pass an opts parameter which is a map with the options you want, and you can provide default values in a convenient manner with destructuring:



          (defn get-user-projects-by-user-id-with-opts
          ([db-conn userid]
          (get-user-projects-by-user-id-with-opts db-conn userid nil))
          ([db-conn userid {:keys [sort filters offset size]
          :or {sort "asc" offset 10 size 10}}]
          (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

          ;; (get-user-projects-by-user-id-with-opts 'db 'userid)
          ;; => arguments: sort: asc filters: nil offset: 10 size: 10

          ;; (get-user-projects-by-user-id-with-opts 'db 'userid {:sort "desc" :offset 20})
          ;; => arguments: sort: desc filters: nil offset: 20 size: 10


          Finally, there's a third approach which was used sometimes in older libraries, which was to pass an arbitrary number of arguments to your function, and take the optional arguments after the others (this is a bit like Python I guess):



          (defn get-user-projects-by-user-id-with-varargs
          [db-conn userid & args]
          (let [arg-map (apply hash-map args)
          {:keys [sort filters offset size]
          :or {sort "asc" offset 10 size 10}} arg-map]
          (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

          ;; (get-user-projects-by-user-id-with-varargs 'db 'userid)
          ;; => arguments: sort: asc filters: nil offset: 10 size: 10

          ;; (get-user-projects-by-user-id-with-varargs 'db 'userid :sort "desc" :offset 20)
          ;; => arguments: sort: desc filters: nil offset: 20 size: 10





          share|improve this answer



















          • 3





            While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

            – dpassen
            Nov 24 '18 at 23:34











          • Thanks. The first way still prints nil nil nil nil. But the second way works!

            – Kaisin Li
            Nov 25 '18 at 4:38











          • Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

            – Kaisin Li
            Nov 25 '18 at 5:38



















          0














          There are several ways for providing optional arguments and their default values. Which to choose depends on how you want to provide those optional arguments to the function call.



          Strictly Serial Arguments



          Your arguments are already ordered by decreasing likelihood for setting them. You wish to be able to call the function like this (assuming a println function body and ignoring the nil return value):



          user> (get-user-projects-by-user-id :conn :uid)
          [:conn :uid asc nil 10 10]
          user> (get-user-projects-by-user-id :conn :uid :sort)
          [:conn :uid :sort nil 10 10]
          user> (get-user-projects-by-user-id :conn :uid :sort "filter")
          [:conn :uid :sort filter 10 10]
          user> (get-user-projects-by-user-id :conn :uid :sort "filter" 9)
          [:conn :uid :sort filter 9 10]


          For this, you can overload the function by arity as you already started:



          (defn get-user-projects-by-user-id
          ([db-conn userid]
          (get-user-projects-by-user-id db-conn userid
          (str "asc")
          nil
          10
          10))
          ([db-conn userid sort]
          (get-user-projects-by-user-id db-conn userid
          sort
          nil
          10
          10))
          ([db-conn userid sort filters]
          (get-user-projects-by-user-id db-conn userid
          sort
          filters
          10
          10))
          ([db-conn userid sort filters offset]
          (get-user-projects-by-user-id db-conn userid
          sort
          filters
          offset
          10))
          ([db-conn userid sort filters offset size]
          (println [db-conn userid sort filters offset size])))


          It's a bit tedious in the function definition and you must take care when refactoring to keep the default values correct.



          Optional Arguments as a Map



          You can use destructuring in your argument vector to allow passing a map with extra arguments. This allows passing them in any order: you can override offset without having to pass sort and others, too:



          (defn get-user-projects-by-user-id-extra-map
          [db-conn userid & [{:keys [sort filters offset size]
          :or {sort "asc"
          filters nil
          offset 10
          size 10}}]]
          (println [db-conn userid sort filters offset size]))


          You use it like this:



          user> (get-user-projects-by-user-id-extra-map :conn :uid {:offset 9})
          [:conn :uid asc nil 9 10]


          Optional Arguments as Pairs



          If you change the destructuring slightly (note the missing ), it allows you to pass the optional arguments as key-value-pairs without the need for a map. This is usually easier to use when your function calls are all explicit whereas the previous option is often easier when you apply your function with programmatically collected extra arguments.



          (defn get-user-projects-by-user-id-pairs
          [db-conn userid & {:keys [sort filters offset size]
          :or {sort "asc"
          filters nil
          offset 10
          size 10}}]
          (println [db-conn userid sort filters offset size]))


          Use it (note missing {}):



          user> (get-user-projects-by-user-id-pairs :conn :uid :offset 9)
          [:conn :uid asc nil 9 10]





          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%2f53455826%2fsetting-default-values-in-clojure-defn%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            2














            Here there are 3 ways I can think of:



            Your version:



            (defn get-user-projects-by-user-id
            ([db-conn userid] (get-user-projects-by-user-id db-conn userid "asc" nil 10 10))
            ([db-conn userid sort filters offset size]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id 'db 'userid)
            ;; => arguments: sort asc , filters nil , offset 10 , size 10


            Another style would be to pass an opts parameter which is a map with the options you want, and you can provide default values in a convenient manner with destructuring:



            (defn get-user-projects-by-user-id-with-opts
            ([db-conn userid]
            (get-user-projects-by-user-id-with-opts db-conn userid nil))
            ([db-conn userid {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}}]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid {:sort "desc" :offset 20})
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10


            Finally, there's a third approach which was used sometimes in older libraries, which was to pass an arbitrary number of arguments to your function, and take the optional arguments after the others (this is a bit like Python I guess):



            (defn get-user-projects-by-user-id-with-varargs
            [db-conn userid & args]
            (let [arg-map (apply hash-map args)
            {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}} arg-map]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid :sort "desc" :offset 20)
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10





            share|improve this answer



















            • 3





              While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

              – dpassen
              Nov 24 '18 at 23:34











            • Thanks. The first way still prints nil nil nil nil. But the second way works!

              – Kaisin Li
              Nov 25 '18 at 4:38











            • Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

              – Kaisin Li
              Nov 25 '18 at 5:38
















            2














            Here there are 3 ways I can think of:



            Your version:



            (defn get-user-projects-by-user-id
            ([db-conn userid] (get-user-projects-by-user-id db-conn userid "asc" nil 10 10))
            ([db-conn userid sort filters offset size]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id 'db 'userid)
            ;; => arguments: sort asc , filters nil , offset 10 , size 10


            Another style would be to pass an opts parameter which is a map with the options you want, and you can provide default values in a convenient manner with destructuring:



            (defn get-user-projects-by-user-id-with-opts
            ([db-conn userid]
            (get-user-projects-by-user-id-with-opts db-conn userid nil))
            ([db-conn userid {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}}]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid {:sort "desc" :offset 20})
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10


            Finally, there's a third approach which was used sometimes in older libraries, which was to pass an arbitrary number of arguments to your function, and take the optional arguments after the others (this is a bit like Python I guess):



            (defn get-user-projects-by-user-id-with-varargs
            [db-conn userid & args]
            (let [arg-map (apply hash-map args)
            {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}} arg-map]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid :sort "desc" :offset 20)
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10





            share|improve this answer



















            • 3





              While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

              – dpassen
              Nov 24 '18 at 23:34











            • Thanks. The first way still prints nil nil nil nil. But the second way works!

              – Kaisin Li
              Nov 25 '18 at 4:38











            • Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

              – Kaisin Li
              Nov 25 '18 at 5:38














            2












            2








            2







            Here there are 3 ways I can think of:



            Your version:



            (defn get-user-projects-by-user-id
            ([db-conn userid] (get-user-projects-by-user-id db-conn userid "asc" nil 10 10))
            ([db-conn userid sort filters offset size]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id 'db 'userid)
            ;; => arguments: sort asc , filters nil , offset 10 , size 10


            Another style would be to pass an opts parameter which is a map with the options you want, and you can provide default values in a convenient manner with destructuring:



            (defn get-user-projects-by-user-id-with-opts
            ([db-conn userid]
            (get-user-projects-by-user-id-with-opts db-conn userid nil))
            ([db-conn userid {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}}]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid {:sort "desc" :offset 20})
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10


            Finally, there's a third approach which was used sometimes in older libraries, which was to pass an arbitrary number of arguments to your function, and take the optional arguments after the others (this is a bit like Python I guess):



            (defn get-user-projects-by-user-id-with-varargs
            [db-conn userid & args]
            (let [arg-map (apply hash-map args)
            {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}} arg-map]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid :sort "desc" :offset 20)
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10





            share|improve this answer













            Here there are 3 ways I can think of:



            Your version:



            (defn get-user-projects-by-user-id
            ([db-conn userid] (get-user-projects-by-user-id db-conn userid "asc" nil 10 10))
            ([db-conn userid sort filters offset size]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id 'db 'userid)
            ;; => arguments: sort asc , filters nil , offset 10 , size 10


            Another style would be to pass an opts parameter which is a map with the options you want, and you can provide default values in a convenient manner with destructuring:



            (defn get-user-projects-by-user-id-with-opts
            ([db-conn userid]
            (get-user-projects-by-user-id-with-opts db-conn userid nil))
            ([db-conn userid {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}}]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-opts 'db 'userid {:sort "desc" :offset 20})
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10


            Finally, there's a third approach which was used sometimes in older libraries, which was to pass an arbitrary number of arguments to your function, and take the optional arguments after the others (this is a bit like Python I guess):



            (defn get-user-projects-by-user-id-with-varargs
            [db-conn userid & args]
            (let [arg-map (apply hash-map args)
            {:keys [sort filters offset size]
            :or {sort "asc" offset 10 size 10}} arg-map]
            (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size)))

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid)
            ;; => arguments: sort: asc filters: nil offset: 10 size: 10

            ;; (get-user-projects-by-user-id-with-varargs 'db 'userid :sort "desc" :offset 20)
            ;; => arguments: sort: desc filters: nil offset: 20 size: 10






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 24 '18 at 8:11









            Denis FuenzalidaDenis Fuenzalida

            939714




            939714








            • 3





              While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

              – dpassen
              Nov 24 '18 at 23:34











            • Thanks. The first way still prints nil nil nil nil. But the second way works!

              – Kaisin Li
              Nov 25 '18 at 4:38











            • Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

              – Kaisin Li
              Nov 25 '18 at 5:38














            • 3





              While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

              – dpassen
              Nov 24 '18 at 23:34











            • Thanks. The first way still prints nil nil nil nil. But the second way works!

              – Kaisin Li
              Nov 25 '18 at 4:38











            • Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

              – Kaisin Li
              Nov 25 '18 at 5:38








            3




            3





            While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

            – dpassen
            Nov 24 '18 at 23:34





            While your varargs method works, I think the more idiomatic to have flattened options is as follows: (defn get-user-projects-by-user-id-with-flat-opts [db-conn userid & {:keys [sort filters offset size] :or {sort "asc" offset 10 size 10}}] (println "arguments: sort:" sort "filters:" filters "offset:" offset "size:" size))) Note the '&' before the destructuring.

            – dpassen
            Nov 24 '18 at 23:34













            Thanks. The first way still prints nil nil nil nil. But the second way works!

            – Kaisin Li
            Nov 25 '18 at 4:38





            Thanks. The first way still prints nil nil nil nil. But the second way works!

            – Kaisin Li
            Nov 25 '18 at 4:38













            Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

            – Kaisin Li
            Nov 25 '18 at 5:38





            Actaully, for the second way, they values are set. But when I actually sent the arguments to the function, they still come out as the default. I sent in sort as "desc" but my println sort still prints my default value, asc.

            – Kaisin Li
            Nov 25 '18 at 5:38













            0














            There are several ways for providing optional arguments and their default values. Which to choose depends on how you want to provide those optional arguments to the function call.



            Strictly Serial Arguments



            Your arguments are already ordered by decreasing likelihood for setting them. You wish to be able to call the function like this (assuming a println function body and ignoring the nil return value):



            user> (get-user-projects-by-user-id :conn :uid)
            [:conn :uid asc nil 10 10]
            user> (get-user-projects-by-user-id :conn :uid :sort)
            [:conn :uid :sort nil 10 10]
            user> (get-user-projects-by-user-id :conn :uid :sort "filter")
            [:conn :uid :sort filter 10 10]
            user> (get-user-projects-by-user-id :conn :uid :sort "filter" 9)
            [:conn :uid :sort filter 9 10]


            For this, you can overload the function by arity as you already started:



            (defn get-user-projects-by-user-id
            ([db-conn userid]
            (get-user-projects-by-user-id db-conn userid
            (str "asc")
            nil
            10
            10))
            ([db-conn userid sort]
            (get-user-projects-by-user-id db-conn userid
            sort
            nil
            10
            10))
            ([db-conn userid sort filters]
            (get-user-projects-by-user-id db-conn userid
            sort
            filters
            10
            10))
            ([db-conn userid sort filters offset]
            (get-user-projects-by-user-id db-conn userid
            sort
            filters
            offset
            10))
            ([db-conn userid sort filters offset size]
            (println [db-conn userid sort filters offset size])))


            It's a bit tedious in the function definition and you must take care when refactoring to keep the default values correct.



            Optional Arguments as a Map



            You can use destructuring in your argument vector to allow passing a map with extra arguments. This allows passing them in any order: you can override offset without having to pass sort and others, too:



            (defn get-user-projects-by-user-id-extra-map
            [db-conn userid & [{:keys [sort filters offset size]
            :or {sort "asc"
            filters nil
            offset 10
            size 10}}]]
            (println [db-conn userid sort filters offset size]))


            You use it like this:



            user> (get-user-projects-by-user-id-extra-map :conn :uid {:offset 9})
            [:conn :uid asc nil 9 10]


            Optional Arguments as Pairs



            If you change the destructuring slightly (note the missing ), it allows you to pass the optional arguments as key-value-pairs without the need for a map. This is usually easier to use when your function calls are all explicit whereas the previous option is often easier when you apply your function with programmatically collected extra arguments.



            (defn get-user-projects-by-user-id-pairs
            [db-conn userid & {:keys [sort filters offset size]
            :or {sort "asc"
            filters nil
            offset 10
            size 10}}]
            (println [db-conn userid sort filters offset size]))


            Use it (note missing {}):



            user> (get-user-projects-by-user-id-pairs :conn :uid :offset 9)
            [:conn :uid asc nil 9 10]





            share|improve this answer




























              0














              There are several ways for providing optional arguments and their default values. Which to choose depends on how you want to provide those optional arguments to the function call.



              Strictly Serial Arguments



              Your arguments are already ordered by decreasing likelihood for setting them. You wish to be able to call the function like this (assuming a println function body and ignoring the nil return value):



              user> (get-user-projects-by-user-id :conn :uid)
              [:conn :uid asc nil 10 10]
              user> (get-user-projects-by-user-id :conn :uid :sort)
              [:conn :uid :sort nil 10 10]
              user> (get-user-projects-by-user-id :conn :uid :sort "filter")
              [:conn :uid :sort filter 10 10]
              user> (get-user-projects-by-user-id :conn :uid :sort "filter" 9)
              [:conn :uid :sort filter 9 10]


              For this, you can overload the function by arity as you already started:



              (defn get-user-projects-by-user-id
              ([db-conn userid]
              (get-user-projects-by-user-id db-conn userid
              (str "asc")
              nil
              10
              10))
              ([db-conn userid sort]
              (get-user-projects-by-user-id db-conn userid
              sort
              nil
              10
              10))
              ([db-conn userid sort filters]
              (get-user-projects-by-user-id db-conn userid
              sort
              filters
              10
              10))
              ([db-conn userid sort filters offset]
              (get-user-projects-by-user-id db-conn userid
              sort
              filters
              offset
              10))
              ([db-conn userid sort filters offset size]
              (println [db-conn userid sort filters offset size])))


              It's a bit tedious in the function definition and you must take care when refactoring to keep the default values correct.



              Optional Arguments as a Map



              You can use destructuring in your argument vector to allow passing a map with extra arguments. This allows passing them in any order: you can override offset without having to pass sort and others, too:



              (defn get-user-projects-by-user-id-extra-map
              [db-conn userid & [{:keys [sort filters offset size]
              :or {sort "asc"
              filters nil
              offset 10
              size 10}}]]
              (println [db-conn userid sort filters offset size]))


              You use it like this:



              user> (get-user-projects-by-user-id-extra-map :conn :uid {:offset 9})
              [:conn :uid asc nil 9 10]


              Optional Arguments as Pairs



              If you change the destructuring slightly (note the missing ), it allows you to pass the optional arguments as key-value-pairs without the need for a map. This is usually easier to use when your function calls are all explicit whereas the previous option is often easier when you apply your function with programmatically collected extra arguments.



              (defn get-user-projects-by-user-id-pairs
              [db-conn userid & {:keys [sort filters offset size]
              :or {sort "asc"
              filters nil
              offset 10
              size 10}}]
              (println [db-conn userid sort filters offset size]))


              Use it (note missing {}):



              user> (get-user-projects-by-user-id-pairs :conn :uid :offset 9)
              [:conn :uid asc nil 9 10]





              share|improve this answer


























                0












                0








                0







                There are several ways for providing optional arguments and their default values. Which to choose depends on how you want to provide those optional arguments to the function call.



                Strictly Serial Arguments



                Your arguments are already ordered by decreasing likelihood for setting them. You wish to be able to call the function like this (assuming a println function body and ignoring the nil return value):



                user> (get-user-projects-by-user-id :conn :uid)
                [:conn :uid asc nil 10 10]
                user> (get-user-projects-by-user-id :conn :uid :sort)
                [:conn :uid :sort nil 10 10]
                user> (get-user-projects-by-user-id :conn :uid :sort "filter")
                [:conn :uid :sort filter 10 10]
                user> (get-user-projects-by-user-id :conn :uid :sort "filter" 9)
                [:conn :uid :sort filter 9 10]


                For this, you can overload the function by arity as you already started:



                (defn get-user-projects-by-user-id
                ([db-conn userid]
                (get-user-projects-by-user-id db-conn userid
                (str "asc")
                nil
                10
                10))
                ([db-conn userid sort]
                (get-user-projects-by-user-id db-conn userid
                sort
                nil
                10
                10))
                ([db-conn userid sort filters]
                (get-user-projects-by-user-id db-conn userid
                sort
                filters
                10
                10))
                ([db-conn userid sort filters offset]
                (get-user-projects-by-user-id db-conn userid
                sort
                filters
                offset
                10))
                ([db-conn userid sort filters offset size]
                (println [db-conn userid sort filters offset size])))


                It's a bit tedious in the function definition and you must take care when refactoring to keep the default values correct.



                Optional Arguments as a Map



                You can use destructuring in your argument vector to allow passing a map with extra arguments. This allows passing them in any order: you can override offset without having to pass sort and others, too:



                (defn get-user-projects-by-user-id-extra-map
                [db-conn userid & [{:keys [sort filters offset size]
                :or {sort "asc"
                filters nil
                offset 10
                size 10}}]]
                (println [db-conn userid sort filters offset size]))


                You use it like this:



                user> (get-user-projects-by-user-id-extra-map :conn :uid {:offset 9})
                [:conn :uid asc nil 9 10]


                Optional Arguments as Pairs



                If you change the destructuring slightly (note the missing ), it allows you to pass the optional arguments as key-value-pairs without the need for a map. This is usually easier to use when your function calls are all explicit whereas the previous option is often easier when you apply your function with programmatically collected extra arguments.



                (defn get-user-projects-by-user-id-pairs
                [db-conn userid & {:keys [sort filters offset size]
                :or {sort "asc"
                filters nil
                offset 10
                size 10}}]
                (println [db-conn userid sort filters offset size]))


                Use it (note missing {}):



                user> (get-user-projects-by-user-id-pairs :conn :uid :offset 9)
                [:conn :uid asc nil 9 10]





                share|improve this answer













                There are several ways for providing optional arguments and their default values. Which to choose depends on how you want to provide those optional arguments to the function call.



                Strictly Serial Arguments



                Your arguments are already ordered by decreasing likelihood for setting them. You wish to be able to call the function like this (assuming a println function body and ignoring the nil return value):



                user> (get-user-projects-by-user-id :conn :uid)
                [:conn :uid asc nil 10 10]
                user> (get-user-projects-by-user-id :conn :uid :sort)
                [:conn :uid :sort nil 10 10]
                user> (get-user-projects-by-user-id :conn :uid :sort "filter")
                [:conn :uid :sort filter 10 10]
                user> (get-user-projects-by-user-id :conn :uid :sort "filter" 9)
                [:conn :uid :sort filter 9 10]


                For this, you can overload the function by arity as you already started:



                (defn get-user-projects-by-user-id
                ([db-conn userid]
                (get-user-projects-by-user-id db-conn userid
                (str "asc")
                nil
                10
                10))
                ([db-conn userid sort]
                (get-user-projects-by-user-id db-conn userid
                sort
                nil
                10
                10))
                ([db-conn userid sort filters]
                (get-user-projects-by-user-id db-conn userid
                sort
                filters
                10
                10))
                ([db-conn userid sort filters offset]
                (get-user-projects-by-user-id db-conn userid
                sort
                filters
                offset
                10))
                ([db-conn userid sort filters offset size]
                (println [db-conn userid sort filters offset size])))


                It's a bit tedious in the function definition and you must take care when refactoring to keep the default values correct.



                Optional Arguments as a Map



                You can use destructuring in your argument vector to allow passing a map with extra arguments. This allows passing them in any order: you can override offset without having to pass sort and others, too:



                (defn get-user-projects-by-user-id-extra-map
                [db-conn userid & [{:keys [sort filters offset size]
                :or {sort "asc"
                filters nil
                offset 10
                size 10}}]]
                (println [db-conn userid sort filters offset size]))


                You use it like this:



                user> (get-user-projects-by-user-id-extra-map :conn :uid {:offset 9})
                [:conn :uid asc nil 9 10]


                Optional Arguments as Pairs



                If you change the destructuring slightly (note the missing ), it allows you to pass the optional arguments as key-value-pairs without the need for a map. This is usually easier to use when your function calls are all explicit whereas the previous option is often easier when you apply your function with programmatically collected extra arguments.



                (defn get-user-projects-by-user-id-pairs
                [db-conn userid & {:keys [sort filters offset size]
                :or {sort "asc"
                filters nil
                offset 10
                size 10}}]
                (println [db-conn userid sort filters offset size]))


                Use it (note missing {}):



                user> (get-user-projects-by-user-id-pairs :conn :uid :offset 9)
                [:conn :uid asc nil 9 10]






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 26 '18 at 10:45









                Stefan KamphausenStefan Kamphausen

                976413




                976413






























                    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%2f53455826%2fsetting-default-values-in-clojure-defn%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

                    Create new schema in PostgreSQL using DBeaver

                    Deepest pit of an array with Javascript: test on Codility

                    Costa Masnaga