LINUX.ORG.RU

Может ли ФП работать с непримитивными типами данных?

 


0

1

Функция типа вот этой считается чистой:


pure := method(x, x + x)

pure(1)  # --> 2
pure(1)  # --> 2

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

Number foo := "bar"

pure(1) foo  # --> bar (тут и далее мы отсылаем сообщение объекту 2, чтобы проверить его состояние)
Number foo = "baz"  
pure(1) foo  # --> baz

Поскольку, у нас любые данные типа Number имеют стейт, мы уже не можем утверждать, что наша pure возвращает всегда одно и то же. Понятное дело, что это будет происходить при любых непримитивных данных, не только с числами. Из этого должно следовать, что в ФП должны быть запрещены любые непримитивные данные. Так ли это?



Последнее исправление: theKingOfJava (всего исправлений: 2)

pure(1) foo

У тебя функция применяется к единице, и результат конкатенируется с foo?

А, понял, метод вызываешь.

В чистом ФП у тебя не будет возможности изменить тип на ходу.

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

Нет. pure(1) возвращает число 1, которое имеет состояние. foo — это просто для проверки того, что состояние числа 1 изменилось.

theKingOfJava
() автор топика
Ответ на: комментарий от buddhist

Спасибо, ясно. Грубо говоря, мы можем иметь непримитивные типы, но без состояния. Это, тащемта, почти то же самое, что примитивные типы, в целом, все правильно я предположил:).

theKingOfJava
() автор топика

Прими уже цианид, ничтожество. Ничего другого тебе не поможет.

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

pure(1) возвращает число 1, которое имеет состояние

Лови наркомана!

hateyoufeel ★★★★★
()

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

Нет. Стейт может иметь вычисление, а не данные и тем более не тип.

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

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

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

Стейт может иметь вычисление, а не данные

Я под стейтом тут подразумевал буквально — состояние. А под данными — объект. То есть, объект(число 1) в данном примере имеет сотояние (изменяемое во времени).

определения терминов

Да, я тут использую неформальные определения. Важно не определение, а важно, чтобы было ясно, что имеется в виду. Так вот, неизменяемые объекты, можно, в некотором смысле, рассматривать как примитивные типы данных (как они понимаются в обычных языках). Например строки, в большинстве языков, являются неизменяемыми объектами — соответственно — примитивными типами данных. То есть, иммутабельные данные можно рассматривать как аналог примитивных данных в других ЯП, как то так. Во всяком случае, семантическая аналогия очевидна.

theKingOfJava
() автор топика

float - ничего себе примитив...

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

А что, из примера не видно?

Нет. Он на каком-то странном языке, которого я не знаю.

Св-во foo меняется. В данном случае bar baz.

У числа нет свойства foo. Если у объекта есть свойство foo - это уже не число.

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

Если у объекта есть свойство foo - это уже не число.

В нормальных ООП ЯП все есть объект.

Это ты типа возразил? Впрочем, ты же наверняка анонiмус, что тебе объяснять...

tailgunner ★★★★★
()

У тебя каша в голове, бро, нет понимания даже элементарных вещей, не позорься уж.

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

мы можем иметь непримитивные типы, но без состояния. Это, тащемта, почти то же самое, что примитивные типы,

тащемта, это ортогональные вещи. otherwise, define «примитивные»

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

В обычных языках примитивными являются типы, которые вычисляются сами в себя (self-evaluated) и неизменяемые. Обычно, к таковым относят строки, числа, були, и тд. Их можно рассматривать как неизменяемые объекты, разница в том, что они захардкорены на уровне исполнителя.

theKingOfJava
() автор топика

Вопрос всем: как называется патология, при которой эффект Даннинга-Крюгера доведён до абсолюта?

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

А дело тут не в отсылке сообщений, а в том, что чистая функция при каждом вызове возвращает объект с разным состоянием.

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

В контексте этой функции нам это не важно, мы получили ссылку на объект и вернули ссылку на объект, остальное - суета.

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

мы получили ссылку на объект и вернули ссылку на объект, остальное - суета.

В таком случае вот такой код:


pure := method(x, x + x)

one := 1
pure(one)  # --> 2
one = 2
pure(one)  # --> 4

тоже ссылочно-прозрачен?

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

Тогда какое вообще отношение имеет иммутабельность к ссылочной прозрачности?

Никакого, а где в примере мутабельность?

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

Какое же редкостное говно у тебя в голове.

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

то есть, ты хочешь сказать, что ссылочная прозрачность исчезает когда ф-ция содержит в своем теле присваивание? Когда присваивание происходит в ходе выполнения тела ф-ции?

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

Написали вы абсолютно не понятно, т.к. под примитивными типами могут иметь ввиду разные вещи такие как базовые типы поддерживаемые на уровне компилятора, на основе каких программист может делать свои, или некоторые могут иметь ввиду скалярные типы или как в Haskell - unboxed unlifted (распакованые и без bottom).

У тебя если я правильно понял «непримитивные типы» это такие типы данных у которых для одного экземпляра данных разные времена «значения» могут отличаться. Т.е. \exists t1,t2 : a_t1 ~== a_t2, a_t1 /= a_t2, где ~== - pointer equality. Ок, пусть так. Такие штуки вполне выразимы в FP и ООП, но раз мы говорим про чистые функции, то видимо мы говорим о языке с контролем за эффектами (иначе о какой чистоте речь). И тут чтобы понять, что ты понаписал надо бы расписать типы (если мы в динамике, то ни о какой чистоте не может быть и речи). Итак, у нас есть f x = x + x, в ней x имеет тип, говорящий что у него есть словарь с операцией '+', обычно у такой операции тип 'а -> а -> а', соотв функция чистая и в языках с контролем эффектов ты просто не сможешь написать такую реализацию, которая будет использовать 'состояние'. Если очень хочется то ты напишешь другую функцию в типе которой будет отражен эффект. Очевидно, что эта функция не будет чистой.

Итого: а. используйте классическую терминологию или поясняй, б. в целом в ФП этот вопрос не имеет смысла и все выразиться как ты написал в. Языках с контролем эффектов (неважно фп или императивных) данная функция не будет чистой или в неё нельзя будет передать объекты для которых она не будет чистой.

//писалось с телефона с больной головой, так что могут быть ошибки и очепятки

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

Вполне может:

sendMessage :: Receiver -> Message -> IO Response
anonymous
()
Ответ на: комментарий от holuiitipun

Никакого

Или вообще никакого? Откуда тогда все эти басни, что фп обеспечивает ссылочную прозрачность?

theKingOfJava
() автор топика
Ответ на: комментарий от qnikst

В динамике может быть чистота. Доказательство довольно тривиально: берем валидную программу на хаскеле, стираем типы, получаем динамически-типизированную чистую программу, qed.

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

По-честному нужно еще заинлайнить все словари и запретить полиморфную рекурсию, но это мелочи.

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

Да я пытаюсь угадать твои мысли, я тоже считаю, что нет. Ты же никакой конкретики не говоришь. Скажи прямо, как иммутабельность связана со ссылочной прозрачностью. Приведи пример.

theKingOfJava
() автор топика
Ответ на: комментарий от qnikst

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

qnikst ★★★★★
()

Функция типа вот этой считается чистой:

pure := method(x, x + x)

pure := method(x, x + x)
:=

Присваивание не может быть чистым, учи дальше.

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

идентификатор pure - это ссылка на ф-цию. Никакого отношения к самой функции и ее чистоте/нечистоте это не имеет. К тому же, := — это сахар для newSlot, это связывание а не присваивание, строго говоря. Связывание есть и в ФП-языках.

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

И каким образом связывание обеспечивает чистоту? Вот я возьму метод, свяжу его с pure1 и pure2. С помощью pure1 изменю метод по ссылке. Теперь и pure2 будет ссылаться на измененный метод.

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

Вот я возьму метод, свяжу его с pure1 и pure2. С помощью pure1 изменю метод по ссылке. Теперь и pure2 будет ссылаться на измененный метод.

ты че там куришь?


pure1 := method(x, x + x)
pure2 := getSlot("pure1")
pure1 := method(x, x - x)

pure1(1)  println
pure2(1)  println

# ::: 0
# ::: 2

theKingOfJava
() автор топика

Я тебе уже приводил ссылку на блогпост, где всё достаточно годно разжевано на примере примитивных операций в GHC. Просмотрел? Или ниасилил?

Macil ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.