Sonar tells me "Replace this lambda with a method reference"
public class MyClass {
private List<SomeValue> createSomeValues(List<Anything> anyList) {
return anyList //
.stream() //
.map(anything -> createSomeValue(anything)) //
.collect(Collectors.toList());
}
private SomeValue createSomeValue(Anything anything) {
StatusId statusId = statusId.fromId(anything.getStatus().getStatusId());
return new SomeValue(anything.getExternId(), statusId);
}
}
Is this possible here? I tried several things, like
.map(MyClass::createSomeValue) //
but I need to change the method to static then. And I am not a big fan of static methods.
Explanation of SonarQube is:
Method/constructor references are more compact and readable than using lambdas, and are therefore preferred.
Yes, you can use this::createSomeValue:
private List<SomeValue> createSomeValues(List<Anything> anyList) {
return anyList //
.stream() //
.map(this::createSomeValue) //
.collect(Collectors.toList());
}
This kind of method reference is called "Reference to an instance method of a particular object". In this case, you are referring to the method createSomeValue of the instance this.
Whether it is "better" or not that using a lambda expression is a matter of opinion. However, you can refer to this answer written by Brian Goetz that explains why method-references were added in the language in the first place.
Related
This question already has answers here:
How does method reference casting work?
(3 answers)
Closed last month.
This post was edited and submitted for review last month and failed to reopen the post:
Original close reason(s) were not resolved
I'm learning Java 8 with Lambda, Streams, and method reference. Regarding the example below,
Optional<String> s = Optional.of("test");
System.out.println(s.map(String::toUpperCase).get());
I don't understand how is it possible to use String::toUpperCase as an input for this map() method.
This is the method implementation:
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
So it requires a function interface, and it has this apply() method: R apply(T t); This method has an input argument.
And toUpperCase() method doesn't have any argument:
public String toUpperCase() {
return toUpperCase(Locale.getDefault());
}
If the abstract method apply(T t) has one argument, then the implemented method should have one argument of the same type. How can parameterless method toUpperCase() implement the apply(T t) method from a function interface?
I try to recreate the same conditions:
I create a functional interface:
public interface Interf {
String m1(String value);
}
Then I create a class with the method reference for m1():
public class Impl {
public String value;
public String toUpp() {
return value.toUpperCase();
}
}
And here is a class for test:
public class Test {
public static void main(String[] args) {
Interf i = String::toUpperCase;
System.out.println(i.m1("hey"));
Interf i1 = Impl::toUpp;
System.out.println(i.m1("hello"));
}
}
There isn't any issue at this statement: Interf i = String::toUpperCase; but there is a compilation error on this line: Interf i1 = Impl::toUpp;. It says:
Non-static method cannot be referenced from a static context
But toUpperCase() is also a non-static method. And even if I make the toUpp() static, it is still not working, it is working only if I add a String argument as an input argument for toUpp(). But then why is it working for String::toUpperCase?
TL;DR
Parameters that a Method reference is expected to consume according to the contract imposed by a Functional interface it implements are NOT necessarily the same as parameters of the method used in the Method reference.
This answer is a journey from this common misconception towards understanding all syntactical flavors of Method references.
Let's take tiny baby steps to dispel misunderstanding, starting from the definition of the Method reference.
What is Method reference
Here is the definition of the Method reference according to the Java Language Specification §15.13. Method Reference Expressions
A method reference expression is used to refer to the invocation of a
method without actually performing the invocation. Certain forms of
method reference expression also allow class instance creation (§15.9)
or array creation (§15.10) to be treated as if it were a method
invocation.
emphasis added
So, a Method reference is a mean of referring the method-invocation without invoking a method. Or in other words, it's a way of describing a certain behavior by delegating to the existing functionality.
Let's take a small detour and have a look at the sibling of a Method reference, a Lambda expression.
Lambda expressions are also a way to describe behavior (without executing it), and both lambdas and Method references should conform to a Functional interface. Let's declare some lambdas.
Consider, we have a domain class Foo and utility class FooUtils.
public class FooUtils {
public static Foo doSomethingWithFoo(Foo foo) {
// do something
return new Foo();
}
}
And we need to define a function of type UnaryOperator<Foo>, let's start with writing a lambda expression:
UnaryOperator<Foo> fooChanger = foo -> FooUtils.doSomethingWithFoo(foo);
Lambda receives an instance of Foo as an argument and feeds it into the existing utility method. Quite simple, right? Nothing special happens inside the lambda's body, and since have defined the type as UnaryOperator<Foo> the lambda should expect Foo. Everything is absolutely predictable, isn't it? Now the question is: can we alternate that?
Sure, we can!
UnaryOperator<Foo> fooChanger = FooUtils::doSomethingWithFoo;
That's where a Method reference comes to the rescue. It provides a shortened syntax by:
1. Dropping the lambda's arguments (they are still there, we're simply not displaying them because we know what they are).
2. Removing the parentheses after the method name. Again the method declaration is known (and let's assume that there are no ambiguities), and we are not performing any prior transformation with arguments, and we are not using any additional arguments apart from those that should come according to the contract of the Functional interface. Only in this case everything is predictable and can a method reference.
Key takeaways:
you may think of method references as if they are shortened lambdas.
the arguments of the method reference are the same the equivalent lambda receives because they are implementations to the same interface. These parameters are still there implicitly, just dropped for the purpose of conciseness. And more importantly, parameters that a method reference consumes should not be confused with parameters expected method it refers to. In other word the first parameters an input of the method reference (and they are compliant with the contract defined by the interface) and the latter related to what happens inside the reference, and have no connection to the first ones.
More examples
Let's examine a few more examples. Let's say we have a simple object representing a coin with a single property isHeads describing which side the coin is showing (i.e. heads or tails).
public static class Coin {
public static final Random RAND = new Random();
private final boolean isHeads;
public Coin() {
this.isHeads = RAND.nextBoolean();
}
private Coin(boolean isHeads) {
this.isHeads = isHeads;
}
public Coin reverse() {
return new Coin(!isHeads);
}
public boolean isHeads() {
return isHeads;
}
}
Let's generate a coin. For that we can use implement of Supplier which very generous, supplier doesn't receive arguments, it produces a value. Let's definable both a lambda and a reference
Supplier<Coin> coinProducer = () -> new Coin(); // no argument required according to the contract of Supplier
Supplier<Coin> coinProducer1 = Coin::new; // Supplier expressed as a reference to no-args constructor
Both don't receive any argument (as per contract of the Supplier), both refer to the no-arguments constructor.
Now let's consider the predicates determining if the coin shows heads implemented via a lambda and a method reference:
Predicate<Coin> isHeads = coin -> coin.isHeads();
Predicate<Coin> isHeads1 = Coin::isHeads;
Again, both the lambda and the method reference are compliant with the Predicate's contract and both receive an instance of Coin as an argument (it can't be otherwise, simply concise syntax of the method reference doesn't show that).
So far, so good? Let's move further and try another way to obtain a Coin, let's define a Function:
Function<Boolean, Coin> booleanToCoin = value -> new Coin(value);
Function<Boolean, Coin> booleanToCoin1 = Coin::new;
Now both the lambda and the reference are consuming a boolean value and making use of the parameterized constructor. Did not notice that method reference describing Supplier<Coin> and Function<Boolean, Coin> looks identical.
Reminder: both Lambda expressions and Method references have no type by itself. They are so-called poly-expressions, which means their type should be inferred by the compiler based on the context in which they appear. Both the lambda and the reference should conform to a Functional interface, and the interface they implement dictates who they are and what they are doing.
In all examples described earlier, arguments of consumed by a method reference appeared to be the same as the ones expected by the referenced method, but it's not mandatory for them to be the identical. It's time to examine a couple or examples where it not the case to dispel the illusions.
Let's consider a UnaryOperator reversing a coin:
UnaryOperator<Coin> coinFlipper = coin -> coin.reverse(); // UnaryOperator requires one argument
UnaryOperator<Coin> coinFlipper1 = Coin::reverse; // UnaryOperator still requires one argument expressed as a reference to no arg method
All implementations of the UnaryOperator receive a Coin instance as an argument, and another coin is being produced as a result of the invocation of reverse(). The fact that reverse is parameterless is not an issue, because we concerned about what it produces, and not what it consumes.
Let's try to define a tougher method reference. To begin with, introduce in the Coin class a new instance method called xor(), which is immensely useful for XOR-ing two coins:
public Coin xor(Coin other) {
return new Coin(isHeads ^ other.isHeads);
}
Now when two object come into play we have more possibilities, let's start with the simplest case one by defining a UnariOperator:
final Coin baseCoin = new Coin();
UnaryOperator<Coin> xorAgainstBase = coin -> baseCoin.xor(coin);
UnaryOperator<Coin> xorAgainstBase1 = baseCoin::xor;
In the above example an instance of Coin defined outside the function is used to perform the transformation via the instance-method.
A little bit more complicated case would be a BinaryOperator for XOR-ing a couple of coins might look like this:
BinaryOperator<Coin> xor = (coin1, coin2) -> coin1.xor(coin2);
BinaryOperator<Coin> xor1 = Coin::xor;
Now we have two arguments coming as an input and a Coin instance should be produce as an output as per BinaryOperators contract.
The interesting thing is the first argument serves as an instance on which the method xor() would be invoked, and the second is passed to the method (note that xor() expect only one argument).
You might ask what would happen if there would be another method for XOR-ing coins. A static method expecting two arguments:
public static Coin xor(Coin coin1, Coin coin2) {
return new Coin(coin1.isHeads ^ coin2.isHeads);
}
Then the compiler would fail to resolve the method reference, because here we have more the one potentially applicable method and none of them can be considered to be more specific than the other since the types of arguments are the same. That would cause a compilation error. But if we would have either of them (not both together), reference Coin::xor would work fine.
Types of Method references
Basically, the examples that we have walked through covered all the types of method references. Now, let's enumerate them.
The official tutorial provided by Oracle re are four kinds of method references:
Reference to a Static method
Class::staticMethod
Example Coin::xor which refers to the static method xor(Coin coin1, Coin coin2).
Examples with standard JDK-classes:
BinaryOperator<Integer> sum = Integer::sum; // (i1, i2) -> Integer.sum(i1, i2)
BiFunction<CharSequence, Iterable<CharSequence>, String> iterableToString
= String::join; // (delimiter, strings) -> String.join(delimiter, strings)
Reference to an instance method of a particular object
instance::instanceMethod
The example illustrating this case would the usage of the instance method xor(Coin other) with a coin defined outside the function, which is internaly used to invoke xor() on it passing the function-argument into the method.
final Coin baseCoin = new Coin();
UnaryOperator<Coin> xorAgainstBase1 = baseCoin::xor; // same as coin -> baseCoin.xor(coin)
Examples with standard JDK-classes:
Set<Foo> fooSet = // initialing the Set
Predicate<Foo> isPresentInFooSet = fooSet::contains;
Reference to an Instance Method of an Arbitrary Object of a Particular Type
Class::methodName
In this case method refernce operates on an instance that comes as an argument (we would have reference to it only it we would use a lambda), therefore containing type, which can be tha actual type or one the super types, is used to refer to this instance.
An example would a Predicate checking if the coin shows heads Coin::isHeads.
Examples with standard JDK-classes:
Function<List<String>, Stream<String>> toStream = Collection::stream;
List<List<String>> lists = List.of(List.of("a", "b", "c"), List.of("x", "y", "z"));
List<String> strings1 = lists.stream()
.flatMap(toStream)
.toList();
// A slightly more complicate example taken from the linked tutorial
// Equivalent lambda: (a, b) -> a.compareToIgnoreCase(b)
String[] stringArray = { "Barbara", "James", "Mary" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
Reference to a Constructor
Class::new
We have cove this case already with the following examples:
Supplier<Coin> refering to no args-constracor implemented as Coin::new;
Function<Boolean, Coin> which makes use of the single-arg constructor by passing incoming boolean value also expressed as Coin::new.
How can toUpperCase() method implement apply(T t) method from Function
interface?
The method reference String::toUpperCase has unbound receiver.
Java 8: Difference between method reference Bound Receiver and UnBound Receiver
Then the argument T t would be the receiver
In your example
public <U, T> Optional<U> map(Function<? super T, ? extends U> mapper) {
...
return Optional.ofNullable(mapper.apply(value));
}
by calling map(String::toUpperCase)
If value, let's say equal to "Example String", would be the receiver so mapper.apply("Example String"); would be equivalent to "Example String".toUpperCase();
In Java 8+ we have Function.identity() which will return back the input object - equivalent to t -> t
Is there a predefined function or another way that returns this - equivalent to () -> this? If so, does it provide a benefit? (for example, saved allocations and anonymous class definitions)
Edit
Perhaps this question deserves some expansion. A specific case I am looking at is java.util.concurrent.CompletableFuture#completeAsync(java.util.function.Supplier<? extends T>)
I have a class that holds a value and a future that will eventually resolve, but not until another component is ready. I don't want to complete it with future.complete(...) because the calling thread would have to perform any chained actions.
class Thing<T> {
final T value;
final CompletableFuture<T> future;
Thing<T> self() {
return this;
}
void reject() {
future.cancel(false);
}
void complete() {
// Does allocating the lambda here have a cost?
future.complete(() -> this);
// Does passing a method reference avoid one?
future.complete(this::self);
}
}
From outside: If you have an object o and want to get something like o.getThis() and expect the refernce to oas a result, why not use o directly?
From inside: As soon as you are running code within o, it can reference other fields or methods by indicating this.otherField. An alternative would be to reference something inherited, which could end up in super.otherField.
So I do not see any benefit here to have one more function.
My code:
class BlogPost {
String title;
String author;
BlogPostType type;
int likes;
public BlogPost(String title, String author, BlogPostType type, int likes) {
this.title = title;
this.author = author;
this.type = type;
this.likes = likes;
}
//getter setter
}
and:
public enum BlogPostType {
NEWS,
REVIEW,
GUIDE
}
and:
public static void main(String[] args) {
List<BlogPost> posts = Arrays.asList(new BlogPost("Start Java", "Ram", BlogPostType.NEWS, 11),
new BlogPost("Start Java 8", "Rajou", BlogPostType.REVIEW, 101),
new BlogPost("Functional programming", "Das", BlogPostType.REVIEW, 111),
new BlogPost("Lambda", "Ramos", BlogPostType.GUIDE, 541));
Map<BlogPostType, List<BlogPost>> Blist = posts.stream().collect(groupingBy(BlogPost::getType));
System.out.println(Blist);
}}
I have three classes one is BlogPost , BlogPostType and Main.
I am making a map of Map<BlogPostType, List<BlogPost>> Blist by using groupingBy() and it works perfectly fine. i used a method reference there BlogPost::getType , i can use lambda expression also (x) -> x.getType().
But when i try to change the type of Map , i.e Map<String, List<BlogPost>> Blist1 then i cannot use Method reference. Is there any possible way to use method reference and get the type also changed??
I am thinking why cant we use like this: BlogPost::getType.toString() or (String)BlogPost::getType while we can do this in lambda (x) -> x.getType().toString().
Any possible ways to use Method reference and get along with conversion of type also?
you can use Function.identity() to chain method references (as many as you want). For example, put the following function in groupingBy:
Function.<BlogPost>identity()
.andThen(BlogPost::getType)
.andThen(BlogPostType::toString)
but it's better to use lambda
Method reference in place of lambda expression makes your code more
readable, hence it is advised to replace lambda expression with method
reference, Whenever Possible.
Remember a method reference replace a single method invocation , in your case BlogPost::getType will work fine while BlogPost::getType.toString() will not work as it is not single method invocation.
A method reference replace a single method invocation, so it can’t simply replace a lambda expression consisting of more than one method invocation.
You can do it with two method references as follows, but I'd stick with the lambda expression, which is much simpler.
Map<String, List<BlogPost>> Blist =
posts.stream()
.collect(Collectors.groupingBy(((Function<BlogPost,BlogPostType>)BlogPost::getType).andThen(BlogPostType::toString)));
or
Function<BlogPost,BlogPostType> getType = BlogPost::getType;
Map<String, List<BlogPost>> Blist =
posts.stream()
.collect(Collectors.groupingBy(getType.andThen(BlogPostType::toString)));
A method reference is just that: a "reference" to some specific method.
There is no implicit conversion or anything. Just a method that has a certain signature, and syntactic shortcut to express that without writing down a lambda expression.
If you want to use a method reference, that thing must exist as method. In other words, you would need to a new method like
String getTypeAsString()
to your BlogPost class. Only then you can go and directly invoke that method via a method reference.
But in your case, simply use that lambda expression instead that calls toString() explicitly. It sounds wrong to have a special method there that does "almost" the same as another method, just to enable you to write down a method reference.
Alternatively, follow the interesting approach pointed out in Eran's answer to use andThen().
In the end, your focus should be to write code that is easy to read and understand for you and your team. My personal recommendation would be to use the lambda right there, as all other solutions just add a lot of noise for no real gain.
I was reading this tutorial on Java 8 where the writer showed the code:
interface Formula {
double calculate(int a);
default double sqrt(int a) {
return Math.sqrt(a);
}
}
And then said
Default methods cannot be accessed from within lambda expressions. The
following code does not compile:
Formula formula = (a) -> sqrt( a * 100);
But he did not explain why it is not possible. I ran the code, and it gave an error,
incompatible types: Formula is not a functional interface`
So why is it not possible or what is the meaning of the error? The interface fulfills the requirement of a functional interface having one abstract method.
It's more or less a question of scope. From the JLS
Unlike code appearing in anonymous class declarations, the meaning of
names and the this and super keywords appearing in a lambda body,
along with the accessibility of referenced declarations, are the same
as in the surrounding context (except that lambda parameters introduce
new names).
In your attempted example
Formula formula = (a) -> sqrt( a * 100);
the scope does not contain a declaration for the name sqrt.
This is also hinted at in the JLS
Practically speaking, it is unusual for a lambda expression to need to
talk about itself (either to call itself recursively or to invoke its
other methods), while it is more common to want to use names to refer
to things in the enclosing class that would otherwise be shadowed
(this, toString()). If it is necessary for a lambda expression to
refer to itself (as if via this), a method reference or an anonymous
inner class should be used instead.
I think it could have been implemented. They chose not to allow it.
Lambda expressions work in a completely different way from anonymous classes in that this represents the same thing that it would in the scope surrounding the expression.
For example, this compiles
class Main {
public static void main(String[] args) {
new Main().foo();
}
void foo() {
System.out.println(this);
Runnable r = () -> {
System.out.println(this);
};
r.run();
}
}
and it prints something like
Main#f6f4d33
Main#f6f4d33
In other words this is a Main, rather than the object created by the lambda expression.
So you cannot use sqrt in your lambda expression because the type of the this reference is not Formula, or a subtype, and it does not have a sqrt method.
Formula is a functional interface though, and the code
Formula f = a -> a;
compiles and runs for me without any problem.
Although you cannot use a lambda expression for this, you can do it using an anonymous class, like this:
Formula f = new Formula() {
#Override
public double calculate(int a) {
return sqrt(a * 100);
}
};
That's not exactly true. Default methods can be used in lambda expressions.
interface Value {
int get();
default int getDouble() {
return get() * 2;
}
}
public static void main(String[] args) {
List<Value> list = Arrays.asList(
() -> 1,
() -> 2
);
int maxDoubled = list.stream()
.mapToInt(val -> val.getDouble())
.max()
.orElse(0);
System.out.println(maxDoubled);
}
prints 4 as expected and uses a default method inside a lambda expression (.mapToInt(val -> val.getDouble()))
What the author of your article tries to do here
Formula formula = (a) -> sqrt( a * 100);
is to define a Formula, which works as functional interface, directly via a lambda expression.
That works fine, in above example code, Value value = () -> 5 or with Formula as interface for example
Formula formula = (a) -> 2 * a * a + 1;
But
Formula formula = (a) -> sqrt( a * 100);
fails because it's trying to access the (this.)sqrt method but it can't.
Lambdas as per spec inherit their scope from their surroundings, meaning that this inside a lambda refers to the same thing as directly outside of it. And there is no sqrt method outside.
My personal explanation for this: Inside the lambda expression, it's not really clear to what concrete functional interface the lambda is going to be "converted". Compare
interface NotRunnable {
void notRun();
}
private final Runnable r = () -> {
System.out.println("Hello");
};
private final NotRunnable r2 = r::run;
The very same lambda expression can be "cast" to multiple types. I think of it as if a lambda doesn't have a type. It's a special typeless function that can be used for any Interface with the right parameters. But that restriction means that you can't use methods of the future type because you can't know it.
This adds little to the discussion, but I found it interesting anyways.
Another way to see the problem would be to think about it from the standpoint of a self-referencing lambda.
For example:
Formula formula = (a) -> formula.sqrt(a * 100);
It would seem that this ought to make sense, since by the time the lambda gets to be executed the formula reference must have already being initialized (i.e. there is not way to do formula.apply() until formula has been properly initialized, in whose case, from the body of the lambda, the body of apply, it should be possible to reference the same variable).
However this does not work either. Interestingly, it used to be possible at the beginning. You can see that Maurice Naftalin had it documented in his Lambda FAQ Web Site. But for some reason the support for this feature was ultimately removed.
Some of the suggestions given in other answers to this question have been already mentioned there in the very discussion in the lambda mailing list.
Default methods can be accessed only with object references, if you want to access default method you'd have an object reference of Functional Interface, in lambda expression method body you won't have so can't access it.
You are getting an error incompatible types: Formula is not a functional interface because you have not provided #FunctionalInterface annotation, if you have provided you'll get 'method undefined' error, compiler will force you to create a method in the class.
#FunctionalInterface must have only one abstract method your Interface has that but it is missing the annotation.
But static methods have no such restriction, since we can access it with out object reference like below.
#FunctionalInterface
public interface Formula {
double calculate(int a);
static double sqrt(int a) {
return Math.sqrt(a);
}
}
public class Lambda {
public static void main(String[] args) {
Formula formula = (a) -> Formula.sqrt(a);
System.out.println(formula.calculate(100));
}
}
I just started to learn about Lambda Expression and I did something like this:
public class LambdaTest {
public static void main(String[] args) {
int num = returnNumber((num) -> { return 4 });
}
public static int returnNumber(int num) {
return num;
}
}
But it gives me an error: "invalid tokens". Here is an image:
Can someone please explain me what's wrong? It's just a test.
I have Java 1.8 supported in my Eclipse installation (Luna 4.4).
There are a few restrictions on what can be done in the body of the lambda, most of which are pretty intuitive—a lambda body can’t “break” or “continue” out of the lambda, and if the lambda returns a value, every code path must return a value or throw an exception, and so on. These are much the same rules as for a standard Java method, so they shouldn’t be too surprising.
Reference : http://www.oracle.com/technetwork/articles/java/architect-lambdas-part1-2080972.html
The method's body has the effect of evaluating the lambda body, if it
is an expression, or of executing the lambda body, if it is a block;
if a result is expected, it is returned from the method.
If the function type's result is void, the lambda body is either a
statement expression or a void-compatible block.
Reference : http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.27.4
The syntax error is pretty straight-forward. It says that there is a ; missing after a statement and that’s in no ways other than with statements outside lambda expressions. If you write (num) -> { return 4 }, there must be a semicolon after return 4 as it would have to be at every place where you can write return 4 (I’m astounded why nobody else was capable of telling you that).
You can write a lambda expression returning an int in two ways, either like (num) -> { return 4; } or, much simpler, as num -> 4 (here, without semicolon).
But, of course, you can’t call returnNumber(int num) with a lambda expression as parameter as it expects an int and not a functional interface. Your compiler will tell you that once you fixed the structural syntax error of the missing semicolon.
Lambdas are just implementations for method of functional interface (interfaces with one abstract methods), but in case of
returnNumber(int num)
lambdas can't be used because:
int is not an functional interface
so lambdas can't be used to supply implementation of its only abstract method (since primitive types are primitive - they have no methods).
Before lambdas to execute method like
method(SomeInterface si){...}
you would need to either create separate class which would implement this interface
class MyClass implements SomeInterface{
void method(Type1 arg1, Type2 arg2){
//body
}
}
...
MyClass mc = new MyClass();
method(md);
or add its implementation on fly by creating anonymous class
method(new SomeInterface{
void method(Type1 arg1, Type2 arg2){
//body
}
});
Lambdas can shorten this process by skipping this idiom and letting you focus only on arguments types, and implementation.
So instead of
new SomeInterface{
void method(Type1 arg1, Type2 arg2){
//body
}
}
you can simply write
(Type1 arg1, Type2 arg2) -> { body } // you can actually shorten it even farther
// but that is not important now