So, I'm trying to figure out Expression trees. I'm trying to add in a dynamic equals to a Queryable where T is one of several different tables. I'm first checking the table contains the field I want to filter on.
ParameterExpression param = Expression.Parameter(typeof(TSource), "x");
Expression conversionExpression = Expression.Convert(Expression.Property(param, _sourceProperty), typeof(TList));
Expression<Func<TSource, TList>> propertyExpression = Expression.Lambda<Func<TSource, TList>>(conversionExpression, param);
Expression<Func<TList, TList, bool>> methodExpression = (x, y) => x.Equals(y);
ReadOnlyCollection<ParameterExpression> parameters = propertyExpression.Parameters;
InvocationExpression getFieldPropertyExpression = Expression.Invoke(
propertyExpression,
parameters.Cast<Expression>());
MethodCallExpression methodBody = methodExpression.Body as MethodCallExpression;
MethodCallExpression methodCall = Expression.Call(methodBody.Method, Expression.Constant(equalTo), getFieldPropertyExpression);
Expression<Func<TSource, bool>> equalsStatement = Expression.Lambda<Func<TSource, bool>>(methodCall, parameters);
return source.Where(equalsStatement);
When I execute this, I get an issue with the MethodInfo in the Call statement. It tells me;
Static method requires null instance, non-static method requires non-null instance.
I'm no master of Expression trees, but I think I understand about 75% of what I'm doing here and know what I'm trying to achieve. The TList is a bad name right now, but I took this from an example that works to produce an In statement just fine.
I'm really looking for an explanation here so I can work through the code myself, or a solution with an explanation of what I was missing.
Edit:
Ok, so after a very frustrating afternoon and still not quite feeling like I understand what I'm looking at entirely, I think I have an answer.
ParameterExpression sourceObject = Expression.Parameter(typeof(TSource), "x");
Expression<Func<TSource, bool>> check = Expression.Lambda<Func<TSource, bool>>
(
Expression.Equal(
Expression.MakeMemberAccess(sourceObject, typeof(TSource).GetProperty(_sourceProperty)),
Expression.Constant(equalTo)
),
sourceObject
);
return source.Where(check);
Is anybody able to explain to me why the original just wasn't fit for what I was trying to do? I want to understand more about the actual process, but I feel I'm not picking it up as fast as I would like.
Expression.Call has two sets of overloads (with lots of overloads in each). One set is for instance methods and the other set is for static methods. In those for static methods, the first argument is a MethodInfo object -- exactly like you have. For instance methods, the first argument should be an Expression representing the target (i.e. the left-hand-side of the "." in a method call.) Given the error you are receiving, it sounds like the MethodInfo represents a non-static method, and therefore you must provide an expression representing the instance as the first argument.
Related
How can I know if I actually need to return an l-value when using FALLBACK?
I'm using return-rw but I'd like to only use return where possible. I want to track if I've actually modified %!attrs or have only just read the value when FALLBACK was called.
Or (alternate plan B) can I attach a callback or something similar to my %!attrs to monitor for changes?
class Foo {
has %.attrs;
submethod BUILD { %!attrs{'bar'} = 'bar' }
# multi method FALLBACK(Str:D $name, *#rest) {
# say 'read-only';
# return %!attrs{$name} if %!attrs«$name»:exists;
# }
multi method FALLBACK(Str:D $name, *#rest) {
say 'read-write';
return-rw %!attrs{$name} if %!attrs«$name»:exists;
}
}
my $foo = Foo.new;
say $foo.bar;
$foo.bar = 'baz';
say $foo.bar;
This feels a bit like a X-Y question, so let's simplify the example, and see if that answers helps in your decisions.
First of all: if you return the "value" of a non-existing key in a hash, you are in fact returning a container that will auto-vivify the key in the hash when assigned to:
my %hash;
sub get($key) { return-rw %hash{$key} }
get("foo") = 42;
dd %hash; # Hash %hash = {:foo(42)}
Please note that you need to use return-rw here to ensure the actual container is returned, rather than just the value in the container. Alternately, you can use the is raw trait, which allows you to just set the last value:
my %hash;
sub get($key) is raw { %hash{$key} }
get("foo") = 42;
dd %hash; # Hash %hash = {:foo(42)}
Note that you should not use return in that case, as that will still de-containerize again.
To get back to your question:
I want to track if I've actually modified %!attrs or have only just read the value when FALLBACK was called.
class Foo {
has %!attrs;
has %!unexpected;
method TWEAK() { %!attrs<bar> = 'bar' }
method FALLBACK(Str:D $name, *#rest) is raw {
if %!attrs{$name}:exists {
%!attrs{$name}
}
else {
%!unexpected{$name}++;
Any
}
}
}
This would either return the container found in the hash, or record the access to the unknown key and return an immutable Any.
Regarding plan B, recording changes: for that you could use a Proxy object for that.
Hope this helps in your quest.
Liz's answer is full of useful info and you've accepted it but I thought the following might still be of interest.
How to know if returning an l-value ... ?
Let's start by ignoring the FALLBACK clause.
You would have to test the value. To deal with Scalars, you must test the .VAR of the value. (For non-Scalar values the .VAR acts like a "no op".) I think (but don't quote me) that Scalar|Array|Hash covers all the l-value super-types:
my \value = 42; # Int is an l-value is False
my \l-value-one = $; # Scalar is an l-value is True
my \l-value-too = #; # Array is an l-value is True
say "{.VAR.^name} is an l-value is {.VAR ~~ Scalar|Array|Hash}"
for value, l-value-one, l-value-too
How to know if returning an l-value when using FALLBACK?
Adding "when using FALLBACK" makes no difference to the answer.
How can I know if I actually need to return an l-value ... ?
Again, let's start by ignoring the FALLBACK clause.
This is a completely different question than "How to know if returning an l-value ... ?". I think it's the core of your question.
Afaik, the answer is, you need to anticipate how the returned value will be used. If there's any chance it'll be used as an l-value, and you want that usage to work, then you need to return an l-value. The language/compiler can't (or at least doesn't) help you make that decision.
Consider some related scenarios:
my $baz := foo.bar;
... (100s of lines of code) ...
$baz = 42;
Unless the first line returns an l-value, the second line will fail.
But the situation is actually much more immediate than that:
routine-foo = 42;
routine-foo is evaluated first, in its entirety, before the lhs = rhs expression is evaluated.
Unless the compiler's resolution of the routine-foo call somehow incorporated the fact that the very next thing to happen would be that the lhs will be assigned to, then there would be no way for a singly or multiply dispatched routine-foo to know whether it can safely return an r-value or must return an l-value.
And the compiler's resolution does not incorporate that. Thus, for example:
multi term:<bar> is rw { ... }
multi term:<bar> { ... }
bar = 99; # Ambiguous call to 'term:<bar>(...)'
I can imagine this one day (N years from now) being solved by a combination of allowing = to be an overloadable operator, robust macros that allow overloading of = being available, and routine resolution being modified so the above ambiguous call could do something equivalent to resolving to the is rw multi. But I doubt it will actually come to pass even with N=10. Perhaps there is another way but I can't think of one at the moment.
How can I know if I actually need to return an l-value when using FALLBACK?
Again, adding "when using FALLBACK" makes no difference to the answer.
I want to track if I've actually modified %!attrs or have only just read the value when FALLBACK was called.
When FALLBACK is called it doesn't know what context it's being called in -- r-value or l-value. Any modification comes after it has already returned.
In other words, whatever solution you come up with will being nothing to do per se with FALLBACK (even if you have to use it to implement some other aspect of whatever it is you're trying to do).
(Even if it were, I suspect trying to solve it via FALLBACK itself would just make matters worse. One can imagine writing two FALLBACK multis, one with an is rw trait, but, as explained above, my imagination doesn't stretch to that making any difference any time soon, if ever, and could only happen if the above imaginary things happened (the macros etc.) and the compiler was also modified to pay attention to the two FALLBACK multi variants, and I'm not at all meaning to suggest that that even makes sense.)
Plan B
Or (alternate plan B) can I attach a callback or something similar to my %!attrs to monitor for changes?
As Lizmat notes, that's the realm of Proxys. And thus your next SO question... :)
I have an old compiler server (VS 2010), which, obviously, can't compile such instructions:
var result = a?.b()?.c?.d;
Is there alternative I can use? Is it possible to do this through expression tree? For example, like this:
var result = NullSafe(()=> a.b().c.d);
There were quite a few attempts to do this before it became a language feature. It's a bit hard to find the references now, but you can get an idea how it can be done and why it's not that easy.
This snippet for example looks simple:
public static R NullSafe<T, R>(this T obj, Func<T, R> f) where T : class
{
return obj != null ? f(obj) : default(R);
}
You can use it almost like an operator:
deliveryCode = order.NullSafe(o => o.DeliveryCompany).NullSafe(dc => dc.FileArtworkCode);
But it doesn't work with value types. This older snippet uses EqualityComparer :
public static TOut NullSafe<TIn, TOut>(this TIn obj, Func<TIn, TOut> memberAction)
{
//Note we should not use obj != null because it can not test value types and also
//compiler has to lift the type to a nullable type for doing the comparision with null.
return (EqualityComparer<TIn>.Default.Equals(obj, default(TIn)))
? memberAction(obj)
: default(TOut);
}
It will take a bit of digging to find more complete examples. I remember trying methods similar to these way back when until I found a more complete one.
This SO answer to a similar question does away with chaining and allows one to write:
foo.PropagateNulls(x => x.ExtensionMethod().Property.Field.Method());
The implementation is a bit involved though, to say the least.
Coming from a C# background, I would say that the ref keyword is very useful in certain situations where changes to a method parameter are desired to directly influence the passed value for value types of for setting a parameter to null.
Also, the out keyword can come in handy when returning a multitude of various logically unconnected values.
My question is: is it possible to pass a parameter to a function by reference in Haskell? If not, what is the direct alternative (if any)?
There is no difference between "pass-by-value" and "pass-by-reference" in languages like Haskell and ML, because it's not possible to assign to a variable in these languages. It's not possible to have "changes to a method parameter" in the first place in influence any passed variable.
It depends on context. Without any context, no, you can't (at least not in the way you mean). With context, you may very well be able to do this if you want. In particular, if you're working in IO or ST, you can use IORef or STRef respectively, as well as mutable arrays, vectors, hash tables, weak hash tables (IO only, I believe), etc. A function can take one or more of these and produce an action that (when executed) will modify the contents of those references.
Another sort of context, StateT, gives the illusion of a mutable "state" value implemented purely. You can use a compound state and pass around lenses into it, simulating references for certain purposes.
My question is: is it possible to pass a parameter to a function by reference in Haskell? If not, what is the direct alternative (if any)?
No, values in Haskell are immutable (well, the do notation can create some illusion of mutability, but it all happens inside a function and is an entirely different topic). If you want to change the value, you will have to return the changed value and let the caller deal with it. For instance, see the random number generating function next that returns the value and the updated RNG.
Also, the out keyword can come in handy when returning a multitude of various logically unconnected values.
Consequently, you can't have out either. If you want to return several entirely disconnected values (at which point you should probably think why are disconnected values being returned from a single function), return a tuple.
No, it's not possible, because Haskell variables are immutable, therefore, the creators of Haskell must have reasoned there's no point of passing a reference that cannot be changed.
consider a Haskell variable:
let x = 37
In order to change this, we need to make a temporary variable, and then set the first variable to the temporary variable (with modifications).
let tripleX = x * 3
let x = tripleX
If Haskell had pass by reference, could we do this?
The answer is no.
Suppose we tried:
tripleVar :: Int -> IO()
tripleVar var = do
let times_3 = var * 3
let var = times_3
The problem with this code is the last line; Although we can imagine the variable being passed by reference, the new variable isn't.
In other words, we're introducing a new local variable with the same name;
Take a look again at the last line:
let var = times_3
Haskell doesn't know that we want to "change" a global variable; since we can't reassign it, we are creating a new variable with the same name on the local scope, thus not changing the reference. :-(
tripleVar :: Int -> IO()
tripleVar var = do
let tripleVar = var
let var = tripleVar * 3
return()
main = do
let x = 4
tripleVar x
print x -- 4 :(
I have a question about using the new Objects.compare(o1, o2, Comparator) method - from my own testing of it, if both o1 and o2 are null then it returns 0, however, if one of them is null then it still throws a null pointer exception. I have found a lot of material on Objects.equals and some of the other Objects utility methods but not much at all on Objects.compare and when we are expected to use it / replace old code with it.
So here I could do this:
String s1 = "hi";
String s2 = "hi";
int x = Objects.compare(s1, s2, Comparator.naturalOrder());
System.out.println("x = " + x);
That works fine, returns 0, now this:
String s1 = null;
String s2 = null;
Also works fine and returns 0. However, this:
String s1 = "hi";
Strng s2 = null;
Throws a NullPointerException. I'm guessing the benefit of Objects.compare(o1,o2,Comparator) vs o1.compareTo(o2) is that it at least handles circumstances where both objects are null and when one of them is null it allows you to design a Comparator to handle it. I'm supposing, e.g.
int x = Objects.compare(s1, s2, Comparator.nullsFirst(Comparator.naturalOrder()));
Whereas with x.compareTo(y) there's no way to handle null unless you do so beforehand? So do the Java library developers now intend us to replace all calls to compareTo with Objects.compare, when we're concerned about nulls? e.g. would we do this in our Comparable implementations?
Side query 1: With regards to using nullsFirst if you use it then pass in a Comparator, which is chained using comparing, thenComparing, etc, does it apply to all of the inner comparators? e.g.
Comparator.nullsFirst(Comparator.comparing(Song::getTitle)
.thenComparing(Song::getArtist)
.thenComparing(Song::getDuration)
)
Would that apply nullsFirst to everything inside or do you need to use nullsFirst individually on each of them? I think from testing that it only applies to the actual Song objects being null, not for the fields of title or artist being null, i.e. if they are null then a NullPointerException is still thrown. Anyway around that?
Side query 2: final question is that because I like the Comparator.comparing syntax, I'm proposing to start to write my compareTo implementions using it - I was struggling to think how to replace this traditional approach, e.g.
public int compareTo(Song other) {
int result = this.title.compareTo(other.title);
if (result == 0) {
result = this.artist.compareTo(other.artist);
if (result == 0) {
result = Integer.compare(this.duration, other.duration);
}
}
return result;
}
then I thought I could use Objects.compare(...) as follows:
public int compareTo(Song other) {
return Objects.compare(this, other, Comparator.nullsFirst(
Comparator.comparing(Song::getTitle)
.thenComparing(Song::getArtist)
.thenComparingInt(Song::getDuration)
));
}
I thought this version was more elegant - I am assuming it is working as I think it is, e.g. by passing this and other as the first 2 arguments then the comparator, it has the same effect as the traditional compareTo approach with if statements? Whilst I can see that the benefit of Objects.compare catching two nulls would never occur as if this was null then the compareTo method call would never be reached (either by handling the exception or it being thrown). But by using nullsFirst I suppose if the argument passed in, i.e. other, was null, then this would handle this safely?
Many thanks in advance for any help.
Objects.compare is not meant to provide a null safe comparison, since there is no default behavior that could be implemented. It just implements a shortcut of not invoking the Comparator’s method when both objects are identical. In other words, it does a==b? 0: c.compare(a, b), nothing more. So not breaking when both objects are null is just a side-effect. The encapsulated code might look trivial but the other methods in this class are of a similar category. Using small utility methods a lot might still result in a notable win.
By the way, it’s not a Java 8 method at all. It exists since Java 7.
Regarding your second question, Comparator.nullsFirst(…) decorates an existing Comparator and will enforce the rule for null values before delegating to the provided comparator as it is the purpose of this comparator to shield the existing one from ever seeing null values. It doesn’t matter whether the decorated comparator is a chained one or not. As long as it is what you called the “inner comparator”, as
you must not invoke thenComparing on the result of nullsFirst as that would imply calling the next comparator when both values are null.
Comparator.nullsFirst(Comparator.comparing(a).thenComparing(b)) // perfect
Comparator.nullsFirst(Comparator.comparing(a)).thenComparing(b) // ouch
Now to your third question, implementing a compareTo method using a nullsFirst comparator is violating the interface specification:
The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)
This implies that passing null as argument should always result in a NullPointerException as swapping argument and receiver would throw as well, unconditionally.
Orders including a null policy should always be provided as separate Comparators.
Note that it would also be quite inefficient as you would create a new Comparator (multiple Comparators, to be precise) for every compareTo call. Now image sorting a rather large list of these objects…
What I normally do for your final question is to first create a static comparator reference within the class:
public static final Comparator<Song> COMP_DEFAULT
= nullsFirst(comparing(Song::getTitle, nullsFirst(naturalOrder()))
.thenComparing(Song::getArtist, nullsFirst(naturalOrder()))
.thenComparingInt(Song::getDuration));
And then refer to this comparator in compareTo
public int compareTo(Song other) {
return COMP_DEFAULT.compare(this, other);
}
This way you're not recreating your comparator for each compareTo call, null safety of Song is guaranteed as is the result of a.comparetTo(b) == b.compareTo(a).
We also ensure null safety of each property by using nullsFirst(naturalOrder()) for the passed in key comparator (second argument).
As the Comparator returned is immutable it can be made public which can be handy for bundling some alternate Comparators with the class that consumers may use.
I am using the PredicateBuilder class from http://www.albahari.com/nutshell/predicatebuilder.aspx
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
this extension method is chaining Predicates with the OR operator. on the page, the explanation says
We start by invoking the second expression with the first expression’s parameters. An Invoke expression calls another lambda expression using the given expressions as arguments. We can create the conditional expression from the body of the first expression and the invoked version of the second. The final step is to wrap this in a new lambda expression.
so if for example i have
Predicate<Book> p1 = b => b.Title.Contains("economy");
Predicate<Book> p2 = b=>b.PublicationYear>2001;
Predicate chain = p1.And(p2);
I didn't quite get the exlanation. can someone please explain how the code of the extension method above is working?
thanks
Let's rewrite the method body like this:
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
expr1.Body,
Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>())
),
expr1.Parameters);
We should also keep in mind that expr1 is your existing expression that takes a T and returns a bool. Additionally, while the expression trees we are working with do not actually do anything (they represent something instead), I am going to use "do" henceforth because it makes for much easier reading. Technically for an expression tree to actually do something you have to compile it first and then invoke the resulting delegate.
Ok, so what do we have here? This is a lambda expression that takes whatever parameters expr1 takes (see last line) and whose body, as per the documentation, is
a BinaryExpression that represents a conditional OR operation that
evaluates the second operand only if the first operand evaluates to
false.
The first operand is expr1.Body, which means the resulting function (not actually a function, see note above) evaluates expr1. If the result is true it returns true on the spot. Otherwise, it invokes expr2 with the same parameters as those passed to expr1 (this means the single T parameter) and returns the result of that.