Lasso 9 Conditional for Existence in Nested Maps & Arrays - lasso-lang

I frequently run into a situation where I am testing for the existence of a value in a nested map or array. To prevent verbose conditionals, I would like to simplify the code to not test for existence at each level of the node, instead going right after what I want.
For example:
local(mymap = map('a' = (:1,2,3), 'b' = (:4,5,6)))
if (#mymap->find('c')->contains(9) ) => {}
If key 'c' does not exist in #mymap, then the contains() method throws an error.
Would it be foolish of me to define this in Lasso Startup?
define void->contains(...) => false
That would allow the above conditional to work, without having to add compound expressions to first test if 'c' exists. Am I missing some unintended consequences? Am I overlooking a more efficient way to do this?

The way I go about it is to use an "or":
if((#mymap->find('c') || (:)) >> 9) => {}
What happens here is that if #mymap->find('c') produces a non-false value, it's used for the contains, otherwise the empty staticarray is use for the contains.

Related

How to include multiple function calls or assignments in an if-then statement

I am new to xquery and have a hard time finding more than just the basics online. I have existing code I want to change but I don't know how to include multiple function calls or variable assignments in a single if-then statement.
Say I have this block
if (fn:namespace-uri(.) = 'http://xmlns.oracle.com/communications/sce/dictionary/testNamespace'
and //tns:CreateSalesOrder/tns:ListOfSWIOrderIO/tns:SWIOrder/tns:OrderTypeCode/text() = 'Test Order'
and $isDefaultVersion)
then true()
else false()
How can I include a function call after true()?
Something like this but I dont know the exact syntax:
if (fn:namespace-uri(.) = 'http://xmlns.oracle.com/communications/sce/dictionary/testNamespace'
and //tns:CreateSalesOrder/tns:ListOfSWIOrderIO/tns:SWIOrder/tns:OrderTypeCode/text() = 'Test Order'
and $isDefaultVersion)
then true(), util:write-record('123','johndoe')
else false()
You can write:
if (...) then (true(), util:write-record('123','johndoe')) else ...
Note the parentheses.
I suspect from the name that util:write-record() is a function that has side-effects. Functions with side-effects are very tricky in XQuery and you need to understand how they are handled by your particular implementation. There is always a risk that the query optimizer will change the order of evaluation so side-effects happen in an unexpected order, or that particular calls will not happen at all because the optimizer decides the result is not needed.

Replacing types in AST rascal

I am trying to replace all types in an AST.
Analyzing Java language using m3 model; definitions from here
If we take this code:
Int a = 1;
I am able to update the type of 1 to void for example.
But I am not able to change the type of the variable itself.
I've included some example lines.
Is someone able to point out the errors in the lines?
case \method(Type \return, str name, list[Declaration] parameters, list[Expression] exceptions)
=> \method(\int(), "funcHolder", parameters, exceptions)
case \type(Type \type) => \void()
case \type => \void
Ok, excellent question. First your code and the errors it might have:
This looks good:
case \method(Type \return, str name, list[Declaration] parameters, list[Expression] exceptions)
=> \method(\int(), "funcHolder", parameters, exceptions)
The definition is: data Declaration = \method(Type \return, str name, list[Declaration] parameters, list[Expression] exceptions, Statement impl); (see here), and your code follows exactly the definition. Every abstract method declaration in the ASTs you've parsed will match with this, since there is another \method declaration for methods with bodies with an additional argument.
It may be that you do not have abstract method bodies in your example code, in that case this does nothing.
A simpler version would also work fine:
case \method(_, _, parameters, exceptions) => \method(\int(), "funcHolder", parameters, exceptions)
The next one has issues:
case \type(Type \type) => \void()
Because data Expression = \type(Type \type), that is an Expression and data Type = \void() that is a Type or data TypeSymbol = \void() it is a TypeSymbol the rewrite is not type-preserving and would do wrong things if the Rascal compiler would not detect this. Mostly it will probably not work for you because your example code does not contain this particular kind of expression. I suspect it might be the abstract notation for things such as int.class and Integer.class.
Then this one is "interesting":
case \type => \void()
In principle, if \type is not bound in the current scope, then this matches literally anything. But probably there is a function called \type or a variable or something somewhere, and thus this pattern tests for equality with that other thing in scope. Very nasty! It will not match with anything I would guess. BTW, we are planning a "Rascal Amendement Proposal" for a language change to avoid such accidental bindings of things in the scope of a pattern.
Later from the commments I learned that the goal was to replace all instances of a Type in the AST by void(), to help in clone detection modulo type names. This is done as follows:
case Type _ => \void()
We use a [TypedVariable] pattern, with the variable name _ to match any node of algebraic type Type and forget about the binding. That node will then be replaced by void().
My way of working in the absence of a content-assist tool for pattern matching is as follows:
find full one AST example of something you want to match, say Int a = 1;
copy it into the Rascal source file
remove the parts you want to abstract from by introducing variables or _
test on the original example
test on the rest of the system by printing out the loc that have matched and clicking on the locs to bring you to the code and see if it wasn't a false positive.
for example I want to rewrite Int to void, I find an example of Int in an AST and paste it:
visit (ast) {
case simpleType(simpleName("Int")) => Type::\void() // I added Type:: to be sure to disambiguate with TypeSymbol::void()
}
With some debugging code attached to print out all matches:
visit (ast) {
case e:simpleType(simpleName("Int")) => Type::\void()
when bprintln("found a type at <e.src?|unknown:///|>");
}
Maybe you find out that that has way too many matches, and you have to become more specific, so let's only change declarations Int _ = ....;, we first take an example:
\variables(simpleType(simpleName("Int")), [...lots of stuff here...])
and then we simplify it:
\variables(simpleType(simpleName("Int")), names)
and then include it in the visit:
visit (ast) {
case \variables(simpleType(simpleName("Int")), names) => \variables(Type::\void(), names)
}
Final remark, as you can see you can nest patterns as deeply as you want, so any combination is fine. A "complex" example:
\variables(/"Int", names)
This pattern finds any variable declaration where the name "Int" is used somewhere as part of the type declaration. That's more loose than our original and might catch more than you bargained for. It's just to show what combinations you might want to do.
A final example of this: find all variable declarations with a type name which starts with "Int" but could end with anything else, like "Integer" or "IntFractal", etc:
\variables(simpleType(simpleName(/^Int/)), names)

Execute function in FLWOR without using 'let'

Let's say I create a map:
let $map := map:map()
How can I put something in that map without using let? Usually I have to do something like
let $map := map:map()
let $useless-var := map:put($map, $key, $value)
Seems strange that if I want to execute something and I don't care about the return value, I still have to store the result. What am I missing here?
Note: The important part is not map(), but the fact that I can't run a function without storing the result in some pointless variable.
One approach is to execute the functions as items in a sequence where only one item (typically, the first or last) in the sequence supplies the real value for an assignment or return, as in:
let $roundedX := (
math:floor($x),
local:function1(...),
local:function2(...)[false()],
...
)
...
return (
local:functionA(...),
local:functionB(...)[false()],
...,
$roundedX * 10
)
If the function returns a value that you want to throw away, just use a false predicate, as with two of the functions above.
Of course, this approach is only useful for functions with side effects.
Don't use a FLWOR unless you need it. In my opinion FLWOR expressions are somewhat overused. I often see expressions like:
let $a := current-time()
return $a
...when it would work just as well to write:
current-time()
See also: http://blakeley.com/blogofile/2012/03/19/let-free-style-and-streaming/
In MarkLogic 7 you can use the map constructor to generate maps recursively. I think this is probably what you want:
let $map := map:new(
(1 to 10) ! map:entry(., .)
)
Or you execute map:put as part of another sequence, or in the return statement before you return the map:
let $map := map:map()
let $not-useless-var := ...
return (map:put($map, string($not-useless-var), $not-useless-var), $map)
In plain XQuery (ignoring extensions like the XQuery scripting extension) there are no side-effects, so calling a function without using its return value is meaningless.
What you may be missing here is that map:put() returns a new map with an extra item added, it does not mutate the original map. So your $useless-var is not actually useless.
EDIT: Actually I'm not sure if MarkLogic's map:put() mutates the map. (If it does, that is really gross.) I was thinking of the proposed XQuery 3.1 maps (which I've used in BaseX) which definitely are immutable.
Since the focus of your question is about running a function without storing intermediate results, you might find the map operator (!) helpful:
local:build-sequence() ! local:do-something-to-each(.)
That's good for processing sequences. If you're thinking more about processing the result of something, the answer is likely in embracing the functional nature of XQuery:
local:produce-result(
local:build-parameter(),
local:retrieve-config()
)
Not sure exactly what you're looking for, but hopefully those help.

Returning multiple values in Ruby, to be used to call a function

Is it possible to return multiple values from a function?
I want to pass the return values into another function, and I wonder if I can avoid having to explode the array into multiple values
My problem?
I am upgrading Capybara for my project, and I realized, thanks to CSS 'contains' selector & upgrade of Capybara, that the statement below will no longer work
has_selector?(:css, "#rightCol:contains(\"#{page_name}\")")
I want to get it working with minimum effort (there are a lot of such cases), So I came up with the idea of using Nokogiri to convert the css to xpath. I wanted to write it so that the above function can become
has_selector? xpath(:css, "#rightCol:contains(\"#{page_name}\")")
But since xpath has to return an array, I need to actually write this
has_selector?(*xpath(:css, "#rightCol:contains(\"#{page_name}\")"))
Is there a way to get the former behavior?
It can be assumed that right now xpath func is like the below, for brevity.
def xpath(*a)
[1, 2]
end
You cannot let a method return multiple values. In order to do what you want, you have to change has_selector?, maybe something like this:
alias old_has_selector? :has_selector?
def has_selector? arg
case arg
when Array then old_has_selector?(*arg)
else old_has_selector?(arg)
end
end
Ruby has limited support for returning multiple values from a function. In particular a returned Array will get "destructured" when assigning to multiple variables:
def foo
[1, 2]
end
a, b = foo
a #=> 1
b #=> 2
However in your case you need the splat (*) to make it clear you're not just passing the array as the first argument.
If you want a cleaner syntax, why not just write your own wrapper:
def has_xpath?(xp)
has_selector?(*xpath(:css, xp))
end

What is the exact definition of a closure?

I've read through previous topics on closures on stackflow and other sources and one thing is still confusing me. From what I've been able to piece together technically a closure is simply the set of data containing the code of a function and the value of bound variables in that function.
In other words technically the following C function should be a closure from my understanding:
int count()
{
static int x = 0;
return x++;
}
Yet everything I read seems to imply closures must somehow involve passing functions as first class objects. In addition it usually seems to be implied that closures are not part of procedural programming. Is this a case of a solution being overly associated with the problem it solves or am I misunderstanding the exact definition?
No, that's not a closure. Your example is simply a function that returns the result of incrementing a static variable.
Here's how a closure would work:
function makeCounter( int x )
{
return int counter() {
return x++;
}
}
c = makeCounter( 3 );
printf( "%d" c() ); => 4
printf( "%d" c() ); => 5
d = makeCounter( 0 );
printf( "%d" d() ); => 1
printf( "%d" c() ); => 6
In other words, different invocations of makeCounter() produce different functions with their own binding of variables in their lexical environment that they have "closed over".
Edit: I think examples like this make closures easier to understand than definitions, but if you want a definition I'd say, "A closure is a combination of a function and an environment. The environment contains the variables that are defined in the function as well as those that are visible to the function when it was created. These variables must remain available to the function as long as the function exists."
For the exact definition, I suggest looking at its Wikipedia entry. It's especially good. I just want to clarify it with an example.
Assume this C# code snippet (that's supposed to perform an AND search in a list):
List<string> list = new List<string> { "hello world", "goodbye world" };
IEnumerable<string> filteredList = list;
var keywords = new [] { "hello", "world" };
foreach (var keyword in keywords)
filteredList = filteredList.Where(item => item.Contains(keyword));
foreach (var s in filteredList) // closure is called here
Console.WriteLine(s);
It's a common pitfall in C# to do something like that. If you look at the lambda expression inside Where, you'll see that it defines a function that it's behavior depends on the value of a variable at its definition site. It's like passing a variable itself to the function, rather than the value of that variable. Effectively, when this closure is called, it retrieves the value of keyword variable at that time. The result of this sample is very interesting. It prints out both "hello world" and "goodbye world", which is not what we wanted. What happened? As I said above, the function we declared with the lambda expression is a closure over keyword variable so this is what happens:
filteredList = filteredList.Where(item => item.Contains(keyword))
.Where(item => item.Contains(keyword));
and at the time of closure execution, keyword has the value "world," so we're basically filtering the list a couple times with the same keyword. The solution is:
foreach (var keyword in keywords) {
var temporaryVariable = keyword;
filteredList = filteredList.Where(item => item.Contains(temporaryVariable));
}
Since temporaryVariable is scoped to the body of the foreach loop, in every iteration, it is a different variable. In effect, each closure will bind to a distinct variable (those are different instances of temporaryVariable at each iteration). This time, it'll give the correct results ("hello world"):
filteredList = filteredList.Where(item => item.Contains(temporaryVariable_1))
.Where(item => item.Contains(temporaryVariable_2));
in which temporaryVariable_1 has the value of "hello" and temporaryVariable_2 has the value "world" at the time of closure execution.
Note that the closures have caused an extension to the lifetime of variables (their life were supposed to end after each iteration of the loop). This is also an important side effect of closures.
From what I understand a closure also has to have access to the variables in the calling context. Closures are usually associated with functional programming. Languages can have elements from different types of programming perspectives, functional, procedural, imperative, declarative, etc. They get their name from being closed over a specified context. They may also have lexical binding in that they can reference the specified context with the same names that are used in that context. Your example has no reference to any other context but a global static one.
From Wikipedia
A closure closes over the free variables (variables which are not local variables)
A closure is an implementation technique for representing procedures/functions with local state. One way to implement closures is described in SICP. I will present the gist of it, anyway.
All expressions, including functions are evaluated in an environement, An environment is a sequence of frames. A frame maps variable names to values. Each frame also has a
pointer to it's enclosing environment. A function is evaluated in a new environment with a frame containing bindings for it's arguments. Now let us look at the following interesting scenario. Imagine that we have a function called accumulator, which when evaluated, will return another function:
// This is some C like language that has first class functions and closures.
function accumulator(counter) {
return (function() { return ++counter; });
}
What will happen when we evaluate the following line?
accum1 = accumulator(0);
First a new environment is created and an integer object (for counter) is bound to 0 in it's first frame. The returned value, which is a new function, is bound in the global environment. Usually the new environment will be garbage collected once the function
evaluation is over. Here that will not happen. accum1 is holding a reference to it, as it needs access to the variable counter. When accum1 is called, it will increment the value of counter in the referenced environment. Now we can call accum1 a function with local state or a closure.
I have described a few practical uses of closures at my blog
http://vijaymathew.wordpress.com. (See the posts "Dangerous designs" and "On Message-Passing").
There's a lot of answers already, but I'll add another one anyone...
Closures aren't unique to functional languages. They occur in Pascal (and family), for instance, which has nested procedures. Standard C doesn't have them (yet), but IIRC there is a GCC extension.
The basic issue is that a nested procedure may refer to variables defined in it's parent. Furthermore, the parent may return a reference to the nested procedure to its caller.
The nested procedure still refers to variables that were local to the parent - specifically to the values those variables had when the line making the function-reference was executed - even though those variables no longer exist as the parent has exited.
The issue even occurs if the procedure is never returned from the parent - different references to the nested procedure constructed at different times may be using different past values of the same variables.
The resolution to this is that when the nested function is referenced, it is packaged up in a "closure" containing the variable values it needs for later.
A Python lambda is a simple functional-style example...
def parent () :
a = "hello"
return (lamda : a)
funcref = parent ()
print funcref ()
My Pythons a bit rusty, but I think that's right. The point is that the nested function (the lambda) is still referring to the value of the local variable a even though parent has exited when it is called. The function needs somewhere to preserve that value until it's needed, and that place is called a closure.
A closure is a bit like an implicit set of parameters.
Great question! Given that one of the OOP principles of OOP is that objects has behavior as well as data, closures are a special type of object because their most important purpose is their behavior. That said, what do I mean when I talk about their "behavior?"
(A lot of this is drawn from "Groovy in Action" by Dierk Konig, which is an awesome book)
On the simplest level a close is really just some code that's wrapped up to become an androgynous object/method. It's a method because it can take params and return a value, but it's also an object in that you can pass around a reference to it.
In the words of Dierk, imagine an envelope that has a piece of paper inside. A typical object would have variables and their values written on this paper, but a closure would have a list of instructions instead. Let's say the letter says to "Give this envelope and letter to your friends."
In Groovy: Closure envelope = { person -> new Letter(person).send() }
addressBookOfFriends.each (envelope)
The closure object here is the value of the envelope variable and it's use is that it's a param to the each method.
Some details:
Scope: The scope of a closure is the data and members that can be accessed within it.
Returning from a closure: Closures often use a callback mechanism to execute and return from itself.
Arguments: If the closure needs to take only 1 param, Groovy and other langs provide a default name: "it", to make coding quicker.
So for example in our previous example:
addressBookOfFriends.each (envelope)
is the same as:
addressBookOfFriends.each { new Letter(it).send() }
Hope this is what you're looking for!
An object is state plus function.
A closure, is function plus state.
function f is a closure when it closes over (captured) x
I think Peter Eddy has it right, but the example could be made more interesting. You could define two functions which close over a local variable, increment & decrement. The counter would be shared between that pair of functions, and unique to them. If you define a new pair of increment/decrement functions, they would be sharing a different counter.
Also, you don't need to pass in that initial value of x, you could let it default to zero inside the function block. That would make it clearer that it's using a value which you no longer have normal access to otherwise.

Resources