[Cs254f11] Two Questions on sets and lazy infinite functions

Lee Spector lspector at hampshire.edu
Sun Oct 2 17:52:47 EDT 2011


To illustrate Omri's first point:

(some #{\3} (str 12345))

; \3

If you are using the "member?" function that I wrote in clojinc then you want to pass it \3, rather than 3 or #{\3} or anything else. The "member?" function takes an item and a list (or actually any collection) and returns true if the list contains the item (or false otherwise). It works by calling "some", with the first argument to "some" being a set containing the provided item (so you don't want to pass "member?" a set in your case, because the item that you pass will be put into a set before being passed to "some". I wrote "member?" because although it's less general than the call to "some" I find it easier to remember (maybe because it's built in to most other Lisps) and it doesn't require you to use the set notation...

In any event, with p defined as the list of primes, as you did in your gist, you can do:

(filter #(member? \3 (set (str % ))) p)

and it gives you all of the primes containing a 3 in their decimal representation.

Or if you don't want to use my "member?" function then you can do:

(filter #(some #{\3} (set (str % ))) p)

One point on which I'll differ with Omri: DO NOT USE contains? FOR THIS! That function is really badly named. It should be called something like "contains-key" and it only does what you'd expect on maps. For example, this is fine:

(contains? {:foo 3 :bar 5} :bar)

; true

But this is annoying:

(contains? [:foo 3 :bar 5] :bar)

; false

And this too:

(contains? '(:foo 3 :bar 5) :bar)

; false

I think that "contains?" should be stricken from the language. What it does can easily be done in other ways, and everyone will think it does what Omri thought it does. But it doesn't.

On wanting something like "repeatedly" but with a function that takes an argument: The question is, where do you want the arguments to come from? If you want your function to take one argument and for it to be given, on each call, the value returned by the last call, then Omri's suggestion of "iterate" is exactly right:

(take 5 (iterate inc 0))

; (0 1 2 3 4)

Note that there's an infinite lazy sequence in there; we're only taking and then printing the first 5 items.

But if you want the arguments to come from a list or an infinite lazy sequence then you can use (map f s), where f is your function and s is your sequence. That returns a lazy sequence of the results of calling f on each item in s.

 -Lee



On Oct 2, 2011, at 5:15 PM, Lee Spector wrote:

> 
> This is an answer from Omri, but:
> 
> - Omri: it was held because you posted from a different address that the one you're subscribed with... 
> 
> - Josiah: can you give me (off list!) the list admin password, so that I can approve such postings in the future?
> 
> 
> Begin forwarded message:
>> From: Omri Bernstein <hippiccolo at gmail.com>
>> Subject: Re: [Cs254f11] Two Questions on sets and lazy infinite functions
>> Date: October 2, 2011 4:48:11 PM EDT
>> To: "cs254f11 at lists.hampshire.edu" <cs254f11 at lists.hampshire.edu>
>> 
>> 
>> I'm going to start with the second question because I'm not sure I understand the first one. As for finding whether something is in a given set you can use either (some #{\3} given-set) or (contains? #{\3} given-set). If \3 is in the given set, the first one (some ...) will return \3 (i.e. the value it finds). If it is not in the set, this first method will return nil. The second option will return true or false. I think for the sake of speed, Lee was suggesting we use the first option (some ...).
>> 
>> However if you are looking for a set within a set--like if you were looking to test whether the set #{\3} was in a given set, the syntax might need to be (some #{#{\3}} given-set) or (contains? #{#{\3}} given-set). Don't quote me on that though, because I haven't tried it.
>> 
>> As for your first question, I'll try to answer it, but I may not understand. For one thing, if you want an infinite lazy sequence of the natural numbers you can do (iterate inc 1). Iterate works like this: (iterate f x) returns an infinite lazy sequence of (x (f x) (f (f x)) ...). So maybe that answers your question about an infinite lazy repeat of a function that requires arguments.
>> 
>> Hope that helps.
>> 
>> -Omri
>> 
>> 
>> On Oct 2, 2011, at 14:21, Jack Laxson <jrl11 at hampshire.edu> wrote:
>> 
>>> 
>>> 
>>> ---------- Forwarded message ----------
>>> From: Jack L. <jackjrabbit at gmail.com>
>>> Date: Sun, Oct 2, 2011 at 2:20 PM
>>> Subject: Two Questions on sets and lazy infinite functions
>>> To: cs254f11 <cs254f11 at lists.hampshire.edu>
>>> 
>>> 
>>> Infinite lazy repeat of a function that requires arguments: repeatedly lets you do it with one without arguments, I'd want to step over prime? with a (range 1 [assumed infinity]). If thats the wrong way to do it maybe I'm missing a better style. 
>>> >> https://gist.github.com/1257722
>>> 
>>> Second issue is with trying to test if #{\3} is in a set.
>>> 
>>> >> https://gist.github.com/1257724
>>> 
>>> _______________________________________________
>>> 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
> 
> _______________________________________________
> 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