Skip to content

Instantly share code, notes, and snippets.

View qingwei91's full-sized avatar

Qing qingwei91

View GitHub Profile
// @param backend - parameter for `cache` annotation
class cache[K, V](backend: SyncCache[K, V]) extends scala.annotation.StaticAnnotation {
// @param defn - the annotated method (it can also be other scala building block like class, but we are restricting here
// using some checks below
inline def apply(defn: Any): Any = meta {
defn match {
// this annotation should only be annotate on `method`, represented as `Defn.Def` in scalameta's AST
case defn: Defn.Def =>
// the signature is slightly different, as our macro need to access `get` and `put` method, but not `getOrElse`
// you can implement both signature though
trait SyncCache[K, V] {
def get(k: K): Option[V]
def put(k: K, v: V): Unit
}
val cacheBackend = new SyncCache[Int, Int]
@cache(cacheBackend)
// this is slow .....
def fib(i: Int): Int = i match {
case 0 => 0
case 1 => 1
case n => fib(n - 2) + fib(n - 1)
}
val cacheBackend = new CacheBackEnd[Int, Int]
def cachedFib(i: Int): Int = cache(fib)(cacheBackend)(i)
class CacheBackEnd[K, V] {
private var map = Map.empty[K, V] // ignore the fact it is not thread safe
// `compute` is a function, only evaluated in case of cache miss
def getOrElse(k: K, compute: K => V): V = {
map.get(k) match {
case Some(v) => v // cache hit
case None =>
val v = compute(k)
map = map + (k -> v)
@qingwei91
qingwei91 / scalameta-tut.md
Last active September 5, 2017 09:52
Creating a cache decorator macro with scalameta

Scalameta tutorial: Cache decorator

This is a tutorial to show how to use Scalameta to develop a generic, parameterized annotation. To know how to setup a project to use scalameta, refer to official docs

What is scalameta?

Scala-meta is the de-facto toolkit for metaprogramming in Scala. For those who are new to metaprogramming, it means programming against code/syntax/AST

Metaprogramming is very useful when you notice a repeating pattern in your code, but you are not able to refactor it due to limitations of the programming language.

@qingwei91
qingwei91 / personal-postmortem.md
Last active August 6, 2017 08:52
post mortem @ 5th August

Things I've learnt after 1 year of working abroad, alone

Software development

  • Dont expect new stuff to work on the 1st time
    • New tools, new technology, new process, anything that you never tried before, you should expect you will fail at the very first time
    • This means you should generally be conservative on first try, try to experiment in small bits before fully commit into the new endeavour you are looking into
  • It also means you should not dismissed the new stuff on first try, as you're more likely to do it wrong at first, as a
@qingwei91
qingwei91 / meeting.md
Last active June 27, 2017 12:58
about meeting

Fantastic meetings and where to find them

Anecdotally most people in the software industry hate meetings; a meeting is a soul-sucking dementor. Jokes aside, I think it's fair to say that people feel meetings are taking too much time and the process is often painful.

In this post, I'll try to provide a few rules of thumb that I believe can make meetings less painful and more efficient.

Rule 1: Always reiterate your goal before start

How many times do you attend a meeting without a goal in mind?

class Client {
def onServerUpdate(state: GameState) = {
renderGameState(state)
}
}
class Server {
def main(): Unit = {
while (true) {
/**
* 1. Read user inputs which can be one of [←, ↑, →, ↓], to change the direction of snake.
* 2. Apply user input if any, which change the direction of snake.
* 3. Move snake by 1 unit space
* 4. Check if any snakes bump into enemy/wall/self, remove them from the game.
* 5. Broadcast the new game state to all clients
@qingwei91
qingwei91 / server.scala
Last active April 11, 2017 07:31
multiplayer-game-blog
def onReceivedInput(i: UserInput) = {
storeInputToBuffer(i)
}
while(!gameEnded) {
val allUserInputs = readInputFromBuffer()
currentState = step(currentState, allUserInputs) // ie. (STATEn , INPUTn) => STATEn+1
sendStateToAllPlayers(currentState)
}