[Cs254f11] Several questions

Thomas Helmuth thGST at hampshire.edu
Tue Oct 4 08:23:47 EDT 2011


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> 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, http://hampshire.edu/lspector/
> Phone: 413-559-5352, Fax: 413-559-5438
>
> _______________________________________________
> Cs254f11 mailing list
> Cs254f11 at lists.hampshire.edu
> https://lists.hampshire.edu/mailman/listinfo/cs254f11
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.hampshire.edu/mailman/private/cs254f11/attachments/20111004/2b0cc537/attachment-0001.htm>


More information about the Cs254f11 mailing list