[Cs254f11] Several questions

Wm. Josiah Erikson wjerikson at hampshire.edu
Tue Oct 4 10:55:25 EDT 2011


Alrighty, so this is awesome, and makes sense, and is fine, but I can 
move on with my life and just write this darn thing, thanks!

However, in the future, I would think that I would want to take input 
from the user, and say "What key do you want your song to be in?" and a 
user would enter "C", not ":C". Is there no way to look up a value in a 
map with its key without telling clojure it's a key by prepending it 
with ":" ?

I can get down with having to define the value of a variable by quoting 
it... I guess. No other language that I've worked with requires you to 
do that, but whatever. By I really can't look up something in a map 
without prepending it with a ":" ? Is there no way to do:

(def song_key 'C)

and then look it up in a map? I have to:

(def song_key :C)
(get musical-keys song_key)

and why does this appear do the same thing:

(def song_key ':C)

I'd think there would be some way for me to stick the ":" in while I'm 
looking it up, but the obvious ways don't seem to work:

josiah.sandbox=>
(get musical-keys :song_key)
nil

josiah.sandbox=>
(get musical-keys ':song_key)
nil

I clearly still don't get it :) Thanks for your patience.

     -Josiah



On 10/4/11 8:23 AM, Thomas Helmuth wrote:
> To finish your question where Lee left off, I think you really want 
> one of the following:
>
> (if (= (get musical-keys song_key)
>        (first my_song))
>     0.8
>     0)
>
> or
>
> (modified_truth (= (get musical-keys song_key)
>                    (first my_song))
>                 0.8)
>
> To start, I've replaced "(:song_key musical-keys)" with Lee's 
> recommendation of "(get musical-keys song_key)". The first of these 
> simply checks if the things are equal, and if so, returns 0.8, and if 
> not, returns 0. The second uses modified_truth, passing it the truth 
> value of whether those things are equal and the value of 0.8. Both of 
> these should do the same thing, given your definition of 
> modified_truth. This shows that modified_truth is basically a modified 
> (if ...) function that always returns 0 in the false case. Either 
> option is fine, though the first seems more transparent to me.
>
> -Tom
>
> On Mon, Oct 3, 2011 at 8:48 PM, Lee Spector <lspector at hampshire.edu 
> <mailto:lspector at hampshire.edu>> wrote:
>
>
>     On Oct 3, 2011, at 6:20 PM, Wm. Josiah Erikson wrote:
>     > Then I am writing a function definition that gets passed a
>     musical key, like "C" for instance, and I want to map it to the
>     corresponding number, but I don't know how to use a string that
>     contains the value of a key in a key-value pair and use it to get
>     the value out of a map. I know how to do this:
>     >
>     > (:C musical-keys)
>     >
>     > But I want to be able to do something like this, assuming that
>     my_song is a list of integers:
>     > (def song_key D)
>     >
>     > (modified_truth (if (= (:song_key musical-keys) (first my_song))
>     0.8)
>     >
>     > Does this make any sense?
>     >
>     > Thanks in advance,
>
>
>     I think I should try to unwind a couple of different things here,
>     although the bottom line is a lot simpler than all of the stuff
>     I'll explain first. That is, you can do what you want without this
>     preamble, and I'll show you how, but for completeness I'm going to
>     explain a few things.
>
>     One important point is that neither C nor :C is a string. C is a
>     symbol and :C is a keyword. Those are different data types, and
>     neither is a string. Both have names, which ARE strings, and these
>     can be obtained using the "name" function:
>
>     (name 'C)
>
>     ; "C"
>
>     (name :C)
>
>     ; "C"
>
>     Note that I have to quote the symbol in the first example because
>     otherwise it would try to evaluate it, and unless I had done
>     something like (def C ...) it'd yell at me. And if I HAD done (def
>     C ...) then (name C) would evaluate C and give me the result of
>     calling name on the value that was given to C in its definition.
>     You don't need to quote the :C in the second example because
>     keywords (like numbers) evaluate to themselves.
>
>     Here's part of the descriptions of keywords and symbols from
>     http://clojure.org/data_structures:
>
>     ---
>     Keywords
>     Keywords are symbolic identifiers that evaluate to themselves.
>     They provide very fast equality tests. Like Symbols, they have
>     names and optional namespaces, both of which are strings. The
>     leading ':' is not part of the namespace or name.
>     ---
>     Symbols
>     Symbols are identifiers that are normally used to refer to
>     something else. They can be used in program forms to refer to
>     function parameters, let bindings, class names and global vars.
>     They have names and optional namespaces, both of which are
>     strings. Symbols can have metadata (see with-meta).
>     ---
>
>     If you look on that page you'll see a little more documentation,
>     including the reason that both keywords and symbols can be used as
>     functions to "look themselves up in" maps.
>
>     Back to your code:
>
>     The line in your code defining song_key is (def song_key D).
>
>     That will try evaluate D, which I presume is not what you want.
>     You could do (def song_key 'D) to put the symbol D in song_key, or
>     (def song_key :D) to use a keyword. The latter is probably better
>     since you're using keywords in your musical-keys map.
>
>     Now let's look at (modified_truth (if (= (:song_key musical-keys)
>     (first my_song)) 0.8).
>
>     First I'm going to break it across lines and auto-format it:
>
>     (modified_truth (if (= (:song_key musical-keys)
>                         (first my_song))
>                    0.8)
>
>     Here (when I view it in clooj, or at least something with a
>     monospaced font) I can see that "if" is being given two arguments
>     -- the expression starting with -, and then 0.8. But it should
>     take three: the condition, the thing to do/return if the condition
>     is true, and the thing to do/return if the condition is false. It
>     looks like you want the "if" to return 0.8 if the condition is
>     true... but you should follow that with whatever you want it to
>     return if it's false.
>
>     I think you intend your condition to ask "Is the number of the
>     song's key equal to the first number in my_song?" You've expressed
>     the second part correctly -- (first my_song) -- but your lookup in
>     the map in the first part isn't right. Assuming that you did (def
>     song_key :D) then the var song_key contains the keyword :D, and
>     that's what you want to look up in the map. To do this -- to get
>     the value out of a var and then look that up in the map -- you
>     really want to use "get", as in:
>
>     (get musical-keys song_key)
>
>     ; 2
>
>     I'm not sure what you intend with the surrounding call to
>     modified_truth, so I'll stop there.
>
>     Bottom lines:
>
>     - Use keywords, which always start with ":", for names that don't
>     name values, but just themselves. You can use symbols for these
>     kinds of things too, but keywords are handier because they don't
>     have to be quoted.
>
>     - Use "get" to look computed things up in maps. The (:keyword map)
>     shortcut works if you are looking up a keyword that you are
>     hard-coding into your code -- and you can even do (map :keyword)
>     if you like it better for some reason --  but "get" is often more
>     clear and the better choice if the thing you're looking up is
>     computed.
>
>     -Lee
>
>     --
>     Lee Spector, Professor of Computer Science
>     Cognitive Science, Hampshire College
>     893 West Street, Amherst, MA 01002-3359
>     lspector at hampshire.edu <mailto:lspector at hampshire.edu>,
>     http://hampshire.edu/lspector/
>     Phone: 413-559-5352 <tel:413-559-5352>, Fax: 413-559-5438
>     <tel:413-559-5438>
>
>     _______________________________________________
>     Cs254f11 mailing list
>     Cs254f11 at lists.hampshire.edu <mailto:Cs254f11 at lists.hampshire.edu>
>     https://lists.hampshire.edu/mailman/listinfo/cs254f11
>
>
>
>
> _______________________________________________
> Cs254f11 mailing list
> Cs254f11 at lists.hampshire.edu
> https://lists.hampshire.edu/mailman/listinfo/cs254f11

-- 
Wm. Josiah Erikson
Network Engineer
Hampshire College
Amherst, MA 01002
(413) 559-6091

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.hampshire.edu/mailman/private/cs254f11/attachments/20111004/6e63ca20/attachment-0001.htm>


More information about the Cs254f11 mailing list