Julian, see my other post, it has nothing to do with map per se.

Apart from philosophical questions, the reason I need this to consistently 
raise an exception, is that I want to interrupt the map evaluation when it 
is slow, throwing an InteruptedException. I then want to recommence 
evaluation later. rinse, repeat. I can't recommence it if the sequence has 
been 'closed' with a final nil. Sounds like a fair use case?

On Monday, 3 December 2012 16:35:39 UTC+11, julianrz wrote:
>
> Hmm.. I think you are raising both a technical and a philosophical issue - 
> what exactly should a higher-order function return when some application of 
> the supplied function throws exception... The behaviors could be:
> 1) throw
> 2) return null
> 3) return an empty collection (do not continue after 1st failure)
> 4) same, but continue through all failures
> 5) return collection with valid applications only
> What is good behavior? We should have as little uncertainly as possible... 
> I have to admit my first thought is 'just don't allow it to throw, return 
> null instead'. This would allow to still collect results (where it does not 
> throw), and they will be at the matching index locations...
>
> Now the technicality. The map code I see for 1.4 is trying to append 
> result of all invocations to a buffer upfront. And each time it will fail, 
> and the buffer will be empty, hence empty result Source is a chunked 
> collection and there is only one chunk, it will be done immediately, and 
> not on subsequent calls - laziness has not started yet  
>
> Please contrast it with mapv, which results in a vector, not sequence
> user=> (def mapped (mapv (fn [_] (throw (Exception.))) [1 2 3]))
> Exception   user/fn--1 (NO_SOURCE_FILE:1)
> user=> mapped
> #<Unbound Unbound: #'user/mapped>
>
> Now the lazy-seq example - maybe the difference in behavior can be 
> explained by the fact that lazy-seq caches the result of body evaluation 
> and will keep returning it. Since there is an exception during each 
> evaluation, the caching does not quite happen, and it is re-evaluated?
>
> Should the behavior be the same in all 3 cases? I think so, at least for 
> consistency (unsure it can be achieved, though). But throwing in function 
> passed to map  really is something you should not do, and I would recommend 
> to change map function to return a null or throw -- to let you know that 
> your code can cause odd behavior. BTW I am not aware of any clojure book 
> that alerts you to that. 
>
> Also, maybe the implementation of map function should catch your exception 
> internally and produce a null, and return a sequence of nulls?
>
> -Julian
>
> On Sunday, December 2, 2012 5:58:08 AM UTC-8, Hank wrote:
>>
>> I'm mapping a function that throws an exception over a collection:
>>
>> => (def mapped (map (fn [_] (throw (Exception.))) [1 2 3]))
>> #'user/mapped
>>
>> 'map' is lazy so we're not expecting to see the exception until we're 
>> trying to access the result:
>> => mapped
>> Exception   user/fn--709 (NO_SOURCE_FILE:1)
>>
>> All good, let's do that again:
>> => mapped
>> ()
>>
>> Whoops! Is this by design? Why? Where does that empty sequence come from?
>>
>> 'map' is really just calling the lazy-seq macro but doing this with lazy 
>> seq works just fine:
>> => (def lazy (lazy-seq (throw (Exception.))))
>> #'user/lazy
>> => lazy
>> Exception   user/fn--733 (NO_SOURCE_FILE:1)
>> => lazy
>> Exception   user/fn--733 (NO_SOURCE_FILE:1)
>>
>> Same exception over and over again as it should be. I stared at the 
>> implementations of 'map' and lazy-seq/LazySeq for some hours but I really 
>> can't see it.
>>
>> Cheers
>> -- hank
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to