简评:喜欢研究编程语言的人,推荐看看 Kasper Peulen 的这篇文章。他利用几种新语言,例如 ReasonKotlinDart、以及 Apple 的 Swift,来介绍几种有趣的程序写法,例如 pipeline、cascade、以及 currying 等。

虽然这些语言相对来讲比较新,但这些写法可能早在 Lisp (1958),Smalltalk (1972),Objective-C (1984),Haskell (1990) 或 OCaml (1996) 的语言里就有了。

#1 管道操作(Pipeline operator)

let result = "hello"
  |> doubleSay
  |> capitalize
  |> exclaim;

/* same as `let result = exclaim(capitalize(doubleSay("hello")));` */
/* result is "Hello, hello!" */

没有找到来自 Reason 的官方文档,不过它似乎与 ECMAScript 有点相似 ~

type person = { score: int };
let me = { score: 25 };
let double = (x) => x + x;
let add = (x, y) => x + y;
let boundScore = (lower, upper, score) => max(lower, min(upper, score));

let newScore = me.score
  |> double
  |> (it) => add(7, it)
  |> (it) => boundScore(0, 100, it);
/* same as boundScore(0, 100, add(7, double(me.score))); */

#2 模式匹配(Pattern matching)

let reply =
  switch message {
  | "Reason's pretty cool" => "Yep"
  | "good night" => "See ya!"
  | "hello" | "hi" | "heya" | "hey" => "hello to you too!"
  | _ => "Nice to meet you!"
  };
when (obj) {
    1          -> "One"
    "Hello"    -> "Greeting"
    is Long    -> "Long"
    !is String -> "Not a string"
    else       -> "Unknown"
}

when (x) {
    in 1..10 -> print("x is in the range")
    in validNumbers -> print("x is valid")
    !in 10..20 -> print("x is outside the range")
    else -> print("none of the above")
}

#3 Reactive (Rx) programming build in the language

input.onKeyDown                                              
  .where((e) => e.ctrlKey && e.code == 'Enter')              
  .forEach((e) => dispatch(addTodoAction(e.target.value)));

// First gets a Async Iterable of Keyboard Events from the input element
// Then filters on Keyboard Events that are Ctrl+Enter
// Dispatches an action for each of those filtered events
var wachterStream = new Wachter('src/library').events;
await for (var event in wachterStream) {
  print('The following path has changed ${event.path}');
}

// The watcherStream is an "Async Iterable" (`Stream` type in Dart)
// It can be iterated in a for loop similarly as normal Iterables
// Async Generator, generates all natural numbers asynchronous
Stream<int> naturals() async* {
  int k = 1; while (true) { yield k++; }
}

// maps the Stream (Async Iterable) so that every iterations takes a second
var delayedNaturals = naturals()
  .asyncMap((e) => new Future.delayed(new Duration(seconds: 1), () => e));

// Prints every second the next natural number (up to infinity)
delayedNaturals.forEach(print);

#4 在 lambda 函数里使用 it 作为单一参数

Implicit name (using “it”) of a single parameter in a lambda function

strings.filter{ it.length == 5 }.map{ it.toUpperCase() }

// same as strings.filter{ it -> it.length == 5 }.map{ it -> it.toUpperCase() }

#5 解构(Destructuring)

let someInts = (10, 20);
let (ten, twenty) = someInts;

type person = {name: string, age: int};
let somePerson = {name: "Guy", age: 30};
let {name, age} = somePerson;
data class Person(val name: String, val age: Int)
val(name, age) = Person("Guy", 20)

#6 级联操作(Cascade operator)

querySelector('#button') // Get an object.
  ..text = 'Confirm' // Use its members.
  ..classes.add('important')
  ..onClick.listen((e) => dispatch(confirmedAction()));

// same as 
// var button = querySelector('#button');
// button.text = 'Confirm';
// button.classed.add('important');
// button.onClick.listen((e) => dispatch(confirmedAction()));

#7 If 表达式

val result = if (param == 1) {
    "one"
} else if (param == 2) {
    "two"
} else {
    "three"
}
// same as val result = param == 1 ? "one" : param == 2 ? "two" : "three"; 

#8 Try 表达式

val result = try {
    count()
} catch (e: ArithmeticException) {
    throw IllegalStateException(e)
}

#9 Automatic currying

let add = (x, y) => x + y;   /* same as (x) => (y) => x + y; */
let five = add(2,3);         /* 5 */
let alsoFive = add(2)(3);    /* 5 */
let addFive = add(5);        /* y => 5 + y; */
let eleven = addFive(6);     /* 11 */
let twelve = addFive(7);     /* 12 */

#10 方法拓展(Method extensions)

public extension Int {
    func clamp (_ min: Int, _ max: Int) -> Int {
        return Swift.max(min, Swift.min(max, self))
    }
    
    func abs () -> Int {
        return Swift.abs(self)
    }
}

1.clamp(0, 10); // 1
20.clamp(0, 10); // 10
-3.abs(); // 3
fun Int.clamp(min:Int, max:Int) = Math.min( Math.max(this, min), max);

// 12.clamp(0,10) gives 10

Happy coding 🙂

说实话我没看太懂,但大家都说有趣,下边有原链,看懂了的可以跟我港一港 ~


原文链接:Ten interesting features from various modern languages

本文首发于极光日报

余下全文(1/3)
分享这篇文章:

请关注我们:

发表评论

电子邮件地址不会被公开。 必填项已用*标注