avatar
Be $#%!ing explicit# Programming - 葵花宝典
d*n
1
Example
Consider fetching a user id from a cookie. How much language knowledge do
you need to answer the following questions given the implementation?
What happens if the cookie is not present?
What happens if the cookie value is not a well formatted number?
What happens if the cookie value is a negative number?
Scala
import play.api.mvc.RequestHeader
def getUserId()(implicit request: RequestHeader) = {
request.cookies.get("uid").map(_.value.toLong).filter(_ > 0)
}
Go
import (
"fmt"
"http"
"strconv"
)
func getUserId(r *http.Request) (int64, error) {
c, err := r.Cookie("uid")
if err != nil {
return 0, err
}
i, err := strconv.ParseInt(c.Value, 10, 64)
if err != nil {
return 0, err
}
if i <= 0 {
return 0, fmt.Errorf("invalid user id")
}
return i, nil
}
In this particular case, the Scala code is clearly shorter and perhaps more
eloquent, but the point that I am trying to illustrate in general is that
the Go code is explicit and the Scala code requires context to understand.
Be $#%!ing explicit
In my experience, explicit code has a lot of benefits.
Explicit code is easier for novices and for non-authors to grok.
Explicit code is easier to edit with small changes.
Explicit code makes the error cases obvious.
Explicit code makes the test cases obvious.
Explicit code is easier to debug (try setting a breakpoint in the Scala code
above).
https://www.quora.com/Scala-vs-Go-Could-people-help-compare-contrast-these-
on-relative-merits-demerits
avatar
l*n
2
how about break it down into machine code, you have to consider the hardware
. be more explicit. dude

【在 d****n 的大作中提到】
: Example
: Consider fetching a user id from a cookie. How much language knowledge do
: you need to answer the following questions given the implementation?
: What happens if the cookie is not present?
: What happens if the cookie value is not a well formatted number?
: What happens if the cookie value is a negative number?
: Scala
: import play.api.mvc.RequestHeader
: def getUserId()(implicit request: RequestHeader) = {
: request.cookies.get("uid").map(_.value.toLong).filter(_ > 0)

avatar
q*c
3
你程序写多了,世界成了 2 进制了,要显式, 就必须机器码,不然就必须隐式到底。
是这样吧?

hardware

【在 l**********n 的大作中提到】
: how about break it down into machine code, you have to consider the hardware
: . be more explicit. dude

avatar
b*e
4
Implicit parameter还是有一定用处的。至少不用吧那个request传来传去。有点象php
...

【在 d****n 的大作中提到】
: Example
: Consider fetching a user id from a cookie. How much language knowledge do
: you need to answer the following questions given the implementation?
: What happens if the cookie is not present?
: What happens if the cookie value is not a well formatted number?
: What happens if the cookie value is a negative number?
: Scala
: import play.api.mvc.RequestHeader
: def getUserId()(implicit request: RequestHeader) = {
: request.cookies.get("uid").map(_.value.toLong).filter(_ > 0)

avatar
l*t
5
map filter还不explicit基本智商暴露
avatar
d*n
6
scala的优势就是有好多java的轮子。没了这个靠山,再feature complete也白扯。
看看rust就知道了。
过两天俺学学scala,混口饭吃。

hardware

【在 l**********n 的大作中提到】
: how about break it down into machine code, you have to consider the hardware
: . be more explicit. dude

avatar
n*7
7
explicit 是重要
但是这跟 expressive 也不矛盾
正常人都会喜欢scala的写法
就跟你写matlab/R/numpy,放着矢量化的表达方式不用,非觉得写循环才explicit
这是行为艺术吧
avatar
z*e
8
scala这个写法就是不好debug
一般ide都是根据行设置断点
还没有根据列设置断点的搞法
不过如果用f7逐步看的话,其实也没啥太大区别
但是我个人喜欢f9

【在 n******7 的大作中提到】
: explicit 是重要
: 但是这跟 expressive 也不矛盾
: 正常人都会喜欢scala的写法
: 就跟你写matlab/R/numpy,放着矢量化的表达方式不用,非觉得写循环才explicit
: 这是行为艺术吧

avatar
d*n
9
Golang 的写法决定了很少需要用break point, 虽然我不认为不许要debugger,
但是实际coding过程中很少很少要用到。
就是因为这个成也萧何败也萧何的feature
if _, err:=MyFuction();err!=nil{
return nil, err
}
写起来好累,但是维护成本大大降低了。

【在 n******7 的大作中提到】
: explicit 是重要
: 但是这跟 expressive 也不矛盾
: 正常人都会喜欢scala的写法
: 就跟你写matlab/R/numpy,放着矢量化的表达方式不用,非觉得写循环才explicit
: 这是行为艺术吧

avatar
n*7
10
确实。不过逻辑清晰了,本身出bug的可能也少了吧

【在 z****e 的大作中提到】
: scala这个写法就是不好debug
: 一般ide都是根据行设置断点
: 还没有根据列设置断点的搞法
: 不过如果用f7逐步看的话,其实也没啥太大区别
: 但是我个人喜欢f9

avatar
n*7
11
虽然我看不懂
这个也实在太丑了

【在 d****n 的大作中提到】
: Golang 的写法决定了很少需要用break point, 虽然我不认为不许要debugger,
: 但是实际coding过程中很少很少要用到。
: 就是因为这个成也萧何败也萧何的feature
: if _, err:=MyFuction();err!=nil{
: return nil, err
: }
: 写起来好累,但是维护成本大大降低了。

avatar
l*t
12
你分成多行就可以设了

【在 z****e 的大作中提到】
: scala这个写法就是不好debug
: 一般ide都是根据行设置断点
: 还没有根据列设置断点的搞法
: 不过如果用f7逐步看的话,其实也没啥太大区别
: 但是我个人喜欢f9

avatar
z*e
13
没大区别,直接设在这一行
然后f7f8进去就好了

【在 l******t 的大作中提到】
: 你分成多行就可以设了
avatar
g*g
14
设断点是小事。产品环境里除了log啥都没有,出错就给你来个行号,哭死。

【在 z****e 的大作中提到】
: scala这个写法就是不好debug
: 一般ide都是根据行设置断点
: 还没有根据列设置断点的搞法
: 不过如果用f7逐步看的话,其实也没啥太大区别
: 但是我个人喜欢f9

avatar
z*e
15

所以要用aop,对每一个func进行拦截
这样就可以看到到底是哪个方法出问题了

【在 g*****g 的大作中提到】
: 设断点是小事。产品环境里除了log啥都没有,出错就给你来个行号,哭死。
avatar
q*c
16
这个依靠人不犯错的想法要不得。

【在 n******7 的大作中提到】
: 确实。不过逻辑清晰了,本身出bug的可能也少了吧
相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。