LINUX.ORG.RU

Юзкейсы для with

 


1

2

Вместо вот этого недоразумения

;(function(){
  var value = 0
  increment = function(){value++}
  decrement = function(){value--}
  show = function(){console.log(value)}
})()

можно написать более изящно

with({ value: 0 }){
  increment = function(){value++}
  decrement = function(){value--}
  show = function(){console.log(value)}
}

А вместо bind, которого, в свое время так долго вожделели некоторые, можно написать

o = {a: 1}

f1 = function(){console.log(this.a)}.bind(o)
with(o) f2 = function(){console.log(a)}

то есть, этот вожделенный bind, фактически вообще не нужен в JS.

Хочу заметить, что во всех перечисленных случаях, использование with никак не сказывается на производительности, поскольку, существует только на момент опрделения.

Вообще, with — очень мощная, гибкая конструкция, естественная для семантики JS, органичная для него.

Предлагаю в этом треде постить всевозможные кейзы для with, это интересно, думаю, будет для многих, и познавательно.

Ответ на: комментарий от newquestion

В компьютерных науках, частичное применение (или частичное применением функции) — процесс фиксации части аргументов функции, который создает другую функцию, меньшей арности

partial = function(){
  var arr = [].slice.call(arguments)
  return function(){
    return arr.concat([].slice.call(arguments))
  }
}

Ну ок. Покажи мне, у какой функции ты зафиксировал часть аргументов.

Да, в простейшем случае будет точно также + куча скобок.

Вообще-то, нет. И у твоего варианта проблемы: не всё можно запихнуть в методы.

x3al ★★★★★
()
Ответ на: комментарий от x3al

И то, что я тебе показал в первом примере, это возможно только благодаря гибкости JS, благодаря тому, что там можно хапнуть аргументы, и менипулировать ими, как массивом данных. То же самое и по твоей ссылке. То есть, это частичное применение с блекджеком и шлюхами. Классически, это выглядит вот так (define fu (lambda (x) (lambda (y) (x + y))))

newquestion
() автор топика
Ответ на: комментарий от x3al

В твоём же примере нельзя однозначно сказать

Конечно, тут похоже одно другому мешает. Гибкость vs однозначность. По-моему гибкость лучше. Все эти отговорки что кто-то не поймет, не прочитает, не осилит итд стоит решать на уровне собеседования.

loz ★★★★★
()
Ответ на: комментарий от x3al

не всё можно запихнуть в методы.

Абсолютно все

Покажи мне, у какой функции ты зафиксировал часть аргументов.

У пораждающей, которая первой вызывается. Но это не совсем классический пример, выше я пояснил. Я просто сделал приблизительный аналог того что по ссылке, отсюда эти выкрутасы с arguments.

newquestion
() автор топика
Ответ на: комментарий от newquestion

Классически, это выглядит вот так (define fu (lambda (x) (lambda (y) (x + y))))

Так вот почему у тебя баттхёрт от хаскеля: ты ничерта не понимаешь ФП.

x3al ★★★★★
()
Ответ на: комментарий от newquestion

О чём можно с тобой спорить? Сигнатура partial — это (a → b → … → i → j → … → m → n) → a → b→ … → i → (j → … → m → n) . Ты тупо пропускаешь исходную функцию и сразу возвращаешь результат. Нет, исходая функция не опциональна и в твоей же википедии (нашёл источник, лол) написано точно то же самое.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Нет, исходая функция не опциональна

А где я сказал, что она опциональна?

newquestion
() автор топика
Ответ на: комментарий от newquestion

Нет. Каррирование — чуть другая вещь. Каррировать vararg-функцию нельзя, например.

Это сахар.

Ты понимаешь разницу между замыканием и частичным применением?

А где я сказал, что она опциональна?

Когда ты начнёшь принимать функцию на входе и возвращать на выходе вместо того, чтобы шланговать — скажешь это.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от x3al

да. Частичное применение использует замыкание, но это не то же самое. История такова. В свое время русский математик, еврейского происхождения, Мозес Шенфинкель пришел к выводу, что функцию от нескольких арнументов, можно представить как множество ф-ций от одного аргумента. Например, \x y --> \x \y. Впоследствии, другой математик, прытался выдать это открытие за свое, откуда и пошло название

У тебя, на уровне сахара языка могут призводится эти неявные преобразования. Вот процес этой развертки, грубо говоря, это каррирование, а процес применения к фактическим параметрам (по одному за раз) — это частичное применение. Но никто не мешает писать функции в уже развернутом виде.

Это все основы, мне не особо интересно тут ликбез проводить, я думал ты пограмотней. Если есть вопросы, дльше углубляйся самостоятельно.

newquestion
() автор топика
Ответ на: комментарий от newquestion

Нифига себе сахар

О да, интерпретаторы научились переписывать исходную функцию вместо того, чтобы вызвать её.

а процес применения к фактическим параметрам (по одному за раз) — это частичное применение.

Эмм. Нет. Результатом partial является функция, арность которой ничем не ограничена, но уменьшена на число заданных. Никаких ограничений «по одному за раз» тоже нет. fixing a number of arguments to a function, producing another function of smaller arity.

x3al ★★★★★
()
Ответ на: Нифига себе сахар от x3al

арность которой ничем не ограничена, но уменьшена на число заданных. Никаких ограничений «по одному за раз» тоже нет

Это в твоей реализации так, это расширение. Почитай классические определения.

newquestion
() автор топика
Ответ на: комментарий от newquestion

Почитай классические определения.

Так ты определись, откуда. В этот раз я тебе скопипастил из твоей любимой википедии. Получается, библиотеки — врут, википедия — врёт, а истинным знанием обладает только анонiмус? Тогда почему это классические определения?

x3al ★★★★★
()
Ответ на: Нифига себе сахар от x3al

О да, интерпретаторы научились переписывать исходную функцию вместо того, чтобы вызвать её.

Это не нужно, достаточно иметь возможность манипулировать ф-циями как значениями. Ты можешь написать ф-ции каррирования, и затем ими пользоваться. Я не имел в виду сахар в смысле синтаксиса.

newquestion
() автор топика
Ответ на: комментарий от x3al

Нет, я тебе привел определение из википедии выше, читай.

Но, повторюсь, в классическом варианте, никакой произвольной арности нет. Это расширение.

newquestion
() автор топика
Ответ на: комментарий от newquestion

Ты тупо пропускаешь исходную функцию и сразу возвращаешь результат.

partial = function(){

↑ покажи мне, которую функцию оно принимает на вход. Нет, это нельзя заменить сахаром, что бы ты там ни имел в виду и как бы ты ни пытался шланговать.

Но, повторюсь, в классическом варианте, никакой произвольной арности нет. Это расширение.

Нет, я тебе привел определение из википедии выше, читай.

Я ж кинул цитату. Там говорится про «меньшую арность». Она не ограничена сверху, можно частично применить 3 аргумента к функции, принимающей «любое число» аргументов (vararg). Но её нельзя каррировать.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от x3al

он принимает не вход не функцию, а аргумент. ты запутался в 2-х соснах, ты вообще похоже не понимаешь, что такое частичное применение. Или путаешь его с каррированием, я хз. Трудно так разговаривать, непонятно о чем.

newquestion
() автор топика
Ответ на: комментарий от newquestion

он принимает не вход не функцию, а аргумент.

Ну а я о чём? То есть ты написал замыкание и весь тред пытаешься доказать, что это частичное применение когда это ничерта не оно.

x3al ★★★★★
()
Ответ на: комментарий от x3al

последний раз. Частичное применение это \xy->xy ==\x\y ->xyможешь сразу написать \x\y->xy и частично применяй. А можешь написать функцию carry, с помощю нее разворачивай(каррируй), и частично применяй.

newquestion
() автор топика
Ответ на: комментарий от newquestion

https://ru.wikipedia.org/wiki/Частичное_применение

Не следует путать с каррированием.

</thread>, поскольку ты не можешь читать даже то, на что ссылаешься. И да,

Стандартная библиотека C++ предоставляет функцию bind(function, args..), которая возвращает функтор, являющийся результатом частичного применения данного числа аргументов к функции.

Угадай, почему оно называется bind.

x3al ★★★★★
()
Последнее исправление: x3al (всего исправлений: 1)
Ответ на: комментарий от x3al

Угадай, почему оно называется bind.

скорей всего, потому что у страуструпа в голове вместо мозгов страусы и трупы.

newquestion
() автор топика
Ответ на: комментарий от x3al

bind

Что касается джаваскриптовской функции bind, она никакого отношения к этому не имеет. Она возвращает новую функцию, лексически связанную с контекстом, который ей подается в качестве аргумента.

newquestion
() автор топика
Ответ на: комментарий от x3al

Вот так примерно можно реализовать bind

Object.prototype.myBind = function(object){
 var f = String(this).replace(/this\./g, "") 
 with(object) return eval("[" + f + "]")[0]
}

o = {a: 1, fu: function(){return this.a}}

fu = o.fu.myBind(o)

console.log(fu()) // 1

newquestion
() автор топика

Разве хоть один из перечисленных кусков кода хоть что-то делает? В этом смысле они все идентичны.

Virtuos86 ★★★★★
()
Ответ на: комментарий от x3al

не было задачи написать точную копию, только базовый функционал, как обычно. Странные какие-то у тебя претензии.

newquestion
() автор топика
Ответ на: комментарий от newquestion
function bind(fn, obj) {
    return function() {
        return fn.apply( obj, arguments );
    };
}

Тогда вот это лучше. В теории можно в прототип засунуть, но нафиг, тем более в прототип объекта — это само по себе упорото.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Это лучше, но сомневаюсь, что это семантически эквивалентно. У тебя при каждом вызове происходит ресольвинг в рантайме.

newquestion
() автор топика
Ответ на: комментарий от x3al

Хотя, де-факто, твоя версия работает в разы быстрей почему-то.

newquestion
() автор топика
Ответ на: комментарий от x3al

Вот любопытные тесты с ноды


Function.prototype.myBind1 = function(object){
 var f = String(this).replace(/this\./g, "") 
 with(object) return eval("[" + f + "]")[0]
}

Function.prototype.myBind2 = function (obj) {
    var self = this
    return function() {
        return self.apply( obj, arguments );
    };
}


function myBind3(fn, obj) {
    return function() {
        return fn.apply( obj);
    };
}


o = {a: 1, fu: function(){return this.a}}

fu1 = o.fu.myBind1(o)
fu2 = o.fu.myBind2(o)
fu3 = myBind3(o.fu, o)
fu4 = o.fu.bind(o)

test = function(i, f, name){
  console.time(name)
  while(i--) f()
  console.timeEnd(name)
}

i = 100000

test(i, fu1, "myBind1")
test(i, fu2, "myBind2")
test(i, fu3, "bind")
test(i, fu4, "native")


//>>>> myBind1: 63ms
//>>>> myBind2: 7ms
//>>>> bind: 9ms
//>>>> native: 53ms


//>>>> myBind1: 67ms
//>>>> myBind2: 5ms
//>>>> bind: 11ms
//>>>> native: 51ms
//>>>> 

//>>>> myBind1: 85ms
//>>>> myBind2: 4ms
//>>>> bind: 12ms
//>>>> native: 51ms
//>>>> 

//>>>> myBind1: 61ms
//>>>> myBind2: 6ms
//>>>> bind: 11ms
//>>>> native: 53ms
//>>>> 
Во первых, самописный байнд заметно быстрей нативного, LOL. Во вторых, после нескольких запусков, становиться понятно, что bind, засунутый в прототип лучше оптимизируется (вопреки ожиданиям)

newquestion
() автор топика
Ответ на: комментарий от newquestion

Тесты некорректные. Изменение прототипа базового типа тормозит весь остальной код, например.

x3al ★★★★★
()
Ответ на: комментарий от x3al

Мы видим что на практике твоя теория не работает

newquestion
() автор топика
Ответ на: комментарий от x3al

Кстати, часто на официальных сайтах мозилы, хрома, советуют писать полифилы с модификацией прототипов нативных классов. Если бы было так как ты говоришь, этого бы не делали.

Алсо, протестировал сейчас с модификацией и без, разницы практически нет

newquestion
() автор топика
Ответ на: комментарий от newquestion

Это не partial, должен быть такой интерфейс:

let fn = (x, y, z) => x + y + z;
let newFn = partial(fn, 1, 2);
newFn(3) === 6;
holuiitipun
()
Ответ на: комментарий от newquestion

Я исследую язык

Открой стандарт и почитай его. Там все, что тебе надо знать. Все, что не указано там, может меняться в зависимости от реализации и потому использовать это нет смысла. Все равно что undefined behavior в плюсах. Твое исследование языка напоминает человека, который сидит в библиотеке и пытается заново открыть закон тяготения вместо того, что бы прочитать книгу, которая рядом.

Aswed ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.