Re[122]: Мнение: объектно-ориентированное программирование —
От: Jack128  
Дата: 18.11.19 06:51
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Jack128, Вы писали:

J>>https://sharplab.io/#v2:EYLgtghgzgLgpgJwDQxNMAfAAgJgIwCwAUFgMwAEu5AwuQN7HlOUUCWAdjOQMoCuY3AA4R2ACiEiAPBxgA+cgBMIMCAEp6jZloBuEBOQRwovADZcAvOQAMAbk1amAMwD2hiAGMAFqN37W5DkVlNQMjUy4AaktWOyIHZiwAdlDjM1itAF97FgDOHn4AQQQEURlyAG0AXSCVdQY4+PJfFPDyS1tsrRc3Lx89ANyakMNUyOj0xqSWtOysogygA=

J>>плюс минус одно и тоже

S>Что-то не работает эта страничка. Ничего кроме мигающих скобок справа не выдаёт

хм, да, что то у них отвалилось.
Хотя если с нуля код ввести, то асм отображается.

using System;

public class C {
    public int SumSpan(Span<int> data) {
        var result = 0;
        foreach(var i in data) result += i;
        return result;
    }
    public int SumArr(int [] data) {
        var result = 0;
        foreach(var i in data) result += i;
        return result;
    }
}


; Core CLR v4.700.19.46205 (coreclr.dll) on x86.

C..ctor()
    L0000: ret

C.SumSpan(System.Span`1<Int32>)
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push edi
    L0004: push esi
    L0005: xor eax, eax
    L0007: lea edx, [ebp+0x8]
    L000a: mov ecx, [edx]
    L000c: mov edx, [edx+0x4]
    L000f: xor esi, esi
    L0011: test edx, edx
    L0013: jle L001f
    L0015: mov edi, [ecx+esi*4]
    L0018: add eax, edi
    L001a: inc esi
    L001b: cmp esi, edx
    L001d: jl L0015
    L001f: pop esi
    L0020: pop edi
    L0021: pop ebp
    L0022: ret 0x8

C.SumArr(Int32[])
    L0000: push ebp
    L0001: mov ebp, esp
    L0003: push edi
    L0004: push esi
    L0005: xor eax, eax
    L0007: xor ecx, ecx
    L0009: mov esi, [edx+0x4]
    L000c: test esi, esi
    L000e: jle L001b
    L0010: mov edi, [edx+ecx*4+0x8]
    L0014: add eax, edi
    L0016: inc ecx
    L0017: cmp esi, ecx
    L0019: jg L0010
    L001b: pop esi
    L001c: pop edi
    L001d: pop ebp
    L001e: ret
Re[118]: Мнение: объектно-ориентированное программирование —
От: samius Япония http://sams-tricks.blogspot.com
Дата: 18.11.19 18:19
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, samius, Вы писали:

S>>Дело не в исполнителе. Даже если мы будем память выделять в бумажной тетрадке, сама постановка задачи подразумевает что мы не должны выдать два байта в одном адресе. Есть задачи, где не важно, где именно выделен байт, им важно лишь содержимое. Для них выделение можно считать чистым. Потому я и настаиваю, что прежде чем заниматься анализом чистоты, нужно договориться, какие именно изменения глобального состояния мы будем считать грязными. И вполне может быть что для одной функции будет определен один набор, для соседней — другой.
S>Обычный подход — такой, что важными считаются эффекты, обнаружимые при помощи некоторого подмножества нашего языка/рантайма.
S>В первом приближении это нетрудно получить: ну, вот есть у нас, допустим, некоторое "публичное" разделяемое состояние. Изменения в нём "видимы" для гражданского кода. Вот они-то и являются побочными эффектами.
S>Если мы хотим математической строгости, то никакого другого состояния у нас и нет.
S>Ну, вот пример мира, оборудованного "консолью", я уже приводил.
S>Можно расширить этот мир до abstract memory, которая представлена в виде mutable hashmap.
S>Тогда одна функция может "положить" в этот мир значение Memory["Hello"]="World!", а другая — соответственно, достать.
S>Даже если мы сделаем мир immutable, а функции будут всего лишь принимать его в аргументах, и возвращать трансформированную версию, мы всё равно сможем отличать чистые функции от грязных.
S>Ну, то есть математически они будут вполне себе чистыми, т.к. возвращаемые значения будут зависеть строго от аргументов; но для практической пользы мы как раз будем называть чистыми только те функции, которые не занимаются трансформацией вот этого мира.
Тут согласен. Подчеркну, отличие в том, смотрим ли мы на память. В случае, когда не смотрим — чистота может выполняться сама. Когда смотрим на память доступными инструментами языка/рантайма — выходит что для чистоты нужно "крутить мир".

S>Всё будет посложнее, если мы начнём приделывать взаимодействие с настоящим миром — банально, функция читающая системное время, даёт нам способ детектировать порядок выполняемых операций без прямой зависимости.

Да, но проблемы нет, если детектируемый порядок детерминирован и мы смотрим на системное время лишь для детектирования порядка. Когда мы начинаем смотреть на время просто так (вне задачи определения детерминированного порядка), мы получаем недетерминированность. И это проблема с точки зрения чистоты.

S>Но опять же, я бы начал с другого конца — все эти термины важны только в той мере, в которой мы их используем. Классический RPC проектировали идеалисты, поэтому в нём была важна похожесть на C API, а не практическая полезность.

S>Поэтому в нём нет никаких различий между unsafe, safe, idempotent методами. А вот REST проектировали люди, которых интересовало построение надёжных систем поверх ненадёжных коммуникаций. Поэтому там есть вот эти варианты.
S>При этом, скажем, понятия детерминизма в REST нету. В его модели из того, что какой-то глагол будет детерминированным, пользу извлечь не удастся.
Интересное замечание. Обычно при коммуникации нет и детерминированных задач, прозрачных для клиента. Даже если нам нужно детерминированным образом прокрутить сессию (по аналогии с миром), это делается намеренно таким образом, что бы клиент не мог сам крутить свою сессию, например, добавлением подписи сервера. Мы и не должны кэшировать или менять порядок того, что подлежит коммуникации. Наоборот, именно через коммуникцию мы получаем сигналы об изменении состояния сервера/протухания клиентских кэшей.

S>Вот и с чистотой — она нам полезна только тогда, когда у нас есть какой-то вычислитель с различными стратегиями исполнения в зависимости от чистоты/нечистоты функции.

S>В зависимости от реализации этого исполнителя нам может быть интересно различать функции "читающие" мир, и функции "пишущие" в мир. А может — неинтересно. Как я понимаю, в Хаскеле нет разницы между такими видами грязи.
Это может быть интересно, но в Хаскеле такую разницу не проводят, т.к. эти разные функции нужно связывать друг с другом в единую цепочку, а потом эту цепочку встраивать в другую цепочку. И потом, когда мы посмотрим на всю трансформацию целиком с высоты main, нам уже нет дела до того, какие там звенья только пишут, а какие лишь читают.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.