[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