LINUX.ORG.RU

First-class поддержка values в racket

 , ,


0

2

Почему values в racket не first class citizen?

Пруф:

(eq? (values 1 2) (values 1 2))
result arity mismatch;
 expected number of values not received
  expected: 1
  received: 2

Я вижу дохера функций вида xxxx-values и xxxx/values? Почему бы не сделать нормально?

UPD: товарищи из #racket говорят, что до появления в racket паттерн-матчинга было бы сложновато делать такие штуки без values:

(let-values ([(evens odds) (partition even? '(1 2 3 4))]) 
                           (list 'evens: evens 'odds: odds))
★★★★★

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

 (eq? (values 1 2))
. . result arity mismatch;
 expected number of values not received
  expected: 1
  received: 2
  values...:
   1
   2
alienclaster ★★★
()

Почему values в racket не first class citizen?

Почему же? first-class.

anonymous
()

Немного поясню, с точки зрения семантики (values x ...) = (let/ec k (k x ...))

anonymous
()

Почему бы не сделать нормально?

А нормально — это как? Приравнять values к списку или массиву? Так просто не используй values, а используй список или массив.

monk ★★★★★
()

Можно так

(define-syntax-rule (values->list form)
    (call-with-values (lambda () form) list))

> (eq? (values->list (values 1 2)) (values->list (values 1 2)))
#f
> (equal? (values->list (values 1 2)) (values->list (values 1 2)))
#t
monk ★★★★★
()
Ответ на: комментарий от monk

я-то стараюсь не использовать, но некоторые библиотечные функции, или тот же for/fold возвращают values

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

некоторые библиотечные функции, или тот же for/fold возвращают values

Тогда используй values->list. :-)

monk ★★★★★
()
6 ноября 2014 г.
Ответ на: комментарий от monk

нормально не получится

<mithos28> just like you can call a function with multiple arguments, a function can return multiple values
<mithos28> They are a low level detail, mostly used to avoid doing allocation
<ijp> multiple values are calling a continuation with more than one arguments
<ijp> more or less than one

x4DA ★★★★★
() автор топика
Ответ на: нормально не получится от x4DA

just like you can call a function with multiple arguments, a function can return multiple values

И что? К списку аргументов функции можно же получить доступ как к списку. Так чем возвращаемый список значений значений хуже?

Делаем: (values 1 2) == (list 1 2), (values 1) == 1. Семантику *-values оставляем неизменной. То есть (define-values (a b) '(1 2)) будет работать.

Что теряем?

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

К списку аргументов функции можно же получить доступ как к списку.

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

Что теряем?

Теряем возможность для ф-й возвращать несколько аргументов. Все будут возвращать один аргумент,

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

Этот «список» аргументов - на самом деле один аргумент, который список.

(lambda args (length args)) считает свои аргументы или длину одного аргумента? Если одного, то как работает ((lambda args (length args)) 'a 'b 'c) ?

Теряем возможность для ф-й возвращать несколько аргументов.

В Erlang http://www.erlang.org/doc/man/gen_tcp.html#connect-3 возвращает {ok, Socket} или {error, Reason}. Чем это отличается от возврата (values 'ok Socket) | (values 'error Reason)?

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

В Erlang http://www.erlang.org/doc/man/gen_tcp.html#connect-3 возвращает {ok, Socket} или {error, Reason}. Чем это отличается от возврата (values 'ok Socket) | (values 'error Reason)?

Тем, что продолжение (values 1 2) должно принимать два аргумента, а не один. Если оно будет принимать список - это будет один аргумент.

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

Если оно будет принимать список - это будет один аргумент.

Вон в Haskell все функции принимают только один аргумент и никому это не мешает. Но в целом согласен, неоднозначность.

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

А я и не говорил, что отсюда появляется какая-то особая выразительная мощь :)

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

Тем, что продолжение (values 1 2) должно принимать два аргумента, а не один.

Так ведь всё равно (values a b) это не два аргумента (list (values 1 2)) != (list 1 2). Что было бы плохого, если бы values была контекстно зависимой с преобразованием в список если попала в позицию аргумента? Обратное преобразование автоматическим быть не может — согласен, так как (values (list 1 2)) и (values 1 2) равновероятны в контексте (let-values ...). Ну так из списка преобразование тривиально: (apply values l).

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

Так ведь всё равно (values a b) это не два аргумента

Это не два аргумента, это штука, которая сует два аргумента своему продолжению. В случае (list (values 1 2)) продолжение (values a b) принимает один аргумент. Ему пытаются сунуть два - ошибка. Чтобы ошибки не было, надо чтобы сколько аргументов values сует, столько продолжение и принимало.

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