HEY: I've turned this into a blog post, which is a little more in depth.
🚨 https://eev.ee/blog/2016/06/04/converting-a-git-repo-from-tabs-to-spaces/ 🚨
object Ok { | |
trait Foo[A] | |
case class Bar(x: Int) | |
object Bar { | |
implicit class BarOps(bar: Foo[Bar]) { | |
val ok = "ok" | |
} | |
} | |
def usage(bar: Foo[Bar]) = bar.ok // Ok, the implicit conversion is found in the Bar companion object |
scala> import scala.language.experimental.macros | |
import scala.language.experimental.macros | |
scala> import scala.reflect.macros.{ Context, TypecheckException } | |
import scala.reflect.macros.{Context, TypecheckException} | |
scala> object NoncompilationTests { | |
| def compiles(code: _): Boolean = macro compiles_impl | |
| def compiles_impl(c: Context)(code: c.Tree) = c.literal( | |
| try { |
/* A better way to tag types? | |
* | |
* 1) object Time: here we are distinguishing between different uses of a Long, | |
* yet there is no boxing whatsoever. | |
* | |
* main calls start: ()J | |
* main calls timed: (Function0, J) | |
* Function0 gives up the result: ()J | |
* timed calls now: ()J | |
* timed calls elapsed$extension: (JJ)J |
package test_shapeless | |
object DI { | |
import shapeless._ | |
trait Injecter[L <: HList, A] { | |
def apply(l: L) : A | |
} | |
trait InjecterAux[L <: HList, A] { |
scala> import shapeless._; import SingletonTypes._; import Record._ | |
import shapeless._ | |
import SingletonTypes._ | |
import Record._ | |
scala> val r = ("foo" ->> 23) :: ("bar" ->> true) :: ("baz" ->> 2.0) :: HNil | |
r: (String("foo"), Int) :: (String("bar"), Boolean) :: (String("baz"), Double) :: HNil = | |
(foo,23) :: (bar,true) :: (baz,2.0) :: HNil | |
scala> r.head // r is an HList of pairs of singleton-typed Strings and values ... |
scala> import shapeless._, syntax.singleton._, record._ | |
import shapeless._ | |
import syntax.singleton._ | |
import record._ | |
scala> object ->> { | |
| def unapply[K, V](f: FieldType[K, V])(implicit k: Witness.Aux[K]) = Option((k.value, f: V)) | |
| } | |
defined module $minus$greater$greater |
import shapeless._ | |
sealed trait List[+T] | |
case class Cons[T](hd: T, tl: List[T]) extends List[T] | |
sealed trait Nil extends List[Nothing] | |
case object Nil extends Nil | |
trait Show[T] { | |
def apply(t: T): String | |
} |
HEY: I've turned this into a blog post, which is a little more in depth.
🚨 https://eev.ee/blog/2016/06/04/converting-a-git-repo-from-tabs-to-spaces/ 🚨
Spurred by recent events (https://news.ycombinator.com/item?id=8244700), this is a quick set of jotted-down thoughts about the state of "Semantic" Versioning, and why we should be fighting the good fight against it.
For a long time in the history of software, version numbers indicated the relative progress and change in a given piece of software. A major release (1.x.x) was major, a minor release (x.1.x) was minor, and a patch release was just a small patch. You could evaluate a given piece of software by name + version, and get a feeling for how far away version 2.0.1 was from version 2.8.0.
But Semantic Versioning (henceforth, SemVer), as specified at http://semver.org/, changes this to prioritize a mechanistic understanding of a codebase over a human one. Any "breaking" change to the software must be accompanied with a new major version number. It's alright for robots, but bad for us.
SemVer tries to compress a huge amount of information — the nature of the change, the percentage of users that wil
Machinist Issue #2 asks:
Is it correct, that this stuff is completely obsolete now due to value classes or are there still some use cases? An example of using value class for zero-cost implicit enrichment: [...]
The short answer is that Machinist is not obsolete: value classes existed before the Machinist macros were implemented, and they do not solve the