1. Как в рантайме правильнее разграничить вызов нативных (реализованных на Java) функций и вызов функций на JavaScript (это весьма разные сущности)?
JsValue call(scope: JsScope, context: JsValue, args: ArrayList<JsValue>)
TypeError: бла-бла-бла is not a function
, а в классах функций (JsNativeFunction
и JsFunction
) переопредели его чтобы возвращал что-то.2. Как оптимальнее хранить scopes? Через Hashtable/HashMap в виде вектора (имитация стека) - нормальное решение?
3. Как правильно организовать поиск функций в цепочке прототипов объекта? Например, мы ищем функцию; она находится в прототипе, ссылку на который мы храним. Но при вызове такая функция должна работать с полями данных исходного объекта, а не прототипа, или прототипа прототипа и т.д. В JavaScript всё будет в такой ситуации работать корректно, а как такое грамотно эмулировать?
x.foo(42)
разворачивается во что-то типа этого:JsObject xVar = scope.getVar("x");
xVar
.attr("foo") // ищет атрибут в объекте или в прототипе
.call(scope, xVar, Arrays.asList(JsInt(42)));
call
- это и есть контекст, то есть объект у которого вызывается метод.4. Эффективный алгоритм разбора выражений тоже не помешал бы. Как быстро разобрать строку, зная приоритеты операторов, корректно выделить все круглые скобки, которые могут быть вложены друг в друга, и т.д. Ссылки на любую литературу, в том числе англоязычную, приветствуются.
* -> *
(то есть это должен быть дженерик с одним параметром) и для него должна быть реализована функция map
:map :: Functor f => (a -> b) -> (f a -> f b)
fmap
, а в Fantasy Land сигнатура выглядит так:map :: Functor f => f a ~> (a -> b) -> f b
map
должны выполняться определённые законы, не буду их копировать сюда, просто оставлю ссылку: https://github.com/fantasyland/fantasy-land#functorArray
— map
применяет функцию к каждому элементу массива.Future
— map
применяет функцию к значению когда оно зарезолвится.Maybe
— map
применяет функцию к значению, если оно существует, иначе возвращает Nothing
.map
, применяющая функцию к каждому элементу массива. Без полиморфизма мы бы писали отдельную функцию для каждого типа:mapIntFloat :: (Int -> Float) -> [Int] -> [Float]
mapIntFloat f [] = []
mapIntFloat f (x:xs) = (f x) : (map f xs)
mapIntString :: (Int -> String) -> [Int] -> [String]
mapIntString f [] = []
mapIntString f (x:xs) = (f x) : (map f xs)
-- и так далее
mapTypeType
. Чтобы избежать повторения логики, параметризуем функцию map
относительно типов исходного массива и массива, получаемого в результате:map :: forall a b. (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = (f x) : (map f xs)
Int
или Float
у нас переменные типов: a
и b.map
для массивов, применима и к другим типам. Например, к optional-значениям. Без ad-hoc полиморфизма мы напишем что-то типа:mapList :: forall a b. (a -> b) -> [a] -> [b]
mapList f [] = []
mapList f (x:xs) = (f x) : (mapList f xs)
mapMaybe :: forall a b. (a -> b) -> Maybe a -> Maybe b
mapMaybe f Nothing = Nothing
mapMaybe f (Just x) = Just (f x)
class Functor f where
map :: (a -> b) -> f a -> f b
f
и теперь можем писать реализации для конкретных типов:instance Functor Maybe where
map f Nothing = Nothing
map f (Just x) = Just (f x)
instance Functor [] where
map f [] = []
map f (x:xs) = (f x) : (map f xs)
map
теперь имеет тип:map :: forall f a b. Functor f => (a -> b) -> f a -> f b
Functor
будет абстрактным классом с абстрактным методом map
, от которого наследуются типы Maybe
, List
и т.д. В таком случае сигнатура функции, принимающей и возвращающей функтор, будет выглядеть примерно так: foo :: Functor Int -> Functor String
. function Foo() {
let counter = 0;
Object.defineProperty(this, "counter", {
get() {
return counter++;
}
})
}
const foo = new Foo();
foo.counter; // => 0
foo.counter; // => 1
Еще я понял, что ramda это самая близкая к фп библиотека , а другие что то типо либ общего назначения.
Подскажите с какой библиотеки лучше начать.
А может Elm?
Еще такая проблема , что я обычно читаю документацию с плагином google translate и нормально понимаю смысл, но с фп у меня так не выходит (пытался читать документацию ramda и underscore). Может сталкивались с переводами документаций или их подобиями?
+
- это как раз системный буфер обмена, в который нужно копировать, чтобы вставить в другой программе. Так что копирование текущей строки в системный буфер обмена производится следующей командой: "+yy
, копирование параграфа - "+yip
, ну и так далее. library.Api
. Либо реализовать нужную логику в виде отдельной функции, а не метода:#...
api = library.Api(API_URL, LOGIN, PASSWORD)
get_something_specific(api)
Везде можно подключить БД
можно сделать сайт отдельно на каждом из фреймворков
Почему просто не сделать все на одном?
use std::io::Read;
trait ReadOneByte: Read {
fn read_one_byte(&mut self) -> Option<u8>;
}
impl<T: Read> ReadOneByte for T {
fn read_one_byte(&mut self) -> Option<u8> {
let mut buf = [0u8];
match self.read(&mut buf) {
Ok(count) if count == 1 => Some(buf[0]),
_ => None,
}
}
}
fn read_one_byte<T: Read>(source: &mut T) -> Option<u8> {
let mut buf = [0u8];
match self.read(&mut buf) {
Ok(count) if count == 1 => Some(buf[0]),
_ => None,
}
}