Что имею?
Frontend
Backend
JavaScript
Лексический разбор на Scala
abstract class Matcher {
def apply(code: String, position: Int): Option[Int]
}
// Терминальный символ
final case class StringMatcher(pattern: String)
extends Matcher {
def apply(code: String, position: Int) =
Some(position + pattern.length)
.filter(next => next <= code.length
&& code.substring(position, next) == pattern)
}
// Оператор | в PEG
final case class ChoiceMatcher(first: Matcher,
second: Matcher) extends Matcher {
def apply(code: String, position: Int) =
first(code, position).orElse(second(code, position))
}
// Пример использования ("hello"* & "world") | "foobar"
choice(sequence(zeroOrMore(string("hello")), string("world")), string("foobar"))
Лексический разбор на Scala
def tokenize(input: String) = {
val rules = this.rules.toIterable
var output = List.empty[Token]
var position = 0
var begin = true
while (position < input.length) {
val start = position
var application = Option.empty[(String, Int)] // Опция
while (position < input.length && application.isEmpty) {
application = rules // ленивые коллекции
.map(rule => (rule._1, rule._2(input, position)))
.find(candidate => candidate._2.isDefined) // компактные лямбды
.map(result => result.copy(_2 = result._2.getOrElse(position + 1)))
if (application.isEmpty) position += 1
}
if (start < position)
output ::= Token.unknown(input.substring(start, position))
for (successful <- application) { // избегаем NPE
output ::= new Token(
kind = successful._1,
value = input.substring(position, successful._2)
)
position = successful._2
}
}
output.reverse
}
Что хочу?
Java Script "из коробки"
Функции:
Массивы:
Расширяемый синтаксис:
Array.prototype.foo = function() {...}
[1, 2, 3].foo
Коллекции данных в JS
Underscore.js
Ленивые вычисления в JS
wu.js
function* fibs() {
let a = 0;
let b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
wu(fibs())
.filter(isEven)
.takeWhile(lessThanTen)
.forEach(console.log.bind(console));
wu.count(5) // (5, 6, 7, 8, 9, 10, ...)
Maybe в JS
[] - Nothing
[x] - Some
wu([])
.map(function(x) { return x + 1; })
.filter(function(x) { return x > 0; })
.forEach(function() {
// case Some
});
Модульность
Один файл - изолированный модуль
// файл API.js
module.exports = {
inc: functino(x) { // публичная функция
return x + 1;
};
}
function internalFunc() { // невидна извне
// ...
};
С помощью browserify:
// файл main.js
var API = require("API.js")
console.log(API.inc(100)); // 101
Параллелизм в JS
Q.js:
Q
.all([
fooFunction,
booFunction
])
.then(function(result) {
var
resultOfFoo = result[0],
resultOfBoo = result[1];
return result[0] + result[1]
})
.then(function(result) {
console.log(result);
});
async.js:
async
.parallel(
[
fooFunction,
booFunction
],
function(result, callback) {
var
resultOfFoo = result[0],
resultOfBoo = result[1];
setTimeout(function() {
callback(resultOfFoo + resultOfBoo)
}, 0)
}
);
Удобные лямбды
JavaScript
application = rules
.map(function(rule) {
return ...
})
.find(function(candidate) {
return ...
});
CoffeeScript
application = rules
.map rule -> ...
.find candidate -> ...