LINUX.ORG.RU

Вопрос по чистоте ф-ций

 , ,


0

1

Вот такой кодец, допустим.


Account := Object clone do(
 balance ::= 0
 deposit := method(amount, setBalance(balance + amount))
)

account := Account clone

deposit := method(amount, account, account deposit(amount); account)

deposit(10, account) print
deposit(30, account) print

# :::  Account_0xbb0a18:
# :::   balance          = 10
# :::  Account_0xbb0a18:
# :::   balance          = 40
Функция депозит всегда возвращает одно и то же — экземпляр аккаунта (который подается в качестве аргумента).

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

То есть, с математической точки зрения, пракчески любая ф-ция чиста, и референциально-прозрачна.

Однако, поклонники ФП утверждают, что это не так. В таком случае, у них некая своя трактовка. Вот, собственно, в этом и вопрос. Хотелось бы услышать эту трактовку, в четкой и ясной форме.

Спасибо.

я не понимаю, тебя так быстро банят или ты тупо пароль свой вспомнить не могёшь и тупо регаешь очередного кло(у)на?

anonymous ()
Ответ на: комментарий от anonymous

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

clean_dude ()

она все равно возвращала бы одно и то же

она объект меняет, причем тут возвращает одно и тоже?

anonymous ()
Ответ на: комментарий от anonymous

Чистая функция — это та, которая при одинаковых аргументах всегда возвращает одинаковый выхлоп. Это чистая функция, и срать, что она там меняет. Не она, кстати, меняет, она всего лишь посылает сообщение.

clean_dude ()
Ответ на: комментарий от clean_dude

Чистая функция — это та, которая при одинаковых аргументах всегда возвращает одинаковый выхлоп.

...это та, которая не имеет сайд-эффектов. Ваш кэп!

yoghurt ★★★★★ ()
Ответ на: комментарий от clean_dude

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

anonymous ()

Пишу в удалённом треде.

mix_mix ★★★★★ ()
Ответ на: комментарий от clean_dude

'+' - читая функция. сколько раз бы ей 2 и 2 не передавай, она всегда вернет 4...ну в этой вселенной, как там в твоей - я хз.

anonymous ()
Ответ на: комментарий от yoghurt

И, кроме того, почему тогда иммутабельность связывают напрямую с референциальной прозрачностью? Какая связь?

clean_dude ()
Ответ на: комментарий от unt1tled

Я считаю, что нет. Обоснуй, почему она грязная. Я тебе потом скажу, в чем твое заблуждение.

clean_dude ()
Ответ на: комментарий от anonymous

'+' - читая функция. сколько раз бы ей 2 и 2 не передавай, она всегда вернет 4...ну в этой вселенной, как там в твоей - я хз.

Моя функция, та что в примере, сколько бы я раз ей не передавал 10 и <данный экземпляр баланса> всегда будет возвращать <данный экземпляр баланса>.

clean_dude ()
Ответ на: комментарий от clean_dude

Если не запомнил тогда - видимо не запомнишь и сейчас => нет смысла :)

Debasher ★★★★★ ()

пракчески любая ф-ция чиста

А какая грязна тогда? Можно примерчик, а то я не совсем понел твой вопрос?

anonymous ()

Я придумал задачу для Царя: необходимо написать программу, которая во всех новых тредах будет вытаскивать содержимое [ code ] и скармливать его интерпретатору io на виртуалке, и если тот не выругался - удалять тред и отправлять автора в шадоубан по подсети. Еще можно попробовать нейросеть/баесовые сети обучить, по принципу спамфильтров, но это, я боюсь, Царь не потянет.

nonimous ()
Ответ на: комментарий от clean_dude

ага, только вот + не меняет двойку...ивторую двойку он, кста, тоже не меняет.

anonymous ()

Такой цирк, что даже отвечать не хочется.

anonymous ()

newjesser, прекрати постить фигню. Опозорился еще тогда, когда начал ерунду загонять про БД. Фу!

bookman900 ★★★★★ ()
Ответ на: комментарий от nonimous

Конечно, она либо меняет внутреннее состояние генератора, либо обращается к внешнему миру.

Побуду наркоманом:

import math


seed = str(math.pi).replace('.', '')


def gen(start=0):
    return int(seed[start % len(seed)]), lambda: gen(start + 1)

num, gen2 = gen()
num2, gen3 = gen2()
print(num, num2, gen3()[0])
>>> 3, 1, 4

holuiitipun ()
Ответ на: комментарий от nonimous

Конечно, она либо меняет внутреннее состояние генератора, либо обращается к внешнему миру.

Либо получает текущее значение генератора, и возвращает пару (случайное число, новое значение генератора).

Как, собственно, и есть в Хаскеле

yoghurt ★★★★★ ()
Ответ на: комментарий от yoghurt

Фишка в том, что мы srand(time(0)) сделать не можем без внешнего мира.

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

mix_mix ★★★★★ ()
Последнее исправление: mix_mix (всего исправлений: 1)
Ответ на: комментарий от holuiitipun

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

nonimous ()
Ответ на: комментарий от hateyoufeel

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

nonimous ()
Ответ на: комментарий от nonimous

Могу предложить более универсальное решение. Если движок лора в похожие определил более 70% тредов с его старых забаненых аккаунтов (как здесь например), то сразу банить. Нейросети не нужны, его уже детектит даже лоровский elasticsearch

goingUp ★★★★★ ()
Последнее исправление: goingUp (всего исправлений: 1)

Назвался бы не clean_dude, а dirty_slut. Это более по тебе

anonymous ()
Ответ на: комментарий от mix_mix

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

Формально подойдёт что-то такое:

(defmacro makegen
  [name]
  (let [seed (str (rand-int 10000))]
    `(defn ~name
       ([start#]
        [(int (get ~seed (mod start# (count ~seed))))
         #(~name (inc start#))])
       ([] (~name 0)))))

(makegen gen)

(let [[val1 gen1] (gen)
      [val2 gen2] (gen1)
      [val3 _] (gen2)]
  (println [val1 val2 val3]))

#> [56 52 51]

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

holuiitipun ()
Ответ на: комментарий от nonimous

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

Формально, даже функция, всегда возвращающая единицу, является генератором случайных числе в множестве {1}.

holuiitipun ()
Ответ на: комментарий от holuiitipun

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

Ты чего доказать-то хочешь? Можно сколько угодно переопределять термины, например переопределить «запуск» так, чтобы он включал в себя компиляцию, или рассуждать о случайных значениях в диапазоне от 1 до 1. Этот никак он не отменит факта, что исключительно из чистых функций нельзя получить источник энтропии, а значит и случайную последовательность. Все остальное это игра словами.

nonimous ()
Ответ на: комментарий от nonimous

Ты чего доказать-то хочешь? Можно сколько угодно переопределять термины, например переопределить «запуск» так, чтобы он включал в себя компиляцию, или рассуждать о случайных значениях в диапазоне от 1 до 1. Этот никак он не отменит факта, что исключительно из чистых функций нельзя получить источник энтропии, а значит и случайную последовательность. Все остальное это игра словами.

Ну я же сразу написал, что «Побуду наркоманом», подстать оп-посту.

holuiitipun ()
Ответ на: комментарий от clean_dude

новоесостояние = чистаяфункция(староесостояние), недоумок.

anonymous ()

Однако, поклонники ФП утверждают, что это не так

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

backburner ()
Ответ на: комментарий от unt1tled

Да вообще-то. Если это функция псевдорандомного генератора какого-нибудь, то она обычно принимает состояние генератора и возвращает псевдослучайное значение и новое состояние генератора.

hlebushek ★★ ()
Ответ на: комментарий от backburner

По-твоему практическое программирование это только говняканье на js? Мне просто интересно(на самом деле нет), что же творится в котелках моих коллег по цеху.

grouzen ★★ ()
Ответ на: комментарий от grouzen

По-твоему практическое программирование это только говняканье на js?

интересный вывод.

backburner ()
Ответ на: комментарий от yoghurt

Согласно википедии. Чистая функция, это функция, которая:

1. является детерминированной;

2. не обладает побочными эффектами.

Наличие только одного из свойств недостаточно, для того чтобы функция была чистой.

at ★★ ()
Ответ на: комментарий от grouzen

Это отнюдь не всегда так.

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

И то, это будет работать только для псевдослучайных числе. Ъ-случайное один черт требует внешний (читай IO) источник энтропии.

Sectoid ★★★★★ ()
Последнее исправление: Sectoid (всего исправлений: 1)
Ответ на: комментарий от nonimous

Да, но в этом же Хаслеле новый генератор создается только в IO.

только

Prelude System.Random> :t mkStdGen
mkStdGen :: Int -> StdGen
yoghurt ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.