use scala macro annotation to create type and method definition at the same level - scala-macros

I created a macro annotation to be used together with another macro to transform case classes into records with dynamic, typed method dispatching.
https://github.com/DeliteEPFL/virtualization-lms-core/blob/macrovirt/src/common/RecordsAnnot.scala
trait T {
#mRecord
case class Region(key: Int)
}
will be transformed into
trait T {
type Region = Record {
val r_regionkey: Rep[Int]
}
def Region(key: Rep[Int], name: Rep[String], comment: Rep[String]): Rep[Region] =
Record (r_regionkey = key) //another macro, but does not really matter
}
The problem is that those are 2 definitions which have to be put in the place of one which I didn't manage to do. When you do:
q"$typedef ; $metdef"
you will end up with a Block() and thus the definitions are local, the workaround I do right now is:
q"object O {$typedef ; $metdef}"
and then
#mRecord
case class Region(key: Int)
import O._
which is not the cleanest as you need unique object names, the IDE will highlight O._ as non existent and other issues.
splicing only works if you known the surrounding context, which is not the case for macro annotations...
val body = q"$typedef ; $metdef"
q"""trait T { $body }""" //created a block inside the body
q"""trait T { ..$body }""" //this will lift the block and add the defintions to the body directly
Thanks for any pointer.
Cedric

Related

Are Go methods first class functions?

The title basically says it all..
Can I create a Go method that returns another Go method, at runtime? A simple example:
type Person struct {
name string
age uint
}
func (p Person) createGetNameMethod() /*return signature is a method for Person*/ {
return /*return a new anonymous method here for Person*/
}
Are Go methods first class functions?
Yes, they are.
Can I create a Golang method that returns another Golang method [...]?
Yes, of course.
[Can I] return a new anonymous method [?]
No, of course not.
The set of methods is determined at compile time. Methods are normal, first class functions, but they cannot be changed or created during runtime:
You can return a method that exists in the method set, but you cannot add one to the method set.
Reflection allows something like that but not in your case.

Adding value to generic collection in class not allowed because of scope

I'm having trouble adding elements to an object that keeps a collection of generic-typed values. I tried a Minimal Working Example that causes the error:
class OneElementQueue {
type eltType;
var elements : [0..0] eltType;
//initializer
proc init(type eltType) {
this.eltType = eltType;
}
proc add(element : eltType) {
this.elements[0] = element;
}
proc remove() : eltType {
return this.elements[0];
}
} //end of OneElementQueue
class Monkey {
var name: string;
var age: int;
proc init(name : string, age : int) {
this.name = name;
this.age = age;
}
} //end of class Monkey
var q = new owned OneElementQueue(Monkey);
var m = new owned Monkey("Kyle", 6);
q.add(m);
When I try to compile all of this, I get an error:
$ chpl BadQueue.chpl
BadQueue.chpl:12: In function 'add':
BadQueue.chpl:13: error: Scoped variable would outlive the value it is set to
BadQueue.chpl:12: note: consider scope of element
$
What is the correct way to go about adding something to a generic data structure like this? How am I going about this the wrong way?
There are two possible approaches you can take here, depending on what behavior you want:
"I want to have my collection take ownership of the Monkey objects"
In this case, you'll want to instantiate your OneElementQueue collection to store owned Monkey objects rather than simply [borrowed] Monkey objects, which is the default for class types. You can do this with the one line change (Try it Online):
var q = new owned OneElementQueue(owned Monkey);
In this approach, passing an owned Monkey to your add() method will pass the ownership to the argument and eventually to the collection, making the original object reference invalid (nil).
"I want to have my collection borrow the existing Monkey objects without taking ownership of them"
In this case, you'll need to tell the add() method that the argument passed into it will outlive the argument itself (and then be sure not to lie about it). In Chapel version 1.19, this can be done via lifetime annotations:
proc add(element : eltType) lifetime element > this {
where the annotation lifetime element > this asserts that the actual argument passed through element will outlive the this collection itself, so the compiler should not fear that the borrow will cease to exist once the formal argument has.
Lifetime annotations were not available in Chapel 1.18, so if you're using that version you need to use a slightly bigger hammer and apply pragma "unsafe" to the method. Note that pragmas are not an officially supported feature and may change in the future, so for this case, served as a stopgap until lifetime annotations had been implemented (Try it Online):
pragma "unsafe"
proc add(element : eltType) {

Access all fields from parent method

I'm developing an application where data is stored in mongodb. There are several collections and of course all of them have some common fields (like Id, creation date, etc) and methods (for example Insert). In my vision, I need to create base model struct with needed fields and methods, and then embed this struct into my models. Unfortunately, this doesn't work because method defined for base model doesn't see child fields.
I don't know how to explain further. Here is code in playground:
https://play.golang.org/p/_x-B78g4TV
It uses json instead of mgo, but idea is still the same.
I want the output to be:
Saving to 'my_model_collection'
{"_id":42, "foo": "Some value for foo", "bar": "Here we set some value for bar"}
Not:
Saving to 'my_model_collection'
{"_id":42}
Writing that insert method for each my model seems to be against DRY, so what is correct/idiomatic way to achieve this in Go?
This is not possible, for details see my answer: Can embedded struct method have knowledge of parent/child?
You may do 2 things:
1. Abandon method and make it a helper / utility function
The idea is to make Insert() detached from BaseModel and make it a simple function, and you pass the document to it which you want to save.
I personally prefer this option, as it requires less hassle and maintenance. It could look like this:
func Insert(doc interface{}) {
j, _ := json.Marshal(doc)
fmt.Println(string(j))
}
You also had a "typo" in the tags:
type MyModel struct {
*BaseModel
Foo string `json:"foo"`
Bar string `json:"bar"`
}
Using it:
Insert(m)
Output (try it on the Go Playground):
{"_id":42,"foo":"Some value for foo","bar":"Here we set some value for bar"}
2. Pass the (pointer to) the wrapper to the BaseModel
In this approach, you have to pass a pointer to the embedder struct so the BaseModel.Insert() method will have a pointer to it, and may use that to save / marshal. This is basically manually maintaining a "reference" to the struct that embeds us and is being saved/marshalled.
This is how it could look like:
type BaseModel struct {
Id int `json:"_id"`
collectionName string
wrapper interface{}
}
And then in the Insert() method save the wrapper:
func (m *BaseModel) Insert() {
fmt.Printf("Saving to '%v'\n", m.collectionName)
j, _ := json.Marshal(m.wrapper)
fmt.Println(string(j))
}
Creation is slightly more complex:
func NewMyModel() *MyModel {
mm := &MyModel{
Foo: "Some value for foo",
}
mm.BaseModel = NewBaseModel("my_model_collection", mm)
return mm
}
But output is as you wish:
Saving to 'my_model_collection'
{"_id":42,"foo":"Some value for foo","bar":"Here we set some value for bar"}
Try it on the Go Playground.
In Golang, you can't override a parent method, because that's not how polymorphism works. The Insert method will apply on the BaseModel member, and not on MyModel.
Also, you're trying to use mgo in an improper way. If you want to insert documents in collections, then you already have an Insert method for a Collection struct which works on interface{} types (same as json.Marshal).
Of course, you can have a BaseModel that will contain fields shared by all of your models. In fact, GORM uses a similar approach and provides a Model struct to be included in every child model.
Well known problem ;o) Member variables (like collectionName) which name starts with lower letter are not visible from other packages (like json). Therefore change struct to:
type BaseModel struct {
Id int `json:"_id"`
CollectionName string `json:"collectionName"`
}
and world will be better place to live in.

How to apply transformations/filters on Lift Record Field before writing/reading its value

I'm using Lift Record persistence and I want to apply some transformations on a Field whenever I set or get its value. For instance, for StringField I want to set it to lower case automatically in Record object.
object someField extends StringField(this, 64) {
...
// how do I apply transformations here?
...
}
In Lift Mapper there is a method setFilter which does exactly that, but I can't find its equivalent in Record. In Mapper it looks like this:
object someField extends MappedString(this, 64) {
...
override def setFilter = trim _ :: toUpper _ :: super.setFilter
...
}
Couple options I'm considering are:
override set method, but there are many of them, I'm afraid to incompletely override subset of required methods, so I can't envision consequences. :)
using lifecycle callbacks - seems like overkill.
Any help is appreciated. Thanks ;)
Credit goes to #jcern for pointing this out:
Record has method def setFilter: List[(ValueType) ⇒ ValueType] which is very similar to def setFilter: List[(FieldType) ⇒ FieldType].
It is used the same way, i.e. filter will be applied when setting or querying values. Here is a quick example:
class Tag extends MongoRecord[Tag] with ObjectIdPk[Tag] {
...
object name extends StringField(this, 32) {
override def setFilter = trim _ :: toLower _ :: super.setFilter
}
...
}
Tag.createRecord.name("UPPER")
// lowercases tag name:
//res1: Tag = class Tag={name=upper, _id=521bb306e4b04eacd74dd217}

A list of predefined groovy variables

I'm new to groovy and I'm wondering where can I find a full list of predefined
groovy variables like it and delegate?
The particular thing that I'm interested in is if there are predefined keyword for
the reference to the object from where the current method was invoked, for example:
5.times { print 5 - it}
with the use of such keyword it should be something like:
5.times { print *keyword* - it }
so the question is what's the keyword should be used there?
P.S.: another example:
MyObject myObject = new myObject();
myObject.getField(); // MyObject has method named getField
myObject.doJob ({
...
((MyObject)*keyword*).getField(); // instead of myObject.getField();
...
})
For a good list of all actual keywords (which are fewer than you'd think) and object-level properties that are like keywords, this article is really good: http://marxsoftware.blogspot.com/2011/09/groovys-special-words.html
If you have control over the doJob method in your example, then you should set the delegate of the closure:
def doJob(Closure closure) {
closure.delegate = this
closure.resolveStrategy = Closure.DELEGATE_FIRST
// loop or whatever
closure()
}
Now, in your closure, you can reference any properties on the parent object directly, like so:
myObject.doJob ({
...
getField()
...
})
Groovy Closures - Implicit Variables.
Are you asking for this?
int number = 5
number.times { print number - it }
Hope this will help you

Resources