LINUX.ORG.RU

Прототипы.

 , ,


1

1

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

Из следующей цитаты, можно понять пафос его «выступления».

Подход создателей Scheme все-таки предпочтительней. Если бы интерпретатор Scheme находился в каждом браузере, можно было бы писать приложения быстрее и проще, чем на JS. Это печальная, но сермяжная правда. Не надо запиливать фичу за фичей, как это сделано в ПХП, Пыхон, Перл, Цпп, и прочих. Ясно же, как божий день. :)

Он приводит там следующую реализацию ООП на схеме:

(define (make-vec2 x y)
    (lambda (message)
       (cond ((eq? message 'x) x)
             ((eq? message 'y) y))))
(define v (make-vec2 1 5))
(v 'x)
1
(v 'y)
5

(define (make-vec2 x y)
    (lambda (message)
       (cond ((eq? message 'x) x)
             ((eq? message 'y) y))))
> (define v (make-vec2 1 5))
> (v 'x)
1
> (v 'y)
5


Далее в комментариях, можно встретить поросячий восторг:

Нда, ситуация «Нихерасе бахнуло...»

видать для кого-то это явилось шокирующим откровением, не иначе.

Не буду спорить о корректности и соответствии его кода концепции, хочу сказать о другом. Почему-то (как я понял из контекста его статьи) профессиональному разработчику на JS, не пришло в голову реализовать то же самое на самом JS?

Я сделал это за него, и получилось то же самое, тока чуть компактней и лаконичней.


mk_vec2=function(x, y){return function(msg){return eval(msg)}}
v=mk_vec2(1, 5)

v("x")// 1
v("y")// 5


mk_proto=function(field, prototype){
	return function(msg){
		try{return eval(msg)}catch(e){return prototype(msg)}
	}
}
f=mk_proto("foobar", v)

f("field")// foobar
f("x")// 1

C-на вопрос, это че тренд такой - обсирать JS и превозносить Лисп?

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

Я, кстати, догадываюсь, смутно, почему такая фигня. Это наверное связано с тем, что в js, только замыкания могут хранить состояния.

Ну, копирования объектов в js решается перегонкой объекта в json и обратно либо другим костылем по вкусу, и в принципе единственная проблема в том, что разработчики не могут запилить что нибудь нативное.

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

Object.create это тот же prototype только в профиль, он не копирует объект, а указывает его в качестве прототипа для нового объекта.

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

По мне, так костыли даже лучше, нехрен лишние сущности плодить. Главное понимать четко, что происходит. В синтаксисе (его переизбытке) больше зла, чем в костылях, так что это не проблема:)

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

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

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

По мне, так костыли даже лучше, нехрен лишние сущности плодить.

Это не лишние сущности, а дополнительные возможности уже существующих.

TDrive ★★★★★
()

Что же с тобой будет, когда ты откроешь для себя ClojureScript. И какие-нибудь поделки на нём вроде того же Om.

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

Да, я уже понял, я к тому о чем я спрашивал, когда это может иметь значение, настоящая копия или объект унаследовавший св-ва своего прототипа.

В js очень своеобразное наследование с очень простой логикой. Ты обращаешься к какому то свойству объекта, если этого свойства нету у объекта то смотрим какой объект указан в прототипе и ищем это свойство у него и так по цепочке пока в прототипе не будет указан null. Причем в прототипах указаны не какие то абстрактные «классы» как в других ЯП, а реальные объекты которые могут самостоятельно меняться в ходе выполнения программы.

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

Вот

var obj1 = {key1:"val1"};
var obj2 = Object.create(obj1);
alert(obj2.key1); // val1
alert(obj2.key2); // undefined
obj1.key2 = "val2";
alert(obj2.key2); // val2

Это даже рядом не копирование объектов.

TDrive ★★★★★
()

коднажснечитаемыйимхо

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

Слушай, я че то щас подумал, а ведь это В ПРИНЦИПЕ не возможно, копировать объекты в JS. Этот чувак, который по ссылке в моем топике, недалек от истины. В JS, кажись, объекты реализованы как функции, которые если не находят запрошенного поля в своем скопе, отсылают к другой функции, т.е. вызывают ее. Значит, как только ты скопируешь эту ф-цию, затем она в рантайме скомпилится, она будет перенаправлять туда же, куда и оригинал. То есть, хоть она и другая, она ничем не отличается от оригинала, по-сути - та же. Если там и можно че-то скопировать, то не сам объект, а его синтаксическое представление. Надо подумать по этому поводу.

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

Да я понял, это тот же пример, что и у меня, по сути дела. Я понял смысл.

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

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

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

Объект скопировать можно. Например вот

var obj1 = {key1:«val1»};
var obj2 = JSON.parse(JSON.stringify(obj1));
alert(obj2.key1); // val1
alert(obj2.key2); // undefined
obj1.key2 = «val2»;
alert(obj2.key2); // undefined
Чем не копирование?

С прототипами сложнее, в моем примере он вообще не копируется, можно копировать значение(адрес родительского объекта), при необходимости можно и родительский объект скопировать. Единственная проблема, что все это будет делаться через жопу.

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

В принципе, это связано, ИМХО, с тем, что в JS его объектная система - это практически сахар для функций с first-class окружениями. Т.е. олдскул лисп. То-есть, то что в схеме делается через глубочайшую жопу гигиену, в можно сделать непосредственно. А что касается в целом, семантики, то в JS есть все то же самое, что в схеме, кроме call/cc и макросов, но я думаю, что в js как языке преимущественно интерпретируемом (ну вроде там сейчас V8 компилит его, но возможности интерпретатора остались) вполне можно замутить нехилое метапрограммирование на строках, а это по-любому помощней любых макросов будет, хоть с гигиеной, хоть без. Но это ИМХО, реально меряться писюнами я сейчас не готов, поскольку слабоват в матчасти. Это так, смутные догадки только.

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

Ну так я ж и говорю, что ты копируешь не объект сам, по ходу, а только его синтаксическое представление, то что в нем внутри записано, то и будет. При такой реализации как в js скопировать объект как он есть, видать, в принципе невозможно. Для этого, нужно будет скопировать не только сам объект(который есть лишь сахар для функции), но и все объекты на которые он ссылается, в какой нибудь неявный скоп, чтоли или как-то так. Это будет помойка а не язык, если вообще возможно (в чем я сомневаюсь, надо подумать). И конечно же это будет противоречить идеологии JS. Не запилят, думаю, эту фичу никогда. Прав был Ilammi? что это нереально в принципе, просто я сразу не догнал.

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

Вот смотри, как реализовано, упрощенно, конечно, наследование в класс-ооп:

mkOb=function(a){return function(){return a}}
ob1=mkOb(1)
ob2=mkOb(2)
console.log(ob1(), ob2()) // 1 2

Здесь очень просто скопировать объект, потому что внутренняя ф=ция которая возвращается из замыкания, содержит в себе локальный скоп отдельный для себя. А теперь сравни с примером из начала топика. «прототипная» ф-ция ссылается не на локальный скоп, а на глобальный, или локальный других объектов, т.е. вообще куда угодно, мля. Поэтому - нет и еще раз нет. Если хотим копировать объекты, нужно создавать их через замыкания (т.е. не нативные объекты создавать, а костыльные), но это не айс, канешна, и это не JS-way.

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

И в свете всего вышесказанного, это твое копирование через JSON.parse, это не просто костыль, а наикривейший бессмысленный костыль. Пользоваться такими вещами смысла нет, это приведет лишь к путанице.

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

Пользоваться такими вещами смысла нет, это приведет лишь к путанице.

Есть альтернатива?) Ну кроме отказа от копирования объектов.

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

Ну я ж написал, замыкания - единственная внятная альтернатива. А так, вообше, я конечно новичек пока, но полагаю, что копирование объектов, это вообще не JS-syle-программирование. Думаю, нужно учиться отстреливать себе ногу:)

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

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

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

Конечно не объекты, это же модель. Это концептуально - то что является объектами в js, на уровне ядра, т.е. это просто демонстрирует, как оно работает

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

вот с объектами

mkOb=function(a){
	return new function(){ 
		this.fn = function(){
			return a;
		}
	}
}
ob1=mkOb(1)
ob2=mkOb(2)
console.log(ob1.fn(), ob2.fn())

В общем все у меня уже голова не соображает, пора спать.

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

Это с нативными объектами, а там объекты сконструированы из функций, так, как будто в языке вообще объектной системы нет, а мы ее на коленке навелосипедили.

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

Следует понимать, что объекты в JS — это ссылки. Подобно указателями в С, только всегда указывают на валидный объект или являются null/undefined.

То есть:

var a = { one: 1 }; // a - ссылка на новый обьект
var b = a; // a и b - ссылки на один и тот же обьект

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

скрипты на Pure C

А с каких это пор проги на компилируемых языках стали скриптами называться? Или это такая шутка юмора? До меня программистский юмор туго доходит, я ведь нуб:)

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

А с каких это пор проги на компилируемых языках стали скриптами называться?

Существуют интерпретаторы С.

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

нехилое метапрограммирование на строках

лол, расскажи потом как получится

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

Без статической типизации штоле?

А интерпретаторы могут быть только с динамической типизацией? GHCi — это что по-твоему?

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

Да не, я просто спросил. Мне вообще не нравится статическая типизация. Я бы мож подучил си но это меня обламывает.

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

И да, кстати, а чем вам пример из топика не пруф? (правильный вариант реализации на схеме тут), в начале топика ошибка. Там выигрыш не очевиден только лишь потому, что символов мало, а представьте себе, что их тысяча. А схемовский eval не имеет доступа к замыканиям. Такие дела.

anonimous
() автор топика
Ответ на: комментарий от anonimous
mk_vec2=function(x, y){return function(msg){return eval(msg)}}
v=mk_vec2(1, 5)

v("x")// 1
v("y")// 5


mk_proto=function(field, prototype){
	return function(msg){
		try{return eval(msg)}catch(e){return prototype(msg)}
	}

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

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

Напрашивается соответствующий вывод о том, что все «беды» ООП лишь от неправильного его применения (и неполного понимания, пожалуй).

и неполного понимания, пожалуй

неполного понимания

Уж сколько копий на КЫВТе было сломано по данной проблематике... Так что правда ваша.

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

Без статической типизации штоле?

Честно говоря, понятия не имею. Но практически уверен, что с «обычной сишной типизацией». Мне как-то интерпретаторы С никогда не требовались.

Но иначе это ведь был «немного» другой язык?

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