Suppose the every or any method is being evaluated on a long list, and the value of the closure on the first element is enough to determine the final result (true for any, false for every). Do these methods continue processing the rest of the elements of the list or do they immediately return?
def lst = [1,2,3,4]
//Do either of these functions evaluate the 2nd, 3rd and 4th element of lst?
boolean value1 = lst.any{element -> element == 1}
boolean value2 = lst.every {element -> element == 2}
any() and every() short-circuit and return as soon as possible.
You can see this in the source for any() and every(). These methods each iterate over each object evaluating the closure and return if the condition is (for any())/is not (for every()) met.
Related
I would like to do the following:
let a = [1,2,3,4]
let res = []
for (i = 0; i < a.length; i++) {
if (someFilterFunction(x) == true) {
res.push(a[i])
}
}
return res
In Haskell, I assumed it would use takewhile but I need the function to not skip when the condition is not met.
We would like to do the following in Haskell: Write a function that takes a list as input, checks each element if it matches some test (aka predicate, filter function), include the element in a result list if the test succeeds.
So we want a function that accepts a list of some type of values (let's call them Ints) and returns a list:
timothyylim :: [Int] -> [Int]
That's the type signature (like a C prototype). Now we need the declaration. Because you are learning Haskell lets define this function without using any of the built in operations. What do we do when the input list is empty? Return an empty list!
timothyylim [] = []
What do we do when the list has at least one element?
timothyylim (firstElement : restOfList) =
-- What goes here?
Well we want to check if someFilterFunction firstElement is true and include that element along with the rest of the filtered list.
if someFilterFunction firstElement
then firstElement : timothyylim restOfList
And if it is false, then we just want to return the rest of the filtered list without this element.
else timothyylim restOfList
At this point we're done - we have a new function timothyylim that applies someFilterFunction to a list and generates a new list. There was no need to look at Prelude functions such as takeWhile - we did this using only language primitives including (in order of introduction) a type signature, case-by-case function declaration, pattern matching, if-then-else statements, function application, list concatenation, and primitive recursion.
In Real Use
In Haskell there is already a definition of a function named filter. It's like our filter except you'd pass in the filter function someFilterFunction as a parameter. So we could say:
timothyylim inputList = filter someFilterFunction inputList
Or equivalently:
timothyylim = filter someFilterFunction
Most of the time if your solution is a manual primitive recursive function, such as the timothyylim function above, then there's already a higher order function (i.e. a function that takes another function as a parameter) in Prelude that can do the job for you (see folds, maps, filters, and zips).
I have caught something in my work returning a list containing an empty string. I've created an example for simplicity:
big_ol_trickster = [""]
if big_ol_trickster:
foo()
else:
print("You can't trick me!")
And this conditional would be satisfied every time. So I've got a question for the python wizards out there: Why is [] == False and "" == False but [""] == True?
Empty lists are Falsey. [""] is not empty. It contains a single element (which happens to be Falsey as well). The Falsey-ness is not evaluated recursively.
To know why is that, look at the implementation of the __bool__ dunder method for the list class. This the method that is called to evaluate truth-value in python. And, yes, you can override it.
[False, False] -> this is also Truthy, it can be counter-intuitive. That's why when you try to use sequences in if conditions you sometimes get "truth-value of sequences can be ambiguous, use any() or all() instead"
I am trying to predict the behavior of this code in Groovy
userList.find { }
.find documentation
When the find method is invoked and passed a closure it returns the first element that evaluates the closure into Groovies understanding of true.
When the find method is called without any parameters it returns the first object in the list that matches true according to Groovy truth.
What happens if an empty closure is used?
Will it evaluate to true and thus the first element of the list is returned?
Will it always evaluate to false and after iterating over the list null is returned?
Will it be behave like .find()?
From the Groovy Closures Formal Definition (Alternative Source):
Closures always have a return value. The value may be specified via one or more explicit return statement in the closure body, or as the value of the last executed statement if return is not explicitly specified. If the last executed statement has no value (for example, if the last statement is a call to a void method), then null is returned.
And from Groovy Truth
Object references
Non-null object references are coerced to true.
...
assert !null
That suggests to me that the truth of the return value of an empty closure is always false, so find will never find anything, and thus presumably return null.
there is no definition of "empty closure" only if you delegate this closure to a Map, then the Map keeps empty :
Map closureToMap(Closure c, Map attrs=[:]) {
c.resolveStrategy = Closure.DELEGATE_FIRST
c.delegate = attrs
c()
return attrs
}
def myEmptyClosure = {}
assert closureToMap(myEmptyClosure).isEmpty()
According to the Groovy docs, the == is just a "clever" equals() as it also takes care of avoiding NullPointerException:
Java’s == is actually Groovy’s is() method, and Groovy’s == is a clever equals()!
[...]
But to do the usual equals() comparison, you should prefer Groovy’s ==, as it also takes care of avoiding NullPointerException, independently of whether the left or right is null or not.
So, the == and equals() should return the same value if the objects are not null. However, I'm getting unexpected results on executing the following script:
println "${'test'}" == 'test'
println "${'test'}".equals('test')
The output that I'm getting is:
true
false
Is this a known bug related to GStringImpl or something that I'm missing?
Nice question, the surprising thing about the code above is that
println "${'test'}".equals('test')
returns false. The other line of code returns the expected result, so let's forget about that.
Summary
"${'test'}".equals('test')
The object that equals is called on is of type GStringImpl whereas 'test' is of type String, so they are not considered equal.
But Why?
Obviously the GStringImpl implementation of equals could have been written such that when it is passed a String that contain the same characters as this, it returns true. Prima facie, this seems like a reasonable thing to do.
I'm guessing that the reason it wasn't written this way is because it would violate the equals contract, which states that:
It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
The implementation of String.equals(Object other) will always return false when passed a GSStringImpl, so if GStringImpl.equals(Object other) returns true when passed any String, it would be in violation of the symmetric requirement.
In groovy a == b checks first for a compareTo method and uses a.compareTo(b) == 0 if a compareTo method exists. Otherwise it will use equals.
Since Strings and GStrings implement Comparable there is a compareTo method available.
The following prints true, as expected:
println "${'test'}".compareTo('test') == 0
The behaviour of == is documented in the Groovy Language Documentation:
In Java == means equality of primitive types or identity for objects. In Groovy == means equality in all cases. It translates to a.compareTo(b) == 0, when evaluating equality for Comparable objects, and a.equals(b) otherwise. To check for identity (reference equality), use the is method: a.is(b). From Groovy 3, you can also use the === operator (or negated version): a === b (or c !== d).
The full list of operators are provided in the Groovy Language Documentation for operator overloading:
Operator
Method
+
a.plus(b)
-
a.minus(b)
*
a.multiply(b)
/
a.div(b)
%
a.mod(b)
**
a.power(b)
|
a.or(b)
&
a.and(b)
^
a.xor(b)
as
a.asType(b)
a()
a.call()
a[b]
a.getAt(b)
a[b] = c
a.putAt(b, c)
a in b
b.isCase(a)
<<
a.leftShift(b)
>>
a.rightShift(b)
>>>
a.rightShiftUnsigned(b)
++
a.next()
--
a.previous()
+a
a.positive()
-a
a.negative()
~a
a.bitwiseNegate()
Leaving this here as an additional answer, so it can be found easily for Groovy beginners.
I am explicitly transforming the GString to a normal String before comparing it.
println "${'test'}".equals("test");
println "${'test'}".toString().equals("test");
results in
false
true
I came across this bit of code:
n = args[0] as Long
[*n..1, n].any{ println ' '*it + '*'*(n - ~n - it*2) }
It's used for printing a tree form of structure. Like this:
*
***
*****
*******
*
(for n=4)
How does the code [*n..1,n] produce [4, 3, 2, 1, 4]?
How does any method works here? The Doc doesn't help me much. What is a predictive that can be passed to any(as mentioned in Doc's)?
Whats the use of any and how its handled in this case?
Q1a: * "unpacks" an array. .. creates a range. [] creates a collection.
Q1b: *n..1 unpacks [4,3,2,1] into its individual parts.
Q1c: [4,3,2,1,n] == [4,3,2,1,4]
Q2: I don't know why any was used here; each works just as well, and makes more sense in context. any does loop over the connection, so the println side-effect functions as intended.
Normally any would be used to determine if any collection elements met a criteria, for example:
[*n..1,n].any { it > 10 } // Returns false, no elements are > 10
[*n..1,n].any { it == 3 } // Returns true, because at least one element is 3
The last statement of the closure is used to determine if each item meets the criteria. println returns null, so any will return false. The value is unused and discarded.
The only reason I can think of that someone might have used any is to avoid seeing the return value of each in the console. each returns the original collection.
1) n..1 is called a range literal, it creates a groovy.lang.Range object that decrements by 1 from n to 1. This is then merged into the surrounding list context using the "Spread operator (*)"
2) the any method is defined in DefaultGroovyMethods and it is a predicate function that returns true if an element in a collection satisfies the supplied predicate closure. In this example, the code doesn't check the return value, so original other could have produced the same output using an each call instead.