Yeah let's see, to boil it down: either way there has to be a way to
signal the user isn't known, and either way the caller has to handle
it. I've always preferred exceptions to null, all else being equal. I
don't mind the idea of exceptions being used for control flow; they
aren't that expensive. (In a performance-critical block, OK, I'd use
null instead, but here, this case is rare enough that I don't think
performance is a factor.)

Catching an exception needs a bit more code than handling null. You
can't force a caller to handle null, but you can force a caller to
handle an exception -- but here I'm using an unchecked exception so
that doesn't matter anyway. You have a point about catching this maybe
masking another exception.

I could be talked into changing this, but here, I think the right
behavior for a DataModel is to know about all users that exist, not
just ones with preferences. That is this user should be known in your
situation.

But are you using FileDataModel or something similar? because this
condition isn't really fulfilled by this implementation. It only knows
about users that have expressed a preference, by its nature. That can
be addressed so that you can express users, without expressing a
preference.

If this is the issue -- let me attack that issue directly to solve
this, and punt on the exception vs. null discussion. Am I right?

Sean


On 21 Jan 2009, 3:23 PM, "Otis Gospodnetic" <otis_gospodne...@yahoo.com> wrote:

Hello,

Question about NoSuchElementException usage in Taste:

I'm using Taste in an environment where lots of requests for
recommended items are for users who are new to the system - users who
have no previously consumed items.  When I try to get recommendations
for such users, the following is thrown:

java.util.NoSuchElementException
   at 
org.apache.mahout.cf.taste.impl.model.BooleanUserGenericDataModel.getUser(BooleanUserGenericDataModel.java:81)
   at 
org.apache.mahout.cf.taste.impl.model.file.BooleanPrefUserFileDataModel.getUser(BooleanPrefUserFileDataModel.java:163)
   at
org.apache.mahout.cf.taste.impl.recommender.BooleanUserGenericUserBasedRecommender.recommend(BooleanUserGenericUserBasedRecommender.java:86)

This looks correct, and comes from this piece of code in
BooleanUserGenericDataModel (the same happens in non-Boolean versions
of the code):

 public User getUser(Object id) {
   User user = userMap.get(id);
   if (user == null) {
     throw new NoSuchElementException();
   }
   return user;
 }


I'm wondering if this is good/best thing to do here.  Here is some reasoning:
- it's not really an error to ask a RE to recommend items for a user
the RE knows nothing about - it's the cold start issue
- I believe throwing exceptions is expensive, and I'm wondering if it
would be cheaper to do something else
- one could say this falls in the "using exceptions for flow control"
category (because that's what I'll have to do on the higher level)
- I briefly looked at returning null, but it looks like this would
require checks for null to avoid NPE in a number of places

I'm not sure this needs to change, but it's been on my mind for a
while now.  On my end I can simply catch this ugly exception and eat
it, although this "NoSuchElementException" is so non-specific that if
I just catch NoSuchElementException the code may one day end up
catching a NoSuchElementException from some other part of Taste.

Thoughts?

Otis
--
Sematext -- http://sematext.com/ -- Lucene - Solr - Nutch

Reply via email to