In what way are Clojure maps functions? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!What's the difference between a method and a function?var functionName = function() vs function functionName() What is the scope of variables in JavaScript?Set a default parameter value for a JavaScript functionScala vs. Groovy vs. ClojureWhat is the difference between call and apply?What does the exclamation mark do before the function?Map to accept singular or collectionDon't know how to create ISeq from clojureHow to use reduce and into properly

What's the difference between using dependency injection with a container and using a service locator?

What documents does someone with a long-term visa need to travel to another Schengen country?

Can 'non' with gerundive mean both lack of obligation and negative obligation?

Can a Wizard take the Magic Initiate feat and select spells from the Wizard list?

2 sample t test for sample sizes - 30,000 and 150,000

How to make an animal which can only breed for a certain number of generations?

Marquee sign letters

Will I be more secure with my own router behind my ISP's router?

Does the Pact of the Blade warlock feature allow me to customize the properties of the pact weapon I create?

What could prevent concentrated local exploration?

When does Bran Stark remember Jamie pushing him?

Is my guitar’s action too high?

How to get a single big right brace?

Meaning of "Not holding on that level of emuna/bitachon"

Married in secret, can marital status in passport be changed at a later date?

Who's this lady in the war room?

Kepler's 3rd law: ratios don't fit data

What is the definining line between a helicopter and a drone a person can ride in?

Pointing to problems without suggesting solutions

Is Bran literally the world's memory?

Assertions In A Mock Callout Test

How to ask rejected full-time candidates to apply to teach individual courses?

What came first? Venom as the movie or as the song?

Raising a bilingual kid. When should we introduce the majority language?



In what way are Clojure maps functions?



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!What's the difference between a method and a function?var functionName = function() vs function functionName() What is the scope of variables in JavaScript?Set a default parameter value for a JavaScript functionScala vs. Groovy vs. ClojureWhat is the difference between call and apply?What does the exclamation mark do before the function?Map to accept singular or collectionDon't know how to create ISeq from clojureHow to use reduce and into properly



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








4















In his talk "Maybe not" Rich Hickey states:




maps are (mathematical) functions!



in Clojure, we can directly write, and invoke



(:a 1 :b 2 :b) => 2




However I have the feeling that they are not in fact first class Clojure functions, or are they?



I can call the map with a keyword, or the other way around:



user=> (:b :a 1 :b 2 :c 3)
2
user=> (:a 1 :b 2 :c 3 :b)
2


But I can't use apply either way it seems:



user=> (apply #(:b %) :a 1 :b 2 :c 3)
ArityException Wrong number of args (3) passed to: user/eval1762/fn--1763 clojure.lang.AFn.throwArity (AFn.java:429)

user=> (apply #(:a 1 :b 2 :c 3 %) :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


And neither can I apply the keyword directly to the map:



user=> (apply :a 1 :b 2 :c 3 :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


So are they functions only in the mathematical sense, or is there more to them in the sense of applying a keyword similar to a "normal" clojure function?










share|improve this question

















  • 2





    If you use (apply #((fn [x] x) %) :b) or (apply #(:b %) (fn [x] x)) to substitute an explicit 1-arity function in the places where you're currently passing maps, you get the same errors -- demonstrating that the problem is not about maps' function-ness, but about the usage patterns themselves.

    – Charles Duffy
    Mar 22 at 15:22


















4















In his talk "Maybe not" Rich Hickey states:




maps are (mathematical) functions!



in Clojure, we can directly write, and invoke



(:a 1 :b 2 :b) => 2




However I have the feeling that they are not in fact first class Clojure functions, or are they?



I can call the map with a keyword, or the other way around:



user=> (:b :a 1 :b 2 :c 3)
2
user=> (:a 1 :b 2 :c 3 :b)
2


But I can't use apply either way it seems:



user=> (apply #(:b %) :a 1 :b 2 :c 3)
ArityException Wrong number of args (3) passed to: user/eval1762/fn--1763 clojure.lang.AFn.throwArity (AFn.java:429)

user=> (apply #(:a 1 :b 2 :c 3 %) :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


And neither can I apply the keyword directly to the map:



user=> (apply :a 1 :b 2 :c 3 :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


So are they functions only in the mathematical sense, or is there more to them in the sense of applying a keyword similar to a "normal" clojure function?










share|improve this question

















  • 2





    If you use (apply #((fn [x] x) %) :b) or (apply #(:b %) (fn [x] x)) to substitute an explicit 1-arity function in the places where you're currently passing maps, you get the same errors -- demonstrating that the problem is not about maps' function-ness, but about the usage patterns themselves.

    – Charles Duffy
    Mar 22 at 15:22














4












4








4








In his talk "Maybe not" Rich Hickey states:




maps are (mathematical) functions!



in Clojure, we can directly write, and invoke



(:a 1 :b 2 :b) => 2




However I have the feeling that they are not in fact first class Clojure functions, or are they?



I can call the map with a keyword, or the other way around:



user=> (:b :a 1 :b 2 :c 3)
2
user=> (:a 1 :b 2 :c 3 :b)
2


But I can't use apply either way it seems:



user=> (apply #(:b %) :a 1 :b 2 :c 3)
ArityException Wrong number of args (3) passed to: user/eval1762/fn--1763 clojure.lang.AFn.throwArity (AFn.java:429)

user=> (apply #(:a 1 :b 2 :c 3 %) :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


And neither can I apply the keyword directly to the map:



user=> (apply :a 1 :b 2 :c 3 :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


So are they functions only in the mathematical sense, or is there more to them in the sense of applying a keyword similar to a "normal" clojure function?










share|improve this question














In his talk "Maybe not" Rich Hickey states:




maps are (mathematical) functions!



in Clojure, we can directly write, and invoke



(:a 1 :b 2 :b) => 2




However I have the feeling that they are not in fact first class Clojure functions, or are they?



I can call the map with a keyword, or the other way around:



user=> (:b :a 1 :b 2 :c 3)
2
user=> (:a 1 :b 2 :c 3 :b)
2


But I can't use apply either way it seems:



user=> (apply #(:b %) :a 1 :b 2 :c 3)
ArityException Wrong number of args (3) passed to: user/eval1762/fn--1763 clojure.lang.AFn.throwArity (AFn.java:429)

user=> (apply #(:a 1 :b 2 :c 3 %) :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


And neither can I apply the keyword directly to the map:



user=> (apply :a 1 :b 2 :c 3 :b)
IllegalArgumentException Don't know how to create ISeq from: clojure.lang.Keyword clojure.lang.RT.seqFrom (RT.java:542)


So are they functions only in the mathematical sense, or is there more to them in the sense of applying a keyword similar to a "normal" clojure function?







function clojure






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 22 at 13:56









ArneArne

1,67921738




1,67921738







  • 2





    If you use (apply #((fn [x] x) %) :b) or (apply #(:b %) (fn [x] x)) to substitute an explicit 1-arity function in the places where you're currently passing maps, you get the same errors -- demonstrating that the problem is not about maps' function-ness, but about the usage patterns themselves.

    – Charles Duffy
    Mar 22 at 15:22













  • 2





    If you use (apply #((fn [x] x) %) :b) or (apply #(:b %) (fn [x] x)) to substitute an explicit 1-arity function in the places where you're currently passing maps, you get the same errors -- demonstrating that the problem is not about maps' function-ness, but about the usage patterns themselves.

    – Charles Duffy
    Mar 22 at 15:22








2




2





If you use (apply #((fn [x] x) %) :b) or (apply #(:b %) (fn [x] x)) to substitute an explicit 1-arity function in the places where you're currently passing maps, you get the same errors -- demonstrating that the problem is not about maps' function-ness, but about the usage patterns themselves.

– Charles Duffy
Mar 22 at 15:22






If you use (apply #((fn [x] x) %) :b) or (apply #(:b %) (fn [x] x)) to substitute an explicit 1-arity function in the places where you're currently passing maps, you get the same errors -- demonstrating that the problem is not about maps' function-ness, but about the usage patterns themselves.

– Charles Duffy
Mar 22 at 15:22













3 Answers
3






active

oldest

votes


















9














Maps are functions of keys, as in your first two examples. Maps implement IFn interface just like "regular" Clojure functions.



The reason apply doesn't work in your examples is due to the "sequence" arguments being passed in the second position.



(apply #(:b %) :a 1 :b 2 :c 3)


In that example, the map argument is being turned into a sequence of key/value vectors/tuples, so they can be applied to #(:b %) (which wouldn't work anyway because that anonymous function only takes one argument). This is how the map would look as it's being turned into a sequence and applied as arguments to the function:



user=> (seq :a 1 :b 2 :c 3)
([:a 1] [:b 2] [:c 3])


This second example doesn't work because :b is not a sequence — it's a single keyword. This works though:



user=> (apply :a 1 :b 2 :c 3 [:b])
2


Note that calling a map-as-function with apply and a sequence of keywords doesn't really make practical sense though.






share|improve this answer






























    7














    A mathematical function is a set of ordered pairs such that there are no distinct pairs with the same first element. A mathematical function so defined takes only one argument.



    Clojure maps are self-evidently mathematical functions, since the there are no distinct key-value pairs with the same key. Moreover, Clojure maps have a finite domain (set of keys) and range/co-domain (set of values).



    As @TaylorWood has stated, Clojure maps are Clojure functions because they implement clojure.lang.IFn. They do so as operators yielding the value for a given key, so consistent with their interpretation as mathematical functions.



    Your apply syntax is wrong. You can write



    user=> (apply :a 1, :b 2 [:a])
    1


    or



    user=> (apply :a 1, :b 2 :a []) 
    1


    You can supply some of the arguments for the function (the first argument to apply) inline. The remainder comprise the sequence that is the last argument to apply. Since there is exactly one argument here, we can put it inline or alone in the terminal sequence.



    Similar considerations apply to the use of keywords as arguments.




    Reply to @AlanThompson's comments



    1. I've listened to and read Rich's talk that the question refers to. My definition of a function agrees with his.


    2. My statement that "A mathematical function so defined takes only one argument" is self evidently correct.


    3. You could contend that my definition isn't the conventional one. But even that is false. If you read the Multivariate_function part of the Wikipedia article we both refer to, you will find



    More formally, a function of n variables is a function whose domain is
    a set of n-tuples



    ...



    When using function notation, one usually omits the parentheses
    surrounding tuples, writing f(x1 , x2) instead of f((x1 , x 2)).




    In other words, the idea that a (mathematical) function takes several arguments is a harmless informality that allows simpler notation.



    Where does that leave programming languages? Most of them have functions of any arity: in Clojure's case, any finite set of arities, including an infinite one.



    The simplest way to regard Clojure functions is that they take an inline sequence of arguments, perhaps an empty one. It would be possible to formulate mathematical functions in this way: mappings from sequences of things to things. But it just isn't done.






    share|improve this answer

























    • Many functions in math take more than 1 arg: z=2x+3y being a simple example.

      – Alan Thompson
      Mar 22 at 17:27











    • @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

      – Nathan Davis
      Mar 22 at 19:29











    • It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

      – Alan Thompson
      Mar 22 at 20:24












    • @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

      – amalloy
      Mar 23 at 0:32











    • I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

      – Alan Thompson
      Mar 23 at 3:28



















    4














    I'm not sure what the practical goal of this question is, but it is interesting from an academic point of view.



    The keyword "function" :b in the following is a function of 1 argument:



    (:b :a 1 :b 2) => 2


    It is like this function:



    (defn get-b [m] (get m :b)) ; takes a single map arg

    (get-b :a 3 :b 33) ; only 1 arg, so no problem
    => 33


    The special form apply re-writes the function call from having a single collection argument to having multiple, individual args. Comparing before & after we get:



    (apply some-fn [1 2 3] ) ; using apply
    (some-fn 1 2 3 ) ; without apply (note missing square brackets!)


    So, apply allows you to "spread" args from a collection as if you had typed them as separate, individual args in the function call. If your collection has only 1 element, using apply has little effect:



    (apply :b [:a 3 :b 33] ) ; a collection of 1 element
    (:b :a 3 :b 33 ) ; only 1 arg, so no problem


    Because the function :b takes only 1 arg, the following won't work:



    (apply #(:b %) [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args


    However, you can invoke the 1-arg function :b multiple times using map or mapv:



    (mapv :b [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args

    => [11 22 33]


    The same rules hold for the inverse case. A map like :a 1 :b 2 is a function of 1 argument, so it can't be invoked with 3 args:



    (apply :a 1, :b 2, :c 3 [:c :b :a]) ; 3 args to single-arg fn, so fails


    but this works fine:



    (mapv :a 1, :b 2, :c 3 [:c :b :a]) => [3 2 1]





    share|improve this answer

























    • apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

      – Taylor Wood
      Mar 23 at 12:39











    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%2f55301184%2fin-what-way-are-clojure-maps-functions%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    9














    Maps are functions of keys, as in your first two examples. Maps implement IFn interface just like "regular" Clojure functions.



    The reason apply doesn't work in your examples is due to the "sequence" arguments being passed in the second position.



    (apply #(:b %) :a 1 :b 2 :c 3)


    In that example, the map argument is being turned into a sequence of key/value vectors/tuples, so they can be applied to #(:b %) (which wouldn't work anyway because that anonymous function only takes one argument). This is how the map would look as it's being turned into a sequence and applied as arguments to the function:



    user=> (seq :a 1 :b 2 :c 3)
    ([:a 1] [:b 2] [:c 3])


    This second example doesn't work because :b is not a sequence — it's a single keyword. This works though:



    user=> (apply :a 1 :b 2 :c 3 [:b])
    2


    Note that calling a map-as-function with apply and a sequence of keywords doesn't really make practical sense though.






    share|improve this answer



























      9














      Maps are functions of keys, as in your first two examples. Maps implement IFn interface just like "regular" Clojure functions.



      The reason apply doesn't work in your examples is due to the "sequence" arguments being passed in the second position.



      (apply #(:b %) :a 1 :b 2 :c 3)


      In that example, the map argument is being turned into a sequence of key/value vectors/tuples, so they can be applied to #(:b %) (which wouldn't work anyway because that anonymous function only takes one argument). This is how the map would look as it's being turned into a sequence and applied as arguments to the function:



      user=> (seq :a 1 :b 2 :c 3)
      ([:a 1] [:b 2] [:c 3])


      This second example doesn't work because :b is not a sequence — it's a single keyword. This works though:



      user=> (apply :a 1 :b 2 :c 3 [:b])
      2


      Note that calling a map-as-function with apply and a sequence of keywords doesn't really make practical sense though.






      share|improve this answer

























        9












        9








        9







        Maps are functions of keys, as in your first two examples. Maps implement IFn interface just like "regular" Clojure functions.



        The reason apply doesn't work in your examples is due to the "sequence" arguments being passed in the second position.



        (apply #(:b %) :a 1 :b 2 :c 3)


        In that example, the map argument is being turned into a sequence of key/value vectors/tuples, so they can be applied to #(:b %) (which wouldn't work anyway because that anonymous function only takes one argument). This is how the map would look as it's being turned into a sequence and applied as arguments to the function:



        user=> (seq :a 1 :b 2 :c 3)
        ([:a 1] [:b 2] [:c 3])


        This second example doesn't work because :b is not a sequence — it's a single keyword. This works though:



        user=> (apply :a 1 :b 2 :c 3 [:b])
        2


        Note that calling a map-as-function with apply and a sequence of keywords doesn't really make practical sense though.






        share|improve this answer













        Maps are functions of keys, as in your first two examples. Maps implement IFn interface just like "regular" Clojure functions.



        The reason apply doesn't work in your examples is due to the "sequence" arguments being passed in the second position.



        (apply #(:b %) :a 1 :b 2 :c 3)


        In that example, the map argument is being turned into a sequence of key/value vectors/tuples, so they can be applied to #(:b %) (which wouldn't work anyway because that anonymous function only takes one argument). This is how the map would look as it's being turned into a sequence and applied as arguments to the function:



        user=> (seq :a 1 :b 2 :c 3)
        ([:a 1] [:b 2] [:c 3])


        This second example doesn't work because :b is not a sequence — it's a single keyword. This works though:



        user=> (apply :a 1 :b 2 :c 3 [:b])
        2


        Note that calling a map-as-function with apply and a sequence of keywords doesn't really make practical sense though.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 22 at 14:24









        Taylor WoodTaylor Wood

        12.1k1825




        12.1k1825























            7














            A mathematical function is a set of ordered pairs such that there are no distinct pairs with the same first element. A mathematical function so defined takes only one argument.



            Clojure maps are self-evidently mathematical functions, since the there are no distinct key-value pairs with the same key. Moreover, Clojure maps have a finite domain (set of keys) and range/co-domain (set of values).



            As @TaylorWood has stated, Clojure maps are Clojure functions because they implement clojure.lang.IFn. They do so as operators yielding the value for a given key, so consistent with their interpretation as mathematical functions.



            Your apply syntax is wrong. You can write



            user=> (apply :a 1, :b 2 [:a])
            1


            or



            user=> (apply :a 1, :b 2 :a []) 
            1


            You can supply some of the arguments for the function (the first argument to apply) inline. The remainder comprise the sequence that is the last argument to apply. Since there is exactly one argument here, we can put it inline or alone in the terminal sequence.



            Similar considerations apply to the use of keywords as arguments.




            Reply to @AlanThompson's comments



            1. I've listened to and read Rich's talk that the question refers to. My definition of a function agrees with his.


            2. My statement that "A mathematical function so defined takes only one argument" is self evidently correct.


            3. You could contend that my definition isn't the conventional one. But even that is false. If you read the Multivariate_function part of the Wikipedia article we both refer to, you will find



            More formally, a function of n variables is a function whose domain is
            a set of n-tuples



            ...



            When using function notation, one usually omits the parentheses
            surrounding tuples, writing f(x1 , x2) instead of f((x1 , x 2)).




            In other words, the idea that a (mathematical) function takes several arguments is a harmless informality that allows simpler notation.



            Where does that leave programming languages? Most of them have functions of any arity: in Clojure's case, any finite set of arities, including an infinite one.



            The simplest way to regard Clojure functions is that they take an inline sequence of arguments, perhaps an empty one. It would be possible to formulate mathematical functions in this way: mappings from sequences of things to things. But it just isn't done.






            share|improve this answer

























            • Many functions in math take more than 1 arg: z=2x+3y being a simple example.

              – Alan Thompson
              Mar 22 at 17:27











            • @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

              – Nathan Davis
              Mar 22 at 19:29











            • It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

              – Alan Thompson
              Mar 22 at 20:24












            • @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

              – amalloy
              Mar 23 at 0:32











            • I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

              – Alan Thompson
              Mar 23 at 3:28
















            7














            A mathematical function is a set of ordered pairs such that there are no distinct pairs with the same first element. A mathematical function so defined takes only one argument.



            Clojure maps are self-evidently mathematical functions, since the there are no distinct key-value pairs with the same key. Moreover, Clojure maps have a finite domain (set of keys) and range/co-domain (set of values).



            As @TaylorWood has stated, Clojure maps are Clojure functions because they implement clojure.lang.IFn. They do so as operators yielding the value for a given key, so consistent with their interpretation as mathematical functions.



            Your apply syntax is wrong. You can write



            user=> (apply :a 1, :b 2 [:a])
            1


            or



            user=> (apply :a 1, :b 2 :a []) 
            1


            You can supply some of the arguments for the function (the first argument to apply) inline. The remainder comprise the sequence that is the last argument to apply. Since there is exactly one argument here, we can put it inline or alone in the terminal sequence.



            Similar considerations apply to the use of keywords as arguments.




            Reply to @AlanThompson's comments



            1. I've listened to and read Rich's talk that the question refers to. My definition of a function agrees with his.


            2. My statement that "A mathematical function so defined takes only one argument" is self evidently correct.


            3. You could contend that my definition isn't the conventional one. But even that is false. If you read the Multivariate_function part of the Wikipedia article we both refer to, you will find



            More formally, a function of n variables is a function whose domain is
            a set of n-tuples



            ...



            When using function notation, one usually omits the parentheses
            surrounding tuples, writing f(x1 , x2) instead of f((x1 , x 2)).




            In other words, the idea that a (mathematical) function takes several arguments is a harmless informality that allows simpler notation.



            Where does that leave programming languages? Most of them have functions of any arity: in Clojure's case, any finite set of arities, including an infinite one.



            The simplest way to regard Clojure functions is that they take an inline sequence of arguments, perhaps an empty one. It would be possible to formulate mathematical functions in this way: mappings from sequences of things to things. But it just isn't done.






            share|improve this answer

























            • Many functions in math take more than 1 arg: z=2x+3y being a simple example.

              – Alan Thompson
              Mar 22 at 17:27











            • @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

              – Nathan Davis
              Mar 22 at 19:29











            • It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

              – Alan Thompson
              Mar 22 at 20:24












            • @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

              – amalloy
              Mar 23 at 0:32











            • I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

              – Alan Thompson
              Mar 23 at 3:28














            7












            7








            7







            A mathematical function is a set of ordered pairs such that there are no distinct pairs with the same first element. A mathematical function so defined takes only one argument.



            Clojure maps are self-evidently mathematical functions, since the there are no distinct key-value pairs with the same key. Moreover, Clojure maps have a finite domain (set of keys) and range/co-domain (set of values).



            As @TaylorWood has stated, Clojure maps are Clojure functions because they implement clojure.lang.IFn. They do so as operators yielding the value for a given key, so consistent with their interpretation as mathematical functions.



            Your apply syntax is wrong. You can write



            user=> (apply :a 1, :b 2 [:a])
            1


            or



            user=> (apply :a 1, :b 2 :a []) 
            1


            You can supply some of the arguments for the function (the first argument to apply) inline. The remainder comprise the sequence that is the last argument to apply. Since there is exactly one argument here, we can put it inline or alone in the terminal sequence.



            Similar considerations apply to the use of keywords as arguments.




            Reply to @AlanThompson's comments



            1. I've listened to and read Rich's talk that the question refers to. My definition of a function agrees with his.


            2. My statement that "A mathematical function so defined takes only one argument" is self evidently correct.


            3. You could contend that my definition isn't the conventional one. But even that is false. If you read the Multivariate_function part of the Wikipedia article we both refer to, you will find



            More formally, a function of n variables is a function whose domain is
            a set of n-tuples



            ...



            When using function notation, one usually omits the parentheses
            surrounding tuples, writing f(x1 , x2) instead of f((x1 , x 2)).




            In other words, the idea that a (mathematical) function takes several arguments is a harmless informality that allows simpler notation.



            Where does that leave programming languages? Most of them have functions of any arity: in Clojure's case, any finite set of arities, including an infinite one.



            The simplest way to regard Clojure functions is that they take an inline sequence of arguments, perhaps an empty one. It would be possible to formulate mathematical functions in this way: mappings from sequences of things to things. But it just isn't done.






            share|improve this answer















            A mathematical function is a set of ordered pairs such that there are no distinct pairs with the same first element. A mathematical function so defined takes only one argument.



            Clojure maps are self-evidently mathematical functions, since the there are no distinct key-value pairs with the same key. Moreover, Clojure maps have a finite domain (set of keys) and range/co-domain (set of values).



            As @TaylorWood has stated, Clojure maps are Clojure functions because they implement clojure.lang.IFn. They do so as operators yielding the value for a given key, so consistent with their interpretation as mathematical functions.



            Your apply syntax is wrong. You can write



            user=> (apply :a 1, :b 2 [:a])
            1


            or



            user=> (apply :a 1, :b 2 :a []) 
            1


            You can supply some of the arguments for the function (the first argument to apply) inline. The remainder comprise the sequence that is the last argument to apply. Since there is exactly one argument here, we can put it inline or alone in the terminal sequence.



            Similar considerations apply to the use of keywords as arguments.




            Reply to @AlanThompson's comments



            1. I've listened to and read Rich's talk that the question refers to. My definition of a function agrees with his.


            2. My statement that "A mathematical function so defined takes only one argument" is self evidently correct.


            3. You could contend that my definition isn't the conventional one. But even that is false. If you read the Multivariate_function part of the Wikipedia article we both refer to, you will find



            More formally, a function of n variables is a function whose domain is
            a set of n-tuples



            ...



            When using function notation, one usually omits the parentheses
            surrounding tuples, writing f(x1 , x2) instead of f((x1 , x 2)).




            In other words, the idea that a (mathematical) function takes several arguments is a harmless informality that allows simpler notation.



            Where does that leave programming languages? Most of them have functions of any arity: in Clojure's case, any finite set of arities, including an infinite one.



            The simplest way to regard Clojure functions is that they take an inline sequence of arguments, perhaps an empty one. It would be possible to formulate mathematical functions in this way: mappings from sequences of things to things. But it just isn't done.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 23 at 23:10

























            answered Mar 22 at 17:10









            ThumbnailThumbnail

            11.2k11628




            11.2k11628












            • Many functions in math take more than 1 arg: z=2x+3y being a simple example.

              – Alan Thompson
              Mar 22 at 17:27











            • @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

              – Nathan Davis
              Mar 22 at 19:29











            • It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

              – Alan Thompson
              Mar 22 at 20:24












            • @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

              – amalloy
              Mar 23 at 0:32











            • I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

              – Alan Thompson
              Mar 23 at 3:28


















            • Many functions in math take more than 1 arg: z=2x+3y being a simple example.

              – Alan Thompson
              Mar 22 at 17:27











            • @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

              – Nathan Davis
              Mar 22 at 19:29











            • It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

              – Alan Thompson
              Mar 22 at 20:24












            • @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

              – amalloy
              Mar 23 at 0:32











            • I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

              – Alan Thompson
              Mar 23 at 3:28

















            Many functions in math take more than 1 arg: z=2x+3y being a simple example.

            – Alan Thompson
            Mar 22 at 17:27





            Many functions in math take more than 1 arg: z=2x+3y being a simple example.

            – Alan Thompson
            Mar 22 at 17:27













            @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

            – Nathan Davis
            Mar 22 at 19:29





            @AlanThompson In that case, the first element in your order pair would simply be another ordered pair -- i.e., ((x,y), z)

            – Nathan Davis
            Mar 22 at 19:29













            It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

            – Alan Thompson
            Mar 22 at 20:24






            It is not that simple. 6 DOF models for aircraft, motorcycles, etc measure both position & rotation (x2) in 3D (x3), and may include derivatives 0, 1 and 2 (x3). That makes 18 input arguments to a function!

            – Alan Thompson
            Mar 22 at 20:24














            @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

            – amalloy
            Mar 23 at 0:32





            @AlanThompson That is quite simple, mathematically. The function is a set of ordered pairs whose first element are 18-tuples. Unpleasant and offensive to you as a programmer, but nothing wrong with it in theory. All functions, of any number of arguments, can be viewed in this way.

            – amalloy
            Mar 23 at 0:32













            I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

            – Alan Thompson
            Mar 23 at 3:28






            I am simply trying to refute the incorrect statement, "A mathematical function so defined takes only one argument". This will mislead people. A generalized function takes N inputs and produces M outputs: en.wikipedia.org/wiki/Function_(mathematics)#Arrow_notation.

            – Alan Thompson
            Mar 23 at 3:28












            4














            I'm not sure what the practical goal of this question is, but it is interesting from an academic point of view.



            The keyword "function" :b in the following is a function of 1 argument:



            (:b :a 1 :b 2) => 2


            It is like this function:



            (defn get-b [m] (get m :b)) ; takes a single map arg

            (get-b :a 3 :b 33) ; only 1 arg, so no problem
            => 33


            The special form apply re-writes the function call from having a single collection argument to having multiple, individual args. Comparing before & after we get:



            (apply some-fn [1 2 3] ) ; using apply
            (some-fn 1 2 3 ) ; without apply (note missing square brackets!)


            So, apply allows you to "spread" args from a collection as if you had typed them as separate, individual args in the function call. If your collection has only 1 element, using apply has little effect:



            (apply :b [:a 3 :b 33] ) ; a collection of 1 element
            (:b :a 3 :b 33 ) ; only 1 arg, so no problem


            Because the function :b takes only 1 arg, the following won't work:



            (apply #(:b %) [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args


            However, you can invoke the 1-arg function :b multiple times using map or mapv:



            (mapv :b [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args

            => [11 22 33]


            The same rules hold for the inverse case. A map like :a 1 :b 2 is a function of 1 argument, so it can't be invoked with 3 args:



            (apply :a 1, :b 2, :c 3 [:c :b :a]) ; 3 args to single-arg fn, so fails


            but this works fine:



            (mapv :a 1, :b 2, :c 3 [:c :b :a]) => [3 2 1]





            share|improve this answer

























            • apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

              – Taylor Wood
              Mar 23 at 12:39















            4














            I'm not sure what the practical goal of this question is, but it is interesting from an academic point of view.



            The keyword "function" :b in the following is a function of 1 argument:



            (:b :a 1 :b 2) => 2


            It is like this function:



            (defn get-b [m] (get m :b)) ; takes a single map arg

            (get-b :a 3 :b 33) ; only 1 arg, so no problem
            => 33


            The special form apply re-writes the function call from having a single collection argument to having multiple, individual args. Comparing before & after we get:



            (apply some-fn [1 2 3] ) ; using apply
            (some-fn 1 2 3 ) ; without apply (note missing square brackets!)


            So, apply allows you to "spread" args from a collection as if you had typed them as separate, individual args in the function call. If your collection has only 1 element, using apply has little effect:



            (apply :b [:a 3 :b 33] ) ; a collection of 1 element
            (:b :a 3 :b 33 ) ; only 1 arg, so no problem


            Because the function :b takes only 1 arg, the following won't work:



            (apply #(:b %) [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args


            However, you can invoke the 1-arg function :b multiple times using map or mapv:



            (mapv :b [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args

            => [11 22 33]


            The same rules hold for the inverse case. A map like :a 1 :b 2 is a function of 1 argument, so it can't be invoked with 3 args:



            (apply :a 1, :b 2, :c 3 [:c :b :a]) ; 3 args to single-arg fn, so fails


            but this works fine:



            (mapv :a 1, :b 2, :c 3 [:c :b :a]) => [3 2 1]





            share|improve this answer

























            • apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

              – Taylor Wood
              Mar 23 at 12:39













            4












            4








            4







            I'm not sure what the practical goal of this question is, but it is interesting from an academic point of view.



            The keyword "function" :b in the following is a function of 1 argument:



            (:b :a 1 :b 2) => 2


            It is like this function:



            (defn get-b [m] (get m :b)) ; takes a single map arg

            (get-b :a 3 :b 33) ; only 1 arg, so no problem
            => 33


            The special form apply re-writes the function call from having a single collection argument to having multiple, individual args. Comparing before & after we get:



            (apply some-fn [1 2 3] ) ; using apply
            (some-fn 1 2 3 ) ; without apply (note missing square brackets!)


            So, apply allows you to "spread" args from a collection as if you had typed them as separate, individual args in the function call. If your collection has only 1 element, using apply has little effect:



            (apply :b [:a 3 :b 33] ) ; a collection of 1 element
            (:b :a 3 :b 33 ) ; only 1 arg, so no problem


            Because the function :b takes only 1 arg, the following won't work:



            (apply #(:b %) [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args


            However, you can invoke the 1-arg function :b multiple times using map or mapv:



            (mapv :b [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args

            => [11 22 33]


            The same rules hold for the inverse case. A map like :a 1 :b 2 is a function of 1 argument, so it can't be invoked with 3 args:



            (apply :a 1, :b 2, :c 3 [:c :b :a]) ; 3 args to single-arg fn, so fails


            but this works fine:



            (mapv :a 1, :b 2, :c 3 [:c :b :a]) => [3 2 1]





            share|improve this answer















            I'm not sure what the practical goal of this question is, but it is interesting from an academic point of view.



            The keyword "function" :b in the following is a function of 1 argument:



            (:b :a 1 :b 2) => 2


            It is like this function:



            (defn get-b [m] (get m :b)) ; takes a single map arg

            (get-b :a 3 :b 33) ; only 1 arg, so no problem
            => 33


            The special form apply re-writes the function call from having a single collection argument to having multiple, individual args. Comparing before & after we get:



            (apply some-fn [1 2 3] ) ; using apply
            (some-fn 1 2 3 ) ; without apply (note missing square brackets!)


            So, apply allows you to "spread" args from a collection as if you had typed them as separate, individual args in the function call. If your collection has only 1 element, using apply has little effect:



            (apply :b [:a 3 :b 33] ) ; a collection of 1 element
            (:b :a 3 :b 33 ) ; only 1 arg, so no problem


            Because the function :b takes only 1 arg, the following won't work:



            (apply #(:b %) [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args


            However, you can invoke the 1-arg function :b multiple times using map or mapv:



            (mapv :b [:a 1 :b 11 :a 2 :b 22 :a 3 :b 33]) ; takes only 1 arg, not 3 args

            => [11 22 33]


            The same rules hold for the inverse case. A map like :a 1 :b 2 is a function of 1 argument, so it can't be invoked with 3 args:



            (apply :a 1, :b 2, :c 3 [:c :b :a]) ; 3 args to single-arg fn, so fails


            but this works fine:



            (mapv :a 1, :b 2, :c 3 [:c :b :a]) => [3 2 1]






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Mar 22 at 18:14

























            answered Mar 22 at 15:12









            Alan ThompsonAlan Thompson

            14.7k22535




            14.7k22535












            • apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

              – Taylor Wood
              Mar 23 at 12:39

















            • apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

              – Taylor Wood
              Mar 23 at 12:39
















            apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

            – Taylor Wood
            Mar 23 at 12:39





            apply isn't a true special form, and maps aren't only unary functions; they can take a second arg for default value: (:foo 1 :bar 2) => 2

            – Taylor Wood
            Mar 23 at 12:39

















            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%2f55301184%2fin-what-way-are-clojure-maps-functions%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

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript