Rego: Set comprehension undefined - set

I am trying to understand why the following examples on using set comprehension give different results:
https://play.openpolicyagent.org/p/5x5mXmsyr0
https://play.openpolicyagent.org/p/IVQlTYcVpD
In the first example, rlt is evaluated to an empty set despite foo["c"] is undefined. I expect rlt to also be undefined.
In the second example, I removed the function but directly set rlt2 to the result of a set comprehension. This time it does return undefined.
Can someone explain the difference here?

I think what you see here is the type checker doing the best it can.
The error you get, is because at compile time, the type checker knows which keys exist.
For the function call, foo is a function argument,
myFunc(foo) = rlt {
rlt := {f | f := foo["c"]}
}
and the compiler cannot tell if foo["c"] exists or does not exist -- that depends on the actual call. You might define the function like that, but use it in other ways like
$ echo '{"c": 123}' | opa eval -I -d policy.rego 'data.play.myFunc(input)'
So it doesn't do any kind of deeper flow analysis.
Now rlt is not undefined because set (object, array) comprehensions are never undefined -- if their bodies are always undefined, the overall collection becomes an empty set (object, array).

Related

How to have multiple (alternate) return types in Nim?

I can declare a proc to return a "union type", but cannot actually return values of more than one type:
proc test(b: bool) : int|string =
if b: 1 else: "hello"
echo test true
echo test false
Expected:
1
hello
Actual:
Error: type mismatch: got 'string' for '"hello"' but expected 'int literal(1)'
Even if I swap the return types (string|int) the error is the same. I am only allowed to return an int. I tried putting the return type in parens; and I tried using or instead of |. No dice.
What am I missing? (I don't want to use a variant object.)
The code can be tested online at the Nim Playground. I've scoured google and the Nim documentation, and come up empty.
Return types have to be known at compile time in Nim. Imagine you tried to return the result of that procedure to a string variable. Now you're in a scenario where one return value works, but the other would be a compilation error. In order to allow Nim to figure out whether to throw an error or not it must be able to figure out which type will be returned at compile time. The solution here is to use a static[bool] and a when in place of the if. If you actually need a type that can hold different types on runtime you have to use variant objects.

Implicitly lazy gather/take not considered a "lazy" object

The documentation for gather/take mentions
Binding to a scalar or sigilless container will also force laziness.
However,
my \result = gather { for 1..3 { take $_² } };
say result.is-lazy # OUTPUT: «False␤»
Same happens if you use a scalar, and binding using := Is there some way to create implicitly lazy gather/take statements?
Update: It's actually lazy, only it does not respond to the is-lazy method in the expected way:
my $result := gather { for 1..3 { say "Hey"; take $_² } };
say $result[0] # OUTPUT: «Hey␤1␤»
So the question is "What are the conditions for is-lazy to consider things actually lazy?"
I think the problem is really that you cannot actually tell what's going on inside a gather block. So that's why that Seq object tells you it is not lazy.
Perhaps it's more a matter of documentation: if is-lazy returns True, then you can be sure that the Seq (well, in fact its underlying Iterator) is not going to end by itself. If is-lazy returns False, it basically means that we cannot be sure.
One could argue that in that case is-lazy should return the Bool type object, which will also be interpreted as being false (as all type objects are considered to be False in boolean context). But that would at least give some indication that it is really undecided / undecidable.

Inside a function, how do I construct a new function based on original function parameters, in order to pass as an argument to another function

I'm having trouble with function declarations and scope in julia. I have a main function, let's call it mainfunc which accepts some arguments. Within this function, I would ultimately like to call a different function, say callfunc, which takes a function as an argument. This function I will call passfunc.
One further complication I have is that there is a final function which I define outside of the logic which depends on the arguments but still depends on the arguments in a different way. I can call this initfunc. This must be composed with some other function, depending on the arguments, to create passfunc.
Based on the arguments given to mainfunc, I will have different definitions of passfunc. Given the answer I got to a related question here, I initially tried to define my function logic in the following way, using anonymous functions which are apparently more efficient:
function mainfunc(args)
init_func = x -> funcA(x, args)
if args[1] == "foo"
anon_func = x -> func1(x, args)
elseif args[1] == "bar"
anon_func = x -> func2(x, args)
end
function passfunc(x)
return init_func(x) + anon_func(x)
end
# ... define other args...
callfunc(passfunc, other_args)
end
Defining my function in this way leads to errors in julia - apparently passfunc is an undefined variable when I run this code. Does the scope not allow the anonymous functions to be defined in the if statements? How else could I write code that achieves this?
I feel like a better understanding of functional programming principles would make the solution here obvious. Thank you in advance for any tips you can offer on improving this.
Also, I am running this with julia v0.7

Ti Nspire: Convert solve(...) output to a callable Function

in order to calculate the inverse function of f(x) I defined following function:
inv(fx):=exp▶list(solve(fx=y,x),x)
which output is:
inv(x^(2)) {piecewise(−√(y),y≥0),piecewise(√(y),y≥0)}
So that part works already, but how can I use this result as a callable function i(y)?
Thanks for your help
Outside of your program, you can turn the result into function i(y) with:
i(y):=piecewise(-√(y),y≥0,√(y),y≥0)
I do not have a CAS, so your results may differ, but, because the function can only return one value, it would only return (and display in the graph) the first value, in this case, -√(y). If you want to display on the graph or get the values of both, you would be better off creating two separate functions (-√(y), and √(y)). Hope this helps you "use the result as a callable function."

Using Ruby to solve a quiz

So I found this quiz on a website that I was excited to solve with my newly acquired Ruby skills (CodeAcademy, not quite finished yet).
What I want to do is make an array with 100 entries, all set to "open". Then, I planned to create a method containing a for loop that iterates through every nth entry of the array and changes it to either "open" or "closed", based on what it was before. In the for loop, n should be increased from 1 to 100.
What I have so far is this:
change_state = Proc.new { |element| element == "open" ? element = "closed" : element = "open" }
def janitor(array,n)
for i in 1..n
array.each { |element| if array.index(element) % i == 0 then element.change_state end }
end
end
lockers = [*1..100]
lockers = lockers.map{ |element| element = "closed" }
result = janitor(lockers,100)
When trying to execute I receive an error saying:
undefined method `change_state' for "closed":String (NoMethodError)
Anybody an idea what is wrong here? I kinda think I'm calling the "change_state" proc incorrectly on the current array element.
If you know the quiz, no spoilers please!
As you have implemented change_state, it is not a method of any class, and definitely not one attached to any of the individual elements of the array, despite you using the same variable name element. So you cannot call it as element.change_state.
Instead, it is a variable pointing to a Proc object.
To call the code in a Proc object, you would use the call method, and syntax like proc_obj.call( params ) - in your case change_state.call( element )
If you just drop in that change, your error message will change to:
NameError: undefined local variable or method `change_state' for main:Object
That's because the change_state variable is not in scope inside the method, in order to be called. There are lots of ways to make it available. One option would be to pass it in as a parameter, so your definition for janitor becomes
def janitor(array,n,state_proc)
(use the variable name state_proc inside your routine instead of change_state - I am suggesting you change the name to avoid confusing yourself)
You could then call it like this:
result = janitor(lockers,100,change_state)
Although your example does not really need this structure, this is one way in which Ruby code can provide a generic "outer" function - working through the elements of an array, say - and have the user of that code provide a small internal custom part of it. A more common way to achieve the same result as your example is to use a Ruby block and the yield method, but Procs also have their uses, because you can treat them like data as well as code - so you can pass them around, put them into hashes or arrays to decide which one to call etc.
There may be other issues to address in your code, but this is the cause of the error message in the question.

Resources