ECMAScript и все-все-все — различия между версиями

Материал из YourcmcWiki
Перейти к: навигация, поиск
(Новая страница: «<slideshow title="" style="custis" scaled="true" font="Segoe UI, cursive" headingmark="@@" centermark="%%" incmark="++" subfooter="ECMAScript и все-все-в…»)
 
м
Строка 1: Строка 1:
<slideshow title="" style="custis" scaled="true" font="Segoe UI, cursive" headingmark="@@" centermark="%%" incmark="++" subfooter="ECMAScript и все-все-все" footer="" />
+
<slideshow title="" style="nobook" scaled="true" font="Segoe UI, cursive" headingmark="@@" centermark="%%" incmark="++" subfooter="ECMAScript и все-все-все" footer="" />
  
 
== ECMAScript - ассемблер будущего,<br /> бэкенд, фронтенд и все-все-все @@ %% ==
 
== ECMAScript - ассемблер будущего,<br /> бэкенд, фронтенд и все-все-все @@ %% ==
Строка 30: Строка 30:
 
<s>JavaScript</s>ECMAScript
 
<s>JavaScript</s>ECMAScript
 
* Скриптота! (динамический язык)
 
* Скриптота! (динамический язык)
 +
* Объект/массив/скаляр (JSON)
 
* Прототипы, замыкания, колбэки, нет многопоточности
 
* Прототипы, замыкания, колбэки, нет многопоточности
 
* ES - язык. А ещё есть окружение (DOM, BOM)
 
* ES - язык. А ещё есть окружение (DOM, BOM)
Строка 46: Строка 47:
 
* Статические... ну, что-то есть... D, Rust, Go, Vala, Swift...
 
* Статические... ну, что-то есть... D, Rust, Go, Vala, Swift...
 
*: ''но кто на них пишет-то?''
 
*: ''но кто на них пишет-то?''
 +
* Удобно: легко работать с данными, дженерики не нужны
  
 
== Все хотят одного @@ ==
 
== Все хотят одного @@ ==
Строка 65: Строка 67:
 
* Мощно развивается
 
* Мощно развивается
  
== Синтаксис @@ ==
+
== Синтаксис @@ %% ==
  
 
== Perl @@ ==
 
== Perl @@ ==
 +
 +
<code-perl>
 +
if ($single)
 +
{
 +
    # Single bug
 +
    my ($id) = list $ARGS->{id};
 +
    push @bugs, Bugzilla::Bug->check($id);
 +
    if (defined $ARGS->{mark})
 +
    {
 +
        foreach my $range (split ',', $ARGS->{mark})
 +
        {
 +
            if ($range =~ /^(\d+)-(\d+)$/)
 +
            {
 +
                foreach my $i ($1..$2)
 +
                {
 +
                    $marks{$i} = 1;
 +
                }
 +
            }
 +
            elsif ($range =~ /^(\d+)$/)
 +
            {
 +
                $marks{$1} = 1;
 +
            }
 +
        }
 +
    }
 +
}
 +
</code-perl>
  
 
== PHP @@ ==
 
== PHP @@ ==
 +
 +
<code-php>
 +
$isExact = [];
 +
foreach ([ 'line' => 'l', 'cfo' => 'cc' ] as $k => $t)
 +
{
 +
    if (!isset($specified[$k.'_id']) && !isset($specified[$k.'_id_exact']) &&
 +
        !isset($groups[$k]) && !isset($groups[$k.'_all']))
 +
        $isExact[] = "$posAlias.${k}_id IS NULL";
 +
    elseif ($lastgrp == $k.'all')
 +
        $isExact[] = "$posAlias.${k}_id=$t.id";
 +
}
 +
foreach ([ 'party', 'account', 'paytype' ] as $k)
 +
    if (!isset($specified[$k.'_id']) && !isset($groups[$k]))
 +
        $isExact[] = "$posAlias.${k}_id IS NULL";
 +
return implode(' AND ', $isExact) ?: '1=1';
 +
</code-php>
 +
 +
* Что за $$$$$?
  
 
== Python @@ ==
 
== Python @@ ==
 +
 +
<code-python>
 +
class FileCache:
 +
  def __init__(self, dir):
 +
    self.dir = dir
 +
    if not os.path.isdir(dir):
 +
      os.mkdir(dir)
 +
  def fn(self, key):
 +
    key = re.sub('([^a-zA-Z0-9_\-]+)', lambda x: binascii.hexlify(x.group(1)), key)
 +
    return self.dir+'/'+key
 +
  def clean(self):
 +
    t = time.time()
 +
    for fn in os.listdir(self.dir):
 +
      if t > os.stat(self.dir+'/'+fn).st_mtime:
 +
        os.unlink(self.dir+'/'+fn)
 +
</code-python>
 +
 +
* Пробелы меняют смысл?!!!!
  
 
== Ruby @@ ==
 
== Ruby @@ ==
 +
 +
<source lang="ruby">
 +
module Gitlab
 +
  class SearchResults
 +
    attr_reader :current_user, :query
 +
 +
    def objects(scope, page = nil)
 +
      case scope
 +
      when 'projects'
 +
        projects.page(page).per(per_page)
 +
      when 'issues'
 +
        issues.page(page).per(per_page)
 +
      when 'merge_requests'
 +
        merge_requests.page(page).per(per_page)
 +
      when 'milestones'
 +
        milestones.page(page).per(per_page)
 +
      else
 +
        Kaminari.paginate_array([]).page(page).per(per_page)
 +
      end
 +
    end
 +
</source>
 +
 +
* projects - переменная? Фигвам. Метод без аргументов.)
  
 
== Go @@ ==
 
== Go @@ ==
 +
 +
<source lang="go">
 +
func TestChannelStoreSave(t *testing.T) {
 +
        Setup()
 +
 +
        teamId := model.NewId()
 +
 +
        o1 := model.Channel{}
 +
        o1.TeamId = teamId
 +
        o1.DisplayName = "Name"
 +
        o1.Name = "a" + model.NewId() + "b"
 +
        o1.Type = model.CHANNEL_OPEN
 +
 +
        if err := (<-store.Channel().Save(&o1)).Err; err != nil {
 +
                t.Fatal("couldn't save item", err)
 +
        }
 +
 +
        if err := (<-store.Channel().Save(&o1)).Err; err == nil {
 +
                t.Fatal("shouldn't be able to update from save")
 +
        }
 +
</source>
 +
 +
* Что за смайлики <tt><nowiki>:= <- & *</nowiki></tt>? Где мои скобочки?
  
 
== Erlang @@ ==
 
== Erlang @@ ==
 +
 +
<source lang="erlang">
 +
iq_handler(From, _To,
 +
  #iq{type=set, lang = Lang,
 +
      sub_el = #xmlel{name = Operation} = SubEl} = IQ, CC)->
 +
    ?DEBUG("carbons IQ received: ~p", [IQ]),
 +
    {U, S, R} = jid:tolower(From),
 +
    Result = case Operation of
 +
        <<"enable">>->
 +
    ?INFO_MSG("carbons enabled for user ~s@~s/~s", [U,S,R]),
 +
            enable(S,U,R,CC);
 +
        <<"disable">>->
 +
    ?INFO_MSG("carbons disabled for user ~s@~s/~s", [U,S,R]),
 +
            disable(S, U, R)
 +
    end,
 +
    case Result of
 +
        ok ->
 +
    ?DEBUG("carbons IQ result: ok", []),
 +
            IQ#iq{type=result, sub_el=[]};
 +
{error,_Error} ->
 +
    ?ERROR_MSG("Error enabling / disabling carbons: ~p", [Result]),
 +
    Txt = <<"Database failure">>,
 +
            IQ#iq{type=error,sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}
 +
end;
 +
</source>
 +
 +
* Ой-ой-ой
 +
* Классов нет, есть процессы
  
 
== OCaml O_O @@ ==
 
== OCaml O_O @@ ==
  
== JS @@ ==
+
<source lang="ocaml">
 +
let log_client_info c sock =  
 +
  let buf = Buffer.create 100 in
 +
  let date = BasicSocket.date_of_int (last_time ()) in
 +
  Printf.bprintf buf "%-12s(%d):%d -> %-30s[%-14s %-20s] connected for %5d secs %-10s bw %5d/%-5d %-6s %2d/%-2d reqs "
 +
    (Date.simple date)
 +
  (nb_sockets ())
 +
  (client_num c)
 +
  (
 +
    let s = c.client_name in
 +
    let len = String.length s in
 +
    if len > 30 then String.sub s 0 30 else s)
 +
 
 +
  (brand_to_string c.client_brand)
 +
  (match c.client_kind with Indirect_address _ | Invalid_address _ -> "LowID"
 +
    | Direct_address (ip,port) -> Printf.sprintf "%s:%d"
 +
          (Ip.to_string ip) port)
 +
  (last_time () - c.client_connect_time)
 +
  (if c.client_rank > 0 then
 +
      Printf.sprintf "rank %d" c.client_rank
 +
      else "")
 +
  (nwritten sock) (nread sock)
 +
  (if c.client_banned then "banned" else "")
 +
  c.client_requests_received
 +
    c.client_requests_sent
 +
  ;
 +
</source>
  
 +
* ПОЛИЗ?!!!!
 +
 +
== JS @@ ==
  
 +
<source lang="javascript>
 +
TreeGridNode.prototype.setChildren = function(isLeaf, newChildren)
 +
{
 +
    if (!this.tr)
 +
        this.grid.tbody.innerHTML = '';
 +
    else
 +
    {
 +
        var tr = this.tr[this.tr.length-1];
 +
        while (tr.nextSibling && tr.nextSibling._node.level > this.level)
 +
            this.grid.tbody.removeChild(tr.nextSibling);
 +
        if (this.leaf != isLeaf)
 +
        {
 +
            if (isLeaf)
 +
            {
 +
                this.tr[0].cells[0].firstChild.className = 'collapser collapser-inactive';
 +
                removeListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
 +
            }
 +
            else
 +
            {
 +
                this.tr[0].cells[0].firstChild.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
 +
                addListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
 +
            }
 +
        }
 +
    }
 +
    this.leaf = isLeaf;
 +
    this.children = [];
 +
    this.childrenByKey = {};
 +
    this.addChildren(newChildren);
 +
}
 +
</source>
  
 
[[Категория:VitaliPrivate]]
 
[[Категория:VitaliPrivate]]

Версия 12:04, 10 октября 2016

Автор

Виталий Филиппов
Дополнительный нижний колонтитул

ECMAScript и все-все-все

ECMAScript - ассемблер будущего,
бэкенд, фронтенд и все-все-все @@ %%

(Об эволюции и фичах JavaScript)

Виталий Филиппов, CUSTIS

О своих предпочтениях @@

«И давно вы занимаетесь программизмом?»

  • Начинал лет в 11 с C/C++ (Turbo C / C++Builder)
  • Потом открыл для себя Linux, свободный софт...
    главное читать логи :)
  • ...LAMP (Perl/PHP), HTML и JS
  • Теперь полюбил серверный JS (nodejs)

О чём доклад? @@

  • Почему JS?
  • История JavaScript
  • Обзор языка, производительность
  • Обзор выдумок
    (фреймворки, системы сборки и т.п)
  • Немного демо

Что такое JS? @@

JavaScriptECMAScript

  • Скриптота! (динамический язык)
  • Объект/массив/скаляр (JSON)
  • Прототипы, замыкания, колбэки, нет многопоточности
  • ES - язык. А ещё есть окружение (DOM, BOM)
  • Куча новых фич (ES2015-2016-2017)
  • Браузерный - Chrome (V8), Firefox (SpiderMonkey) и даже IE (ChakraCore)
  • Серверный - node.js (V8)

Скриптота vs типизация @@

script_kiddies_demotivator.jpeg

Но тема-то серьёзная @@

  • ХОЛИВАР!!!
  • Скриптота развивается - много популярных языков
  • Статические... ну, что-то есть... D, Rust, Go, Vala, Swift...
    но кто на них пишет-то?
  • Удобно: легко работать с данными, дженерики не нужны

Все хотят одного @@

  • Типизация - не необходимость, а лишь один из способов проверки
    ещё есть Rust = borrow checker
    ещё есть функциональщина = по сути "purity" checker

414874_paranojya.jpg

  • auto уже даже в C++
  • тайпчекер (частично) уже даже в PHP (+ Hack)

Почему JS? @@

  • Нейтральный C-подобный синтаксис
  • Быстрые интерпретаторы
  • Событийная машина
  • Мощно развивается

Синтаксис @@ %%

Perl @@

if ($single)
{
    # Single bug
    my ($id) = list $ARGS->{id};
    push @bugs, Bugzilla::Bug->check($id);
    if (defined $ARGS->{mark})
    {
        foreach my $range (split ',', $ARGS->{mark})
        {
            if ($range =~ /^(\d+)-(\d+)$/)
            {
                foreach my $i ($1..$2)
                {
                    $marks{$i} = 1;
                }
            }
            elsif ($range =~ /^(\d+)$/)
            {
                $marks{$1} = 1;
            }
        }
    }
}

PHP @@

$isExact = [];
foreach ([ 'line' => 'l', 'cfo' => 'cc' ] as $k => $t)
{
    if (!isset($specified[$k.'_id']) && !isset($specified[$k.'_id_exact']) && 
        !isset($groups[$k]) && !isset($groups[$k.'_all']))
        $isExact[] = "$posAlias.${k}_id IS NULL";
    elseif ($lastgrp == $k.'all')
        $isExact[] = "$posAlias.${k}_id=$t.id";
}
foreach ([ 'party', 'account', 'paytype' ] as $k)
    if (!isset($specified[$k.'_id']) && !isset($groups[$k]))
        $isExact[] = "$posAlias.${k}_id IS NULL";
return implode(' AND ', $isExact) ?: '1=1';
  • Что за $$$$$?

Python @@

class FileCache:
  def __init__(self, dir):
    self.dir = dir
    if not os.path.isdir(dir):
      os.mkdir(dir)
  def fn(self, key):
    key = re.sub('([^a-zA-Z0-9_\-]+)', lambda x: binascii.hexlify(x.group(1)), key)
    return self.dir+'/'+key
  def clean(self):
    t = time.time()
    for fn in os.listdir(self.dir):
      if t > os.stat(self.dir+'/'+fn).st_mtime:
        os.unlink(self.dir+'/'+fn)
  • Пробелы меняют смысл?!!!!

Ruby @@

module Gitlab
  class SearchResults
    attr_reader :current_user, :query
 
    def objects(scope, page = nil)
      case scope
      when 'projects'
        projects.page(page).per(per_page)
      when 'issues'
        issues.page(page).per(per_page)
      when 'merge_requests'
        merge_requests.page(page).per(per_page)
      when 'milestones'
        milestones.page(page).per(per_page)
      else
        Kaminari.paginate_array([]).page(page).per(per_page)
      end
    end
  • projects - переменная? Фигвам. Метод без аргументов.)

Go @@

func TestChannelStoreSave(t *testing.T) {
        Setup()
 
        teamId := model.NewId()
 
        o1 := model.Channel{}
        o1.TeamId = teamId
        o1.DisplayName = "Name"
        o1.Name = "a" + model.NewId() + "b"
        o1.Type = model.CHANNEL_OPEN
 
        if err := (<-store.Channel().Save(&o1)).Err; err != nil {
                t.Fatal("couldn't save item", err)
        }
 
        if err := (<-store.Channel().Save(&o1)).Err; err == nil {
                t.Fatal("shouldn't be able to update from save")
        }
  • Что за смайлики := <- & *? Где мои скобочки?

Erlang @@

iq_handler(From, _To,
	   #iq{type=set, lang = Lang,
	       sub_el = #xmlel{name = Operation} = SubEl} = IQ, CC)->
    ?DEBUG("carbons IQ received: ~p", [IQ]),
    {U, S, R} = jid:tolower(From),
    Result = case Operation of
        <<"enable">>->
	    ?INFO_MSG("carbons enabled for user ~s@~s/~s", [U,S,R]),
            enable(S,U,R,CC);
        <<"disable">>->
	    ?INFO_MSG("carbons disabled for user ~s@~s/~s", [U,S,R]),
            disable(S, U, R)
    end,
    case Result of
        ok ->
	    ?DEBUG("carbons IQ result: ok", []),
            IQ#iq{type=result, sub_el=[]};
	{error,_Error} ->
	    ?ERROR_MSG("Error enabling / disabling carbons: ~p", [Result]),
	    Txt = <<"Database failure">>,
            IQ#iq{type=error,sub_el = [SubEl, ?ERRT_INTERNAL_SERVER_ERROR(Lang, Txt)]}
end;
  • Ой-ой-ой
  • Классов нет, есть процессы

OCaml O_O @@

let log_client_info c sock = 
  let buf = Buffer.create 100 in
  let date = BasicSocket.date_of_int (last_time ()) in
  Printf.bprintf buf "%-12s(%d):%d -> %-30s[%-14s %-20s] connected for %5d secs %-10s bw %5d/%-5d %-6s %2d/%-2d reqs " 
    (Date.simple date) 
  (nb_sockets ())
  (client_num c)
  (
    let s = c.client_name in
    let len = String.length s in 
    if len > 30 then String.sub s 0 30 else s)
 
  (brand_to_string c.client_brand)
  (match c.client_kind with Indirect_address _ | Invalid_address _ -> "LowID"
    | Direct_address (ip,port) -> Printf.sprintf "%s:%d"
          (Ip.to_string ip) port)
  (last_time () - c.client_connect_time)
  (if c.client_rank > 0 then
      Printf.sprintf "rank %d" c.client_rank
      else "")
  (nwritten sock) (nread sock)
  (if c.client_banned then "banned" else "")
  c.client_requests_received
    c.client_requests_sent
  ;
  • ПОЛИЗ?!!!!

JS @@

TreeGridNode.prototype.setChildren = function(isLeaf, newChildren)
{
    if (!this.tr)
        this.grid.tbody.innerHTML = '';
    else
    {
        var tr = this.tr[this.tr.length-1];
        while (tr.nextSibling && tr.nextSibling._node.level > this.level)
            this.grid.tbody.removeChild(tr.nextSibling);
        if (this.leaf != isLeaf)
        {
            if (isLeaf)
            {
                this.tr[0].cells[0].firstChild.className = 'collapser collapser-inactive';
                removeListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
            }
            else
            {
                this.tr[0].cells[0].firstChild.className = this.collapsed ? 'collapser collapser-collapsed' : 'collapser collapser-expanded';
                addListener(this.tr[0].cells[0].firstChild, 'click', this._getToggleHandler());
            }
        }
    }
    this.leaf = isLeaf;
    this.children = [];
    this.childrenByKey = {};
    this.addChildren(newChildren);
}