All Projects → ThoughtWorksInc → Template.scala

ThoughtWorksInc / Template.scala

Licence: apache-2.0
C++ Flavored Template Metaprogramming in Scala

Programming Languages

scala
5932 projects
metaprogramming
66 projects
macro
33 projects

Projects that are alternatives of or similar to Template.scala

http4s-dom
http4s, in a browser near you
Stars: ✭ 13 (-67.5%)
Mutual labels:  typelevel
Android Inline Youtube View
Utility library around using YouTube inside your android app.
Stars: ✭ 313 (+682.5%)
Mutual labels:  inline
Java Diff Utils
Diff Utils library is an OpenSource library for performing the comparison / diff operations between texts or some kind of data: computing diffs, applying patches, generating unified diffs or parsing them, generating diff output for easy future displaying (like side-by-side view) and so on.
Stars: ✭ 670 (+1575%)
Mutual labels:  inline
keyboa
Keyboa is a project designed to simplify Telegram keyboards creation.
Stars: ✭ 24 (-40%)
Mutual labels:  inline
Email Templates
📫 Create, preview, and send custom email templates for Node.js. Highly configurable and supports automatic inline CSS, stylesheets, embedded images and fonts, and much more!
Stars: ✭ 3,291 (+8127.5%)
Mutual labels:  inline
Algebra
Experimental project to lay out basic algebra type classes
Stars: ✭ 377 (+842.5%)
Mutual labels:  typelevel
phplatex
Inline TeX in PHP pages
Stars: ✭ 34 (-15%)
Mutual labels:  inline
Scala Pet Store
An implementation of the java pet store using FP techniques in scala
Stars: ✭ 812 (+1930%)
Mutual labels:  typelevel
Shapeless
Generic programming for Scala
Stars: ✭ 3,207 (+7917.5%)
Mutual labels:  typelevel
Tut
doc/tutorial generator for scala
Stars: ✭ 593 (+1382.5%)
Mutual labels:  typelevel
fib-anyon
An implementation of Fibonacci Anyons in Haskell
Stars: ✭ 18 (-55%)
Mutual labels:  typelevel
Discipline
Flexible law checking for Scala
Stars: ✭ 286 (+615%)
Mutual labels:  typelevel
Cats Infographic
typeclass diagram for cats
Stars: ✭ 403 (+907.5%)
Mutual labels:  typelevel
alphabet-soup
Type calculations at compile time
Stars: ✭ 40 (+0%)
Mutual labels:  typelevel
Scodec
Scala combinator library for working with binary data
Stars: ✭ 709 (+1672.5%)
Mutual labels:  typelevel
postcss-inline-base64
PostCSS plugin used to replace value inside of url function to base64
Stars: ✭ 23 (-42.5%)
Mutual labels:  inline
Youtube player flutter
Flutter plugin for playing or streaming YouTube videos inline using the official iFrame Player API. Supports both Android and iOS platforms.
Stars: ✭ 366 (+815%)
Mutual labels:  inline
Inline Docs.el
Show inline contextual docs in Emacs.
Stars: ✭ 12 (-70%)
Mutual labels:  inline
Frameless
Expressive types for Spark.
Stars: ✭ 717 (+1692.5%)
Mutual labels:  typelevel
Amplify
A tiny script allowing inline image zoom
Stars: ✭ 458 (+1045%)
Mutual labels:  inline

template.scala

Join the chat at https://gitter.im/ThoughtWorksInc/template.scala Build Status Latest version

template.scala is a library for creating inline functions, similar to C++ templates.

Usage

scalaVersion := "2.12.1" // or "2.11.8"

libraryDependencies += "com.thoughtworks.template" %% "template" % "latest.release" % Provided

addCompilerPlugin("org.scalameta" % "paradise" % "3.0.0-M7" cross CrossVersion.full)

A template function is created with a @template annotation.

@template
def max(x: Any, y: Any) = {
  if (x > y) x else y
}

Unlike normal functions, a template function will not be type-checked until using it. Thus it does not raise a type error on x > y because the real types of x and y have not been determined.

val i: Int = max(1, 2)
val d: Double = max(8.0, 0.5)

The max function will be type-checkd and inlined whenever being invoked.

If the type of x does not support > method, it does not compile:

val s: Symbol = max('foo, 'bar)
<macro>:1: value > is not a member of Symbol
def max(x: Any, y: Any) = if (x > y) x else y
                                ^

Side effects

By default, the side effects in arguments of @template functions will be evaluated before the execution of the function body. For example:

max({
  println("x = 1")
  1
}, {
  println("y = 2")
  2
})

The output is

x = 1
y = 2

However, you can use call-by-name parameter to force the side effects re-evaluate whenever the argument is referenced. For example:

@template
def callByNameMax(x: => Any, y: => Any) = {
  if (x > y) x else y
}

callByNameMax({
  println("x = 1")
  1
}, {
  println("y = 2")
  2
})

The output is

x = 1
y = 2
y = 2

Recursive template functions

Template functions can be recursive, as long as the number of calls are finite and can be determined at compile-time.

The following code creates a heterogeneous list.

sealed trait HList {

  final def ::(head: Any): head.type :: this.type = {
    new (head.type :: this.type)(head, this)
  }

}

case object HNil extends HList

final case class ::[Head, Tail <: HList](head: Head, tail: Tail) extends HList {
  def apply(i: 0): head.type = {
    head
  }

  @template
  def apply(i: Int with Singleton): Any = {
    tail(i - 1)
  }

}

Then you can index elements in the HList via template function apply.

val hlist = "foo" :: 1 :: false :: HNil

val s: String = hlist(0)
val i: Int = hlist(1)
val b: Boolean = hlist(2)

hlist(3) // Compile error

Note that the above HList example need TypeLevel Scala and -Yliteral-types flag.

Limitations

  • By default, @template functions are inline, not sharing similar implementations like C++ templates.
  • @template functions do not support type parameters. You can create type aliases instead. See the test case for example.
  • Recursive @template functions must be resolved at compile-time.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].