Giter Club home page Giter Club logo

csug's Introduction

Scala User Group

这儿用于沉淀Scala相关交流的内容, 包括但不限:

议题分享

  • 通过新建一个 分享 issue, 发起待分享的议题, 正文需简要说明分享内容或议程
  • 通过指派明确分享人, 可以是发起人自己, 可以邀请他人来分享
  • 通过评论来对议题进行反馈, 建议, 以或者投票

代码实践

TODO

csug's People

Contributors

fujohnwang avatar zhongl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

csug's Issues

Scala 与 DSL

最早结识DSL, 还是因为看了Martin Flower的一篇文章叫FluentInterface, 它真正让我明白原来代码也可以这样美的.

TimeInterval meetingTime = fiveOClock.until(sixOClock);

注意, 本文中提到的DSL被狭义的等同于了Internal DSL. 言外之意, 它还有External的部分. 关于DSL更全面的内容, 还请参阅Martin Flower的专著.

以至于后来我爱上写单元测试, 很大程度要归功于mockitoDSL应用上的如火纯青.

尽管jMock要早于mockito, 而我个人却更喜欢后者.

在自己尝试着用Java写DSL的时候, 那永远摆脱不掉的.(), 总让我纠结不已, 当然, 这只是个人洁癖而已.

Scala在实现DSL是很有优势的, 这在combinator.Parsers中已表明了这点, 而且在Programming Scala一书中, 作者专门用一个章节来讨论.

值得强调的是, 阻碍我们设计实现DSL的是我们自己的想象力, 而不应该是一门语言的表现力.

在此引出本文的目的: 大家来聊聊你用Scala写过的哪些DSL?

Actor 间的异步依赖如何单元测试

akka 提供了 TestActorRef 帮助我们同步测试 Actor.

def log(m: => String) = println(s"${Thread.currentThread} - $m") 

def logReceived(m: => Any)(implicit self: ActorRef) = log(s"$self received: $m")

class A extends Actor {
  def receive = {
    case x => logReceived(x)
  }
}

class B extends Actor {
  private val a = context.actorOf(Props(new A))

  def receive = {
    case x => logReceived(x); a ! x
  }
}

val a = TestActorRef(new A, "a")

log("Send a message to a")

a ! "message"

val b = TestActorRef(new B, "b")

log("Send a message to b")

b ! "message"

但运行完上面的完整代码, 打印输出结果会告诉你 :

  1. a发消息时, 收到消息的打印是同步执行的
  2. 当向b发消息时, 但a收到消息的打印却是异步的

实际开发中, 总会有如BA的依赖, 那么针对B的单元测试怎么做好呢?

scala pitfalls 系列

我总结了部分自己以前遇到的问题,主要是scala的表现形式上的。
实际上scala是“形散而神不散”,通过一些具体例子分析这些风格的背后的习俗和规则。

scala雾中风景(0): 序 http://hongjiang.info/scala-pitfalls-0/
scala雾中风景(1): lambda表达式的缩写 http://hongjiang.info/scala-pitfalls-1/
scala雾中风景(2): 小括号与花括号 http://hongjiang.info/scala-pitfalls-2/
scala雾中风景(3): for表达式的背后 http://hongjiang.info/scala-pitfalls-3/

Pattern matching 中 type erasure

问题

scala> val x : List[Any] = List(1.0,2.0,3.0)
x: List[Any] = List(1.0, 2.0, 3.0)

scala> x match {
     |   case l : List[Boolean] => l(0)
     |   case x                 => x
     | }
<console>:10: warning: non-variable type argument Boolean in type pattern List[Boolean] is unchecked since it is eliminated by erasure
                case l : List[Boolean] => l(0)
                         ^
res0: Any = 1.0

解决

import scala.reflect.runtime.universe._

class Def[C: TypeTag] {
  def unapply[X: TypeTag](c: X): Option[C] = {
    if (typeOf[X] <:< typeOf[C]) Some(c.asInstanceOf[C]) else None
  }
}

val BooleanList = new Def[List[Boolean]]

x match {
  case BooleanList(l) => l
  case x              => x
}

参考

用函数的思维解决这个日志转换过滤的问题

假定, tail -f log 会不断输出类似下面日志内容

2013-12-03 10:20:26,889 [nioEventLoopGroup-2-3] DEBUG i.n.handler.logging.LoggingHandler - [id: 0x456ea7b0, /10.68.199.85:36714 => /10.125.48.164:7769] WRITE(42B)
         +-------------------------------------------------+
         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |
+--------+-------------------------------------------------+----------------+
|00000000| 34 30 31 0a 76 69 61 3a 74 63 70 3a 2f 2f 31 30 |401.via:tcp://10|
|00000010| 2e 36 38 2e 31 39 39 2e 38 35 3a 33 36 37 31 34 |.68.199.85:36714|
|00000020| 0a 6d 69 64 3a 32 20 30 0a 0a                   |.mid:2 0..      |
+--------+-------------------------------------------------+----------------+
2013-12-03 10:20:26,889 [nioEventLoopGroup-2-3] DEBUG i.n.handler.logging.LoggingHandler - [id: 0x456ea7b0, /10.68.199.85:36714 => /10.125.48.164:7769] FLUSH
2013-12-03 10:20:27,089 [nioEventLoopGroup-2-3] DEBUG i.n.handler.logging.LoggingHandler - [id: 0x456ea7b0, /10.68.199.85:36714 => /10.125.48.164:7769] RECEIVED(406B)

现, 需要写段 scala 脚本, 使得 tail -f log | scala script.scala 后输出:

2013-12-03 10:20:26,889 /10.68.199.85:36714 => /10.125.48.164:7769 WRITE(42B)

401
via:tcp://10.68.199.85:36714
mid:2 0

2013-12-03 10:20:26,889 /10.68.199.85:36714 => /10.125.48.164:7769 FLUSH
2013-12-03 10:20:27,089 /10.68.199.85:36714 => /10.125.48.164:7769 RECEIVED(406B)

你实现了吗?

嗯, 不错! 然我们提升一点难度, 让你的脚本支持一个 关键字 的参数, 使得执行tail -f log | scala script.scala "401"后输出上面的内容不变, 而执行tail -f log | scala script.scala "400"后则输出:

2013-12-03 10:20:26,889 /10.68.199.85:36714 => /10.125.48.164:7769 WRITE(42B)
2013-12-03 10:20:26,889 /10.68.199.85:36714 => /10.125.48.164:7769 FLUSH
2013-12-03 10:20:27,089 /10.68.199.85:36714 => /10.125.48.164:7769 

请务必用函数的思维来实现你的脚本!

与 19lou 技术团队的Scala交流

缘起 @fujohnwang 在微薄上转发的这条微薄http://weibo.com/1642316384/zwZpTDnSp, 感谢 @argan 联系到19lou的朋友, 让我们有机会做一次交流.

请大家通过回复评论表明参加的意愿和期待的议题.

当然, 希望借此机会做些议题分享的朋友也可在回复中注明.


交流议程纪要

  1. 圆桌自我介绍
  2. 19lou代表简要介绍Scala应用情况, 含:
    • 选型理由
    • 应用技术点
    • 遇到的困难
  3. 19lou就此贴评论中的问题做了解答和讨论
  4. 张纹波(CSUG)带来Scala在laiwang中的应用
  5. @zhongl (CSUG) 带来CSUG和HouseMD的介绍

理解 Either 和 Option

这儿有道题, 从实际的项目中简化而来:

case class User(id: Long, nickname: String, password: String, mobile: String)

object Users {
  def userBy(mobile: String): Option[User] = 
    if (mobile == "01234567890") Some(User(1L, "allen", "******", "01234567890")) else None

  def authenticate(mobile: String, password: String): Either[User, String] = ???
}

assert(Users.authenticate("allen", "******") == Right("Invalid mobile"))
assert(Users.authenticate("01234567891", "******") == Right("Mobile not found"))
assert(Users.authenticate("01234567890", "??????") == Right("Invalid password"))
assert(Users.authenticate("01234567890", "******") == Left(User(1L, "allen", "******", "01234567890")))

请根据assert提示实现authenticate.

spray-routing的分享

我下周准备做一次 spray-routing 的分享。
它的基本原理,怎么实现DSL的。

trait 中 case class

注意, 以下代码都以在 scala 2.10.2 jdk 1.7中编译运行为讨论前提

trait A {
  case class B(i: Int)
}

class C extends A {
  def !(a:Any) = a match {
    case B(0) => println("never be here")
    case b: B => println("never be here")
    case x    => println(s"Oops, received $x")
  }
}

class D extends A {
  new C ! B(0)
}

new D

上面代码在 scala REPL 中运行, 打印输出的结果是Oops, received B(0), 问题就出来了:

为什么case B(0)case b: B都没有能够匹配上?

问题的答案可以从scalac -Xprint:typer结果中找到:

 class C extends AnyRef with A {
    def <init>(): C = {
      C.super.<init>();
      ()
    };
    def !(a: Any): Unit = a match {
      case (i: Int)C.this.B(0) => scala.this.Predef.println("never be here")
      case (b @ (_: C.this.B)) => scala.this.Predef.println("never be here")
      case (x @ _) => scala.this.Predef.println(scala.StringContext.apply("Oops, received ", "").s(x))
    }
  };

  class D extends AnyRef with A {
    def <init>(): D = {
      D.super.<init>();
      ()
    };
    new C().!(D.this.B.apply(0))
  }

new C ! B(0)B的类型是D.this.B, 而在C.!(a: Any)matchB的类型都是C.this.B

那么答案也就很明确了, 引用之 @hongjiang 的论断:

这个 case 类是个内部类,这点性质与java一样,它一定要存活在它的外部对象实例内,外部实例不同,它们也不同

因此, 在实际应用中, 请谨慎使用这种用法, 除非你有特别好的理由


进一步的思考: Scala 编译器是如何实现的呢?

答案在这里, 你找找看:)

10月19日 Scala 爱好者线下交流(杭州阿里巴巴)

议程

  • 13:00 ~ 13:40 Scala类型系统 by 宏江 - 淘宝技术部中间件应用容器技术专家, Scala 布道者
  • 13:50 ~ 14:30 Scala 函数式编程 by 诺铁 - 前支付宝架构师, 现 Thoughtworker
  • 14:40 ~ 15:20 Actor 与 Akka by 老猪 - 上海广谈 Scala 资深专家, ScalaConsole的开源贡献者.
  • 15:30 ~ 16:10 Spray初探 by 老高 - 丰益咨询集团架构师, 快学 Scala的译者
  • 16:20 ~ 17:00 Spark:基于Scala的大数据处理新贵 by 陈超 - 杭州搜视网络数据平台与服务端负责人, 有丰富Hadoop, HBase 开发经验, Scala 爱好者
  • 17:10 ~ 17:50 SBT by 千任 - 天猫技术部高级技术专家, 著有Real World Scala, Spring 揭秘

地点

杭州余杭区文一西路969号 阿里巴巴西溪园区 2号楼 1-13 凤凰山庄

scala中的并发

针对7月份的阿里技术嘉年华上编程语言专场,大概40分钟,准备分享的议题如下:

  1. actor 模型
    1.1) actor的历史
    1.2) actor中的消息机制
    1.3) actor与线程池
  2. akka 的特性
    2.1) akka异步,事件驱动
    2.2) akka伸缩性
    2.3) akka容错性
    2.4) akka远程调用透明性
  3. 并发集合

2014年上半年华东地区scala爱好者聚会(5.31上海)

报名方式:http://www.huodongxing.com/event/2230327357900#4239668-tsina-1-23873-7659f1d128a6531df8fc5de9a1124058

2014年上半年华东地区scala爱好者交流,这次活动的地点仍由“看处方”公司提供。
地点:上海市静安区昌平路990号8号楼102
7号线昌平路站5号口出来,沿昌平路往西走约7、8分钟。明圭都市工业园后面。
时间:5.31号下午1点30开始

活动安排:

  1. 钟伦甫(阿里巴巴),《来往使用scala经验》
  2. 杨云(thoughtworks), 《Scala Collections》
  3. 章业铭(看处方),《初创公司的scala应用经验》
  4. max lv: 《基于 Scala 进行 Android 开发的报告》
  5. 吴雪峰:《slick&scala团队项目实践》
    问答&自由交流

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.