claireneveu / macrame Goto Github PK
View Code? Open in Web Editor NEWMacrame provides macro-based replacements for parts of the Scala standard library.
License: BSD 3-Clause "New" or "Revised" License
Macrame provides macro-based replacements for parts of the Scala standard library.
License: BSD 3-Clause "New" or "Revised" License
autoFold
function that matches the correct functions to the correct cases. Given:
sealed trait Foo
case class Bar(i : Int) extends Foo
case class Baz(s : String) extends Foo
val foo : Foo = Bar(5)
def barF(b : Bar) : String = b.i
def bazF(b : Baz) : String = b.s
both
foo.autoFold(barF _, bazF _)
and
foo.autoFold(bazF _, barF _)
compile to
foo match {
case b @ Bar(_) => barF(b)
case b @ Baz(_) => bazF(b)
}
package myPackage
import macrame.delegate
object Foo {
val s = ""
}
object Bar {
@delegate
val underlying: Foo.type = Foo
}
object Main {
def main(args: Array[String]): Unit = {
val s1: Foo.s.type = Foo.s
val s2: Bar.s.type = Bar.s
assert(s1 eq s2)
}
}
/private/tmp/TypeDelegate/TypeDelegate.scala:22: stable identifier required, but Bar.s found.
val s2: Bar.s.type = Bar.s
^
one error found
99% of the time when I want to delegate methods to a wrapped class it is for generic classes, e.g. case class WithDbMeta[A](id : Id[A], updateTime : DateTime, underlying : A)
. I think I've worked out a way to make @delegate
work with these based on this gist and implicit macros.
The basic idea would look something like this:
// In User.scala
@delegatable
case class User(name : String, password : String)
// in WithDbMeta.scala
case class WithDbMeta[A](id : Id[A], updateTime : DateTime, @delegate underlying : A)
expanding to:
// In User.scala
case class User(name : String, password : String)
object User {
object delegates {
<UserLike typeclass, ops class, extension implementation, etc>
}
}
// in WithDbMeta.scala
case class WithDbMeta[A](id : Id[A], updateTime : DateTime, @delegate underlying : A)
object WithDbMeta {
// We would check that `T` extends some dummy trait here to perform a fast exit if this isn't delegate related. Otherwise, we try to generate the appropriate instance, using whitebox macros to fail gracefully if we have the wrong type.
implicit def delegateInstance[T[_], A]: T[WithDbMeta[A] = macro impl
}
object Foo {
def setType(t: scala.reflect.api.Types#Type): Unit = ???
}
object Bar {
@delegate def foo: Foo.type = Foo
}
[error] Bar.scala:20: not found: type Type
[error] @delegate def foo: Foo.type = Foo
[error] ^
Welcome to Scala version 2.10.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_102).
Type in expressions to have them evaluated.
Type :help for more information.
scala> object Foo {
| implicit final class RichAnyRef[A](val underlying: A) {
| def get: A = underlying
| }
| }
defined module Foo
scala> object Bar {
| @macrame.delegate
| def foo: Foo.type = Foo
| }
defined module Bar
scala> Bar.RichAnyRef("xxx")
res2: Foo.RichAnyRef[String] = Foo$RichAnyRef@4f05610e
scala> import Bar.RichAnyRef
import Bar.RichAnyRef
scala> RichAnyRef("xxx").get
res3: String = xxx
scala> "xxx".get
<console>:11: error: value get is not a member of String
"xxx".get
^
scala> new RichAnyRef("xxx").get
<console>:11: error: not found: type RichAnyRef
new RichAnyRef("xxx").get
^
"xxx".get
would compile if the implicit converter is correctly forwarded.
new RichAnyRef("xxx").get
would compile if there is a type RichAnyRef[A] = Foo.RichAnyRef[A]
alias.
package myPackage
import macrame.delegate
object Foo {
object O
}
object Bar {
@delegate
val underlying: Foo.type = Foo
}
object Main {
def main(args: Array[String]): Unit = {
val o1 = Foo.O
val o2 = Bar.O
assert(o1 eq o2)
}
}
/private/tmp/TypeDelegate/TypeDelegate.scala:22: value O is not a member of object myPackage.Bar
val o2 = Bar.O
^
one error found
Use at Gawker has made it clear that people prefer to use traits rather than use EnumApi
directly, e.g.
trait EnumAsString[Enum] { self: EnumApi[Enum] =>
def asString(e : Enum) : String = asStringImpl(e)
}
Especially when combined with implicit wrapper classes, this really reduces boilerplate. Instead of redefining these all the time it would be better to add them into Macramé. I should also finally get around to publishing macrame-play
and macrame-slick
.
The following code causes /home/chris/Programming/macrame/macrame/src/test/scala/macrame/PostDelegateFailure.scala:9: recursive value byline needs type
object Post {
final case class Byline()
}
final case class CleanPost(byline : Option[Post.Byline] = None)
final case class Post(@delegate clean : CleanPost)
package myPackage
import macrame.delegate
object Foo {
type AnySeq = Seq[_]
def emptySeq: AnySeq = Nil
}
object Bar {
@delegate
val underlying: Foo.type = Foo
}
object Main {
def main(args: Array[String]): Unit = {
val x: AnySeq = Bar.emptySeq
}
}
/private/tmp/TypeDelegate/TypeDelegate.scala:23: type AnySeq is not a member of object myPackage.Bar
val x: Bar.AnySeq = Bar.emptySeq
^
one error found
class F {
def dslBuffer(seq: Seq[Int]): Unit = ???
}
object O {
@delegate
val f: F = new F
}
Error:(30, 4) trait Seq takes type parameters
@delegate
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.