LINUX.ORG.RU

Why static languages sucks?

 


0

2

Возьмем банальный пример из динамического языка

<html>
<head>
</head>
<body>

<div class="bar">div</div>
<div class="foo">div</div>
<div class="bar">div</div>
<div class="foo">div</div>
<div class="bar">div</div>
<div class="foo">div</div>
<div class="bar">div</div>
<div class="foo">div</div>
<script>

chngColor=function(){this.style.background="red"}
var wantedDivs = document.querySelectorAll('.foo');
for (var i = 0; i < wantedDivs.length; i++) {
    wantedDivs[i].addEventListener('click', chngColor);
}
</script>
</body>
</html>

Динамическое связывание, в данном случае, дает нам сразу 2 профита. Во-первых, мы экономим память, так как навешиваем на все требуемые элементы один и тот же обработчик. Во-вторых, это значительно повышает выразительность нашего языка, поскольку нам не надо доставать каждый элемент в отдельности и прописывать ему метод. Кода гораздо меньше, память экономим, выразительность повышается. Статика, соответственно сосет в сторонке. Как-то так.

UPD тему закрываю, поскольку, похоже, никто даже не понял (кроме йогурта, конечно), на текущий момент, о чем тут речь идет. Феерично!



Последнее исправление: J-yes-sir (всего исправлений: 2)

Ответ на: комментарий от J-yes-sir

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

Пиздец. Ты, наверное, свои таблеточки уже месяц как не принимал, раз тебя так дико вштырило.

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

Я не знаю си.

Не прибедняйся.

Ты далеко не только си не знаешь. Ты вообще ничего не знаешь. И жабаскриптика, кстати, тоже не знаешь.

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

У тебя все деструктивные операции могут быть под капотом языка, а тебе выставляют только апи, тогда твое положение, как программиста, еще более осложняется, ты лишаешься гибкости напрочь, кодишь как секретутка в M$ Exel. Я подобные закидоны вообще всерьез не воспринимаю.

Ладно, суть все равно не в этом. Даже лексические замыкания — это уже зло.

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

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

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

Почему не (Haskell)

mapM_ (addEventListener Click $ set (style.background) Red) $ querySelectorAll document $ Class "foo"

или (Scala)

document.querySelectorAll(Class("foo")).foreach(_.addEventListener(Click, _.setBackground(Red) /* ну или лямбду с div.style.background = Red */))

?

Есть http://elm-lang.org/ как раз на DOM рассчитанный.

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

Да есть и в JS map и forEach и прочее. Вот этот код, слегка упрощен, но полностью рабочий

;[].map.call(wantedDivs, (function(el){if(el.className==="foo") el.onclick=chngColor}))
[].call нужен, просто потому что браузерная коллекция не является массивом. Но это все фигня. Как ты заставишь имя this.style.background единственной функции, динамически связываться с каждым из элементов?

J-yes-sir
() автор топика
Ответ на: комментарий от anonymous

ты живешь галлюцинацией и что твоя реальность ничего общего с настоящей не имеет.

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

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

Кажется, ты не совсем понимаешь. Чуть изменим пример

<html>
<head>
</head>
<body>

<div class="bar" color="red">div</div>
<div class="foo" color="yellow">div</div>
<div class="bar" color="green">div</div>
<div class="foo" color="grey">div</div>
<div class="bar" color="black">div</div>
<div class="foo" color="blue">div</div>
<div class="bar" color="purple">div</div>
<script>

chngColor=function(){this.style.background=this.getAttribute("color")}
;[].map.call(document.querySelectorAll(".foo"), (function(el){el.onclick=chngColor}))

</script>
</body>
</html>

Что тут происходит. Обработчик у нас только один. Когда мы проходим мапом, мы связываем имя онклик каждого элемента с этой функцией, и более ничего не происходит. Когда наступает событие клика, вызывается функция, которая читает свойство color данного элемента, и изменяет свойство background этого же элемента. По дефолту, функция эта ни с каким элементом, и ни с каким окружением не связана. Все что она делает, она делает в рантайме.

J-yes-sir
() автор топика
Ответ на: комментарий от reprimand

что ты достаточно годные комментарии пишешь, и по делу

Данный тред — лишнее тому доказательство. Единственный коммент во всем треде, который годный и по делу — это его коммент. (кроме шуток)

J-yes-sir
() автор топика

Динамическое связывание, в данном случае, дает нам сразу 2 профита.

И то и другое можно сделать и в _нормальном_ языке.

crowbar
()
Ответ на: комментарий от J-yes-sir

Она связанна с this, очевидно.

http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

var o = {prop: 37};

function independent() {
  return this.prop;
}

o.f = independent;

o.f(); // => 37
o.f.call(); // => undefined
o.f.call(o); // => 37
var o = {prop: 37};

function independent(o) {
  return o.prop;
}

o.f = independent;

o.f(o); // => 37

Твой код вполне пишется со статической типизацией или с формальной ссылочной прозрачностью — с явной передачей объекта перед точкой или ссылки аргументом, те же однострочники получаются. А разница в том, что 1) методы более статичны, не o.f <=> o[«f»] с возможностью добавлять методы и неявно передавать o через this, 2) в методах не нужно использовать this.prop — просто prop, то есть O::independent() { return prop; }; O o; o.independent() (&o == this).

Так что

1) Статическая типизация.

2) Ссылочная прозрачность.

3) Отличие ООП JS от ООП C++/Java/C#/Scala.

Выбирай о чём ты хочешь говорить и демонстрируй что где sucks.

motto
()
Ответ на: комментарий от J-yes-sir

chngColor=function(){this.style.background=this.getAttribute(«color»)}

Сам себе uglifyjs?

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

Она связанна с this, очевидно.

Вот это статика головного мозга, очевидно. Как может одна и та же переменная быть связана с несколькими значениями, LOL

J-yes-sir
() автор топика
Ответ на: комментарий от motto

1) Статическая типизация.2) Ссылочная прозрачность.

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

J-yes-sir
() автор топика

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

1.Пруфы на это были?
2.На каком языке нельзя написать также?

crutch_master ★★★★★
()
Последнее исправление: crutch_master (всего исправлений: 2)
Ответ на: комментарий от J-yes-sir

То есть, это частный случай динамического связывания, по факту, только с одним окружением.

Дурилка, ты все напутал. Это динамическое связывание - частный случай set! в глобальном контексте.

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

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

Не придется. Просто обработчик принимает объект, для которого дергается, явным аргументом.

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

Как может одна и та же переменная быть связана с несколькими значениями, LOL

На то она и _переменная_, дурачок

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

А в смысле отстаивания своего мнения ты, вероятно, тоже подсасываешь - вначале на пост было шесть слов «динамика», затем три, теперь вместо них - «динамика сосет». Эдак анонимусы тебя обратят и на диету посадят

minakov ★★★★★
()
Ответ на: комментарий от J-yes-sir

Как может одна и та же переменная быть связана с несколькими значениями

Сходи всё-таки почитай

http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

A function's this keyword

это не переменная, а ключевое слово ECMAScript 5.1 — её нельзя изменить (на уровне того, что «this =» синтаксически не разбирается), это не константа, так как она действительно вычисляется в разные значения. Как она вычисляется

http://www.ecma-international.org/ecma-262/5.1/#sec-11.1.1

и далее.

Ну и вообще, пусть в C++ есть свободная функция

void changeColor1(Div& div) {
    div.bg_color = div.fg_color;
}

и в DOM дереве куча div-ов — я буду эту функцию как угодно применять, вешать на события и т.п., почему бы переменной div не связываться с разными мутабельными значениями при разных вызовах и где тут проблема вообще?

Теперь пусть есть метод

void Div::changeColor2() {
    bg_color = fg_color;
    // this->bg_color = this->fg_color;
}

как так получается, что this (и поля bg_color, fg_color) тут можно отождествлять при разных вызовах с разными объектами типа Div (или их полями)?

Потому что разные объекты в метод передаются (явно или нет). И в JS тоже передаются, o.f() эквивалентно o.f.call(o) и this связывается с o.

Пример использования функции в C++

for (auto div : document.querySelectorAll("foo")) div->onClick = changeColor1;

метода

for (auto div : document.querySelectorAll("foo")) div->onClick = MEM_FUN(&Div::changeColor2);

onClick дергается из event loop-а (с передачей объекта), классы можно мокнуть минимально чтобы убедиться, что всё работает как должно (как бы всё это браузерное добро на C++ обычно и пишется, сложнее, конечно, но не суть).

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

Теперь твоя конструктивная критика :)

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

метода

Или с указателем на метод

for (auto div : document.querySelectorAll("foo")) div->onClick2 = &Div::changeColor2;

хотя если есть метод (статический, в смысле по сравнению с JS, а не static) — его можно так и вызывать из event loop-а без указателя onClick на функцию или метод, смысл onClick именно в возможности иметь произвольный callback (который может быть в т.ч. JIT-скомпилированным JS кодом понимающим нативные классы на уровне их интерфейсов и ABI).

onClick дергается из event loop-а (с передачей объекта)

так же как

As a DOM event handler

When a function is used as an event handler, its this is set to the element the event fired from

motto
()
Ответ на: комментарий от J-yes-sir

ЯНП зачем тебе этот кодец, но без всякого контроля хештаблички можно где угодно месить

type O = Map[String, Any]

class A(i: O) {
  private var m: O = Map("1" -> 1) ++ i
  def apply(k: String): Any = m getOrElse (k, null)
  def extendA(m2: Object) { m ++= m2 }
}

class B(i: O) extends A(Map()) {
  private var m: O = Map("2" -> 2) ++ i
  override def apply(k: String) = m getOrElse (k, super.apply(k))
  def extendB(m2: Object) { m ++= m2 }
}

object Test {
  var x = new B(Map("3" -> "4"))
  def test {
    println(x("1"), x("2"), x("3"))
    x.extendA(Map("4" -> true))
    x.extendB(Map("5" -> false))
    println(x("1"), x("2"), x("3"), x("4"), x("5"))
  }
}
motto
()
Ответ на: комментарий от motto

Мешать что угодно и где угодно, но напиши мне аналог

Мы создали конструктор классов, затем определили с помощью него класс. Опционально, в конструкторе можно указать родителя класса — суперкласс (в нашем случае — нигер — совершенно левый класс), а также слоты экземпляров создаваемого класса. Все классы расширяются динамически.

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

J-yes-sir
() автор топика
Ответ на: комментарий от motto

а ключевое слово

Я тебе не за сам this говорю, а за переменные вида this.foo this.bar и тд. В лиспах есть тоже «ключевое слово» defparameter *... знаешь такое?

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

а за переменные вида this.foo this.bar и тд.

Это не переменные, это выражения. Так же как «x+y» не переменная, а выражение.

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

Семантически это переменные. Если бы у нас был дефолтный динамический байндинг, ключевое слово можно было бы не писать. И кто сказал, что переменные — это не выражения, кстати.

J-yes-sir
() автор топика

Если все элементы реализуют один интерфейс (имеют общий тип, надтип), то все ок в любом статически-типизированном языке. Пиздани typescript например

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

Семантически это переменные.

Семантически это выражения

И кто сказал, что переменные — это не выражения, кстати.

Любая переменная - выражение, да. Но не любое выражение - переменная.

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

Переменная в программировании — это вообще адаптация для математического недомозга. В Ъ-языках проще опереировать семантикой передачи сообщений, нет никаких «переменных» в JS.

J-yes-sir
() автор топика

у тебя все дивы - типа Div, или вверх по иерархии классов - DomNode. Лиснер типа Function, 'click' в каком-нибудь статическом языке можно было бы заменить на делегат или решить вопрос на уровне диспетчера сообщений.

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

ты смотрел лекции Катющика?

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от J-yes-sir

даже в Джабе можно ко всем элементам Dom привязать один и тот же лиснер, и потом его запускать по требованию. Где ты берешь языки, где этого нельзя.

stevejobs ★★★★☆
()
Ответ на: комментарий от J-yes-sir

Ты напиши нормально что ты хочешь — что за вещи и как они работают, «копирование», «наследование», «конструктор классов» в твоей вселенной может быть чем угодно, мне лень смотреть что там происходит — открой в chrome все эти объекты, посмотри как там разложены все эти __proto__ и вперёд, это вполне конкретно разложенные хештаблички, замыкания и способы вызова перекрывающихся частей. «указать родителя класса — суперкласс» — я наследую B от A; «опционально» — ну агрегируй тогда; произвольные поля — Map, поля наследника перекрывают поля родителя; «также слоты экземпляров создаваемого класса» — я и поля «1», «2» предопределил в конструкторах и i добавил; «расширяются динамически» — это чтобы обновление некоторого объекта обновляло все существующие и будущие объекты класса? это значит, что с классом ассоциирован синглетон

trait S {
  val m: O = Map()
  def apply(k: String, f: String => Any): Any = m getOrElse (k, f(k))
  def extend(m2: O) { m ++= m2 }
}

object AS extends S
object BS extends S

class A(i: O) extends S {
  private val m: O = Map("A1" -> "A1") ++ i ++ AS.m
  def apply(k: String): Any = m getOrElse (k, AS(k, _ => null))
  def extendA(m2: O) { m ++= m2 }
}

class B(i: O) extends A(Map()) {
  private val m: O = Map("B1" -> "B1") ++ i ++ BS.m
  override def apply(k: String): Any = m getOrElse (k, BS(k, super.apply _))
  def extendB(m2: O) { m ++= m2 }
}

такое по поведению?

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

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

J-yes-sir
() автор топика
Ответ на: комментарий от motto

это чтобы обновление некоторого объекта обновляло все существующие и будущие объекты класса?

Нет, это значит, что при обновлении класса изменения, внесенные в него автоматически «моментально» наследовали все дочерние объекты и классы.

J-yes-sir
() автор топика
Ответ на: комментарий от J-yes-sir

Я тебе не за сам this говорю, а за переменные вида this.foo this.bar и тд.

Я тоже

как так получается, что this (и поля bg_color, fg_color) тут можно отождествлять при разных вызовах с разными объектами типа Div (или их полями)?

The following steps are performed when control enters the execution context for function code contained in function object F, a caller provided thisArg, and a caller provided argumentsList:

If the function code is strict code, set the ThisBinding to thisArg.

o.f() <=> o.f.call(o).

В лиспах есть тоже «ключевое слово» defparameter

defparameter это макрос который определяет обычную специальную переменную (то что ты с this путаешь, так что не приплетай defparameter как «ключевое слово» сюда).

(let ((this o)) o.f()) <=> o.f()?

Ещё раз — this не ведёт себя как специальная переменная в CL, это синтаксис, ключевое слово со своим семантическим способом вычисления. В стандарте есть про лексический и ThisBinding, нет ничего про динамический и специальные переменные.

В C++ o.f() точно так же делает call на функцию f с передачей (через регистр) объекта o, так чтобы ключевое слове this неявно оказалось связано с адресом o в методе, как и все поля (которым не нужно приставлять this.) в коде метода сами собой связаны с адресами полей именно этого объекта.

Расскажи теперь про defparameter, динамическое связывание и специальные переменные в методах в C++ тогда. this нельзя пересвязать, так что он в этом смысле вполне лексический — связан с объектом (лексического) контекста метода.

motto
()
Ответ на: комментарий от J-yes-sir

Выхлопы-то одинаковые, использование тоже.

Это Scala.

при обновлении класса изменения, внесенные в него автоматически «моментально» наследовали все дочерние объекты и классы.

Класс можно либо расширить новым классом, либо связать с объектами синглтонами, его нельзя изменить (если не брать средства рантайма уже).

«Класс» это A + AS и B + BS — меняешь синглтон и все существующие объекты этого «класса», будущие объекты и все объекты классов наследников тоже изменяются «моментально».

И я ещё раз предлагаю подумать каким магическим образом это работает в JS — какие там структуры данных и что с ними происходит.

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

С тобой трудно разговаривать, ты слишком строго-терминологически-специализирован. вместо того, чтобы поймать суть, ты лезешь в терминологические споры. Я еще раз, кратко, скажу. переменные с this связываются динамически

f=function(){return this.a}
o.call({a: 1})
o.call({a: 2})
Но мозг, искалеченный дейкстрой, видимо, отказывается воспринять очевидное.

связан с объектом (лексического) контекста метода.

проблемы ++ меня не волнуют.

J-yes-sir
() автор топика
Ответ на: комментарий от motto

если не брать средства рантайма уже

А кто сказал, что я их не беру.

предлагаю подумать

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

J-yes-sir
() автор топика
Ответ на: комментарий от motto

про лексический и ThisBinding

где написано, что он лексический, ткни пальцем.

нет ничего про динамический

Да? А как же они объясняют

f=function(){eval("var a = 1"); return a}
f()//1
f=function(arg){var a = 1; return eval(arg)}
f("a") // 1

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