What is ipairs in lua stands for? - lua

I know that pairs in lua iterates through pairs according to hash key, which means no specific order, and ipairs iterates from 1 until an absent key, which will not iterate through all pairs if there is a gap.
My question is, what is the i in ipairs stands for? I have a hard time thinking up a mnemonic explanation.
Some of my guesses are:
Incremental-key-order
In-order-iteration
Just because it behaves
like a for loop, which use i a lot

Related

why is tables in lua designed in this way?

I am confused about below grammer in language lua:
w = {x=0, y=0}
w[1] = "another"
in my opinion, the first sentence descirbe the w as a dict-like strcture and next a array, are the w of the first and of the second same? if so, why? why can two different things can be stored in a w?
I'm a rookie in lua and also in english, pardon.
I want to know some thoughts of designation of lua and the explanation of my qustion.
An array is conceptually just a series of key/value pairs. It's just that the "keys" are all integers and are a sequence of integers starting from (in Lua's case) 1.
Lua recognizes that a "dictionary" and "array" are really the same thing. It bundles these two concepts together into a single type: Lua's "table".
In a Lua table, keys can be (almost) anything. Including integers. Including integers starting from 1 and increasing. As such, a Lua table is said to have an "array portion", which are all of the integer keys from the integer 1 to the highest integer whose value is not nil. This is what it means to take the "length" of a table.

Why does the same lua script have inconsistent execution results?

Why does the same lua script have inconsistent execution results?
hello.lua
obj = {
a = 'haha',
b = 'jiji',
c = {
name = 'tom',
age = 15
}
}
for i, v in pairs(obj) do
if (i == 'c') then
print(i,v.age,v.name)
break
end
print(i, v)
end
Result
Result
Thank you for your answer!!
The documentation is very clear, the order is not specified. See https://www.lua.org/manual/5.4/manual.html#pdf-next
The order in which the indices are enumerated is not specified, even for numeric indices. (To traverse a table in numerical order, use a numerical for.)
Lua tables use a hash map for implementing their hash part. The order in which your entries will be iterated by pairs/next depends on the hashes of the keys (in this case, the hashes of the strings "a", "b", "c") and their order of insertion.
First of all, hashing and order of insertion may change across different Lua versions, different interpreters (LuaJIT f.E.), so you should never rely on it being one way or another. You will probably want to either sort a list of table keys before traversal or to use an ordered map.
Second, hashing - and thus order of traversal - varies across program runs as of Lua 5.2, which introduces hash seeding to avoid hash flooding attacks: The interpreter will generate a random seed at runtime to use in the calculation of hashes to make it harder for attackers to force hash collisions (which result in detrimental table performance).

What are buckets in terms of hash functions?

Looking at the book Mining of Massive Datasets, section 1.3.2 has an overview of Hash Functions. Without a computer science background, this is quite new to me; Ruby was my first language, where a hash seems to be equivalent to Dictionary<object, object>. And I had never considered how this kind of datastructure is put together.
The book mentions hash functions, as a means of implementing these dictionary data structures. This paragraph:
First, a hash function h takes a hash-key value as an argument and produces
a bucket number as a result. The bucket number is an integer, normally in the
range 0 to B − 1, where B is the number of buckets. Hash-keys can be of any
type. There is an intuitive property of hash functions that they “randomize”
hash-keys
What exactly are buckets in terms of a hash function? it sounds like buckets are array-like structures, and that the hash function is some kind of algorithm / array-like-structure search that produces the same bucket number every time? What is inside this metaphorical bucket?
I've always read that javascript objects/ruby hashes/ etc don't guarantee order. In practice I've found that keys' order doesn't change (actually, I think using an older version of Mozilla's Rhino interpreter that the JS object order DID change, but I can't be sure...).
Does that mean that hashes (Ruby) / objects (JS) ARE NOT resolved by these hash functions?
Does the word hashing take on different meanings depending on the level at which you are working with computers? i.e. it would seem that a Ruby hash is not the same as a C++ hash...
When you hash a value, any useful hash function generally has a smaller range than the domain. This means that out of a large list of input values (for example all possible combinations of letters) it will output any of a smaller list of values (a number capped at a certain length). This means that more than one input value can map to the same output value.
When this is the case, the output values are refered to as buckets.
Consider the function f(x) = x mod 2
This generates the following outputs;
1 => 1
2 => 0
3 => 1
4 => 0
In this case there are two buckets (1 and 0), with a bunch of input values that fall into each.
A good hash function will fill all of these 'buckets' equally, and so enable faster searching etc. If you take the mod of any number, you get the bucket to look into, and thus have to search through less results than if you just searched initially, since each bucket has less results in it than the whole set of inputs. In the ideal situation, the hash is fast to calculate and there is only one result in each bucket, this enables lookups to take only as long as applying the hash function takes.
This is a simplified example of course but hopefully you get the idea?
The concept of a hash function is always the same. It's a function that calculates some number to represent an object. The properties of this number should be:
it's relatively cheap to compute
it's as different as possible for all objects.
Let's give a really artificial example to show what I mean with this and why/how hashes are usually used.
Take all natural numbers. Now let's assume it's expensive to check if 2 numbers are equal.
Let's also define a relatively cheap hash function as follows:
hash = number % 10
The idea is simple, just take the last digit of the number as the hash. In the explanation you got, this means we put all numbers ending in 1 into an imaginary 1-bucket, all numbers ending in 2 in the 2-bucket etc...
Those buckets don't really exists as data structure. They just make it easy to reason about the hash function.
Now that we have this cheap hash function we can use it to reduce the cost of other things. For example, we want to create a new datastructure to enable cheap searching of numbers. Let's call this datastructure a hashmap.
Here we actually put all the numbers with hash=1 together in a list/set/..., we put the numbers with hash=5 into their own list/set ... etc.
And if we then want to lookup some number, we first calculate it's hash value. Then we check the list/set corresponding to this hash, and then compare only "similar" numbers to find our exact number we want. This means we only had to do a cheap hash calculation and then have to check 1/10th of the numbers with the expensive equality check.
Note here that we use the hash function to define a new datastructure. The hash itself isn't a datastructure.
Consider a phone book.
Imagine that you wanted to look for Donald Duck in a phone book.
It would be very inefficient to have to look every page, and every entry on that page. So rather than doing that, we do the following thing:
We create an index
We create a way to obtain an index key from a name
For a phone book, the index goes from A-Z, and the function used to get the index key, is just getting first letter from the Surname.
In this case, the hashing function takes Donald Duck and gives you D.
Then you take D and go to the index where all the people with Surnames starting with D are.
That would be a very oversimplified way to put it.
Let me explain in simple terms. Buckets come into picture while handling collisions using chaining technique ( Open hashing or Closed addressing)
Here, each array entry shall correspond to a bucket and each array entry (if nonempty) will be having a pointer to the head of the linked list. (The bucket is implemented as a linked list).
The hash function shall be used by hash table to calculate an index into an array of buckets, from which the desired value can be found.
That is, while checking whether an element is in the hash table, the key is first hashed to find the correct bucket to look into. Then, the corresponding linked list is traversed to locate the desired element.
Similarly while any element addition or deletion, hashing is used to find the appropriate bucket. Then, the bucket is checked for presence/absence of required element, and accordingly it is added/removed from the bucket by traversing corresponding linked list.

How do Ruby min and max compare strings?

I'm playing around with iterators. What is Ruby comparing using max and min?
If I have this array:
word_array = ["hi", "bob", "how's", "it", "going"]
and I run:
puts word_array.max
puts word_array.min
I expect to get "going" or "how's" for max, since they're both five characters long, or "going" on the theory that it's the last item in the array. I expect min to return "hi" or "it", since they're tied for the shortest string. Instead, I get back:
puts word_array.max -> it
puts word_array.min -> bob
What is Ruby measuring to make this judgement? It selected the shortest string for max and a middle length string for min.
Actually, you are (kind of) asking the wrong question. max and min are defined on Enumerable. They don't know anything about Strings.
They use the <=> combined comparison operator (aka "spaceship"). (Note: pretty much any method that compares two objects will do so using the <=> operator. That's a general rule in Ruby that you can both rely on when using objects other people have written and that you should adhere to when writing your own objects: if your objects are going to be compared to one another, you should implement the <=> operator.)
So, the question you should be asking is, how does String#<=> compare Strings? Unfortunately, the answer is not quite clear from the documentation. However, it does mention that the shorter string is considered to be less than the longer string if the two strings are equal up to that point. So, it is clear that length is used only as a tie-breaker, not as the primary criterion (as you are assuming in your question).
And really, lexicographic ordering is just the most natural thing to do. If I gave you a list of words and asked you to order them without giving you any criteria, would you order them by length or alphabetically? (Note, however, that this means that '20' is less than '3'.)
I believe it's doing a lexical sort, exactly like a dictionary order. The maximum would be the furthest one in the dictionary.
http://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-max_by
ar = ['one','two','three','four','five']
ar.max_by(&:length) # => "three"

Am I missing something, or do we have a couple inconsistencies / misnomers?

Mathematicians typically count starting with 1, and call the counting variable n (i.e. "the nth term of the sequence). Computer scientists typically count starting with 0, and call the counting variable i (i.e. "the ith index of the array"). Which is why I was confused to learn that Seq.nth actually returns the "n+1 term of the sequence".
Doubly confusing is that Seq.iteri does as it's name implies and traverses a sequence supplying the current index.
Am I missing something? Is there a rational / history for this misnomer / inconsistency? Or was it just a mistake (which likely can't be fixed since we have a commercial release now).
Edit
Admittedly my claim about conventional use of i and n is not strictly true and I should have been more careful about such an assertion. But I think it is hard to deny that the most popularly used languages do start counting at 0 and that i and j are most certainly extremely popular choices for index variable names. So, when I am familiar with using Seq.iteri and Seq.mapi and then come across Seq.nth I think it is reasonable to think, "Oh, this function counts differently, probably the other way things are counted, starting with 1."
And, as I pointed out in the comments, the summaries for Seq.iteri, Seq.mapi, and Seq.nth only served to enforce my assumption (note that intellisense only gives you the summaries, it does not give you the description of each parameter which you have to find on MSDN):
Seq.iter
Applies the given function to each
element of the collection. The integer
passed to the function indicates the
index of element.
Seq.mapi
Creates a new collection whose
elements are the results of applying
the given function to each of the
elements of the collection. The
integer index passed to the function
indicates the index (from 0) of
element being transformed.
Seq.nth
Computes the nth element in the
collection.
Note the emphasis on "nth", not mine, as if everyone knows what the nth element in the sequences is as opposed to the ith element.
Talking of history, nth is zero based in Lisp, which is probably what the F# function is named for. See the common lisp spec for nth.
I haven't found your statement about i and n in mathematics to be true; usually n is the number of something rather than an index. In this case, it was the number of times to call cdr to get the next element.
Arrays are indexed starting from 0 in many computer languages, but some languages start from 1 and some allow a choice. Some allow the index range to be set as part of the array declaration, or even to be changed at runtime.
Mathematicians are as likely to start at zero as one, sometimes use other index ranges, and attach no particular meaning to the letters 'n' and 'i'.
The method names Seq.nth and Seq.iteri are poorly named.

Resources