LINUX.ORG.RU

не знаю как в ракете, но вообще это совершенно разные структуры данных с разными свойствами.

ossa ★★
()

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

ados ★★★★★
()

А если совсем просто, то временем доступа к элементам по индексу. В векторе О(1), в списке О(номер элемента) ~ О(длина)

anonymous
()

Но зачем тогда нужны иммутабельные векторы (vector-immutable)?

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

Вообще мутабельные списки там есть (смотри compatibility/mlist), но они оставлены для совместимости со Scheme.

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

Не знаю о чем ты, но подозреваю что vector — эффективно реализован на C, а list тормозная это куча сцепленных друг за друг приветов из 50х под названием «cons».

crowbar
()

Почитал бы доки

http://docs.racket-lang.org/reference/vectors.html

http://docs.racket-lang.org/reference/pairs.html

Я ничего не знаю о ракете, но судя по этим двум ссылкам, list это обычный linked-list (что-бы добраться до N-го элемента, нужно пройти по всем предыдущим), a vector, это по сути массив в традиционном понимании (fixed length, random access). Если тебе нужен random-access используй vector.

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

Концептуальный вопрос: зачем разработчики racket поддерживают динамическую вариацию языка, если

а) есть lang typed/racket

б)

string-length: contract violation
  expected: string?
  given: 1

Не пытаюсь жирно вбросить, просто видно же, что вся динамичность на самом деле фейк и все проверки просто пересены в рантайм.

Подозреваю, что похоже на пост анонiмуса, надеюсь на понимание с вашей стороны.

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

просто видно же, что вся динамичность на самом деле фейк и все проверки просто пересены в рантайм

Так в этом и суть динамической типизации — проверки в рантайме. Или ты хочешь как в JS — автоматическое приведение типов? Так это называется слабой типизацией.

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

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

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

Низкий порог вхождения назвать плюсом тоже нельзя.

Или вот еще, например, если есть structural typing, то одним махом решается проблема динамических типов и проверок типа x isDuck?[/duck] (потому что можно писать просто def f(allKindsOfDucks: { def quack() }, а дальше все решит система типов. Можно подумать, что это наоборот в пользу динамической типизации, но на самом-то деле нет.

В общем, я про полиморфизм по аргументам, ага.

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

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

Почему же нет? Есть. Типы писать не надо (а с ти их все равно надо писать), драться с тайпчекером и городить костыли для ворк-эроундов не надо, полноценно использовать репл можно. Все ок.

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

Реал к типизации отношения вообще не имеет.

С тайпчекером не дерутся, а опираются на него. Про указание типов я уже сказал - сейчас автоматическое выведение у любого уважающего себя конпелятора. Опиши хоть один случай, когда тайпчекер тебе мешал что-то сделать такое, что бы не было говнокодом. И про воркэраунды тоже расскажи конкретно. Я вот конкретные вещи назвал, а ты что-то общее. Это не ответ.

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

Олсо, любой СТ-язык можно использовать как динамический, просто используя один класс - тот, который в основе иерархии (Object, Any etc), вот. Что символизирует.

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

Реал к типизации отношения вообще не имеет.

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

С тайпчекером не дерутся, а опираются на него.

Да как ты не называй, а результат один - это «опирание на тайпчекер» требует дополнительных трудозатрат и замедляет разработку. Вместо того, чтобы писать код, тебе приходится писать типы.

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

Типы для всех топ-левел определений все равно писать необходимо.

И про воркэраунды тоже расскажи конкретно.

Да посмотри любые вопросы по хачкилю. 90% относятся к «я хочу написать Х, но тайпчекер не дает, что делать?»

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

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

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

Олсо, любой СТ-язык можно использовать как динамический

Это утверждение из разряда «все тьюринг-полные языки эквивалентны». Ну, формально, конечно, да, можно. Но на практике - нельзя.

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

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

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

щто? в любом REPL на этапе каждого R все, что прочитано и где происходят столкновения имен, перебиндивается. Или что ты имел в виду? ЯННП.

Да как ты не называй, а результат один - это «опирание на

тайпчекер» требует дополнительных трудозатрат и замедляет разработку.

Нет, это важное различие, ибо в ЯДТ тебе приходится постоянно шастать по функциям и проверять, что они принимают, либо же именовать функции string-fn-name, number-fn-name и т.д. Т.е. ненадежным образом выполнять работу машины.

Вместо того, чтобы писать код, тебе приходится писать типы.

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

Типы для всех топ-левел определений все равно писать необходимо.

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

Да посмотри любые вопросы по хачкилю. 90% относятся к «я хочу написать Х, но тайпчекер не дает, что делать?»

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

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

Это не пример, а расширенный вариант общей размазни из прошлого поста :)

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

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

В хаскеле есть тайпклассы, ака open-world interfaces, т.е. я так полагаю, самый завалящийся хаскелист сможет написать какой-то архи-базовый тайплкасс, инстансами которого может быть все остальное и... Кстати, а хаскеле же нет RTTI? В общем, раз можно сэмулировать ООП, можно и эту хрень. Но да, кому оно нужно.

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

щто? в любом REPL на этапе каждого R все, что прочитано и где происходят столкновения имен, перебиндивается. Или что ты имел в виду? ЯННП.

Я говорю о том что в статике если ты определим в репле например функцию f: Int -> Int, то ты уже не сможешь ее переопределить на f: String -> String. Нельзя тип поменять.

Нет, это важное различие, ибо в ЯДТ тебе приходится постоянно шастать по функциям и проверять, что они принимают, либо же именовать функции string-fn-name, number-fn-name и т.д.

Не приходится.

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

Лишние трудозатраты - это когда ты тратишь время на то, чтобы придумать, какой тип должен быть у flatten. Баги типизация не отлавливает. Подсказки канпелятора - нинужно. Валидацию и т.п. вещи легко можно делать и в динамике. Это вопрос культуры программирования, не типизации.

Это не пример, а расширенный вариант общей размазни из прошлого поста :)

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

Вот например, когда я первый раз решил написать У-комбинатор на типизированном языке, я понял, что не понимаю, как он на самом деле работает.

Напиши на хачкиле ф-ю twice f = f . f Естественно, должно работать twice twice.

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

Кстати, а хаскеле же нет RTTI?

Да должна быть, иначе бы как high-rank работали?

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

Ай, ты болтун какой-то.

scala> def f(x: Int): Int = x
f: (x: Int)Int

scala> f(1)
res0: Int = 1

scala> def f(x: String): String = x
f: (x: String)String

scala> f("1")
res1: String = 1

Что за twice? Я не понимаю этих ваших точечных нотаций. Это композиция самой с собой, что ли?

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

Ай, ты болтун какой-то.

Ну так нерепл в скале вообще не умеет переопределять ранее определенные ф-и, даже с одним типом. нерепл:

scala> def f(): Int = 1
f: ()Int

scala> def yoba(): Int = f
yoba: ()Int

scala> yoba
res0: Int = 1

scala> def f(): Int = 2
f: ()Int

scala> yoba
res1: Int = 1

scala>
репл:
> (define (f) 1)
> (define (yoba) (f))
> (yoba)
1
> (define (f) 2)
> (yoba)
2
> 

Что за twice?

(define (twice f) (lambda (x) (f (f x))))

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

Ну и что ты показал, разный биндинг?

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

def twice[T](f: T => T) = f compose f

И какой тип у compose(compose)?

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

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

Композиция композиций имеет смысл только в случае, когда типы совпадают (ну они там перемежаются) и тогда тот же тип, что и исходный. А при чем здесь типизация? Кстати, сказал здесь так себе помогает, потому что там эта оопшная мешанина с FunctionN, лучше брать что-то из ML-семейки, где всегда 1 аргумент.

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

Как раз такой репл нужен.

Нахера он такой нужен?

Но не уводи, пожалуйста, разговор во вкусовщину.

При чем тут вкусовщина? Это необходимая штука, без которой репл становится просто бесполезным абсолютно. Какой смысл в репле, если ф-ю переопределить нельзя? Что ты в этом репле делать собрался?

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

Не ну ты конкретно напиши compose(compose) и какой у нее будет тип, я хочу посмотреть.

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

compose(compose)

Тьфу ты. twice(twice), конечно же.

anonymous
()
16 марта 2015 г.
Ответ на: комментарий от crowbar

а list тормозная это куча сцепленных друг за друг приветов из 50х под названием «cons».

Вот странно - почему когда весь «прогрессивный» мир сидит на векторах, в sbcl (в моём случае sbcl 1.1.17) работа с ними слегка медленнее чем с этими консами (хотя видна практически такая же фора в потреблении памяти со стороны векторов)? Это я заметил на тестах с массивами любых объектов.

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