[Cs254f11] bring your programming questions

Lee Spector lspector at hampshire.edu
Tue Oct 4 22:32:24 EDT 2011


Josiah,

One approach *would* be to make the second collection repeat the value as many times as necessary, but to create all of the repetitions on the fly with the "repeat" function, as in:

(def my-list '(2 4 6 8 17 23))

(def my-2nd-arg 10)

(map + my-list (repeat my-2nd-arg))

; (12 14 16 18 27 33)

That repeat expression actually produces an infinite lazy sequence, so don't type it all by itself at the REPL! If you do then the printer will keep forcing more repetitions and you'll have to kill it. But map will stop forcing repetitions as soon as it runs out of my-list, so it's okay here. If you don't want an infinite lazy sequence for some reason then you can give repeat a number before the thing that it repeats and it'll only produce a sequence that long, as in:

(repeat 5 99)

; (99 99 99 99 99)

In your example you could do this:

(map + my-list (repeat (length my-list) my-2nd-arg))

so that you're generating exactly the right number of args no matter how big my-list is... but just making it lazy and infinite is simpler and I don't see a downside to it.

Now suppose that you really don't want to create that second sequence. There are a variety of approaches you might take. The one I'd probably take, maybe more out of habit than anything else, is to build the second argument into the function that I'm mapping, as you're doing but not liking, but I'd do it in an anonymous function that I create on the fly when I want to do the mapping, as in:

(map #(+ % my-2nd-arg) my-list)

; (12 14 16 18 27 33)

Or if you don't like the abbreviated syntax for anonymous functions then you could do:

(map (fn [n] (+ n my-2nd-arg)) my-list)

; (12 14 16 18 27 33)

Yet another approach that's quite elegant in this case is to use the "partial" function:

(doc partial)
-------------------------
clojure.core/partial
([f arg1] [f arg1 arg2] [f arg1 arg2 arg3] [f arg1 arg2 arg3 & more])
  Takes a function f and fewer than the normal arguments to f, and
  returns a fn that takes a variable number of additional args. When
  called, the returned function calls f with args + additional args.

That could be used as:

(map (partial + my-2nd-arg) my-list)

; (12 14 16 18 27 33)

 -Lee


On Oct 4, 2011, at 8:38 PM, Wm. Josiah Erikson wrote:

> I have a question ahead of time that might be helpful for others as well. Or it could be just silly.
> 
> I now have working code that generates and evaluates stuff. Yay! But I'm not happy with the style of some of the coding, so I'd like to improve it.
> 
> First, I want to be able to take a function, func_a ([arg a] [arg b]) , and call it as many times as there are elements in col_a, with two arguments (because func_a takes two arguments) of each of col_a's elements and also the same second argument each time.
> 
> So like map, except with a second argument that stays the same each time. I could just make a collection of the same element that is as long as col_a, I suppose, but that seems silly. Is there a better way?
> 
> (defn func_a
>   "This function does nothing useful really"
>   [arg_a arg_b]
>   (+ arg_a arg_b))
> 
> (def col_a '(12 24 15 39 12 56))
> 
> (def argument_b 3)
> 
> (map func_a col_a argument_b)
> 
> Obviously, that will only call func_a once, since argument_b is a collection that is only 1 long.  But I'd like it to call it 6 times, each time with the same second argument, argument_b. Make sense?
> 
> Right now, I'm getting around this by having func_a just refer directly to the data it needs for the second argument instead of actually having a second argument, and just doing:
> 
> (map func_a col_a)
> 
> But I don't like that. I could also do something like
> 
>   -Josiah
> 
> 
> 
> Lee Spector wrote:
>> I think that the best use for the post show&tell time tomorrow will be for me to do live programming in response to questions/problems/etc that have come up in your work. So think of things between now and then that have been roadblocks for you, or that you can't imagine how to start doing, or just things you don't get, etc., and we'll try to cover as much of that as possible.
>> 
>> Remember that the general schedule is that there's show&tell on what you've been up to so far tomorrow (Oct 5) and then there's a week-long gap because of October break. On the Wed that we return (Oct 12) there will again be show&tell and that one should focus on a fairly well-thought-out description of what you intend to do for your final project. By the end of class on Oct 12 I want each of you to have received detailed comments (from me and each other) on your project idea and to be ready to work on it full steam ahead. Once we enter that phase of the course I will mix in lectures on specific issues, approaches, and advanced techniques in GP. 
>> -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
>>  
> 
> -- 
> -----
> Wm. Josiah Erikson
> Network Engineer
> Hampshire College
> Amherst, MA 01002
> 
> _______________________________________________
> Cs254f11 mailing list
> Cs254f11 at lists.hampshire.edu
> https://lists.hampshire.edu/mailman/listinfo/cs254f11

--
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



More information about the Cs254f11 mailing list