I saw this construction in rationals.jl, and I am trying to understand it. I can write
struct Bar
y
global func(x) = new(x)
end
Then if I try:
a = Bar()
I get an error. It is like func is now an inner constructor. And I can actually use it by writing:
a = func(2)
If I remove the keyword global, I can't use this inner constructor anymore. What is going on? Why is global there, and could I use the inner constructor somehow without it (perhaps by qualifying the name)?
How can the inner constructor have a different name than the struct itself? What, in fact, is an inner constructor?
TL/DR
An inner constructor is a method of the struct type (i.e., (::Type{Bar})(...) which has access to new. You can put arbitrary method definitions inside a struct -- there is no technical requirement to only have inner constructors -- but this is only useful in rare cases.
Long version
This is a rare case that the manual doesn't even cover explicitely (and I long didn't know was legal at all). In my understanding, two rules apply:
Inside the struct definition, and only there, you are allowed to use new.
If any inner constructor method is defined, no default constructor method is provided: it is presumed that you have supplied yourself with all the inner constructors you need.
However, nothing requires the inner constructor to be a method of the struct type! Instead you may actually define arbitrary methods.
And then, scoping applies. With a "regular" inner constructor, what you get is a method for Type{Bar}. This requires no global, as the type is present in outer scope.
In your case, without the global, func is local and so there is no constructor accessible at all outside the struct definition. This makes little sense. The global function definition is something that can be useful in rare cases when you want to prevent direct construction of values of you type, but only allow conversion. I have seen this kind of pattern:
struct Baz
Base.reinterpret(::Type{Baz}, ...) = new(...)
end
This adds a (globally available) method to reinterpret, the only entry point to constructing Bazes. Putting it inside the struct is necessary, as at some place you need to create the object and thus require access to new.
Related
I am aware that a variable can be dynamically typed with the def keyword in Groovy. But I have also noticed that in some circumstances it can be left out, such as when defining method parameters, eg func(p1, p2) instead of func(def p1, def p2). The latter form is discouraged.
I have noticed that this is extendable to all code - anytime you want to define a variable and set its value, eg var = 2 the def keyword can be safely left out. It only appears to be required if not instantiating the variable on creation, ie. def var1 so that it can be instantiated as a NullObject.
Is this the only time def is useful? Can it be safely left out in all other declarations, for example, of classes and methods?
Short answer: you can't. There are some use cases where skipping the type declaration (or def keyword) works, but it is not a general rule. For instance, Groovy scripts allow you to use variables without specific type declaration, e.g.
x = 10
However, it works because groovy.lang.Script class implements getProperty and setProperty methods that get triggered when you access a missing property. In this case, such a variable is promoted to be a global binding, not a local variable. If you try to do the same on any other class that does not implement those methods, you will end up getting groovy.lang.MissingPropertyException.
Skipping types in a method declaration is supported, both in dynamically compiled and statically compiled Groovy. But is it useful? It depends. In most cases, it's much better to declare the type for a better readability and documentation purpose. I would not recommend doing it in the public API - the user of your API will see Object type, while you may expect some specific type. It shows that this may work if your intention is to receive any object, no matter what is its specific type. (E.g. a method like dump(obj) could work like that.)
And last but not least, there is a way to skip type declaration in any context. You can use a final keyword for that.
class Foo {
final id = 1
void bar(final name) {
final greet = "Hello, "
println greet + name + "!"
}
}
This way you can get a code that compiles with dynamic compilation, as well as with static compilation enabled. Of course, using final keyword prevents you from re-assigning the variable, but for the compiler, this is enough information to infer the proper type.
For more information, you can check a similar question that was asked on SO some time ago: Groovy: "def" keyword vs concrete type
in Groovy it plays an important role in Global and Local variable
if the variable name is same with and without def
def is considered local and without def its global
I have explained here in detail https://stackoverflow.com/a/45994227/2986279
So if someone use with and without it will make a difference and can change things.
I need to implement a domain specific language. I have a panel and some shapes on it.
'panel' name = ID '(' title = STRING',' bgcolor = Color',' width = INT',' height = INT ')''{'((rects += Rect)| (ellipse += Ellipse)|(arcs += Arc)|)*'}'
and each shape has a unique rule with some other features. for example:
RoundRect:
'roundrectangle' name = ID '{'
(fill ?= 'filled' (fillpattern?='fillpattern' fillpaint=Paint)?)?
(stroke?='stroke' str=Stroke)?
'paint' paint=Paint
'coordination' x=INT ',' y=INT
'dimention' height=INT ',' width=INT
'arc' archeight=INT ',' arcwidth=INT
'}'
as it obvious in this DSL, I used some references. But I don't know this rules is correct or I should use cross-reference in those?
This rule works fine and I receive the correct output that I expected. But I know when a feature is not of the basic type (string, integer, and so on), it is
actually a reference (an instance of EReference),this is a containment reference, although for non-containment references, the referenced object is stored somewhere else,
for example, in another object of the same resource or even in a different resource.
And point is that a cross-reference is implemented as a non-containment reference.
I need to know when I should use cross-reference and when use containment reference?
As far as I know the difference is as following:
A containment-reference is if you want to reference to the content of a rule so it's just lazy for redefining the rule's content everytime you use the containment-reference.
A cross-reference behaves a bit different: If you use a cross-reference the parser need the user having typed in content of the rule the cross-reference refers to beforeallowing him to refer to that already typed in content.
An example would be a real programming language: A Method call would be a cross-reference as the method of this name should already be declared somewhere in the code because otherwise it doesn't exist. In contrary the normal code would be implemented as a containment-reference as it can be used (for example) within a class, a field or a method and the code you are typing in just needs to fullfill the existance of a few keywords and structures but these are only defined in the parser itself and needn't be defined by the user himself before beeing able to use them.
I hope I have illustrated it well enough so you now know about the difference and the meaning of these reference types.
Greeting Krzmbrzl
Your grammar describes the AST of your language. Therefore, a meta model is derived from your grammar. To describe references between your AST elements you can use containmend references and cross references. A containment reference is used if you want to describe a parent-child relation where the child object is "created" / declared during the parent object is created. A cross reference is used if the parent object points to a child object which is created / declared in an other parent object. To "draw a picture": A containment reference is a top -> bottom reference and a cross reference is a left -> right reference.
For example assume you have a field (private int field = 42;) or method (public void foo() {...}) declaration of a Java class. This declaration is modeled with a containment reference, because a Java class contains field and method declarations. On the other you have a statement field++; within the method body of foo(). There you use the former declared field foo and it is modeled as a cross reference.
In general I would say: Any declaration is modeled as a containment reference and any usage of an already declared whatever is modeled as a cross reference.
I would like to be able to use plain java-style implicit/explicit casting instead of asType overrides so that sources written in Java work properly. I've overridden asType on String similarly to the approach suggested in How to overload some Groovy Type conversion for avoiding try/catch of NumberFormatException? like:
oldAsType = String.metaClass.getMetaMethod("asType", [Class] as Class[])
String.metaClass.asType = {Class typ ->
if (Foo.class.isAssignableFrom(typ)) {
Foo.myCast(delegate)
} else {
oldAsType.invoke(delegate,typ)
}
}
I'd like all of these options to work:
// groovy
String barString
Foo foo = barString asType(Foo.class) // asType works but
Foo foo = barString // implicit cast fails
Foo foo = (Foo) barString // explicit cast fails
The latter two fail because groovy is using DefaultTypeTransformation.castToType, which doesn't attempt to invoke new Foo() unless the object to be cast is either one of a slew of special cases or is some sort of Collection type.
Note that the solution Can I override cast operator in Groovy? doesn't solve the issue because the code that is doing the casting is regular Java code that I cannot alter, at least not at the source code level. I'm hoping that there is either a secret hook into casting or a way to override the static castToType method (in a Java class, called by another Java class - which Can you use Groovy meta programming to override a private method on a Java class says is unsupported)... or some other clever approach I haven't thought of.
Edit: The question is about using Java-style casting syntax, essentially to use groovy facilities to add an autoboxing method. Groovy calls this mechanism "casting," for better or worse (see DefaultTypeTransformation.castToType as referenced above). In particular, I have replaced an enum with a resourced class and want to retain JSON serialization. Groovy's JSON package automatically un/marshals enum values of instance members to strings and I'm trying to make the replacement class serialize compatibly with a minimal changes to the source code.
Part of the problem here is you are confusing conversion with casting. Using the "as" operator is not the same thing as imposing a cast. They seem similar, but they serve separate purposes.
Foo foo = (Foo) barString
That doesn't say something like "create a Foo out of barString". That says "Declare a reference named foo, associate the static type Foo with that reference and then point that reference at the object on the heap that the reference barString currently points to.". Unlike languages like C++, Groovy and Java do not allow you to ever get in a situation where a reference points at an object that is of a type that is incompatible with the reference's type. If you ever got into a situation where a Foo reference was pointing to a String on the heap, that would represent a bug in the JVM. It cannot be done. You can come up with ways to create Foo objects out of String objects, but that isn't what the code above is about.
The answer appears to be "no". Absent a rewrite of the DefaultTypeTransformation.castToType to allow for this sort of metaprogramming, the implication is to use another implementation strategy or use a different language.
The following example is adapted from 'Groovy in Action'
class Mother {
Closure birth() {
def closure = { caller ->
[this, caller]
}
return closure
}
}
Mother julia = new Mother()
closure = julia.birth()
context = closure.call(this)
println context[0].class.name // Will print the name of the Script class
assert context[1] instanceof Script
According to the book, the value of this inside the closure is the outermost scope (i.e. the scope in which julia is declared). Am I right in assuming that
this inside a closure evaluates to the scope in which the closure is called?
within the closure shown above, this and caller refer to the same scope?
Thanks,
Don
"this" in a block mean in Groovy always (be it a normal Java-like block or a Closure) the surrounding class (instance). "owner" is a property of the Closure and points to the embedding object, which is either a class (instance), and then then same as "this", or another Closure. I would forget about the scope thing totally for this part. So in the case above it is correct, that "this" refers to a mother.
And now to make things complicated... "this" and the implicit this are not the same in Groovy. So if you have a Closure {foo()} and {this.foo()} you can get differing results. this.foo() will always be resolved to the embedding class, while only foo() will be resolved using the Groovy meta object protocol (MOP) and can point to something entirely different. A builder may for example set a delegate on that Closure and catch the method invocation, for a Groovy builder that is standard. Anyway... that is why this part is called dynamic scoping.
Historic background:
Before Groovy 1.0 "this" was the Closure object itself. But was changed because actually calling this.foo() became impossible if a builder did capture all calls. then you had no way to call local methods from within the builder anymore. There was a lot of tries with changing the standard resolve strategy - and big emotional discussions too. But in the end, changing "this" to refer to the embedding class was a simple solution to the problem and is more in line with people coming from Java plus it let's you easily bypass the MOP if you insist.
Take a look at page 144
...this refers to the closure, not to
the declaring object. At this point,
closures play a trick for us. They
delegate all method calls to a
so-called delegate object, which by
default happends to be the declaring
object (that is, the owner). This make
the closure appear as if the enclosed
code runs in the birthday context.
For your questions;
this inside a closure evaluates to the scope in which the closure is called?
from the book they state that "this refer to the closure, not to the declaring object"
But from bertport and my experiment, it seems "this" is actually the declaring object.
Either ways, the answer is still "no" for your question.
within the closure shown above, this and caller refer to the same scope?
I'm afraid not.
Be aware that page 143 and 144 in Groovy in Action need some corrections
http://groovy.canoo.com/errata/erratum/show/5
http://groovy.canoo.com/errata/erratum/show/8
{
def self = ({ owner })()
}
owner: the enclosing object (this or a surrounding Closure).
Sake says, "this is the closure not the object where the closure [is] constructed." But when we run this script, we find that this is a Mother, not a Closure.
Binding times can be classified between two types: static and dynamic. What is the difference between static and dynamic binding?
Could you give a quick example of each to further illustrate it?
In the most general terms, static binding means that references are resolved at compile time.
Animal a = new Animal();
a.Roar(); // The compiler can resolve this method call statically.
Dynamic binding means that references are resolved at run time.
public void MakeSomeNoise(object a) {
// Things happen...
((Animal) a).Roar(); // You won't know if this works until runtime!
}
It depends when the binding happens: at compile time (static) or at runtime (dynamic). Static binding is used when you call a simple class method. When you start dealing with class hierarchies and virtual methods, compiler will start using so called VTABLEs. At that time the compiler doesn't know exactly what method to call and it has to wait until runtime to figure out the right method to be invoked (this is done through VTABLE). This is called dynamic binding.
See Wikipedia article on Virtual tables for more details and references.
I came accross this perfect answer of a quora user "Monis Yousuf". He explain this perfectly. I am putting it here for others.
Binding is mostly a concept in object oriented programming related to Polymorphism.
Firstly, understand what Polymorphism is. Books say that it means "one name and multiple forms". True, but too abstract. Let us take a real-life example. You go to a "Doctor", a doctor may be an eye-specialist, ENT specialist, Neuro-Surgeon, Homeopath etc.
Here, a "doctor" is a name and may have multiple types; each performing their own function. This is polymorphism in real life.
Function Overloading: This concept depicts Static Binding. Function overloading may be roughly defined as, two or more methods (functions) which have the same name but different signatures (including number of parameters, types of parameters, differt return types) are called overloaded methods (or functions).
Suppose you have to calculate area of a rectangle and circle. See below code:-
class CalculateArea {
private static final double PI = 3.14;
/*
Method to return area of a rectangle
Area of rectangle = length X width
*/
double Area(double length, double width) {
return (length * width);
}
/*
Method to return area of circle
Area of circle = π * r * r
*/
double Area(double radius) {
return PI * radius * radius;
}
}
In above code, there are two methods "Area" with different parameters. This scenario qualifies as function overloading.
Now, coming to the real question: How is this static binding?
When you call any of the above functions in your code, you have to specify the parameters you are passing. In this scenario, you will pass either:
Two parameters of type double [Which will call the first method, to
calculate are of a rectangle]
Single parameter of type double [Which will call the second method, to calculate area of a circle]
Since, at compile time the java compiler can figure out, WHICH function to call, it is compile-time (or STATIC) binding.
Function Overriding: Function overriding is a concept which is shown in inheritance. It may roughly be defined as: when there is a method present in a parent class and its subclass also has the same method with SAME signature, it is called function overriding. [There is more to it, but for the sake of simplicity, i have written this definition] It will be easier to understand with below piece of code.
class ParentClass {
int show() {
System.out.println("I am from parent class");
}
}
class ChildClass extends ParentClass{
int show() {
System.out.println("I am from child class");
}
}
class SomeOtherClass {
public static void main (String[] s) {
ParentClass obj = new ChildClass();
obj.show();
}
}
In above code, the method show() is being overridden as the same signature (and name) is present in both parent and child classes.
In the third class, SomeOtherClass, A reference variable (obj) of type ParentClass holds the object of ChildClass. Next, the method show() is called from the same reference variable (obj).
Again, the same question: How is this Dynamic Binding?
At compile time, the compiler checks that the Reference variable is of type ParentClass and checks if the method show() is present in this class. Once it checks this, the compilation is successful.
Now, when the programs RUNS, it sees that the object is of ChildClass and hence, it runs the show() method of the ChildClass. Since this decision is taken place at RUNTIME, it is called Dynamic Binding (or Run-time Polymorphism).
Link for original answer
Static Binding: is the process of resolving types, members and operations at compile-time.
For example:
Car car = new Car();
car.Drive();
In this example compiler does the binding by looking for a parameterless Drive method on car object. If did not find that method! search for methods taking optional parameters, and if did not found that method again search base class of Car for that method, and if did not found that method again searches for extension methods for Car type. If no match found you'll get the compilation error!
I this case the binding is done by the compiler, and the binding depends on statically knowing the type of object. This makes it static binding.
Dynamic Binding: dynamic binding defers binding (The process of resolving types, members and operations) from compile-time to runtime.
For example:
dynamic d = new Car();
d.Drive();
A dynamic type tells the compiler we expect the runtime type of d to have Drive method, but we can't prove it statically. Since the d is dynamic, compiler defers binding Drive to d until runtime.
Dynamic binding is useful for cases that at compile-time we know that a certain function, member of operation exists but the compiler didn't know! This commonly occurs when we are interoperating with dynamic programming languages, COM and reflection.
Binding done at compile time is static binding and binding done at run time is dynamic binding.In static binding data type of the pointer resolves which method is invoked.But in dynamic binding data type of the object resolves which method is invoked.
* Execution time:-* bindings of variables to its values,as well as the binding of variable to particular storage location at the time of execution is called execution time binding.
IT MAY BE OF TWO TYPES
on entry to a subprogram.
At arbitrary points during execution time.
COMPILE TIME BINDING :- (TRANSLATION TIME)
It consist of the following.
Binding chosen by programmer.
Binding chosen by the translator.
Binding chosen by the loader.