суббота, 24 июня 2017 г.

Ещё про функторы

PROCEDURE EnumWindowChildren
  nWnd IN aWindow
  FUNCTOR IN aLambda
 
 aWindow aLambda DO
 // - вызываем aLambda на aWindow
 aWindow .EnumChildren ( aLambda call.me )
 // - вызываем себя рекурсивно
; // EnumWindowChildren

FunctorToIterator Desktop EnumWindowChildren .for .Out
// - перебираем все окна от Desktop рекурсивно

А теперь с анонимной функцией:

FunctorToIterator Desktop (
  nWnd IN aWindow
  FUNCTOR IN aLambda
 
 aWindow aLambda DO
 // - вызываем aLambda на aWindow
 aWindow .EnumChildren ( aLambda call.me )
 // - вызываем себя рекурсивно
) .for .Out
// - перебираем все окна от Desktop рекурсивно

Про функторы и итераторы. Простой пример

PROCEDURE .To
  IN aLowBound
  IN aHighBound
  FUNCTOR IN aLambda
 if ( aLowBound <= aHighBound ) then
 // - граничное условие
 begin
  aLowBound aLambda DO // - вызываем aLambda на aLowBound 
  Inc aLowBound // - увеличиваем aLowBound 
  aLowBound aHighBound aLambda call.me
  // - вызываем себя рекурсивно  
 end // ( aLowBound <= aHighBound )
; // .To

FunctorToIterator ( 1 10 ) .To .for .Out 
// - печатает числа от 1 до 10

FunctorToIterator ( 1 10 ) .To 
.filter ( <> 2 ) 
.for .Out 
// - печатает числа от 1 до 10, исключая 2

FunctorToIterator ( 1 10 ) .To 
.filter ( <> 2 ) 
.map ( 1 + ) 
.for .Out 
// - печатает числа от 2 до 11, исключая 3

То же самое, но с параметром справа:
PROCEDURE To
  IN aLowBound
  FUNCTOR IN aLambda
  Right IN aHighBound
 if ( aLowBound <= aHighBound ) then
 // - граничное условие
 begin
  aLowBound aLambda DO // - вызываем aLambda на aLowBound 
  Inc aLowBound // - увеличиваем aLowBound 
  aLowBound aLambda call.me aHighBound
  // - вызываем себя рекурсивно  
 end // ( aLowBound <= aHighBound )
; // To

FunctorToIterator 1 To 10 .for .Out 
// - печатает числа от 1 до 10

FunctorToIterator 1 To 10
.filter ( <> 2 ) 
.for .Out 
// - печатает числа от 1 до 10, исключая 2

FunctorToIterator 1 To 10
.filter ( <> 2 ) 
.map ( 1 + ) 
.for .Out 
// - печатает числа от 2 до 11, исключая 3

Немножко косметики:

ARRAY FUNCTION To
  IN aLowBound
  Right IN aHighBound

 PROCEDURE InnerTo
   IN aLowBound
   FUNCTOR IN aLambda
   Right IN aHighBound
  if ( aLowBound <= aHighBound ) then
  // - граничное условие
  begin
   aLowBound aLambda DO // - вызываем aLambda на aLowBound 
   Inc aLowBound // - увеличиваем aLowBound 
   aLowBound aLambda call.me aHighBound
   // - вызываем себя рекурсивно  
  end // ( aLowBound <= aHighBound )
 ; // InnerTo

 FunctorToIterator aLowBound InnerTo aHighBound
 >>> Result
; // To 

1 To 10 .for .Out 
// - печатает числа от 1 до 10

1 To 10
.filter ( <> 2 ) 
.for .Out 
// - печатает числа от 1 до 10, исключая 2

1 To 10
.filter ( <> 2 ) 
.map ( 1 + ) 
.for .Out 
// - печатает числа от 2 до 11, исключая 3

Ещё косметики:
ARRAY FUNCTION To
  IN aLowBound
  Right IN aHighBound

 PROCEDURE InnerTo
   IN aLowBound
   FUNCTOR IN aLambda
   Right IN aHighBound
  if ( aLowBound <= aHighBound ) then
  // - граничное условие
  begin
   aLowBound aLambda DO // - вызываем aLambda на aLowBound 
   Inc aLowBound // - увеличиваем aLowBound 
   aLowBound aLambda call.me aHighBound
   // - вызываем себя рекурсивно  
  end // ( aLowBound <= aHighBound )
 ; // InnerTo

 FunctorToIterator aLowBound InnerTo aHighBound
 >>> Result
; // To 

PROCEDURE for
  ARRAY Right anArray
  FUNCTOR Right aLambda
 anArray .for> aLambda  
; // for

for ( 1 To 10 ) 
.Out 
// - печатает числа от 1 до 10

for
( 1 To 10
.filter ( <> 2 ) 
)
.Out 
// - печатает числа от 1 до 10, исключая 2

for 
( 1 To 10
.filter ( <> 2 ) 
.map ( 1 + ) 
)
.Out 
// - печатает числа от 2 до 11, исключая 3


Ещё про скрипты


Также это в некотором смысле - аналог json.

Можно написать:

Elem A
 Elem B
 ; // B
 Elem C
 ; // C
; // A

PROCEDURE .Print
  IN anElement
 anElement .Stereotype .Out // - печатаем стереотип элемента
 anElement .Name .Out // - печатаем имя элемента
 anElement .MembersIterator .for call.me
 // - итерируем вложенные элементы и вызываем себя рекурсивно
; // .Print

@ A .Print

Будет напечатано:

Elem
A
Elem
B
Elem
C

А можно написать так:

STRING VAR S
S :=
'
Elem A
 Elem B
 ;
 Elem C
 ;
;
' 
>>> S // - кладём "код в строку"
// Да - строки в кавычках могут содержать в себе и переводы строк тоже 

S
.CompileStringAndDo .Print
// - компилируем строку и вызываем для построенного кода функцию .Print

Результат будет тот же.

А можно написать так:

: .ToStack
  IN anElement
 anElement // - это кладём на стек
 anElement .MembersIterator .for call.me
 // - итерируем вложенные элементы и вызываем себя рекурсивно
; // .ToStack

STRING VAR S
S :=
'
Elem A
 Elem B
 ;
 Elem C
 ;
;
' 
>>> S // - кладём "код в строку"
// Да - строки в кавычках могут содержать в себе и переводы строк тоже 

ARRAY VAR A
[ // - открываем массив
S .CompileStringAndDo .ToStack
] // - закрываем массив
>>> A // - кладём массив в переменную A

A .for .Out // - печатаем массив полностью
A .filter ( .Name <> 'B' ) .for .Out // - печатаем из массива элементы имя которых НЕ РАВНО B

Ну и всякие подобные штучки.

А можно без копирования:

PROCEDURE .Unfold
  IN anElement
  FUNCTOR IN aLambda
 anElement aLambda DO // - вызываем функтор aLambda на элементе anElement
 anElement .MembersIterator .for ( aLambda call.me )
 // - итерируем вложенные элементы и вызываем себя рекурсивно
; // .Unfold

STRING VAR S
S :=
'
Elem A
 Elem B
 ;
 Elem C
 ;
;
' 
>>> S // - кладём "код в строку"
// Да - строки в кавычках могут содержать в себе и переводы строк тоже 

VAR A
S .CompileStringAndDo ( >>> A ) // - компилируем код из строки S и кладём результат в переменную A

FunctorToIterator 
// - преобразование функтора в итератор
A 
// - параметр функтора
.Unfold 
// - сам функтор
.for .Out // - печатаем массив полностью

FunctorToIterator A .Unfold .filter ( .Name <> 'B' ) .for .Out // - печатаем из массива элементы имя которых НЕ РАВНО B

четверг, 22 июня 2017 г.

ToDo

Try..finally..end заменить на:

Try_finally ( a ) ( b )
Try_except ( a ) ( b )

И пихать begin в поток токенов.

Чтобы try a finally b end разворачивалось в:

Try_finally begin a end begin b end

Ну и try a except b end соответственно:

Try_except begin a end begin b end

Убрать FirstHalf и DualCompilingWord.

ToDo

Для слов сделать экземпляры, а не классы.

С event'ами.

среда, 21 июня 2017 г.

ToDo

Сделать Bind. С проверкой типов:

A pop:Word:Name
- типы не проверяются

A .Bind pop:Word:Name
- типы проверяются

И алиас ¦-> с подстановкой "pop:":

A ¦-> pop:Word:Name
- типы проверяются

A ¦-> Word:Name
- типы проверяются (производится постановка)

И "выбор типа":

A ¦¦-> Name
- типы проверяются (и производится выбор типа).

Для этого сделать на ValueTypes метод SelfName.

пятница, 16 июня 2017 г.

Написали...

"Привет! Есть вопрос один рядом с программированием. Я поддерживаю прогу одну, ранее участвовал в ее разработке. Обычно запускали ее на полноценных ноутах и разницы с настольным компом не видели. А вот сейчас запустили ее на мини-ноуте и работает в два раза медленнее. На мини ноуте проц стоит Atom x5-z8350? памяти 4Гб. графика не знаю какая, система 10-ка домашняя 64разряда. Обычно мы работали на Core i5 4570 или старше, оперативки 16Гб, система 7-ка профессиональная. Программа использует .net  При запуске программы на мини ноуте проц нагружается процентов на 10, память - суммарно со всеми службами - процентов на 50. Собственно вопрос - как выяснить, где узкое место? Проц/память/графика/система/платформа/все вместе? Никогда просто этим не занимался - и попал в тупик."

Алгоритм маляра - одна из ПЕРВЫХ причин:
http://russian.joelonsoftware.com/Articles/BacktoBasics.html

По моему скромному мнению - в алгоритме маляра" наблюдается 80% проблем.

Вторая проблема - фрагментированность памяти. "Давить аллокации" - как писал мой друг Максим Лапшин.

Третья проблема - неудачная сортировка в контейнерах. Возможно надо использовать дихотомию (бинарную сортировку) вместо сортировки "пузырьком" (на контейнерах больше 1000 элементов, если верить Кнуту). Ну или использовать "мапы" вместо "векторов".

Ну и как советут Степанов - "сначала набираем данные, потом их фильтруем, , потом трансформируем, потом опять фильтруем, потом сортируем, потом ищем".

Add, Reduce, Map, Reduce, Sort, Find.

Array
.join> [ 1 2 3 "a" ]
.join> [ 3 2 1 "b" ]
.removeDuplicates>
.filter> .ItemIsInteger
.map> .ToString
.filter> .ItemNot "1"
.sort> .AsText
.find> "2"

Четвёртая проблема - работа с файлами, вместо работы с файлами. Кеширование - наше всё.

Пятая проблема связана со второй. "Множество мелких и короткоживущих объектов". Которые часто распределяются. Тут нам поможет шаблон LightWeight:
https://ru.m.wikipedia.org/wiki/Приспособленец_(шаблон_проектирования)

Ну и с этим же связана проблема выделения Mutable и Immutable объектов.

Ну и всяческие "фабрики" и "кеши".

Кешируемые Immutable объекты - "это хорошо".

Опять же - "давить аллокации".

http://www.gamedev.ru/code/forum/?id=205093&page=2

Навскидку - всё.

Ну и профайлер надо конечно использовать.

Больше проблем на своём опыте - я не встречал.

среда, 14 июня 2017 г.

ToDo. Проверка типов

Сделать INTEGER Cast и INTEGER :(

Ссылка. TVirtualInterface

Не устаю публиковать ссылку - http://docwiki.embarcadero.com/CodeExamples/XE8/en/Rtti.TVirtualInterface_(Delphi)

Уж очень мне идея нравится.

Я тут прикручиваю это дело к вариантам. Позже - напишу как получилось.

Offtopic

Соловьёв опять разрабатывает кулаками. Критикует немецкого министра обороны. Которая сказала, что "С Россией надо говорить с позиции силы".

Орёт. Иронизирует. Мол "немцы забыли Кузькину мать". Мол "мы им покажем".

Идиот. Извините. Вояка хренов. Он в армии то служил?

"Покажет он"...

Из Итальянского имения...

А аудитория строит и убивает головами...

Идиоты. Извините...

Они будут показывать? Сомневаюсь...

Мне не нравятся люди, которые не были в армии и махают кулаками. Я сам в армии не был. Но не махаю. Ибо понимаю, что окопы копать, как минимум, придётся мне, а не им.

А что такое - на морозе долбить мёрзлую землю - я знаю.


Offtopic. О жизни. Наблюдения

#байка

Сейчас на аллее. Идут парень с девушкой. Ну парень - "хипстер". А девушка. Ну ничего так девушка. В платье. И всё такое. А не то что - "пацанка". С цветами.

Обрывок разговора. Он ей говорит - "а я беру и рублю системный процесс..."

Наверное девушке ОЧЕНЬ интересно ;)

Она смеётся.

Update. Обратно идут - он ей - "ты понимаешь, что в нашей индустрии надо быть на голову выше остальных".

Она опять смеётся. ;)

четверг, 8 июня 2017 г.

Offtopic. Отвечаю на комментарий

"Я "из того Гаранта". Но в doom я не играю. Я вообще в игры не играю. Меня работа больше захватывает. Нет вру... в "цивилизацию" немножко играл... но с тех пор как появился UML - играю в основном в него. Это гораздо захватывающе. А игроки в doom у нас конечно же тоже были."

http://18delphi.blogspot.ru/2013/04/uml_21.html?m=1

Offtopic. Зарисовка из жизни.

#байка

Вхожу в подъезд.

Навстречу два пацана "хипстерского" вида.

Ну других сейчас уже почти не бывает.

Один со скейтом, а другой - самокатом и необъятным вейпом и "бородой".

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

Видимо речь о каком-то спорте идёт...

Эх... когда я последний раз "собирал компьютеры".

Кажется, что уже и "никогда"...

Предпочитаю, чтобы каждую работу делали профессионалы...

А ведь было дело... И собирал...

Побрюзжу. TStrings

Если в коде реализации встречается TStrings (не для поддержки "унаследованного кода"), то этот код (по моему мнению) - "дурно пахнет".

TStrings (имхо) - не самая лучшая придумка Borland/Embarcadero.

Offtopic. "О жизни". #3

Не знаю. "Зацепила" что-то "критика". Скажу за себя. Я когда начинал заниматься айкидо - я "видел в этом практическое применение". И пока первые два экзамена сдал - "тоже видел". Мне казалось - "вот оно откровение". Но потом я понял, что "не всё так просто". Попробовав с разными людьми. А потом оказалось - "совсем не просто". Ну и я ещё переосмыслил. Борьба которой я до этого занимался - тоже "в практическом плане" - не очень актуальна. И это всё видится мне теперь как "геометрия для тела" и "алгебра для ума". Опять же - за СЕБЯ ЛИЧНО говорю. Возможно - я что-то не понимаю. Так что я занимаюсь этим во-первых потому, что "это красиво", а во-вторых - потому, что "полезно". Для души и тела. Если кого-то волнует "реальный бой", то альтернативы лому или бите - НЕ СУЩЕСТВУЕТ. А уж пулемёту и подавно. Что касается "танцев". Не стоит так уничижительно. Мне знаю что сложнее - "танцы" или "айкидо". Для меня лично - "танцы" - наверное сложнее.

Ну а красоту и полезность - и в становой тяге можно найти.

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

Ещё я вспоминаю как к нам дзюдоисты приходили заниматься. Они всё пытались делать "на силу". Недолго они отзанимались.

Я сам многое делал "на силу". Тоже опыт борьбы сказывается. Пока партнёр слабее или неопытнее - "на силу" - получается. Иначе - не получается. Иначе - надо мозги включать. Оказывается.

Сейчас стал - "старый и больной". Всё совершенно по-другому видится. Мозги надо включать. Оказывается. А не пытаться "на силу". Откровение! Блин.

Опять же - "за себя лично" всё говорю. Возможно - опять же - многого не понимаю.

Ну и что касается опять же "реального боя". Я когда занимался борьбой - чувствовал себя достаточно уверенно. Ещё некоторая ударная практика была. Но когда меня били "всё те же десантники" в тамбуре поезда. Там двух ударов сапогом ниже пояса хватило, чтобы уверенность пропала раз и навсегда.

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

Что касается ножа (тоже было затронуто) - если достал нож - будь готов действовать до конца. Если не готов - лучше не доставай. Тебя же им и прирежут.

Про себя знаю - не готов.

Ну и "подводя итог". Ещё одна немаловажная вещь - это "готовность убивать" или мягче говоря "настроенность на победу". Бъёшь - бей. Честно и без раздумий. Бросаешь - бросай. Так чтобы у противника рёбра сложились. Достал нож - действуй. Орудуешь ледорубом - дай ему по голове. Ввязываешься в драку - готовься убивать. А не просто "порешать дела".

Кому-то дано, кому-то - нет.

Мне лично - не дано.

А для "реального боя" - это главное. Всё остальное - частности.

Или не ввязывайся.

Почему "условные чеченцы" выигрывают бой? Да потому, что у них мальчик "берёт нож и идёт резать барана" (сам видел). А мы - "думаем".

Вот и всё.

Ну а "критикам" надо ответить на вопрос - "они сами глаза не закрывают?"

Offtopic. "О жизни". #2

#байка

Раньше "бывало"... сходишь в горы... вернёшься в "город".. к "своему программированию"... окинешь взглядом код.. и думаешь - " это разве проблемы ?!"... вот у меня "на том перевале" - ДЕЙСТВИТЕЛЬНО проблемы были... на "третьей верёвке", когда крюк не бился.. и "на четвёртой", когда проушина не делалась... и "на пятой", когда она не сдёргивалась... а "это" - НУ РАЗВЕ ПРОБЛЕМЫ? Поправил "пару строк" и ВСЁ!

Offtopic. "О жизни"

#байка

Ну "а если серьёзно". Я какое-то время занимался айкидо. И как "неофита" - меня это прям сначала "пёрло". Прям "откровение". Больших успехов правда не достиг. Потом бросил. В силу разных причин. И потом масса "отговорок" находилась. То "времени нет". То "здоровья не хватает". Ну и "неудобно" было вернуться. В какой-то момент. Но мне часто снилось, что я прихожу в зал и занимаюсь. Просто "для себя". Без всяких раздумий о "реальном бое". Сейчас - вернулся. Когда "здоровье уже совсем кончилось". Когда уже "НАДО было". Занимаюсь. Такой кайф ощущаю. Чувствую, что ко мне вернулось "что-то важное". Что сложно выразить словами. И опять же - какой-то "коллектив единомышленников". Люди "разные", но "тут" занимаются одним ОБЩИМ делом.
Это как горы. Они мне тоже снятся. Как я иду по ледники. Троплю. Вешаю верёвки. Закрываю глаза, а передо мною - хребты, вершины, ледники, снега. Всё такое "в розовой дымке заката или рассвета". И "люди разные". Но все занимаются ОДНИМ ОБЩИМ делом. И нет "путиных", "Украины", "навальных" и "если ты такой умный, то почему такой бедный". Сублимация. Всё "просто и понятно". Это опять же - сложно словами выразить. Возможно и в горы я тоже ещё вернусь.

P.S. В "программировании" СООБЩЕСТВО ЕДИНОМЫШЛЕННИКОВ встречается почему-то всё реже и реже. Возможно из-за "узкой специализации" и возросшего количества "степеней свободы". Можно "сидеть с человеком в одной комнате и не найти точек соприкосновения". Ну или это я просто такой.

Брюзжу

Мне нравятся "советчики". Типа я "сейчас научу тебя жить".

И ведь не в курсе -- "чему же учить".

"а, скриптовую машину/движок пишем?

так бы сразу и сказали, а то я не понял и шутка оказалась не к месту.

-------
я вообще делал через:
function Compile(const Source:string; var Output:TStrings):Boolean;

Result = true только тогда, когда успешно скомпилилось.
Output - полный всегда, вот там и ловить исключения.

а полный он потому, что там вперемежку идут ещё и Warning типа "declared but never used" и пр."

TStrings... хочу я посмотреть как оно гигабайт скриптов переварит...

Снобизм у программистов - в крови...

Не разобрались в вопросе и давай комментировать.

вторник, 6 июня 2017 г.

Offtopic. Побрюзжу

Ну "а если серьёзно". Я какое-то время занимался айкидо. И как "неофита" - меня это прям сначала "пёрло". Прям "откровение". Больших успехов правда не достиг. Потом бросил. В силу разных причин. И потом масса "отговорок" находилась. То "времени нет". То "здоровья не хватает". Ну и "неудобно" было вернуться. В какой-то момент. Но мне часто снилось, что я прихожу в зал и занимаюсь. Просто "для себя". Без всяких раздумий о "реальном бое". Сейчас - вернулся. Когда "здоровье уже совсем кончилось". Когда уже "НАДО было". Занимаюсь. Такой кайф ощущаю. Чувствую, что ко мне вернулось "что-то важное". Что сложно выразить словами. И опять же - какой-то "коллектив единомышленников". Люди "разные", но "тут" занимаются одним ОБЩИМ делом.
Это как горы. Они мне тоже снятся. Как я иду по ледники. Троплю. Вешаю верёвки. Закрываю глаза, а передо мною - хребты, вершины, ледники, снега. Всё такое "в розовой дымке заката или рассвета". И "люди разные". Но все занимаются ОДНИМ ОБЩИМ делом. И нет "путиных", "Украины", "навальных" и "если ты такой умный, то почему такой бедный". Сублимация. Всё "просто и понятно". Это опять же - сложно словами выразить. Возможно и в горы я тоже ещё вернусь.

P.S. В "программировании" СООБЩЕСТВО ЕДИНОМЫШЛЕННИКОВ встречается почему-то всё реже и реже. Возможно из-за "узкой специализации" и возросшего количества "степеней свободы". Можно "сидеть с человеком в одной комнате и не найти точек соприкосновения".

четверг, 1 июня 2017 г.

А ещё хочется написать

По мотивам:

http://programmingmindstream.blogspot.ru/2017/05/blog-post_31.html?m=1

А ещё хочется написать про то как код на Delphi "плавно" заменяется на код скриптовой машины. Со всякими map/reduce и прочими "функциональными штучками".

И насколько он лаконичнее и производительней.

Ссылка. Unit тесты

https://habrahabr.ru/company/jugru/blog/329372/

Толково. Но я лично для себя нового ничего не открыл.

Offtopic. Тоже про горы. Не моё

http://www.mountain.ru/article/article_display1.php?article_id=4507

Интересно себя со стороны наблюдать. Хотя мы все там и не в самом радужном ракурсе.

Ни о чём #2

Я обычно "обычным людям" стараюсь не рассказывать про работу.

Ну знаете. Из той серии как герой Бодрова. Даже если спрашивают - говорю "работаю писарем", мол занимаюсь обработкой текстов.

Чтобы не смотрели как на "чудака".

Но тут шли мы как-то компанией после тренировки.

Ну и завязался разговор туда-сюда.

Кто-то пару историй "про работу" рассказал

Все поржали.

Ну и я - не выдержал и "рассказал" (то что там написано - http://programmingmindstream.blogspot.ru/2017/05/blog-post_24.html?m=1).

Гробовая тишина...

А потом - "Шура, это ты с нами разговаривал или думал вслух" ;)

В общем. Смеяться после слова "лопата"... ;)

А так хочется "живого человеческого общения", а я кроме как над "сервантами октетов" и поржать не могу. ;)

Шучу. Брюзжу помаленьку...