LINUX.ORG.RU

Реализация функции apply

 , ,


0

2

В лиспе ф-ция apply принимает на вход один аргумент — список для подстановки аргументов ф-ции. В js — 2 — объект в контексте которого применяется функция (т.е значения для подстановки свободных переменных в теле функции с this) и непосредственно список для подстановки аргументов, как и в лиспе. В лиспе, этот первый аргумент подставляется неявно, в виде лексического скопа. Таким образом, в JS мы имеем гораздо более мощную модель, включающую first-class environments. Интересно, почему в лиспе этого нет?

имеем гораздо более мощную модель, включающую first-class environments.

Это конечно круто, но что оно умеет такое особенное?

ados ★★★★★ ()

AИB трубили на седле...

anonymous ()

булшит

в схемке неймспейс можно задать явно через eval вообще для любого выражения.

> (module m racket/base
    (define x 11))
> (require 'm)
> (define ns (module->namespace ''m))
> (eval 'x ns)
11
x4DA ★★★★★ ()
(defvar *this*)

(defun js-like-apply (function this arglist)
  (let ((*this* (or this *this*)))
    (apply function
           arglist)))

Я правильно понял JS?

ados ★★★★★ ()
Ответ на: булшит от x4DA

А там не только неймспейс, там еще и цепочка наследования.

terminator-101 ()
Ответ на: комментарий от terminator-101

и зачем в данном случае прибивать себя гвоздями к ооп?

x4DA ★★★★★ ()
Ответ на: комментарий от terminator-101
CL-USER> (js-like-apply (lambda (x) (+ (getf *this*
                                             :x)
                                       x))
                        '(:x 10)
                        '(1))
11
CL-USER> 
ados ★★★★★ ()
Ответ на: комментарий от x4DA

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

terminator-101 ()
Ответ на: комментарий от terminator-101

уровень абстракции тут ниже, поскольку ты ограничиваешь себя объектами, то есть это частный случай.

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

это не то, тебе нужно на лету объект сгенерить

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

Но это ещещ не все


ob_proto_proto={x: 10}
ob_proto=Object.create(ob_proto_proto)
ob=Object.create(ob_proto)
console.log(ob) // {} не содержит x
console.log(ob.x) // 10 унаследованное x
;(function(x){console.log(this.x+x)}.apply(ob, [1])) // 11 применили функецию к унаследованному по третьему колену свойству x

terminator-101 ()
Ответ на: комментарий от terminator-101

прототипное ООП на лиспе имплементится, этим никого не удивишь, лавсан недавно высер родил на эту тему, можешь на хабре посмотреть

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

ты ограничиваешь себя объектами, то есть это частный случай.

Я не ограничиваю себя объектами. у меня все явно описанные (связаные) аргументы заменяются значениями из массива (который есть расширенный плюшками список), переменные с this берут значения из объекта, а свободные — из лексического окружения. То есть, этот apply умеет все то же самое, что и лисповский, только намного больше.

terminator-101 ()
Ответ на: комментарий от x4DA

прототипное ООП на лиспе имплементится,

Одно дело, прибитое гвоздями, а другое — на уровне семантики языка. На JS оно тоже имплементится, причем легче чем на лиспе.

лавсан недавно высер родил на эту тему, можешь на хабре посмотреть

Странно, что лавсан за это взялся, ЕМНИП, он был не в восторге от JS, непонятно тогда, чем он ему не нравился.

terminator-101 ()

EVAL С ДВУМЯ АРГУМЕНТАМИ ИМЕЕТ БОЛЕЕ ВЫСОКИЙ УРОВЕНЬ АБАСТРАКЦИЙ ЧЕМ EVAL С ОДНИМ ЕТОЖЕ ОЧЕВИДНО.

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

Нет, более высокий уровень абстракции имеет применение функции к объекту.

terminator-101 ()
Ответ на: комментарий от terminator-101
(ПРИМЕНЕНИЕ-ФУНКЦИИ-К-ОБЪЕКУ my-ФУНКЦИЯ my-ОБЪЕКТ) 

;; НЕ АБСТРАКЦИИ
(eval '(+ 2 2))

;; ДЕФАЙН АБСТРАКЦИИ
(define (true-eval ОБЪЕКТ ФУНЦИЯ)
  (eval `(ПРИМЕНЕНИЕ-ФУНКЦИИ-К-ОБЪЕКУ ,ОБЪЕКТ ,ФУНЦИЯ)))
Kuzy ★★ ()
Ответ на: комментарий от Kuzy

ПРИМЕНЕНИЕ-ФУНКЦИИ-К-ОБЪЕКУ ,ОБЪЕКТ ,ФУНЦИЯ

Ты че этим хотел сказать?

(eval '(+ 2 2))

Тогда уж (eval '(x x)) и с этого места подробней. Пока будем считать, что твое сообщение имело какой-то неочевидный смысл.

terminator-101 ()
Ответ на: комментарий от PolarFox

А чё за мужик? Я что-то частенько его вижу

anonymous ()

Ты гей, ебись в жеппу!

anonymous ()

Попробуй вместо того, чтобы регистрироваться под разными именами и писать всякую фигню, _таки взять и прочитать хорошую книжку по лиспу_, скажем, «ANSI Common Lisp». Не, правда, книжка простая, для въезжания в лисп самое-то. Есть на русском. Дай себе шанс.

seg-fault ()
Ответ на: комментарий от seg-fault

ANSI Common Lisp

Это Грехем написал? Забавно, что (вероятно уже после написания) он сам же плевался на CL:)

А почему фигня? Сравниваем выразительные возможности разных языков.

terminator-101 ()
Ответ на: комментарий от terminator-101

Угу. Ну Грэхема только xach хаит, так-то pg сделал очень много для CL сообщества, пусть и высказывался как-то там о CL. Эта книга IMHO лучше чем PCL для въезжания.

А почему фигня?

Я если честно не читаю что ты пишешь, сам понимаешь троллинг читать нет желания.

seg-fault ()

Угадал автора, только посмотрев уведомления

buddhist ★★★★★ ()
Ответ на: комментарий от seg-fault

Честно сказать, я не горю желанием изучать глубоко CL. На это нужно время, он довольно сложен, и, в то же время, это он не чета тем лиспам, которые действительно были лиспами. Тратить годы на изучение языка, в котором бескостыльно нельзя сделать (function-call or and map another-function) не хочется. Я более менее знаю схему, немного newlisp и picolisp, а для число*бства я лучше ассемблер буду учить

terminator-101 ()
Ответ на: комментарий от terminator-101

вот тебе абстракция которую ты хочешь на scheme

#lang racket
(require syntax/parse/define)
(require racket/stxparam)

(define-syntax-parameter ths 
    (lambda (stx) (raise-syntax-error #f "Not used inside js-apply!" stx)))

(define-simple-macro (js-apply obj:expr fn:expr args...)
  (let ([this-obj obj])
    (syntax-parameterize ([ths (make-rename-transformer #'this-obj)])
			 (apply fn args...))))


(js-apply (new (class object% 
		 (super-new) 
		 (init-field [x 10])))
	  (lambda (y) (+ y (get-field x ths)))
	  (list 1))

;; 11

x4DA ★★★★★ ()
Ответ на: комментарий от terminator-101

Common lisp и есть тот самый Ъ лисп, остальное не торт. А ты еби гусей

anonymous ()
Ответ на: комментарий от terminator-101

скажи мне что ты хочешь от first-class объекта языка

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

От first-class объекта языка обычно требуется, чтобы его можно было в любой ситуации передать в качестве аргумента, вернуть в качестве значения, присвоить переменной, присвоить в качестве свойства или метода объекту, хранить в массиве. Короче, делать с ним все что с обычной функцией, в данном случае.

terminator-101 ()
Ответ на: комментарий от terminator-101

без проблем.

данный макрос раскрывается в замыкание, которое является first-class.

x4DA ★★★★★ ()
Ответ на: без проблем. от x4DA

Re: без проблем.

Видимо, речь тут не о том, во что он раскрывается, а о нем самом. Макросы, не являются first-class объектами языка.

anonymous ()
Ответ на: без проблем. от x4DA

Re: без проблем.

Вообще говоря, в жаваскрипте, функцией не только можно вертеть как хочешь, ее можно даже пропарсить в рантайме, получив в виде строки.

anonymous ()
Ответ на: Re: без проблем. от anonymous

ну, в схемке ты так же можешь расчленить функцию на синтаксические объекты и склеить их по новому.

x4DA ★★★★★ ()
Ответ на: Re: без проблем. от anonymous

не являются, но здесь я не вижу никаких практических проблем.

x4DA ★★★★★ ()
Ответ на: Re: без проблем. от anonymous

ее можно даже пропарсить в рантайме, получив в виде строки

Правда за такое можно и канделябра отхватить.

Deleted ()

Надо просто принять то, что джаваскрипт создавался Айком за неделю чтобы успеть выпустить хоть что-то пока МS не захватили веб. Он о многом сожалеет и считает что мог сделать гораздо лучше, да и вобще он хотел лисп, но нужен был сиподобный синтаксис. Продолжение читать в coders at work.

anonymous ()

наркоман, ты опять выходишь на связь?

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

Dependency Injection только так можно сделать, насколько я понимаю..

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

мне кажется это враки. покажите ваш исходник, где делается dependency injection.

x4DA ★★★★★ ()

... first-class environments. Интересно, почему в лиспе этого нет?

У тебя неправильный лисп и у него неправильные скобочки.

$ picolisp +
: (setq *Env (let (A 1 B 2) (env)))
-> ((A . 1) (B . 2))
: A
-> NIL
: (bind *Env A)    
-> 1

anonymous ()
Ответ на: комментарий от ados

.... first-class environments.

Это конечно круто, но что оно умеет такое особенное?

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

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

Например, можно значения всех переменных скинуть в файл/базу

first-class не значит сериализуемость. На одно значение может ссылаться несколько переменных, как будешь разруливать?

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

у тебя в пиколиспе там dynamic shallow binding? развалится к чертям при мультитредовом коде поди.

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

развалится к чертям при мультитредовом коде поди

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

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