четверг, 19 октября 2017 г.

first:second:tail

first:second:tail

ARRAY VAR A
VAR first
VAR second
VAR tail

A .Split ( first second tail )

first:second:tail

ARRAY VAR A
VAR first
VAR tail

A .Split ( first tail )

first:second:third:tail

ARRAY VAR A
VAR first
VAR second
VAR third
VAR tail

A .Split ( first second third tail )

ToDo. Изменение положения оператора

Обратные тики-кавычки нужны для инфиксной записи бинарной функции. То есть мы располагаем mod между аргументами.

1 2 + =>
1 :`  + 2

Или:

1 2 + =>
1 `  + 2

operator `
 in ValueLeft
 ^ in Lambda
 ^ in ValueRight
 ValueLeft // - значение слева
 ValueRight DO // - разыменовываем значение справа
Lambda DO // - вызываем "лямбду"/"функтор"
;

Реализация sum на Haskell

sum ( [] ) = 0
sum (x:xs) = x + sum (xs)

Concat на Haskell

Как нить так (это сходу и наверняка не совсем верно):
concat' [] = []
concat' ([]:ys) = concat' ys
concat' ((x:xs):ys) = x : concat' (xs:ys)

Ссылка. Чат про Haskell для новичков

https://gitter.im/ruHaskell/novice

среда, 18 октября 2017 г.

Ссылка. Чат про Haskell

https://gitter.im/ruHaskell/forall

Ссылка. О Haskell по-человечески

https://www.ohaskell.guide/init.html

Вопрос

[ [ 1 2 ] [ 3 4 ] ] как на Haskell преобразовать к [ 1 2 3 4 ] ?

Ну или на каком-нибудь другом функциональном языке?

У меня так:

[ [ 1 2 ] [ 3 4 ] ] .Fold

Но у меня же - "на коленке". Хочется понимать как "у людей" устроено.

А [ 1 2 ] .Join [ 3 4 ] как?

А [ 1 2 ] .Map .ToString как?

А [ 1 2 ] .Filter .IsOdd как?

А 0 [ 1 2 ] .For + /*сумма элементов*/ как?

Надеюсь, что смысл примеров понятен. Хотя они конечно "на коленке".

Если они всё же понятны, то может быть кто-то откликнется и расскажет как подобное на настоящих языках можно сделать?

ToDo. Сериализация

Похоже, что элементы опубликованные в скрипты автоматом сериализуются. Типа как в json.

Надо эту тему "покурить".

ToDo

Опубликовать конструкторы от tryFinally и tryExcept.

И ещё ко всем конструкторам сделать "пару" - CreateWithClass/XXXCreateWithClass.

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

Для финальных классов не делать такую пару.

пятница, 13 октября 2017 г.

Массивы

Range: 0 10 // диапазон от 0 до 10
.Filter .IsOdd // отбираем нечётные
.Join ( // объединение
Range: 20 30 // диапазон от 20 до 30
.Filter . IsEven // отбираем чётные
)
.Join // объединение
 [ 31 32 33 ] // массив из элементов 31 32 33
.Join // объединение
ProduceArray: 100 Random // генерируем массив из 100 случайных элементов
.Join // объединение
ProduceArray: 200 ReadIntFromFile: File // читаем 200 элементов из файла
.Join // объединение
[ 100 1024 ] // массив из элементов 100 1024
.Map ( + 1 ) // прибавлям 1
.Map ( * 3 ) // умножаем на 3
.Map .ToString // преобразуем к строке
.Slice 2 // разбиваем массив на пары
.Slice 3 // разбиваем массив на тройки
.Trunc 10 // обрезаем массив до 10 элементов

Array Var A // объявляем переменную типа массив

>>> A // кладём результат вычислений в A

A .Copy // делаем копию массива

>>> A // кладём результат вычислений в A

A .Join A // объединяем A с A

>>> A // кладём результат вычислений в A

A .Fold // преобразуем массив массивов обратно к плоскому списку
.Map .ToInt // преобразуем строки обратно к числам
.RemoveDuplicates // удаляем дубликаты
.Sort // сортируем массив
.Invert // инвертируем массив
.Slice 2 // разбиваем на пары
.Map ( 0 .Swap .For + ) // суммируем пары
.Sort // сортируем
.For // перебираем массив
.Print // печатаем элемент массива

Все вычисления - "ленивые".

Кроме Copy, RemoveDuplicates и Sort.

понедельник, 9 октября 2017 г.

Тут подумалось

Прям самопроцитирую: "Я к тому, что "аллегория" это скажем так "некоторое преобразование" одного более сложного объекта к другому, более простому. Как хеш-функция.

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

Рекомендую книгу

https://www.ozon.ru/context/detail/id/35009452/
https://m.livelib.ru/work/1002522273/reviews-abstraktnye-tipy-dannyh-v-yazyke-atpaskal-anatolij-dedkov

четверг, 5 октября 2017 г.

Научился делать "настоящие" immutable объекты

Научился делать "настоящие" immutable объекты.

Через перекрытие NewInstance + VirtualAlloc + VirtualProtect.

Перекрываем NewInstance - там аллоцируем память через VirtualAlloc (там есть тонкости с размером страниц и стратегией выделения памяти).

Потом заполняем поля объекта в конструкторе. И "закрываем" доступ на запись через VirtualProtect + Page_ReadOnly - в AfterCreate.

Потом в FreeInstance (или destroy - тут есть тонкости) опять разрешаем доступ.

Получаем гарантировано неизменяемые объекты.

Например для паттерна flyweight.

Или например для случая:

ConstString = interface
 Function S: PChar;
End;

Ничто не мешает сделать так:

Var Cs: ConstString;

Cs := Factory.GetCs('value');
Cs.S^ := 'xxx';

Т.е "кишки" объекта будут испорчены.

А вот virtualProtect + page_readonly - решают эту проблему.

Просто

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

Компонент разрушается, но из списка компонент родителя - не удаляется.

А под отладчиком - вроде всё хорошо.

Только под Delphi Tokyo. Под Berlin и Delphi 7 - всё хорошо.

Уже разные способы ловли испробовал. Вплоть до VirtualProtect...

Меняю способ распределения памяти под компонент - ошибка уходит.

Не помогает...

Завтра тупо начну логировать убитые компоненты с их адресами и адресами родителей. И trhreadId.

Смущает тот факт, что ошибка под Tokyo есть, а под Berlin - её нет. Обязательно напишу, если чего накопаю. Хотя конечно скорее всего это какая-то наша ошибка.

среда, 4 октября 2017 г.

Иногда случаются проезды по памяти при использовании getMem/freeMem

Иногда случаются проезды по памяти при использовании getMem/freeMem.

Как их искать?

VirtualAlloc/VirtualProtect далеко не всегда помогают. В силу их специфики.

Как быть?

Придумал вот что:

Const
 Filler : array [0..1] of integer = (high(integer), high(integer) -1);

SafeGetMem: Pointer
Var allocated: pointer;
 GetMem(result, SizeOf(pointer) + sizeOf(Filler));
 GetMem(allocated, aSize + SizeOf(pointer));

Move(result^, result^, sizeOf(result));
Move(result + SizeOf(result)^, Filler, SizeOf(filler));

Move(allocated^, result^, SizeOf(result));

Result := allocated + SizeOf(result);

А в safeFreeMem - проверяем все инварианты.

ToDo

Сделать newInstance через getMem + offset + high(pointer).

Возможно так можно будет отследить - кто ездит по памяти.

четверг, 28 сентября 2017 г.

Ссылка

http://www.sql.ru/forum/605052-a/kto-chto-dumaet-ob-uml-moda-proshla

Ссылка. HyTech

https://tyvik.ru/blog/48

Ссылка. MySQL

http://www.mysql.ru/docs/man/Counting_rows.html

Интересно послушать

Ну так может кто расскажет чем заменить select count *?

Ещё

Цитата: "uml-модели отдаляют заказчика от понимания реальной сути проблемы, а разработчика от понимания того как это всё устроено на уровне "байтов" (Joel)".

(Неточный перевод с немецкого)

Ещё неплохо сказано

Ещё цитата: "c++ uml-модели не нужны ибо там и так есть сильно развитые средства мета-программирования. Надо лишь уметь грамотно ими пользоваться".

Хорошо так сказано

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

Про immutable

Последнее время очень хочется "сказать компилятору", что объект неизменяемый.

Что-то вроде:

type TPoint = class
 public
  X : Integer;
  Y : Integer;
  costructor Create(aX, aY: Integer);
end; // TPoint

...

Var [Immutable] p : TPoint;

...

p := TPoint.Create(10, 20);
p.X := 30; // - тут компилятор ругается

Ну и естественно методы хочется метить const/noconst.

Я в своих скриптах такое уже почти сделал.

Почти - потому, что компилятор пока не все случаи отлавливает. Но это специфика реализации компилятора скриптов. Слишком уж он гибок. И местами на duckTyping заточен.

Но хотя бы в runTime - ругается. Если в compileTime не распознал.

среда, 27 сентября 2017 г.

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

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

TPixel VAR Pixel
Pixel := 100
Pixel := px: 100
Pixel := inch: 1
Pixel := cm: 3
Pixel := mm: 300
Pixel := twips: 10
Pixel := m: 3
Pixel := n: 4
Pixel := (default): 100

Т.е. можно задавать значения в разных единицах измерения. И они будут преобразовыватся к типу переменной.

Понятно, что это на самом деле конструктор + определение оператора :=.

Ссылка. Gui в "функциональном" стиле

Задумался о программировании GUI в "функциональном" стиле

Как-то так:

RunApplicationWithForms: (
 Form: Main TMainForm (
    Prop: Width 400
    Prop: Height 500
    Event: OnShow ( Message ( 'Show' Name: Sender ) )
    Event: OnExit ( Message ( 'Exit' Name: Sender ) )
   Control: Edit1 TEdit (
   )
   Control: Edit2 TEdit (
     Prop: Left 100
     Prop: Top 200
     Event: OnEnter ( Message ( 'Enter' Name: Sender ) )
     Control: Button1 TButton (
      Event: OnClick ( Message ( 'Click' Name: Sender ) )
     )
   )
  Control: Edit3 TEdit ()
  )
 )
)

Это на самом деле - цепочка лямбд. Все объекты - Immutable.

Надо обмозговать эту тему.

вторник, 26 сентября 2017 г.

Размышления. В каком порядке изучать языки программирования

Первый - C/C++ даже без вопросов. Потом Pascal. Потом ObjectPascal. Потом FORTH. Потом LISP. Потом Prolog. А потом только Python, Java, Ruby и все остальные.

Не про школьников естественно речь.

Для школьников надо начинать с Pascal (Object) и Python.

Мне так кажется.

Ассемблер надо конечно знать. Но "параллельно" всему остальному.

Ну и "в конце-концов" - функциональщина всё равно замаячит на горизонте.

среда, 20 сентября 2017 г.

Наблюдение

Лучше всего почему-то получаются рабочие задачи, которые записал на бумажке. Потом ещё раз записал. Потом опять записал. Потом выкинул бумажки в урну. Потом вспомнил и записал опять. Потом три раза вернулся. Подумал - "да не, бред". Потом опять записал. А потом тебе ставят "другую задачу" и "совсем не про то". А ты вспоминаешь про бумажки. И думаешь "вот оно"! И делаешь и задачу, которую поставили. И то, что так долго "мусолил". Вылежалось...

Ссылка. Тестирование

вторник, 5 сентября 2017 г.

Не перестаю удивляться

Не перестаю удивляться тому, что все операции сравнения могут быть выведены, через < (less), ! (not) и && (и):

bool operator> (A, B) {
 return (B < A);
}

bool operator>= (A, B) {
 return !(A < B);
}

bool operator<= (A, B) {
 return !(B < A);
}

bool operator== (A, B) {
 return ((A <= B) && (B >= A));
}

bool operator!= (A, B) {
 return !(A == B);
}

https://ru.m.wikipedia.org/wiki/Степанов,_Александр_Александрович_(учёный)

вторник, 29 августа 2017 г.

Ссылка. КОМПОЗИЦИЯ ПРОТИВ МЕХАНИЗМА НАСЛЕДОВАНИЯ

https://abraxabra.ru/react.js/bystryy-start/kompozitsiya-protiv-mekhanizma-nasledovaniya/

Процитировав одного знакомого. Надеюсь, что он не будет против:

"
Экзистенциальненько... :-)
Ну, понимание того, что наследование ненужно, что это тупиковый путь, возникло почти сразу после знакомства с ним.
В принципе, это понятно и из общих соображений: при работе с весьма общими вещами трудно (я бы сказал - невозможно в общем случае) выделить *один* признак, по которому проводить классификацию.
В тех случаях, когда это всё-таки делается, получается негибкое решение, неустойчивое к изменениям в предметной области.
От множественного же наследования больше проблем, чем толку.
В общем, агрегация с композицией то, что следует широко использовать. Наследование же может пригодиться лишь изредка, да и то для вещей, которые меняются очень и очень редко.
Ну ещё вопрос производительности. Решение, основанное на наследовании, вероятнее всего окажется производительнее."

https://plus.google.com/u/0/100903871335644471614/posts/USU25WJA2eh?cfem=1

четверг, 24 августа 2017 г.

Off-topic. Наблюдение

Сегодня на совещании при обсуждении "технических моментов" коллеги "припомнили" (по доброму) мне мои ошибки прошлого. Которые я признал. Я стал говорить "возможно я ошибался" или "возможно я пересмотрел свою позицию" или "возможно я тогда вас не так понял".

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

Хороший вариант. Возможно.

Хотя - я лично сомневаюсь.

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

Так - наверное скорее.

Ну и наверное всё же научился "слышать", а не только "слушать".

Возможно.

Но не "умнее". Умнеть в последнее время - что-то не получается.

пятница, 18 августа 2017 г.

ToDo. Сделать Named:

Именованные "анонимные функции":

.filter> Named: n1 ( bla )
.filter> Named: n2 global

Их имя нужно только для отладки и диагностики.

Это можно применять для "именования" post- и pred-условий:

Pre:
 ( x = 1 ?assure 'bla' )
 Named: n1 ( y = 2 ?assure 'bla' )
;

Post:
 ( z = 1 ?assure 'bla' )
 Named: n1 ( i = 2 ?assure 'bla' )
;

Или:

Pre:
 ( x = 1 ?assure 'bla' )
 Условие: n1 ( y1 = 2 ?assure 'bla' )
 Условие: n2 ( y2 = 2 ?assure 'bla' )
 global1
 global2
 Условие: n3 ( y3 = 2 ?assure 'bla' )
 ( x1 = 10 ?assure 'bla' )
;

Или:

До:
 ( x = 1 ?верно 'bla' )
 Условие: n1 ( y1 = 2 ?верно 'bla' )
 Условие: n2 ( y2 = 2 ?верно 'bla' )
 global1
 global2
 Условие: n3 ( y3 = 2 ?верно 'bla' )
 ( x1 = 10 ?верно 'bla' )
;

Или:

Предусловия:
 ( должно: ( x = 1 ) 'bla' )
 Условие: n1 ( должно: ( y1 = 2 ) 'bla' )
 Условие: n2 ( должно: ( y2 = 2 ) 'bla' )
 "Глобальное условие 1"
 "Глобальное условие 2"
 Условие: n3 ( должно: ( y3 = 2 ) 'bla' )
 ( должно: ( x1 = 10 ) 'bla' )
;

До:
 "Очищать тестовую базу" // - это ДО
 "Очищать таблицу стилей"
 "Открыть документ" "Конституция"
;

Параметры:
 "Выливать в RTF"
 "Восстанавливать позицию мыши"
;

Тест:
 "Выделить документ"
 "Заменить" 'а' на 'б'
;

Постусловия:
 "Drag&Drop завершён"
;

После:
  "Закрывать все окна"
 "Очищать тестовую базу" // - это ПОСЛЕ
;

В таком порядке и вызывается:
Предусловия, До, Параметры, Тест, Постусловия, После.

Все секции - опциональны.

Для этого сделать TtfwNamedBeginLike с соответствующим конструктором.

И звать его из Named:, который определить на стороне скриптов.

Не забыть про трансляцию resultType и paramTypes, а также innerDictionary etc.

И прочей инфраструктуры для работы с компилированными словами.

Сделать ещё конструкции:

"В диалоге" "Номер 2 или больше" "Удаление конституции" отвечать Всегда
"В диалоге" "Удаление конституции" отвечать Нет
"В диалоге" "Удаление документа" отвечать Да
"В диалоге" "Поиск/замена" выполнять "Выбор метки"
"Для диалога" "Выход из приложения" "Проверять его отсутствие"
"В диалоге" "Любом другом" отвечать Нет

После слова "В диалоге" предполагаются на самом деле две лямбды:
1. Comparator. Туда передаётся DialogInfo, а возвращается Boolean.
2. Executor.

Comparator и Executor - самом деле могут связываться в цепочки, как в примере про диалог #2.

Предикатов на самом деле просто складываются в список и последовательно выполняются для каждого диалога.

По аналогии с RULES.

Никакого "волшебства".

Это некоторым образом похоже на "предикаты" и "машину вывода" Prolog'а.

Порядок предикатов  - влияет на порядок вычисления предикатов.

Это вместо wait:XXX/waited?

Т.е. делаем "декларативность", а не "императивность".

Мы НЕ ОЖИДАЕМ, диалога, а говорим, что надо делать, если он появился.

Ну и старый "добрый" (на самом деле - бардачный) механизм пока оставляем. Для обратной совместимости.

Возможно для наглядности стоит ещё ввести секцию Диалоги: перед секцией Тест:.

Ещё надо сделать конструкцию:

"Локальные диалоги":
(
Предикат1
Предикат2
Предикат3
...
ПредикатN
)
( код )

предикатов для диалогов действительны ТОЛЬКО для указанного локального кода.

Там две лямбды:
1. Регистрация обработчиков диалогов.
2. Код, приводящие к диалогу.

Ели один из ожидаемых дипломов не показан, то надо поднимать исключение - 'неожиданный диалог'.

Для совместимости со старым кодом.

Собственно с этого и надо начать.

Это больше похоже на текущий механизм.

И это похоже на механизм TF aVar (). Тоже лямбда, обёрнутая в try..finally.

Ещё надо сделать:
PredicatExecutor.
LambdaExecutor.
Etc.

Для удобства работы со словами на стороне Delphi.

В итоге - убрать wait, waited, answer, modal, etc.

А всё свести к modalService и dialogStack.

И написать что-то вроде:

Function modalService.Execute (aForm): TModalResult;

Result := mrCancel;
if dialogStack.Execute(aForm, Result) then
 Exit
else
if TBatchService.IsBatchMode then
 raise EBatchMode.Create('нельзя показывать модальный диалог в пакетном режиме')
else
 Result := aForm.ShowModal;

Слова wait:XXX временно перенести на сторону скриптов, вывести их через wait:Button. А потом их вообще убить.

Потом переделать всё это на Thread. И убрать hackedVCL/needCancelModal.

А потом подобным образом отрефакторить menu.Popup.

Ещё сделать глобальную функцию/примесь для переделки ShowModal и copyPaste "от Димы".

Переделать регистрацию констант mrXXX на RTTI. Ну как TColor и TCursor.

Вообще подумать о регистрации ВСЕХ констант, через RTTI и RegisterIdent.

http://docwiki.embarcadero.com/RADStudio/Seattle/en/Colors_in_the_VCL

четверг, 17 августа 2017 г.

Ссылка. Mock

Инверсия зависимостей

"Правильнее" было бы делать не:

If theForm.ShowModal ... then

А:

If TModalService.Execute(theForm) ... Then

Это и расширяется и тестируется гораздо гибче.

А вместо:

theMenu.Popup

Лучше:

TPopupService.Execute(theMenu)

или вместо:
theSaveDialog.Execute

Пишем:

TSaveDialogService.Execute(theSaveDialog)

А для сервисов можно сделать:

TModalService.Inject(TmyModalService.Instance)
TPopupService.Inject(TmyPopupService.Instance)
TSaveDialogService.Inject(TmySaveDialogService.Instance)

- иньекция реализации.

Подменяем реализацию сервиса. Например для тестирования.

"Клиенты" сервиса про такую "подмену" - даже не узнают.

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

Это всё реализуется либо при генерации из UML либо при помощи Generic'ов.

И например для тестов не показываем диалоги/меню. А зовём mock'и. К примеру.

Подумалось. Про инверсию зависимостей

Вот во времена Turbo Pascal/Turbo Vision у контролов была концепция Validator'ов.
Ввода/вывода.

Очень правильная концепция, как я теперь понимаю.

Жалко что Borland когда сделал Delphi - выпилил эту концепцию.

Тогда бы например не надо было бы "городить" отдельный класс типа TMaskEdit.

А уж теперь при наличии "лямбд".

Приходится прикручивать свой аналог.

Даже VisualLiveBinding - "вроде про то же",  но не "про то".

ToDo

1. Васстановить isSmart на imageList.
2. Сделать imageListService.
3. На сервисах делать обёртки iXXX.
4. Попробовать внедрить imageListService в back, через заплатки.
5. Включить stackFrames для nsTest и insiderTest.
6. Обрабатывать исключения в l3GetFileSize.
7. Стирать diff и sdiff перед сравнением.
8. Assert при поиске diff заменить на  вывод в лог.
9. Расширить Il3ImageList и сделать его интеллектуальную фабрику. На imageListService.
10. Дописывать сервисам суффиксы service и serviceImpl.
11. Сделать сервис для showModal. Реализовать его для тестов.

вторник, 8 августа 2017 г.

ToDo. Сделать outx, varx

Сделать outx, varx:

outx obj: iunknown
varx p: Pointer
varx o: TObject

Перевести на них QueryInterface, FreeMem, FreeAndNil etc. 

ToDo. Сделать для Delphi7 UnicodeString

Сделать для Delphi7 UnicodeString, UnicodeChar.

PUnicodeString, PUnicodeChar.

В l3Core.

А также:

Tl3UnicodeString, Tl3UnicodeChar.

Pl3UnicodeString, Pl3UnicodeChar.

PWinApiChar, PWinApiCharA, PWinApiCharW.

PFileChar, PFileCharA, PFileCharW.

А также - всё что связано с IStream/IStorage. Large,ULarge/PLarge/PULarge/StreamPos/StreamSize/HighStreamPos/HighStreamSize/VoidStreamPos/VoidStreamSize.

В модуль l3XE/Berlin.

Поискать IfDef Berlin.

Сделать стереотип TypeDefProxy. Без вывода в код, но с uc.

Перевести на него Tl3NativeInt/Tl3NativeUInt.

ToDo. Опубликовать в скриптах Pointer

Опубликовать в скриптах Pointer/PMem/PByte/PLong,PInteger,PCardinal,PWord/Pxxx.

PChar/PAnsiChar (?)

Сделать Pointer:Deref/Add/Sub.

Сделать метод .IsPointer.

ToDo. Сделать IsConst/IsAssignable/IsLValue

Сделать IsConst/IsAssignable/IsLValue.

В CONST проверять IsConst.

True/false/nil/null/kwInteger/kwString/tfwInteger/tfwString etc сделать IsConst.

Сделать модификатор CONSTANT.

Для указания того, что слово возвращает КОНСТАНТУ.

BOOLEAN CONSTANT : TRUE true >>> Result ;

На keyword(?)/globalkeyword сделать up - CONSTANT.

Сделать INTEGER CONSTANT IN/ValueAtLeft/ValueAtRight.

Для этого сделать:
 PopValue/SetToDefaultValue.

- чтобы параметры можно было минимизировать со стека и более - НЕ ТРОГАТЬ.

В := и >>> в compile-time проверять IsConst.

ToDo. Сделать ValueAtRight

Сделать ValueAtRight.

ValueAtLeft.

Попробовать на:
Integer:+:

RefAtRight/RefAtLeft.

Попробовать на:
Inc/Dec.

FunctorAtLeft/FunctorAtRight/Functor.

суббота, 5 августа 2017 г.

Off-topic. Ремарк

Ремарк...

Ну и конечно "На западном фронте без перемен"/"Im Westen nichts Neues". Это - шедевр. Кровь, грязь, кишки, боль, поход к французским проституткам через линию фронта, снова кровь, грязь, и боль. Консервы. Воронки. Гранаты. Колючая проволока. Пулемёты. Сапоги с мёртвого товарища.

 Ожидание. Смерти. Других. А потом... "он погиб, когда газеты сообщали о затишье, на западном фронте"...

Ну и конечно "время жить и время умирать" и "возлюби ближнего своего".

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

Ну и "три товарища". Уличные бои между нацистами коммунистами.

ToDo. Вывести всё через Less

Сделать <, >, <=, =>, <>, ==, !== производными от Less.

В compile-time.

пятница, 4 августа 2017 г.

ToDo. Сделать [[ и ]]

Сделать [[ и ]].

Типа - константный массив.

[] - пустой массив. Предопределённый. Неконстантный.

[[]] - пустой массив. Предопределённый. Константный. Видимо равен [nil], [empty].

Также сделать:

!( - анонимная функция, без видимости переменных родителя.
:( - анонимная функция с результатом.
:!( - анонимная функция с результатом и без видимости родителя.

Сделать IsConst на TtfwWord. Проверять возможность присваивания.

И вытащить это в compile-time.

Сделать IsFullyDefined - определять, что слово полностью завершено.

Определить его в true для переменных, констант, ->, и слов без параметров, а также для слов у которых полностью захвачен контекст, Capture, !(, :!(, etc.

ToDo. Регистрировать с модели Compare, Add, Sub, ToPrintable, etc.

Регистрировать с модели Compare, Add, Sub, ToPrintable, etc.

А также:

Mul, Div, Mod, Mul2, Div2, >0, <0, =0, etc.

четверг, 3 августа 2017 г.

Хочется чего-то нового

Может кто-то возьмёт меня на аутсорсинг "на обучение".

Типа JS, React, Angular, Python, Groovy, Velocity и всё такое. QT возможно...

Я JS ни хрена не знаю, Qt - тоже, зато знаю Delphi, DUnit, FORTH, C/C++/stl, Objective-C, asm386, asmPDP-11. Ну и про Python - "читал" и представляю себе как их виртуалка устроена. Та же стековая машина и словари ключ-значение. Ну и про MVC - я тоже "слышал". Ну и "функциональщину" я теперь тоже в общем себе представляю.

Про boost и "лямбды" - я тоже где-то слышал.

Знаю чем "сортировка пузырьком" отличается от qsort. Log2(N) vs N*N.

Также слышал про "сортировку слиянием".

Примерно представляю себе разницу между vector, list, set, map.

Понимаю разницу между mutable и immutable объектами.

Имею представление о шаблонах проектирования - publisher/subscriber, command, lightweight, factory, algorythm/strategy, decorator, proxy, facade.

Имею "смутные представления" о Dependency Inversion и Inversion of control.

Также - даже понял как устроены стековые фреймы в x86 и x64.

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

Знаю, что такое, Pascal, cdecl, register, stdcall.

Примерно понимаю, что такое thread и "защищаемые ресурсы", а также всякие объекты синхронизации - interlockedIncrement/decrement/exchange, criticalSection, mutex, event, waitForSingleObject.

Умею пользоваться CVS/SVN/git. Из gui-клиентов, а не из коммандной строки.

Примерно представляю себе концепцию TDD. Использую её интерпретацию в основной работе.

Основная операционка - Windows. Также работал под xOS.

Про Linux/Unix - "слышал".

Знаком с UML. Использую его и собственную кодогенерацию в основной работе.

Примерно представляю себе как устроен XML/XSLT. А также - json. Но именно - "примерно".

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

На период "обучения" и въезжания в тему - денег особо не надо. А там - как пойдёт.

БД и SQL - я правда ни хрена не знаю. Не занимался такими задачами. Все хранилища были "самопальными".

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

А то "мозги застаиваются" и квалификация уходит.

Хочется чего-то нового попробовать. Но не хочется "учебные задачи" из пальца высасывать.

На hh.ru и прочих - сознательно не пишу. Ибо это не "поиск работы", а скорее поиск какого-то "симбиоза".

Чтобы я чему-то поучился, ну и в ответ - чего-то дал.

А то кругом BigData и прочие HighLoad'ы а я всё собственные "велосипеды", да "на коленке" делаю.

Хочется пообщаться с людьми из "не своего круга".

Чтобы посмотреть - "а чем там ещё люди занимаются".

Глядишь - и для основной работы польза будет.

Ну и из "спортивного интереса".

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

На вопрос - "тебя мало загружают на работе" - отвечу - "меня много загружают. Более чем". Но всё - единообразно. 20 лет уже как.

Все задачи - "примерно одинаковые". И примерно на одном и том же инструментарии.

А хочется - "свежего воздуха". Общения с "другими людьми". Не "более лучшими", именно с "другими".

среда, 2 августа 2017 г.

Off-topic. День ВДВ говорите

Off-topic. Займусь самокопанием

Вот так... учишь учишь человека... думаешь, что он от тебя чему-то научился... И даже типа - "вроде благодарен"... А потом слышишь - "нет - ты хреновый капитан"... И не "порть мол других"... :(

Эх...

Всё правильно...

"Вкладываешься" в людей. А они тебе - "хреновый ты капитан".

Одного только не понимают, что они "БЕСПЛАТНО" - научились на МОИХ ошибках, а не на СВОИХ и "за деньги".

Но всё равно - не очень приятно это слышать от тех, кому считал - "отдал всё что мог".

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

Но мол - "я не перестаю наступать на одни и те же грабли".

Потому что, мол - "людям всё равно надо верить".

И далеко не каждый "ученик" переросший "учителя" - сможет остаться благодарным.

Я сам - грешен. Хотя в последнее время - перерос это. И даже - "самый гадкий лектор моих ученических времён" - кажется мне теперь "средоточием мудрости".

А так и есть. Просто я "тогда" - не смог "воспринять его". Ну или - "не захотел".

Ну или - "гордыня"...

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

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

Off-topic. Извините

Надо читать "настоящие книги".

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

http://ruslit.traumlibrary.net/book/sbornik-nikogda-ne-zabudem/sbornik-nikogda-ne-zabudem.html

https://www.ozon.ru/context/detail/id/5519357/

https://www.ozon.ru/context/detail/id/27428785/

ToDo. ToValue

ToValue для записей сделать методом записи, а не static.

четверг, 27 июля 2017 г.

ToDo. Перевести DoCache на compare. Убрать valueToKey.

Перевести DoCache на compare. Убрать valueToKey.

Лёгкая "альтернатива" редактору Word

http://everesteditor.chat.ru

Если кому интересно - могу выдать свежайшую версию.

ToDo. Capture & Seq:

Попробовать Capture с Seq:

И seq и joinWithLambded - перенести в асиоматику.

ToDo. Перевести sort и compareItems на оператор less

Перевести sort и compareItems на оператор less.

Для обеспечения симметричности сравнения.

ToDo. WordOrBox

Сделать WordOrBox.

Перевести на него do и работу с массивами.

И списки слов.

Поддержать wordBox на capture.

ToDo. JoinWithLambded

JoinWithLabded переделать на zip.

Использовать Capture где надо.

Убрать array:copy.

Сделать array:sort. "Хитрый".

Fold - тоже.

А map - назвать transform. Как "людей".

ToDo. Slice

Сделать, чтобы slice возвращал массив.

Сразу станет легче жить.

Скрестить его с unzip. 

64 бита

Перевёл наш основной проект на 64 бита. Один из основных.

Даже почти всё работает. Не работают очень специфические сторонние вещи типа docX etc.

Даже "велосипедная" сторонняя БД - работает. И наши собственные хранилища.

ToDo. Сделать comparable

Сделать Comparable. И перевести на него. =, !=, <, >

Аналогично - add - +, sub - -, etc.

ToString, GetHash, ToPrintable etc.

Также публиковать в скриптовой машине function of object. Это пожалуй последнее, что осталось неопубликовано.

ToDo. Итераторы

Сделать итераторы в стиле C++.

Перевести на них скрипты.

Сделать их совместимыми с enumerator Delphi xe. http://wiki.freepascal.org/for-in_loop/ru

Перевести потом на них всё остальное.

Сделать кроме for ещё и forIf.

среда, 26 июля 2017 г.

Ни о чём. Хотя и о "многом". Как посмотреть

Вообще - "функциональщина" - она "рулит" - http://programmingmindstream.blogspot.ru/2017/07/blog-post.html?m=1

Вспоминается LISP и FORTH. И "множество скобочек".

А ещё я сделал реализацию "алгебры отношений" для кодогенерации.

Вместо:

Elem a
 Elem b
  Elem c
  End c
  Elem d
  End d
  Elem e
  End e
 End b
End a

Я сделал:

Elem a
Elem b
Elem c
Elem d
Elem e

Relation Children a ( b )
Relation Children b ( c d e )

То есть я сначала вытянула все "понятия" в плоский список (буквы словаря опрелелил), а потом ОТДЕЛЬНО определил "отношения" (слова) - между "понятиями".

И стало возможно определять другие "отношения":

Relation Uses b ( a )
Relation Inherits d ( c )
Relation Implements d ( e )

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

b .Uses .join ( d .Inherits ) .filter ( != c ) .transform .toString .sort .stringCompare .forEach .print

- надеюсь "интуитивно понятно".

Объединяем элементы используемые b с элементами унаследованного от d. Выкидываем те, что равны c. Результат преобразуем к массива строк. Сортируем. Перебирается поэлементно. Каждый элемент - печатаем.

И тут уже вспоминается Prolog и его "атомы" и "предикаты".

LINQ для Delphi. Набор ссылок

LINQ для Delphi. Набор ссылок.

https://m.habrahabr.ru/post/203970/

https://www.devart.com/entitydac/

http://blog.devart.com/using-linq-in-entitydac.html

https://www.osp.ru/pcworld/2009/09/10333910/

http://www.sql.ru/forum/1157390/linq

При "всём богатстве выбора" - я всё же планирую сделать собственную реализацию - http://programmingmindstream.blogspot.ru/2017/07/todo-linq.html?m=1

Сделал стабы для вызова локальных функций под Win64

Аналог "анонимных функций". Но более гибко.

Если интересно - могу подробно расписать.

http://programmingmindstream.blogspot.ru/2016/12/1321.html?m=1

http://programmingmindstream.blogspot.ru/2016/12/1323-win64.html?m=1

ToDo. Сделать "аналог" LINQ

http://programmingmindstream.blogspot.com/2017/07/blog-post.html

Через промежуточную примеси и промежуточный интерфейс.

.transform можно сделать через "кеш интерфейсов". Это надо ещё обдумать.

На Delphi XE - понятно как делать. А вот под Delphi 7 - "задачка". Но решаемая.

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

Функциональщина

Конструкция вида:

Vector1 .filter .IsClass
.join ( Vector2 .transform .Parent .filter .IsUnit )
.join ( Vector3 .filter .IsRecord )
.transform .TypeName
.sort .stringCompare
.forEach .print

Или:

0
[ 1 2 3 4 ]
.join [ 5 6 7 8 9 ]
.revert
.filter ( != 5 )
.transform ( + 2 )
.forEach +
.print

- это - "ураган"!

Начинаю проникаться "функциональщиной".

Это на "моих скриптах. На современных Delphi подобное тоже возможно. Несколько более многословно. Но возможно.

Очень продуктивный подход. Учитывая константность объектов и возможность кеширования результата.

У Штефана Глинке есть конечно, что-то подобное.

Ну и на LINQ (https://ru.m.wikipedia.org/wiki/Language_Integrated_Query) похоже.

Ну и вспоминаются "fluent-interface'ы".

понедельник, 24 июля 2017 г.

Off-topic. Интересная книга

http://knihi.by/knihi/kraina-bielarus-vialikaje-kniastva-litouskaje-druhi-varyjant-vokladki

Интересная книга. Но спорная.

Off-topic. Люди. Они разные

#байка

Я вам расскажу другую историю...

Ездили мы лет 10 назад с приятелем "по лесам и болотам".

И занесло нас в Волоколамск. В монастырь. Иосифо-Волоцкий.

Мы переночевали в лесу. А с утра пошли осматривать достопримечательности.

И тут - храм открыт. Утренняя служба.

Приятель мой - в храм пошёл.

Стоит, крестится. Службу слушает.

Ну а я - мнусь на крыльце.  Курю. Дождь идёт. Курю и мёрзну.

И тут батюшка подходит. Говорит - что мол на крыльце. Заходите мол в храм.

А я говорю - я атеист и коммунист. Нечего мне в храм ходить.

А батюшка мне - так замёрзли мол и дождь. Войдите в храм. Погрейтесь. Я вам фрески интересные покажу.

И показал. И рассказал. Очень интересно было и душевно.

Люди, все, они - разные бывают.

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

Off-topic. Прадед

http://www.computer-museum.ru/connect/peresyp2.htm

"В середине июня поступил тревожный сигнал от начальника Центральной междугородной станции И. М. Тупанова. Он доложил, что в последние дни стала неустойчиво работать телефонная связь с городами Европы. Телефонистки Берлинской телефонной станции, через которую шли многие транзитные связи, чинили препятствия и не соединяли с другими европейскими столицами. Ссылаются на войну, на неисправность телефонных каналов, другие технические неполадки.

Было ясно, что это делается умышленно. [Количество недовольных невозможностью получить разговор с абонентом западноевропейского города все время росло. Особенно возмущались дипломаты и иностранные корреспонденты, аккредитованные в Москве. Начали поступать письменные жалобы. Немедленно была написана докладная в Совет Народных Комиссаров. Впоследствии я узнал, что она была переслана в Наркомат иностранных дел (и безмятежно подшита в папку)]. Положение со связью на Европу так и не изменилось вплоть до начала войны."

И.М. Тупанов - это мой прадед.

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

Off-topic. Про "математику"

А ещё бывает...

Вот человек рассказывает про то "какая математика крутая тут задействована, функциональный анализ, теория множеств, вектора... И всё такое...."

Думаешь - "да круто".

Присмотрелся. "Ну и какая математика".

Ну контейнеры...

 Ну в частности "вектора". Stl (Степанов).

Но не линейная алгебра.

Но! Ни тебе "скалярного произведения, ни векторного, ни нормы в Евклидовом пространстве".

Ни самого "завалящего определителя матрицы".

Не то что "принципа максимума Понтрягина или уравнения в частных производных, ну или пространства Минковского или Гильберта или принципа динамического управления, ну или на худой конец симплекс-метода или задачи Дейсктры или комивояжера".

Ну или "метод хи-квадрат".

Может быть какое-нибудь уравнение какой-нибудь поверхности?

Ничего!

Банально - ничего!

А всё туда же! "Крутая математика".

Ну скажем похожесть документов (к примеру) решается нахождением угла между векторами. Осталось только методику в Евклидовом пространстве определить. Та ещё задачка.

Это к примеру.

А "туда же крутая математика"....

Никакой "математики" на самом деле нет.

Есть "ремесленничество". Аккуратное. Грамотное. Конкретное.

Но! Ремесленничество. Просто умение ГРАМОТНО и АККУРАТНО обращаться с контейнерами stl.

ГРАМОТНОЕ перекладывание из одной stl-коллекции в другую. ХОРОШЕЕ знание stl и C++.

Но! Не более того.

Да! Грамотно и ХОРОШО сделано. Но зачем про математику тогда говорить?

2х2=4 - ну сложно назвать "применением сложной математики".

Я сам - совсем не математик, а ремесленник. Но я никогда не говорю - "ах я использую крутую математику". Даже когда применяю афинные преобразования и перемножение матриц.

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

Ну и "на закуску" - совсем немного про математику:

http://programmingmindstream.blogspot.ru/2014/07/blog-post_7.html?m=1

Я к чему всё это написал?

Не к тому, чтобы кого-то "поругать".

Упаси боже.

Мне бы просто "хоть одним глазком" взглянуть на применение "принципа максимума Понтрягина" - в жизни.

Чтобы "работало". И "руками пощупать".

Off-topic. Ну и жести...

Когда меня спрашивают, а "почему функция XXX возвращает, YYY и имеет побочный эффект ZZZ". А объект OOO имеет ответственность RRR и RRR' (штрих), RRR'' (два штриха).

Я терпеливо начинаю рассказывать - "ну так уж повелось ещё с 17го года".

А "мол на самом деле было ещё и RRR1 и RRR2, но их героически изжил,та на самом деле..."

Тут многие начинают зажимать нос и говорить, что "оно дурно пахнет"...

Не все добираются до RRR3 и RRR4, а тем более до RRR'4.5.

Некоторых тянет "на воздух".

Но всему "есть очевидные причины"...

И далеко не все смогли "распутать этот клубок" и отрефакторить его...

Хотя "на самом деле"....

Так и задумывалось... By design...

Шучу...

Off-topic. И ещё

Что касается "зависти". Каждому своё. Не поймите меня только тут неправильно.

У меня в юности был знакомый. Хороший знакомый. Практически друг.

И тогда я ходил в горы. Что-то "там уже сделал". Для своих лет - вполне.

По своим ощущениям - был "крутым волком со страниц Джека Лондона" (это сарказм конечно).

И мы с этим знакомым сначала сходили куда-то в подмосковье.

На байдарках.

Потом куда-то в горы.

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

Потом мы вместе ещё куда-то несколько раз ходили.

И я был "техническим лидером", а он "так верёвки подавал".

А потом у меня наступила "стабильная работа". Вырваться в горы стало сложно. Некогда и всё такое.

А товарищ мой стал круто ходить. Сделал несколько крутых походов. Закрыл даже то ли КМС, то ли МС. Сходил на несколько семитысячников. А я даже пик Ленина "слил".

И меня несколько "заедало". Мол как же так. Мол - "я его учил ходить на кошках и держать ледоруб".

Юношеский максимализм... Пусть "белая", но зависть...

Но потом он погиб. В горах. По нелепой случайности. Совершенно на пустом месте.

Не хотел бы я "оказаться в его туфлях", как говорят китайцы....

четверг, 13 июля 2017 г.

Off-topic. Ну и ещё. Извините. На технические темы, что-то пока не пишется

Один человек, прочитав некоторые мои на коленке "посты" про программирование написал - "вам бы самолёты строить, а вы строите вагоны". Имея в виду совсем не меня, а сам подход.

А даже на какой-то момент вдохновился. Мол "движемся в правильном направлении".

Но потом получил массу критики и от "своих" и от "чужих".

От "своих" - даже больше.

И вернулся в состояние "скепсиса". Даже если и "самолёты", то с "обратной стреловидностью". И всё равно - "на коленке".

Надо много над этим думать.

Off-topic. Ну и так бывает

А ещё бывает...

Вот ты "пишешь на коленке".

"Изобретаешь велосипед".

Все "смеются". Мол так никто не делает.

Потом проходит время.

Берёшь "крутой фреймворк". От крутого производителя. Начинаешь "прикручивать".

И понимаешь, что "эта полечка мне уже знакома".

И точно! Крутой производитель сделал так же как ты.

Лучше КОНЕЧНО. НО! МЫСЛИ те же.

Ну и радостно как-то становится.

Не зря "велосипед" изобретал....

Тут даже есть пример из жизни - CoreText.

Или даже IUnknown.

А бывает и круче. Сделал "велосипед".

Он не пошёл в серию. Использует его лишь пара сотен "пострадавших".

Потом проходит 10 лет. Приходит твой "коллега" из соседней комнаты (условно) и ты должен прикрутить его фреймворк.

И ты прикручиваешь, а "полечка опять знакома".

И - да! Знакома! На новом витке он сделал то же самое. ЛУЧШЕ конечно.

И ты ему потом даёшь свой старый "велосипед". А он "вдруг" берёт из него "гайку", которой "ему не хватало".

И кайф!

Не зря делал...

Ну и "на закуску" - http://programmingmindstream.blogspot.ru/2017/07/blog-post.html?m=1

Тоже "велосипед".

Off-topic. И так тоже бывает

Расскажу "сложнее". "Абстрактно". Вот работал человек. Прогрессировал. Радовал. Потом прогрессировать. Перестал. Его даже "менее умные" коллеги стали "обгонять". А у него - "отговорка" - мол "денег мало". Хотя зарплата "иногда" и повышалась. Но - не прогрессирует и всё. Хотя "виды были".

А потом "вдруг" - всем зарплату повысили. И ему "заодно". Все счастливы. Он - тем более.

Работает "хорошо". Но прогрессировать - окончательно перестал.

Off-topic. И так бывает

А есть скажем другой человек. "Блуждает в потёмках. Совсем не прогрессирует. Тыкается как "слепой котёнок". Дёргает за всякие ручки. Работает "перебором". И Не раз хотели уволить. "Недалёк". Но усерден.  Пытается решить задачу во что бы то ни стало. И его "вроде побоку". Так "с губы" - мол сделай хоть что-нибудь. А он упорен. Дёргает ручки. Ищет. И вдруг.. бац и прогрессирует... И вдруг.. бац.. И задачу сам решил... И вдруг бац.. И уже СПЕЦИАЛИСТ.

А не ценили. А человек - ВЫРОС.

Off-topic. Брюзжу

Крайне плох тот факт, что "опозиционные настроения" людей перекидываются и "локально" на работу. Повсеместно уже. Мол "кругом бардак", "да и коллеги до меня тут дурно пахнущего понаделали". Ну и что мол "я буду рвать жопу" (извините). Лучше я "поржу" и "покритикую". И в "детали" вдаваться не буду.

"Всё равно бардак".

Сам грешен...

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

Но что-то я устал уже от "критики" и "подтрунивания".

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

Хотя грешен. Да.

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

суббота, 8 июля 2017 г.

Off-topic. Байка

#байка
#полячки
#Эльбрус
#польки
#незамутненнаяюность

Тут неожиданно вспомнилось одна история. Реально произошедшая в жизни.

Про полячек.

Как правильно тут поправили - про полек.

Ходили мы в году 97м на Эльбрус.

Мы сделали полукольцо (или почти кольцо) вокруг Эльбруса и собирались на восхождение.

И надо было нам с приятелем сбегать в посёлок Хурзук за заброской продуктов. Которую мы прежде там оставили.

Туда мы сбегали. Заброску забрали.

А вот обратно - не успели.

И нам маячила перспектива спать под открытым небом.

Но тут на наше счастье мы повстречали группу поляков, которые уже заканчивали свой маршрут и стояли лагерем в посёлке Хурзук на своей завершающей ночёвку.

Они нас приветливо встретили. Накормили горячим ужином. Выделили спальные места под тентом и какие-то фольгированные коврики , правда спальников лишних конечно не было.

Рядом находилась палатка двух "фигуристых" полячек.

Собственно полячки нас ужином и кормили. А молодые люди - самоустранились.

Русский они "типа не знали". Или делали вид.

Не стали с нами общаться.

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

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

Тут я сказал - "Ох держите меня семеро".  Наступила гробовая тишина.

Поляки, сидевшие у костра, тут же "вспомнили русский" и сначала "кинулись меня держать", а потом дружно заржали. ;)

После этого мы уже с ними мило пообщались.

Много общих тем сразу нашли.

Даже звали друг-друга в гости, но адресами не обменялись.

Ночь прошла спокойно ;)

На утро мы распрощались с полячками и поляками.

Опять дружно поржали.

Уже все говорили по-русски.

И каждый двинулся в свою сторону.

P.S. Когда в следующий раз накатит вдохновение (или моча в голову ударит) - я напишу как мы заносили и завозили ту самую заброску в Хурзук и чуть не ушли в Грузию.

Как я катался на "волге" с местными авторитетами. И меня пытались поить местным самогоном. Не отрываясь от руля.

Потом ехал на внешней подвеске на тракторе Беларусь.

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

И получал погранпропуска.

Но это - отдельная история.

четверг, 6 июля 2017 г.

Off-topic. В преддверии 43летия

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

А тут пришли "злые дяди" и говорят, что мне надо "денацифицироваться".

Я, как послушный мальчик, сказал "яволь", взял под козырёк и пошёл "денацифицироваться".

И стал милым и послушным.

И организовал Евросоюз из общества "Германо-Французской стали и угля".

Но!

Только - Я - не ОН.

Я не тот "послушный немецкий мальчик". И это МОИ ДЕДЫ - выиграли эту войну.

Хотя и "были заодно" при разделе Польши в 39м.

ДАЖЕ ЕСЛИ ТАК!

НИКТО НЕ ТЯНУЛ Гитлера воевать против СССР. НАОБОРОТ.

"Дядюшка Джо" делал всё возможное, чтобы войны не было.

И НИКТО НЕ заставлял Гитлера строить крематории и решать "восточный" и "еврейский" вопросы.

Для справки - крематории задымили в декабре 41го года.

Когда Гитлеру показалось, что он "поймал удачу за хвост". И что он более не ответственнен не перед кем.

И всё же - МОИ деды выиграли эту войну.

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

Я беру под козырёк, говорю "есть" и "декоммунизируюсь".

И готов к "примирению" и "прощению".

И читаю "архипелаг гулаг" и "проникаюсь".

Проходит ещё 20 лет и "оказывается", что Гитлер не такая уж сволочь. А Власов, Бандера, Шкуро, Маннергейм, Шухевич - так вообще - приличные люди.

Меня опять макают мордой в дерьмо. Я беру под козырёк и продолжаю "декоммунизироваться".

Говорю лично ЗА СЕБЯ.

А потом люди начинают скакать и орать "москалей на ножи", "кто не скачет тот москаль".

Мне продолжать "декоммунизироваться"?

Нет уж рыбяты... дудки!

Ну сколько можно меня мордой в дерьмо макать?

При том, что это МОИ деды ВЫИГРАЛИ ту страшную войну, а не деды того белобрысого мальчика, который пел "ди фане хох".

Извините.

Наши либералы любят Высоцкого. Мне кажется, что они его не поняли. Даже "всего лишь час дают на артобстрел, всего лишь час пехоте передышка".

Хотя... кто знает....

Так вот я - тот самый белобрысый мальчик.

И меня пришли денацифицивать через 40 лет после той страшной войны.

А я - не хочу. Извините.

Это моя наверное проблема.

И пел я лично, не "до фане хох", а "как здорово, что все мы здесь сегодня собрались".

А меня всё денацифицируют и денацифицируют.

Извините.

Накатило.

День рождения....

FORTH. Ссылка

http://demin.ws/blog/russian/2012/09/27/fcode/

суббота, 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).

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

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

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

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

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

среда, 31 мая 2017 г.

Offtopic. Казбек. Трубка

Почему-то ещё вспомнилось. Мы как-то ходили на Казбек. Со стороны Майли и Колки.

Весной. В тот год когда потом лавина сошла и Бодров погиб. И многие другие.

Погода была жуткая.

Так вот почему-то - БЕСЦЕННЫМ удовольствием показалось, что мои коллеги по восхождения дали мне время спокойно на вершине сесть и выкурить трубку ароматного табака. Несмотря на все превратности погоды.

Незабываемое ощущение.

А потом нас накрыла непогода и на спуске мы не смогли дойти до лагеря и словили холодную сидячую ночёвку. Рыли в снегу ямы и ночевали в них. Укрываясь плащами.

А на следующий день опять была непогода.

И мы рыли снежную пещеру в наддуве.

Но это - другая история.

Возможно это всё - "цена выкуреной трубки". ;)

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

Ни о чём

Продолжим "вечер брюзжания".

Многое хочется в блоге написать про программирование.

Прям вот реально чувствую, что в последнее время - "пересматриваю свои ошибки молодости".

И вроде вижу пути - "как их не делать".

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

Никак только с духом не соберусь.

Себя кстати критиковать - гораздо интереснее, чем других.

Это - реально "вкусно". Разнести себя в пух и прах. Зная всю подноготную.

И поизмываться вволю. Над другими так не поиздеваешься.

Я правда как-то уже пытался.

Воспринималось публикой как - "ну что же вы нам очевидные вещи рассказываете".

Ну попробую найти "изюминку".

#1356. Как я делаю бекапы. СУБД FireBird

14010197737483.png
Беда пришла откуда не ждали…
У клиента завис процесс “Касса”, так что не смог снять процесс через Диспетчер задач.
Рабочее место “Касса” - одновременно сервер всей системы.

Клиент принял решение ресетнуть через кнопку.

В итоге умерла DB. FireBird 2.5

Backup’ы настроены не были, так что последняя версия БД, которая случайно лежала у меня на винте, была минус 8 дней. Подняли по-быстрому с неё. Но суть дальше.

Как делать бекапы для FireBird.
  • Я написал скрипт, который, когда его запускают, делает резервное копирование базы данных с именем БазаДаннах_30_05_2017_23_07_51.fbk

@echo off
set "currentTime=%Time: =0%"
set now=%date:~-4%_%date:~3,2%_%date:~0,2%_%currentTime:~0,2%_%currentTime:~3,2%_%currentTime:~6,2%
  
set user=SYSDBA
set password=masterkey
set database_name=PARKDB.FDB
set backup_name=Backup\PARKDB
set ext=.fbk

set backup_filename=%backup_name%_%now%%ext%
echo %backup_filename%

nbackup -U %user% -P %password% -B 0 %database_name% %backup_filename%

%date:~3,2%

Это означает взять из результата date(Это системная функция Windows), 2 символа, начиная с 3 позиции в строке
Обычный %date%  = 31.05.2017

set "currentTime=%Time: =0%"

Означает брать время, учитывая 0, когда часы меньше 10, то есть без этой команды, мы при выполнении команд:

set now=%date:~-4%_%date:~3,2%_%date:~0,2%_%currentTime:~0,2%_%currentTime:~3,2%_%currentTime:~6,2%

получили бы, что now=2017_05_31_ 0_44_33 ,

а имя файла выглядело бы так: Backup\PARKDB_2017_05_31_ 0_44_33.fbk

Пробел не сильно виден, но он неприемлем в названии файла для nbackup

  • дата и время берутся из текущего времени системы

Это вроде рассказал :).

  • далее, чтобы скрипт выполнялся постоянно,
  • я добавил задачу в планировщик задач виндовс,
  • он каждые 4 часа запускает мой скрипт
  • и создается новая БД,
  • далее я научился создавать задачи в планировщике задач через командную строку

@echo off
set script_name=e:\SoftBuild\Parking\DB\DB_Backup.bat
set task_name=LotParkingBackup
SCHTASKS /Create /SC DAILY /TN %task_name% /TR %script_name% /HRESULT /F /RI 240 /DU 24:00 /v1

Детали параметров можете посмотреть в хелпе. SCHTASKS /Create /?

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

function NextButtonClick(CurPageID: Integer): Boolean;
var
  ServerHost, ServerPort, DBFileName, FBDirPath: string;
  ResultCode, ErrorCode: Integer;
  UDFFrom, UDFTo, ReaderPort: string;
  RegistryTaskFile, DBDirPath, BackupScriptPath, RegistryFileName: string;
begin
  if CurPageID = SettingsPage.ID then
  begin
    ServerHost := SettingsPage.Values[0];
    ServerPort := SettingsPage.Values[1];
    DBFileName := SettingsPage.Values[2];

    if IsComponentSelected(cDB) then
    begin
      DBDirPath := Copy(DBFileName, 1, Pos('PARKDB.FDB', DBFileName) - 1);
      BackupScriptPath := DBDirPath + 'DB_Backup.bat'
      RegistryTaskFile := '@echo off' + #13#10 + 
                          'set script_name=' + BackupScriptPath + #13#10 + 
                          'set task_name=LotParkingBackup' + #13#10 + 
                          'SCHTASKS /Create /SC DAILY /TN %task_name% /TR %script_name% /HRESULT /F /RI 240 /DU 24:00 /v1' + #13#10;
      
      RegistryFileName := DBDirPath + 'DB_RegistryBackup.bat';
      SaveStringToFile(RegistryFileName, RegistryTaskFile, False);
      
      Exec(ExpandConstant(RegistryFileName), '', '', SW_SHOW, ewWaitUntilTerminated, ResultCode);
    end;    
  end;
end;
  • теперь у меня есть скрипт, который делает резервную копию,
  • и скрипт, который регистрирует задачу,
  • далее я научился удалять задачу из планировщика,
  • опять же из командной строки

@echo off
set task_name=LotParkingBackup
SCHTASKS /DELETE /TN %task_name% /F

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

[UninstallRun]
Filename: "{app}\DB\DB_DeleteTask.bat"; WorkingDir: "{app}\DB\"; Flags: runhidden waituntilterminated; Components: DB

В итоге у нас каждые 4 часа есть бекап, и если мы делаем UnInstall, то всё чисто :)