SlideShare une entreprise Scribd logo
1  sur  31
Télécharger pour lire hors ligne
Лямбды, блоки,
замыкания


А давайте посмотрим, что у
них внутри
Дмитрий Кириенко
               Twitter:
               @DimKiriyenko

               Github: dmitriy-
               kiriyenko
rb_block_t

     ???
10.times do
 str = "Hello world."
 puts str
end

putstring "Hello world."   rb_block_t
setlocal str, 0
putself
getlocal str, 0                iseq
send :puts, 1
leave
str_ext = "Hello"
10.times do
 str = "world."
 puts "#{str_ext} #{str}"
end
"Чтобы решить эту проблему мы вводим
понятие    замыкания   как  структуры,
содержащей      лямбда-выражение     и
окружение, которое будет использовано,
когда это выражение будет применено к
своим аргументам."
Scheme: An Interpreter for Extended Lambda Calculus
str_ext = "Hello"
10.times do
 str = "world."
 puts "#{str_ext} #{str}"
end
                          Кадр стека верхнего
Внутренний стек YARV            уровня
                          rb_control_frame_t

        locals: str_ext          EP
str_ext = "Hello"
10.times do
 str = "world."
 puts "#{str_ext} #{str}"   rb_block_t
end
                                   iseq
                                  EP

                            Кадр стека верхнего
Внутренний стек YARV              уровня
                            rb_control_frame_t

        locals: str_ext            EP
str_ext = "Hello"
10.times do
 str = "world."
 puts "#{str_ext} #{str}"
end
                                Кадр стека
Внутренний стек YARV           Fixnum#times
                            rb_control_frame_t

                                  EP

        locals: str_ext
str_ext = "Hello"
10.times do
 str = "world."
 puts "#{str_ext} #{str}"
end
                                      Кадр стека
  Внутренний стек YARV                Block#yield
                                   rb_control_frame_t
                     locals: str
                                         EP
                            EP




                                   rb_block_t

                 locals: str_ext          iseq
                                          EP
DEFINE_INSN
getlocal
(lindex_t idx, rb_num_t level)
()
(VALUE val)
{
    int i, lev = (int)level;
    VALUE *ep = GET_EP();

       for (i = 0; i < lev; i++) {
           ep = GET_PREV_EP(ep);
       }
       val = *(ep - idx);
}



    https://github.com/ruby/ruby/blob/trunk/insns.def#L43L67
"Чтобы решить эту проблему мы вводим
понятие    замыкания   как  структуры,
содержащей      лямбда-выражение     и
окружение, которое будет использовано,
когда это выражение будет применено к
своим аргументам."
Scheme: An Interpreter for Extended Lambda Calculus
Control frame              Block
typedef struct
rb_control_frame_struct {
   VALUE *pc;
   VALUE *sp;
   rb_iseq_t *iseq;
                             typedef struct
   VALUE flag;
                             rb_block_struct {
   VALUE self;
                                VALUE self;
   VALUE klass;
                                VALUE klass
   VALUE *ep;
                                VALUE *ep;
   rb_iseq_t *block_iseq;
                                rb_iseq_t *iseq;
   VALUE proc;
                                VALUE proc;
   const rb_method_entry_t
                             } rb_block_t;
*me;

#if VM_DEBUG_BP_CHECK
   VALUE *bp_check;
#endif
} rb_control_frame_t;
require 'benchmark'                 while 6763524 in 5.036406s
require 'benchmark/ips'
                                    block 4267105 in 5.016071s
Benchmark.ips do |b|                reduce 3606540 in 5.054937s
 b.report 'while' do
  sum = 0; i = 0
  while i <= 10
    sum += i; i += 1
  end
 end

 b.report 'block' do
  sum = 0
  (1..10).each do |i|
    sum += 1
  end
 end

 b.report 'reduce' do
  (1..10).reduce {|acc, i| acc+i}
 end
end
def get_helloer
 str_ext = "Hello"
 lambda do |who|
   puts "#{str_ext} #{who}!"
 end
end

helloer = get_helloer
helloer.call('there')
В 1930-х годах Алонзо Чёрч ввёл лямбда-нотацию в своём исследовании
                        "Лямбда-исчисление"
def get_helloer
 str_ext = "Hello"
 lambda do |who|
   puts "#{str_ext} #{who}!"
 end
end

helloer = get_helloer
helloer.call('there')
rb_lambda_t

     ???
locals: str_ext   rb_control_frame_t

                             Кадр стека
                             get_helloer




Стек

Куча
        RString

           "Hello"
locals: str_ext   rb_control_frame_t

                                    Кадр стека
                                    get_helloer




Стек
Куча                             rb_proc_t
                                 rb_block_t
                     str_ext             iseq
   rb_env_t                             EP
       env                             envval
                                     is_lambda
helloer
       locals: str_ext   rb_control_frame_t

                             Кадр стека
                           внешнего кода




Стек
Куча

       rb_proc_t


       rb_env_t                 str_ext
argument: who
              locals: str_ext
              EP
                                rb_control_frame_t

                                Кадр стека helloer.
                                       call




Стек
Куча                             rb_proc_t
                                 rb_block_t
                     str_ext             iseq
   rb_env_t                             EP
       env                             envval
                                     is_lambda
def get_helloer
 str_ext = "Hello"
 res = lambda do |who|
  puts "#{str_ext} #{who}!"
 end
 str_ext = "Goodbye"
 res
end

helloer = get_helloer
helloer.call('there')
def get_helloer
 str_ext = "Hello"
 res = lambda do |who|
  puts "#{str_ext} #{who}!"
 end
 str_ext = "Goodbye"
 res
end

helloer = get_helloer
helloer.call('there')



               Goodbye there!
Кадр стека
                                    get_helloer
              locals: str_ext   rb_control_frame_t
                                       EP




Стек
Куча

                      str_ext

   rb_env_t

       env
def create_counter(start)
 value = start
 { inc: ->{value+=1}, dec: ->{value-=1},
  get: ->{value} }
end

counter = create_counter(500)
counter[:inc].call
puts counter[:get].call #=> 501
10.times { counter[:dec].call }
puts counter[:get].call #=> 491



                       501
                       491
require 'benchmark/ips'
                             block 19659752 in 5.000587s
                             lambda 4574745 in 5.033561s
def do_with_block
 yield
end

def do_with_lambda(&block)
 block.call
end

Benchmark.ips do |b|
 b.report 'block' do
  do_with_block { 1+1 }
 end
 b.report 'lambda' do
  do_with_lambda {1+1}
 end
end
str_ext = "Hello"
      10.times do
       str = "world."
       puts "#{str_ext} #{str}"
      end
       _file_               DynamicScope
                                  str_ext


RubyFixnum.times
                                        родитель

                           DynamicScope
block_0$RUBY$__file__



                        JRuby
str_ext = "Hello"
     10.times do
      str = "world."
      puts "#{str_ext} #{str}"
     end
код верхнего уровня        VariableScope
                                  str_ext


 Integer.times
                                        родитель

                           VariableScope
    код блока



                      Rubinius
Блоки, лямбды, замыкания

Contenu connexe

Tendances

"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...
"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма..."Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...
"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...Yandex
 
Программирование Linux
Программирование LinuxПрограммирование Linux
Программирование LinuxAnthony Shoumikhin
 
Нетривиальная обработка ошибок
Нетривиальная обработка ошибокНетривиальная обработка ошибок
Нетривиальная обработка ошибокoelifantiev
 
Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.
Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.
Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.DataArt
 
Python
PythonPython
Pythonpelid
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf Conference
 
Программирование Linux
Программирование LinuxПрограммирование Linux
Программирование LinuxAnthony Shoumikhin
 
Present saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPresent saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPavel Vlasov
 
Ecma script 6 yevhen diachenko
Ecma script 6 yevhen diachenkoEcma script 6 yevhen diachenko
Ecma script 6 yevhen diachenkoDenis Khabrenko
 
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...Moscow.pm
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)Mikhail Davydov
 
Что нового в Perl 5.14
Что нового в Perl 5.14Что нового в Perl 5.14
Что нового в Perl 5.14Andrew Shitov
 
Не верь никому или разработка эффективных приложений (Как писать по настоящем...
Не верь никому или разработка эффективных приложений (Как писать по настоящем...Не верь никому или разработка эффективных приложений (Как писать по настоящем...
Не верь никому или разработка эффективных приложений (Как писать по настоящем...Moscow.pm
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonPython Meetup
 
Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...
Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...
Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...Vadim Kruchkov
 
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...Ontico
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6Dmitry Soshnikov
 

Tendances (20)

"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...
"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма..."Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...
"Инструментарий разработчика iOS: Xcode, AppCode и сторонние инструменты". Ма...
 
Программирование Linux
Программирование LinuxПрограммирование Linux
Программирование Linux
 
Нетривиальная обработка ошибок
Нетривиальная обработка ошибокНетривиальная обработка ошибок
Нетривиальная обработка ошибок
 
Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.
Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.
Игорь Ходырев — Введение в Ruby, gem’ы и другие бриллианты.
 
Python
PythonPython
Python
 
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to UsZFConf 2010: What News Zend Framework 2.0 Brings to Us
ZFConf 2010: What News Zend Framework 2.0 Brings to Us
 
new JavaScript
new JavaScriptnew JavaScript
new JavaScript
 
Программирование Linux
Программирование LinuxПрограммирование Linux
Программирование Linux
 
Present saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasovPresent saint-per3-by-pavel-vlasov
Present saint-per3-by-pavel-vlasov
 
Ecma script 6 yevhen diachenko
Ecma script 6 yevhen diachenkoEcma script 6 yevhen diachenko
Ecma script 6 yevhen diachenko
 
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...
Динамический код: модифицируем таблицу символов во время выполнения. Елена Ши...
 
JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)JavaScript. Loops and functions (in russian)
JavaScript. Loops and functions (in russian)
 
Что нового в Perl 5.14
Что нового в Perl 5.14Что нового в Perl 5.14
Что нового в Perl 5.14
 
Не верь никому или разработка эффективных приложений (Как писать по настоящем...
Не верь никому или разработка эффективных приложений (Как писать по настоящем...Не верь никому или разработка эффективных приложений (Как писать по настоящем...
Не верь никому или разработка эффективных приложений (Как писать по настоящем...
 
Красота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки PythonКрасота и изящность стандартной библиотеки Python
Красота и изящность стандартной библиотеки Python
 
Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...
Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...
Пора ли отправлять С на свалку истории? Пишем демонов на PHP с использованием...
 
Парсим CSS
Парсим CSSПарсим CSS
Парсим CSS
 
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
Как перестать отлаживать асинхронный код и начать жить / Андрей Саломатин (Pr...
 
DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6DevConf. Дмитрий Сошников - ECMAScript 6
DevConf. Дмитрий Сошников - ECMAScript 6
 
Collider
ColliderCollider
Collider
 

En vedette

Chune PM Awards Presentation
Chune PM Awards PresentationChune PM Awards Presentation
Chune PM Awards PresentationKern Elliott
 
Функциональное реактивное программирование
Функциональное реактивное программированиеФункциональное реактивное программирование
Функциональное реактивное программированиеDmitriy Kiriyenko
 
Marketing local music via digital technology
Marketing local music via digital technologyMarketing local music via digital technology
Marketing local music via digital technologyKern Elliott
 
Chune - PitchIT Caribbean 5 Minute Pitch Deck
Chune - PitchIT Caribbean 5 Minute Pitch DeckChune - PitchIT Caribbean 5 Minute Pitch Deck
Chune - PitchIT Caribbean 5 Minute Pitch DeckKern Elliott
 
15 korea introduction
15 korea introduction15 korea introduction
15 korea introductioniancerep
 
PCBs for MICROELECTRONICS - Design for Manufacturability
PCBs for MICROELECTRONICS - Design for ManufacturabilityPCBs for MICROELECTRONICS - Design for Manufacturability
PCBs for MICROELECTRONICS - Design for ManufacturabilitySierra Circuits, Inc.
 
Bitcoin Data Pipeline - Insight Data Science project - September 2014
Bitcoin Data Pipeline - Insight Data Science project - September 2014Bitcoin Data Pipeline - Insight Data Science project - September 2014
Bitcoin Data Pipeline - Insight Data Science project - September 2014Jean-Marc Soumet
 
Streaming Music in 2016
Streaming Music in 2016Streaming Music in 2016
Streaming Music in 2016Kern Elliott
 

En vedette (12)

Chune PM Awards Presentation
Chune PM Awards PresentationChune PM Awards Presentation
Chune PM Awards Presentation
 
2013 28-03-dak-why-fp
2013 28-03-dak-why-fp2013 28-03-dak-why-fp
2013 28-03-dak-why-fp
 
February 2014 column slideshare
February 2014 column slideshareFebruary 2014 column slideshare
February 2014 column slideshare
 
Функциональное реактивное программирование
Функциональное реактивное программированиеФункциональное реактивное программирование
Функциональное реактивное программирование
 
Marketing local music via digital technology
Marketing local music via digital technologyMarketing local music via digital technology
Marketing local music via digital technology
 
Rbrown
RbrownRbrown
Rbrown
 
Chune - PitchIT Caribbean 5 Minute Pitch Deck
Chune - PitchIT Caribbean 5 Minute Pitch DeckChune - PitchIT Caribbean 5 Minute Pitch Deck
Chune - PitchIT Caribbean 5 Minute Pitch Deck
 
15 korea introduction
15 korea introduction15 korea introduction
15 korea introduction
 
PCBs for MICROELECTRONICS - Design for Manufacturability
PCBs for MICROELECTRONICS - Design for ManufacturabilityPCBs for MICROELECTRONICS - Design for Manufacturability
PCBs for MICROELECTRONICS - Design for Manufacturability
 
Bitcoin Data Pipeline - Insight Data Science project - September 2014
Bitcoin Data Pipeline - Insight Data Science project - September 2014Bitcoin Data Pipeline - Insight Data Science project - September 2014
Bitcoin Data Pipeline - Insight Data Science project - September 2014
 
стандарты
стандартыстандарты
стандарты
 
Streaming Music in 2016
Streaming Music in 2016Streaming Music in 2016
Streaming Music in 2016
 

Similaire à Блоки, лямбды, замыкания

Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода Pavel Tsukanov
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кодаAndrey Karpov
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castRoman Orlov
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работуcorehard_by
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupMail.ru Group
 
Статический анализ: ошибки в медиаплеере и безглючная аська
Статический анализ: ошибки в медиаплеере и безглючная аська Статический анализ: ошибки в медиаплеере и безглючная аська
Статический анализ: ошибки в медиаплеере и безглючная аська Tatyanazaxarova
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CГлеб Тарасов
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksMikhail Kurnosov
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioAndrey Karpov
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...Alexey Paznikov
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухинcorehard_by
 
PHP Tricks
PHP TricksPHP Tricks
PHP TricksBlackFan
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...CocoaHeads
 
Python и его тормоза
Python и его тормозаPython и его тормоза
Python и его тормозаAlexander Shigin
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Yandex
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Andrey Karpov
 
Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Alexander Kirillov
 

Similaire à Блоки, лямбды, замыкания (20)

Статический анализ кода
Статический анализ кода Статический анализ кода
Статический анализ кода
 
статический анализ кода
статический анализ кодастатический анализ кода
статический анализ кода
 
Догнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_castДогнать и перегнать boost::lexical_cast
Догнать и перегнать boost::lexical_cast
 
Programming c++ (begin-if-else)
Programming c++ (begin-if-else)Programming c++ (begin-if-else)
Programming c++ (begin-if-else)
 
Как за час сделать недельную работу
Как за час сделать недельную работуКак за час сделать недельную работу
Как за час сделать недельную работу
 
msumobi2. Лекция 2
msumobi2. Лекция 2msumobi2. Лекция 2
msumobi2. Лекция 2
 
Clojure #2 (2014)
Clojure #2 (2014)Clojure #2 (2014)
Clojure #2 (2014)
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
 
Статический анализ: ошибки в медиаплеере и безглючная аська
Статический анализ: ошибки в медиаплеере и безглючная аська Статический анализ: ошибки в медиаплеере и безглючная аська
Статический анализ: ошибки в медиаплеере и безглючная аська
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
 
Лекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building BlocksЛекция 8. Intel Threading Building Blocks
Лекция 8. Intel Threading Building Blocks
 
Принципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-StudioПринципы работы статического анализатора кода PVS-Studio
Принципы работы статического анализатора кода PVS-Studio
 
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
ПВТ - осень 2014 - Лекция 4 - Стандарт POSIX Threads. Реентерабельность. Сигн...
 
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон ПолухинC++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
C++ CoreHard Autumn 2018. Полезный constexpr - Антон Полухин
 
PHP Tricks
PHP TricksPHP Tricks
PHP Tricks
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
 
Python и его тормоза
Python и его тормозаPython и его тормоза
Python и его тормоза
 
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
Андрей Субботин "Локализация приложений для iOS: как не прострелить себе ногу"
 
Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?Статический анализ кода: Что? Как? Зачем?
Статический анализ кода: Что? Как? Зачем?
 
Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)Предметно-ориентированные языки программирования (DSL)
Предметно-ориентированные языки программирования (DSL)
 

Блоки, лямбды, замыкания

  • 1. Лямбды, блоки, замыкания А давайте посмотрим, что у них внутри
  • 2. Дмитрий Кириенко Twitter: @DimKiriyenko Github: dmitriy- kiriyenko
  • 3.
  • 5. 10.times do str = "Hello world." puts str end putstring "Hello world." rb_block_t setlocal str, 0 putself getlocal str, 0 iseq send :puts, 1 leave
  • 6. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" end
  • 7. "Чтобы решить эту проблему мы вводим понятие замыкания как структуры, содержащей лямбда-выражение и окружение, которое будет использовано, когда это выражение будет применено к своим аргументам." Scheme: An Interpreter for Extended Lambda Calculus
  • 8. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" end Кадр стека верхнего Внутренний стек YARV уровня rb_control_frame_t locals: str_ext EP
  • 9. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" rb_block_t end iseq EP Кадр стека верхнего Внутренний стек YARV уровня rb_control_frame_t locals: str_ext EP
  • 10. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" end Кадр стека Внутренний стек YARV Fixnum#times rb_control_frame_t EP locals: str_ext
  • 11. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" end Кадр стека Внутренний стек YARV Block#yield rb_control_frame_t locals: str EP EP rb_block_t locals: str_ext iseq EP
  • 12. DEFINE_INSN getlocal (lindex_t idx, rb_num_t level) () (VALUE val) { int i, lev = (int)level; VALUE *ep = GET_EP(); for (i = 0; i < lev; i++) { ep = GET_PREV_EP(ep); } val = *(ep - idx); } https://github.com/ruby/ruby/blob/trunk/insns.def#L43L67
  • 13. "Чтобы решить эту проблему мы вводим понятие замыкания как структуры, содержащей лямбда-выражение и окружение, которое будет использовано, когда это выражение будет применено к своим аргументам." Scheme: An Interpreter for Extended Lambda Calculus
  • 14. Control frame Block typedef struct rb_control_frame_struct { VALUE *pc; VALUE *sp; rb_iseq_t *iseq; typedef struct VALUE flag; rb_block_struct { VALUE self; VALUE self; VALUE klass; VALUE klass VALUE *ep; VALUE *ep; rb_iseq_t *block_iseq; rb_iseq_t *iseq; VALUE proc; VALUE proc; const rb_method_entry_t } rb_block_t; *me; #if VM_DEBUG_BP_CHECK VALUE *bp_check; #endif } rb_control_frame_t;
  • 15. require 'benchmark' while 6763524 in 5.036406s require 'benchmark/ips' block 4267105 in 5.016071s Benchmark.ips do |b| reduce 3606540 in 5.054937s b.report 'while' do sum = 0; i = 0 while i <= 10 sum += i; i += 1 end end b.report 'block' do sum = 0 (1..10).each do |i| sum += 1 end end b.report 'reduce' do (1..10).reduce {|acc, i| acc+i} end end
  • 16. def get_helloer str_ext = "Hello" lambda do |who| puts "#{str_ext} #{who}!" end end helloer = get_helloer helloer.call('there')
  • 17. В 1930-х годах Алонзо Чёрч ввёл лямбда-нотацию в своём исследовании "Лямбда-исчисление"
  • 18. def get_helloer str_ext = "Hello" lambda do |who| puts "#{str_ext} #{who}!" end end helloer = get_helloer helloer.call('there')
  • 19. rb_lambda_t ???
  • 20. locals: str_ext rb_control_frame_t Кадр стека get_helloer Стек Куча RString "Hello"
  • 21. locals: str_ext rb_control_frame_t Кадр стека get_helloer Стек Куча rb_proc_t rb_block_t str_ext iseq rb_env_t EP env envval is_lambda
  • 22. helloer locals: str_ext rb_control_frame_t Кадр стека внешнего кода Стек Куча rb_proc_t rb_env_t str_ext
  • 23. argument: who locals: str_ext EP rb_control_frame_t Кадр стека helloer. call Стек Куча rb_proc_t rb_block_t str_ext iseq rb_env_t EP env envval is_lambda
  • 24. def get_helloer str_ext = "Hello" res = lambda do |who| puts "#{str_ext} #{who}!" end str_ext = "Goodbye" res end helloer = get_helloer helloer.call('there')
  • 25. def get_helloer str_ext = "Hello" res = lambda do |who| puts "#{str_ext} #{who}!" end str_ext = "Goodbye" res end helloer = get_helloer helloer.call('there') Goodbye there!
  • 26. Кадр стека get_helloer locals: str_ext rb_control_frame_t EP Стек Куча str_ext rb_env_t env
  • 27. def create_counter(start) value = start { inc: ->{value+=1}, dec: ->{value-=1}, get: ->{value} } end counter = create_counter(500) counter[:inc].call puts counter[:get].call #=> 501 10.times { counter[:dec].call } puts counter[:get].call #=> 491 501 491
  • 28. require 'benchmark/ips' block 19659752 in 5.000587s lambda 4574745 in 5.033561s def do_with_block yield end def do_with_lambda(&block) block.call end Benchmark.ips do |b| b.report 'block' do do_with_block { 1+1 } end b.report 'lambda' do do_with_lambda {1+1} end end
  • 29. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" end _file_ DynamicScope str_ext RubyFixnum.times родитель DynamicScope block_0$RUBY$__file__ JRuby
  • 30. str_ext = "Hello" 10.times do str = "world." puts "#{str_ext} #{str}" end код верхнего уровня VariableScope str_ext Integer.times родитель VariableScope код блока Rubinius