惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Stack Overflow Blog
Stack Overflow Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
爱范儿
爱范儿
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
小众软件
小众软件
L
LINUX DO - 最新话题
T
Troy Hunt's Blog
博客园_首页
量子位
Jina AI
Jina AI
S
SegmentFault 最新的问题
IT之家
IT之家
Hacker News - Newest:
Hacker News - Newest: "LLM"
大猫的无限游戏
大猫的无限游戏
N
News | PayPal Newsroom
P
Proofpoint News Feed
Cyberwarzone
Cyberwarzone
S
Securelist
Google Online Security Blog
Google Online Security Blog
P
Privacy International News Feed
博客园 - Franky
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
NISL@THU
NISL@THU
C
Cisco Blogs
V
Vulnerabilities – Threatpost
腾讯CDC
The Hacker News
The Hacker News
K
Kaspersky official blog
C
Cyber Attacks, Cyber Crime and Cyber Security
雷峰网
雷峰网
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Security Archives - TechRepublic
Security Archives - TechRepublic
A
About on SuperTechFans
Webroot Blog
Webroot Blog
The Register - Security
The Register - Security
Scott Helme
Scott Helme
B
Blog
Security Latest
Security Latest
Last Week in AI
Last Week in AI
Google DeepMind News
Google DeepMind News
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Tenable Blog
Blog — PlanetScale
Blog — PlanetScale
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
S
Schneier on Security

K.I.S.S

身在 Kimi 的 800 天 写在 Kimi K2 发布之后:再也不仅仅是 ChatBot macOS 按域名切换 DNS 解析 | K.I.S.S 为什么说 GPT 是无损压缩 | K.I.S.S 握着你的手训一个类GPT语言模型 (二) | K.I.S.S 握着你的手训一个类GPT语言模型 (一) | K.I.S.S Rosetta in Linux Virtual Machine on Apple Silicon Fit an Overfit with MegEngine 把 CUPS 扔进 docker 里 ASUS Chromebook Flip | K.I.S.S GPG 与 SSH Agent 转发 使用 dnsmasq 和 ipset 的策略路由 YubiKey 4 简介与配置 | K.I.S.S 定制GH60机械键盘 | K.I.S.S Debian 网络安装内核参数 | K.I.S.S 我的 Vim 配置 | K.I.S.S Libinput 与 Udev | K.I.S.S 给妹子看的 Arch Linux 桌面日常安装 | K.I.S.S 修复GTK3 CSD外观 | K.I.S.S 握着你的手教你画哀女王 | K.I.S.S R.I.P Google Reader | K.I.S.S Richard Stallman仍然是对的 | K.I.S.S 入手Wacom Bamboo CTL470 | K.I.S.S 转个型? | K.I.S.S Wish List | K.I.S.S pulseaudio音量问题 | K.I.S.S 入手yubikey,一点小心得 | K.I.S.S 迁移到Octopress | K.I.S.S 自动更新DNSPod记录 | K.I.S.S Linux 用作 IPv6 网关 | K.I.S.S Conky从豆瓣获取MPD专辑封面 | K.I.S.S 我和Linus大学时那些事儿 | K.I.S.S Micro$oft依然是那副老德行 | K.I.S.S 用PulseAudio TCP Forwarding实现网络传声 | K.I.S.S 利用tmpfs加速gnome-shell overview模式Applications索引 | K.I.S.S 新的短网址 | K.I.S.S 紧张的一个月 | K.I.S.S 5月11日活动有感 | K.I.S.S 西电开源社区2011年Tee 最终版 | K.I.S.S 多头多尾的Linux | K.I.S.S Linux的中文名称怎么翻译呢? | K.I.S.S iPhone使用OpenVPN | K.I.S.S 我的人人网敏感词 | K.I.S.S 纪念钱立生老师 | K.I.S.S twitter键盘控:Twittperator | K.I.S.S 天生的暴力倾向? | K.I.S.S The Open Source Spirit | K.I.S.S Libreoffice | K.I.S.S Hello world! | K.I.S.S Python 调用gnuplot的例子 | K.I.S.S The Beginning | K.I.S.S About Me | K.I.S.S
Scala 自定义控制结构 | K.I.S.S
2012-09-25 · via K.I.S.S

写了两年Python了想换换口味,正好在coursera上参加Functional Programming Principles in Scala课程,考虑到Scala那一大票很诱人的特性就学Scala吧~ //golang 我对不起你… …

话说Scala被定义为 Scalable Language ,其实解释一下不就是可以扩展自己的语法么,作为Pythoner感觉这种事情一点也不算稀奇,然而当我真的看/用到这种特性的时候的确感觉惊叹,这不是静态或动态语言的区别,这是函数式与非函数式语言的区别。

虽然Python支持函数式的风格,但其编程思想终究是指令式为主的,所以有一些函数式特性并不能被真正发挥出来。

Programming in Scala 的第14章讲到 断言与测试 ,其中给出一个关于测试的例子:

class ElementSuite extends FunSuite {
    test("elem result should have passed width") {
        val ele = elem('x', 2, 3) 
        assert(ele.width == 2)
    }    
}

这其中的test并不是一个内建的的关键字,它是被自定义出来的,在常见的语言中,这样的功能被定义为一个函数,例如如果这段代码用javascript来写的话那么大概会长这样 /* 原想用python写可惜lambda不支持多行 */:

function element_suite(){
    ele = elem('x', 2, 3);
    test( 'elem result should have passed width', function(){
        var ele = elem('x', 2, 3);
        assert( ele.width == 2 );  // javascript并没有内建的assert,这里只是意思一下
    })
}

也就是说在其他的支持函数式特性的语言中,同样的功能是可以被足够优雅的实现的,但是这个test并没有被扩展到语法中,多少令人感觉不够酷。

Scala提供了一颗很甜的语法糖,就是如果一个方法只有一个参数,那么可以把()替换为{},例如 println("Hello World")println{"Hello World"} 是等价的,但是多于一个参数的方法就不能这么用了。不过我们可以定义一个匿名函数,把语句封装到函数中,再将这个函数作为参数传入。例如:

def foo( bar: () => Unit ) = {
    bar()
}
foo{ () => { 
            println("hello world!") 
            printlin("hello world, again!") 
   }
}

现在的foo长得有点像控制符了,但是还是不太爽,因为 () => {} 暴露了匿名函数的存在,事实上这点语法也比较多余,然而scala提供了一块很甜的语法糖: by-name parameter 。我们稍稍改写一下上面那段代码:

def foo2( bar: => Unit ) = {
    bar
}
foo2{ 
    println("hello world!") 
    printlin("hello world, again!") 
}

这里并没有指定bar是一个函数,而是使用了 call-by-name 的一种求值策略( Evaluation Strategy ),也就是说参数被传入后再进行求值,于是bar被求值的过程中那两条println语句也被执行。

现在看看上面那段代码跟第一段代码中的test还是有区别,因为事实上test接受了两个参数,而上文说到使用{}代替()仅对单个参数有效,那么多个参数怎么办? 于是我们需要用到函数式编程的大杀器: currying

currying is the technique of transforming a function that takes multiple arguments (or an n-tuple of arguments) in such a way that it can be called as a chain of functions each with a single argument – Wikipedia

Currying就是将一个带多个参数的函数转化为一系列带一个参数的函数链,用数学公式表达即是 若有函数$f(x,y)$, 令$g=f(x,\cdot)$ 那么 $g(y)$ 等价于 $f(x,y)$,显然这里的 $g(\cdot)$ 是一个二阶函数。在scala中,我们可以使用currying扩展上一段代码:

def foo3(message: String)(bar: => Unit ) = {
    println(message)
    bar
}
foo3("I will say hello world~ "){ 
    println("hello world!") 
    printlin("hello world, again!") 
}

这里foo3是一个二阶函数,foo3("baz")才是一个(bar: =>Unit)Unit型的一阶函数,现在就完美的仿真了一个控制符,至少从外表看我们成功地扩展了Scala的语法。当然事实上我们并没有扩展,只是改了一个面貌,但不得不说这颗语法糖真的很甜。