what you do is aggregating
normally this query would return otherPerson many times (as often as it appears in a path from david to a fried of friend)
using otherPerson in return or with together with aggregation functions like count, min,max,avg,collect makes it an aggregation (like the SQL group by)
so it returns otherPerson just once and pulls all the other values through the aggregation functions and returns the result of all the other values _per_ otherPerson
count(*) just counts the number of subgraphs aka "rows" you can also use something like count(distinct friend_of_friend)
Michael