On Monday, November 13, 2017 at 11:40:10 AM UTC-6, Stephen Feyrer wrote:
>
> Updating subject to make it make more sense, hopefully. 
>
> On 13 November 2017 at 14:15, Alex Miller <a...@puredanger.com> wrote:
>
>> Regarding the title, this is incorrect. Map keys are not functions; 
>> keywords are functions that take an associative data structure and will 
>> look themselves up in it. So, the premise here is not even correct to start.
>>
>> Usually we prefer to work by starting from a problem and consider 
>> alternatives, but as you state below, you don't have a problem in mind.
>>
>>
> Normally, I don't offer possible solutions when I enquiring about a 
> problem.  Maybe with forethought context and or constraints...
>
> This is  more of a solution (based on a lack of understanding) without a 
> problem.  If you like the problem I'm hoping to address is to reduce my 
> lack of understanding.
>
>  
>
>>
>> On Monday, November 13, 2017 at 3:49:41 AM UTC-6, Stephen Feyrer wrote:
>>>
>>> Hi there,
>>>
>>> This is possibly a silly question (and may have been asked before but I 
>>> couldn't find earlier examples) so here it goes.
>>>  
>>>
>>
>>> Get the nth element of the vector
>>>
>>> user=> (3 [1 "is" the :same])
>>> :same
>>>
>>>
>>>
>> Note that you can do something similar now with:
>>
>> ([1 "is" the :same] 3)
>>
>
> This works for me :)
>

The important thing here is that thing being invoked is the vector (which 
is a custom Clojure type that implements the IFn invocation interface). 
Putting arbitrary types in the operator position of a call is where the 
issues lie.
 

>  
>
>>
>> Whereas in the situation with maps, keywords (a specific common key type) 
>> are functions, here you are implying that anything could implicitly be 
>> invokable as a lookup function on an associative data structure. This 
>> doesn't make a lot of sense to me and would undoubtedly have performance 
>> effects. Maybe there is some case like `(map 1 [[:a 0] [:b 1] [:c 2]])` 
>> where this would make sense. But this doesn't make sense for all indexed 
>> data structures, just those indexed by longs. Layering invocability on 
>> longs would require special handling in the compiler (Keywords are a type 
>> that embeds this by implementing IFn naturally, so it's not a special case).
>>
>>>
>>> Get the nthiness of an element in the vector
>>>
>>> user=> (::same [1 "is" the :same])
>>> 3
>>>
>>>
>> This is something completely different - a linear search for a match. 
>> Clojure has considered and rejected making linear searching easier multiple 
>> times. It's almost always a sign that you are using the wrong data 
>> structure in the first place and should be using a hashed data structure 
>> instead. There is no chance we would do something like this.
>>
>
> Perhaps, I'm not understanding vectors properly.  A vector is a set of 
> ordered elements, I think that is right. 
>

More importantly, vectors are indexed (you can look up an element by index) 
and this property is extended to make vectors associative where you 
associate a key (the index) with the value (the element at the index). This 
operation is fast (what we call "effectively constant" time as it's 
O(log32(n)) which is a function that grows very slowly compared to O(n)).
 

> Then at some point you might want to get one of those elements picking it 
> out by its index.  Equally, this is probably where I've lost the plot you 
> might want to know where in a vector your element is residing.
>

These two sentences are talking about two different kinds of operations, 
but I think you believe they are the same kind of operation. The first 
sentence is a fast (effectively constant time) lookup by key (the index). 
The second sentence is a slow (linear time) search through the vector. 
Generally, if your program is doing a lot of the latter, you should change 
it so it does more of the former. :)
 

>
> Get the nthiness of an element in the vector
>>>
>>> user=> (:1 [1 "is" the :same])
>>> (0 2)
>>>
>>>
>> I don't even understand what is intended here.
>>
>>
> You've already covered this above but I'll explain what I meant (just to 
> be clear). 
>
> user=> (nth [1 "is" the :same] 2) 
> 1
>
> And
>
> user=> ([1 "is" the :same] 0) 
> 1
>
> Therefore, a lookup of value '1' would return the indices for both 
> occurrences in a list.
>

Both cases here are the fast lookup operation - both of these can go pluck 
out the i-th element without examining any other elements, just like you 
were instead doing:

(nth {0 1, 1 "is", 2 the, 3 :same} 0) or 
({0 1, 1 "is", 2 the, 3 :same} 0)
 

>
>  
>
>> Taking things further into the realms of really you should have stopped 
>>> there!
>>>
>>> Get the these element of the vector
>>>
>>> user=> ((1 3) [1 "is" the :same])
>>> ("is" :same)
>>>
>>>
>>> Just for fun I tried:
>>>
>>> user=> ((:this :the) {:this "is" :the "same"}) 
>>>                                    
>>>
>>>                                                                             
>>>      
>>> NullPointerException   user/eval786 (NO_SOURCE_FILE:1)
>>>
>>>
>>>
> The thought here was the same as the above only with a list of invocations 
> to return a list of values.
>

>  
>
>>
>>> I may be barking up the wrong tree or possibly just barking...  I hope 
>>> what I'm asking makes some sort of sense.  
>>>
>>
>> Not particularly.
>>  
>>
>>> By way of apology to the reader, when I began writing this question it 
>>> was ill thought out and seemed a lot simpler.  As a disclaimer, I can't 
>>> think of direct examples how this would improve readability or such or even 
>>> necessarily be useful.  
>>>
>>
>> Seems like that should have been a sign. :)
>>
>
> That was one yes, the other was the suggestion that this might be a silly 
> question.  In hindsight, I think the question I'm looking at now maybe 
> quite different to the one I thought I had when I started.
>
> At this point I think I would ask, how do you find the indices of elements 
> within a vector for a certain value?  
>

In general, this requires examining each element till you find them (a 
linear-time search).
 

> Or perhaps, should you be needing to obtain the positional component of a 
> value, what would be the correct data structure to use?
>

This is a better question. :) I'd recommending using a data structure that 
allows you to do a constant time lookup, and avoid linear searches if 
possible. That is usually a hashed data structure like a map or set (or 
occasionally a vector if the values happen to be index-like).
 

> For example, you're given a list (in an unspecified form) of horses from a 
> race in their finishing order.
>
> Carrot
> Colonel Mustard
> Sugar
>
> Binky
>
> Mr. Ned
> Go Faster Stripes
> Stick
> Scary Monster Not Technically A Horse
>
> Binky
>
>
> Then (using Clojure) you're asked to get the positional value of 'Go 
> Faster Stripes' or 'Binky'?
>

If you don't have control over the input, then you will need to walk in a 
linear search, either leveraging the natural indexes (probably with an 
explicit loop/recur), or using your own as you go (using something like 
keep-indexed). Or if checking for any match at all, something like (some 
#{"Go Faster Stripes" "Binky"} finishes).

But really, I'd endeavor to instead take as input a map like this:

{"Carrot" 1, "Colonel Mustard" 2, ...} and then just look up the answer 
without needing to examine every horse. Without more context on use, it's 
hard to suggest precise replacements.


-- 
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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to