LINUX.ORG.RU

Числа, строки, указатели в ООП языках.

 , , ,


0

2

ООП языки это языки где все объект без исключений! Но как там представляются числа? С Java все понятно, там int не объект, а в ООП языках? Эмулируется существование всех объектов-чисел? Или у объектов-чисел все же особое поведение? Все не пойму что то.

Deleted

ООП языки это языки где все объект без исключений!

Это вопрос или ты у нас Алан Кей?

Но как там представляются числа?

Как объекты со свойствами чисел, ну.

Эмулируется существование всех объектов-чисел?

Все числа заранее не создашь. А вот маленькие можно.

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

Это вопрос

Знак восклицательный же, спрашиваю про ООП языки где все объекты.

Все числа заранее не создашь

Можно притвориться что они есть.

Как объекты со свойствами чисел, ну.

А что именно складывается если мыслить в контексте объектов когда я пишу object:int + object:int?

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

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

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

С точки зрения использования: да.

С точки зрения «что надо реализовать»: да, вот эти все правила. Сядь да напиши свой int без использования существующего (для арифметических операций, для конвертации оставь, а то запаришься вывод делать).

С точки зрения «как реализовано на самом деле в серьезных рантаймах»: открой да почитай.

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

В смысле?) Как я реализую свой int без использования чисел? Можно реализацию int объекта который поддерживает сложение и вывод псевдокодом каким нибудь?

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

Clisp говорит что integer %) Однако понимания мне этого не дало, даже с чтением описания integer. Может на коде пойму!

Можно реализацию int объекта который поддерживает сложение и вывод псевдокодом каким нибудь?

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

Креативнее надо быть. Вот например int со сложением и конвертацией:

class lint:
    def __init__(self, inner=None):
        self._inner = inner
    def inc(self):
        return lint(self)
    def __add__(self, b):
        a = self
        c = lint()
        while a:
            c = c.inc()
            a = a._inner
        while b:
            c = c.inc()
            b = b._inner
        return c
    def int(self):
        a = self
        i = 0
        while a:
            i += 1
        return i

Должно хватить любого indirection.

ноль = NULL
плюсодин(x) = указательна(x)
один = указательна(ноль)
сумма(a, b) = (пока a = значениеот(a) применять плюсодин к b)

Домашнее чтение: реализация объектной модели на замыканиях.

t184256 ★★★★★
()

Обычно они выносятся в отдельные типы, вроде «примитивов». У них есть свойства, методы, вроде, .toString(), но при этом они не передаются по ссылкам, а тупо копируются.

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

Как я реализую свой int без использования чисел?

Ты можешь использовать свойство объектов иметь адрес, и закрыть глаза на то, что адрес - это число. Как-то так на условном голанге:

// если «Предыдущее» отсутствует, то это 0 по построению.
type НатуральноеЧисло {
 *НатуральноеЧисло Предыдущее
}

func ЯвиНоль (*НатуральноеЧисло) {
 return &НатуральноеЧисло{Предыдущее: nil}
}

func НольЛи (n *НатуральноеЧисло) {
 return n.Предыдущее == nil
}

func (n *НатуральноеЧисло) Добавь1 (*НатуральноеЧисло) {
 return &НатуральноеЧисло{Предыдущее: n}
}
И т.д, далее надо определить сравнение и другие операции, как это, наверное, делается в алгебре.

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

Числа несовместимы с ООП. Целые, рациональные, плавающие (при том церые в жизни являются плавающими, а в компьютере, вообще говоря, нет), и в другом направлении - 8-битные положительные, 8-битные все, 16-битные положительные, 16-битные все. Такая «иерархия наследования» невыразима в ООП вообще, или выразима с помощью каких-то невероятно неудобных костылей. Аналогичная фигня с массивами. Поэтому попытка сделать из лиспа ООП без потери функционала была бы невозможна. В CLOS это «обошли» тем, что там есть type-of и class-of. type-of даёт более тонкую классификацию, например, позволяет отличить «число» от «целое число от 0 до 28», а class-of увидит просто «целое число».

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

И вообще есть разница между «типом значения», «типом при проверке типа» и «типом переменной».

Эта разница есть, наверное, во всех языках. Во-первых, в лиспе можно узнать тип любого значения (в нём нет void*).

type-of возвращает тип значения. Тут есть произвол в выборе того, что является типом 27. 27 - это число, целое число, и число от 0 до 28. Обычно возвращается fixnum, т.е. целое число, представленное машинным словом. Но в принципе ничто не мешало бы вернуть integer или «число от 0 до 28», хотя надо читать стандарт, чтобы чётко понять. Во всяком случае, можно помыслить себе стандарт лиспа, где (typeof 27) = (integer 0 28). Но в лиспе type-of возвращает только какой-то один из типов, которым соответствует данное значение, при выборе этого типа возможен произвол. А типов, которым удовлетворяет число 27 - безконечное количество. Именно поэтому type-of возвращает разное в SBCL и CLISP.

Проверка типа (typep 27 (integer 0 28)) заведомо возможна и справа можно поставить любой тип, например и (integer 26 29), fixnum, rational и т.п.

С этим связан subtypep, который вкладывает типы друг в друга.

Тип переменной в лиспе работает через проверку типа, т.е. объявление типа переменной - это не более, чем (unless (typep x some-type) (error ...)) .

В С++ есть частный случай typep - параметр-класс из ООП. Если переменная имеет тип КлассПредок, то в неё можно записать и любой КлассПотомок. Т.е. в ООП многообразие взаимоотношений между типами сильно урезано. Другой вариант в С++ - это void *, который может содержать любой указатель. А также есть квази-типы в stdarg.

Но всё это - меньше, чем система типов в лиспе, которая мощнее, чем ООП.

den73 ★★★★★
()

С Java все понятно, там int не объект

Есть и объект.

Или у объектов-чисел все же особое поведение?

Не обязательно. Понятие объекта - абстрактное, но в некоторых языках оно связано с реализацией, а в некоторых нет. В частности в жабке объект жёстко связан с конкретным аспектом реализации VM, а в CL как тебе уже показали, это абстракция и не связана с тем, как и чем конкретно представлен объект (числом или специальной структурой).

no-such-file ★★★★★
()
Ответ на: комментарий от den73

Числа несовместимы с ООП

Совместимы. Есть абстрактная алгебра и конкретные классы чисел. Лисповый number tower к этому не имеет отношения.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от Deleted

Как я реализую свой int без использования чисел?

Как в древности - на пальцах, т.е. просто складывая что-то в список. Положил три фиговины - это 3, положил пять - это 5. Сложил два списка вместе получилось 8.

no-such-file ★★★★★
()
Ответ на: комментарий от Deleted

В смысле?) Как я реализую свой int без использования чисел? Можно реализацию int объекта который поддерживает сложение и вывод псевдокодом каким нибудь?

man арифметика Пеано

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

Хм, а у меня была такая идея, правда я додумать ее не смог. Спасиба.

Deleted
()

Владимир

Имеется такое понятие - «простые типы данных» /на их основе создаются объекты/.

PS: «Имеются и другие точки зрения».

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

Владимир

Добавочка /об языковых войнах/.

"Суровые годы уходят
В борьбе за красивый язык
За ними другие приходят
Они будут тоже трудны"
anonymous
()

Меня вообще возмущает до глубины души, как язык может называться ОО, когда операторы у него являются чем-то вырожденным. Ведь, например, то же сложение - это по сути функция. А функция - это объект. А у объекта должен быть родитель, какие-то методы, его можно передавать, что-то с ним делать. Почему я не могу сделать что-то типа такого?

let x = apply(array, +, *, /);
let y = +.call(1, 2, 3);
Пока это не будет реализовано, нельзя называть язык объектно ориентированным!11

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

Конечно нельзя, вот в Smalltalk все так.

Deleted
()

Если на практике, то в этих языках вместе со значением каким-то образом носят и его класс (тип). Значения они ведь хранятся в конкретных известных рантайму местах, будь то по ключу в каком-то объекте или на стеке. Там же рядом и ссылка на класс. Или классы заранее предугаданы компилятором и не хранятся, но подразумеваются. Так вот когда ты у инта берешь .tostr(), то это просто метод класса вызывается и в него передается этот инт как self. Копированием или по ссылке - это уже от особенностей рантайма зависит, от его схемы юзания памяти и от того, что он там обещал программисту в плане мутаций - будет ли мутабельный аргумент влиять на место вызова или же только на локальное принятое значение.

Просто в отличие от сложных объектов, представленных в виде (тип значения, ссылка на инстанс), числа можно хранить как (тип значения, само число) и не создавать боксы в динамической памяти на каждый i++. Но не все так делают, потому что можно != обязательно.

тлдр: да, особое поведение, но не такое уж и особое, если снизу смотреть.

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

А еще лет должен быть объектом, и сам факт вызова тоже. Ведь вызов это процесс, а процесс это объект. И само описание лета и вызова - тоже объект. И его описание (класс класса вызова). Это упускают очень многие так называемые ооп-языки программирования. А ведь можно было бы унаследовать такой класс вызова, который переданный метод трансформировал бы в дурку и вызывал сразу ее, незаметно для программиста.

anonymous
()

ООП языки это языки где все объект без исключений!

Пруф или небыло

goingUp ★★★★★
()

Эмулируется существование всех объектов-чисел? Или у объектов-чисел все же особое поведение? Все не пойму что то.

ок, начнём с простого: расскажи, что такое число?

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

А есть какие-то случаи, где автобигинт оправдан?

Просто сложно представить какую-нибудь вебопитономакаку, которой вдруг пригодились бы инты больше 2^52, и она продолжала бы понимать, что делает. На этих порядках возникает достаточно проблем, чтобы оверфлоу и ограниченность битов (и тормоза рантайма) считать известными для программиста. Или я не прав?

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

Можно притвориться что они есть.

Все так.

А что именно складывается если мыслить в контексте объектов когда я пишу object:int + object:int?

В смолтолке первый объект всегда получает сообщение / вызывается его метод. Поэтому `float + int` и `int + float` вызывает разные методы.

loz ★★★★★
()
Ответ на: комментарий от no-such-file

Положил три фиговины - это 3

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

loz ★★★★★
()

Можно упороться и представить инт функцией, которая принимает номер бита (короткое перечисление, не число) и возвращает бул.

enum Bool { false, true }
enum Bit64 { _0, _1, ..., _63 }
type Int64 = Bit64 -> Bool

Тогда, например число 5 - это будет функция, которая принимая _0 и _2 возвращает  true, а на все остальное false.

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

Дык есть же еще и long double! Он там вообще огромный, и 512 регистры на последних процах вроде.

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

Чтобы его положить на место ссылки, придется и ссылку делать огромной, что раздует все значения (и накинь еще alignment). Иначе значения будут разных размеров и их нельзя будет индексировать через [i]. Так что у нас из практического только void * + nan tagging.

И сам лонг дабл не стандартный афаир и не такой уж огромный.

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

и не такой уж огромный.

В консоль 80x25 не вмещается.

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

ты неповериш, на прошлой неделе такое наблюдал - брали 2 айдишника товаров (инты) конвертили в строки, конкатили и делали обратно инт. и то был продакшен код в одной из крупнейших в рашке корпораций...

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

что они получали конкатя два ида? новый ид? а их не смущало, что ид может не уникальным получится, типа если конкатятся: 12 и 3 = 123 1 и 23 = 123

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

Знак восклицательный же

Значит таки Алан Кей. :)

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

Интересно, много ли на ЛОРе людей, могущих рассказать про тот же Смоллток? Нет, не «нагуглил — ответил», это и я могу. А тех, кто на нём реально писал?

P.S. Интересно, всякие Cython и PyPy такое же генерят? Типа перед каждым интом указатель на его тип и всё такое...

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

Интересно, много ли на ЛОРе людей, могущих рассказать про тот же Смоллток?

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

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

Отлично. Но твою конструкцию можно улучшить (в математическом смысле). Для этого достаточно заметить, что Bit64 можно выразить аналогично Int64.

enum Bool { false, true }
enum Bit6 { _0, _1, ..., _5 }

type Int6 = Bit6 -> Bool
type Int64 = Int6 -> Bool
Crocodoom ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.