В чем разница между `a: [b 1]` и `a: [b: 1]`, выделенными красным?

В чем разница между

a: [b 1]
; and
a: [b: 1]

оба дают одинаковые результаты для

> a/b
1

они отличаются для a/1 хотя. Когда вы что используете? А 2-й это комплект, а что 1-й?


person Wolfram Kriesing    schedule 17.10.2016    source источник


Ответы (2)


2-й набор, а что 1-й?

Вы можете получить ответы, посмотрев на тип:

>> type? first [b 1]
== word!

>> type? first [b: 1]
== set-word!

В чем разница

Когда вы используете выражение a/b, вы пишете что-то, что действует как оператор SELECT, ища «любой тип слова», соответствующий b в блоке, указанном a, а затем возвращает элемент после него в блоке.

Красный следует наследию от Rebol — выбор пути по умолчанию является «нестрогой» формой SELECT, которая использует «нестрогую» форму равенства.

>> (first [a:]) = (first [a]) ;-- default comparison
true

>> select [b 1] (quote b)
== 1

>> select [b: 1] (quote b)
== 1

Чтобы получить строгое поведение при указании различий, вам нужно использовать уточнение /CASE (в смысле «с учетом регистра»):

>> (first [a:]) == (first [a]) ;-- strict comparison
true

>> select/case [b: 1] (quote b)
== none

>> select/case [b: 1] (quote b:)
== 1

Красный, кажется, по крайней мере немного более последователен в этом, чем R3-Alpha, например, соблюдая равенство 1% и 0,01:

>> 1% = 0.01
== true ;-- both R3-Alpha and Red

>> select [0.01 "test"] 1%
== "test" ;-- in Red

>> select [0.01 "test"] 1%
== none ;-- in R3-Alpha

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

Когда вы что используете?

Хороший вопрос. :-/ Что касается обозначений в вашем источнике, вы должны использовать то, что, по вашему мнению, наиболее естественно соответствует тому, что вы хотите выразить. Если вы думаете SET-WORD! уместно, то используйте его, в противном случае используйте СЛОВО!. С точки зрения реализации есть некоторые нюансы, которые выходят за рамки простого ответа (например, местные жители собираются в FUNCTION). Если вы знаете, что в конечном итоге что-то нужно будет преобразовать в задание, может быть полезно использовать SET-WORD.

Оценка пути схематична, на мой взгляд. Он возник как синтаксическое удобство, но затем произвел перекрестный продукт поведения для каждого типа, выбираемого из любого другого типа. И это не говоря уже о различиях в том, как работают функции (что означает x: :append/dup/only/10/a?)

Маленький пример: ПУТЬ! поведение в Rebol использовало эвристику, где, если вы оцениваете путь, он будет действовать как ВЫБОР, если компонент пути является целым числом:

>> numbers: [3 2 1]

>> pick numbers 3
== 1 ;-- because the 3rd element is a 1

>> select numbers 3
== 2 ;-- because 2 comes after finding a 3

>> numbers/3
== 1 ;-- acts like PICK because (...)/3 uses an INTEGER!

... но, как и выше, он будет действовать как SELECT (нестрогий), если выбираемая вещь является СЛОВОМ!:

>> words: [a b c]

>> select words 'a
== b ;-- because b is the thing after a in the block

>> pick words 'a
;-- In Rebol this is an error, Red gives NONE at the moment

>> words/a
== b ;-- acts like SELECT because (...)/a uses a WORD!

Таким образом, разница между SELECT и PICK объясняет ту разницу, которую вы видите.

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

person HostileFork says dont trust SE    schedule 18.10.2016
comment
спасибо большое, очень подробный ответ! Я многому научился (еще учусь :)) - person Wolfram Kriesing; 19.10.2016

А 2-й это комплект, а что 1-й?

Кажется, что вы смотрите на [b 1] и [b: 1] как на код, но на самом деле это просто данные. Точнее, это списки из двух элементов: значения word! или set-word!, за которым следует значение integer!.

a/b — это синтаксический сахар для select a 'b, который извлекает значение, следующее за словом 'b (используя внутренний вызов find). Для удобства поиск 'b также соответствует другим типам слов:

red>> find [:b] 'b
== [:b]
red>> find [/b] 'b
== [/b]
red>> find ['b] 'b
== ['b]
red>> find [b] 'b
== [b]

В качестве побочного примечания помните, что освещенное слово будет оцениваться как слово, которое иногда называют правилом «разложения слов»:

red>> 'b
== b

/case уточнение для find и select применит более строгое соответствие, гарантируя, что типы также будут одинаковыми. Хотя вы, очевидно, не можете использовать его с обозначением пути, вместо этого вам нужно заменить путь вызовом select/case.

Итак, оба дают одинаковый результат для a/b, потому что оба вернут значение, следующее за словом b (независимо от его «подтипа слова»):

red>> [b 1] = [b: 1]        ;-- loose comparison, used by `find` and `select`.
== true
red>> [b 1] == [b: 1]       ;-- strict comparison, used by `find/case` and `select/case`.
== false

хотя они отличаются для a/1.

Целочисленные значения имеют определенную семантику в путях. Они действуют как сахар для pick, поэтому a/1 эквивалентно pick a 1. Вы также можете заставить это поведение другими словами, относящимися к целым числам в путях, сделать их get-word! значениями:

red>> c: 1
== 1
red>> a: [b 123]
== [b 1]
red>> a/:c
== b
red>> a: [b: 123]
== [b: 123]
red>> a/:c
== b:
red>> c: 2
== 2
red>> a/:c
== 123

Подробнее о путях читайте в руководстве Rebol Core: http://www.rebol.com/docs/core23/rebolcore-16.html#section-2.10

Когда вы что используете?

Для использования a/b против a/1 это зависит от того, хотите ли вы достичь операции select или pick.

Для [b 1] против [b: 1] это зависит от последующего использования блока. Например, если вы строите блок для использования в качестве спецификации объекта или карты, то форма set-word подходит лучше:

red>> a: [b:]
== [b:]
red>> append a 123
== [b: 123]
red>> c: object a
== make object! [
    b: 123
]

Кроме того, вы должны использовать форму set-word каждый раз, когда вы подразумеваете отношение «ключ/значение», это делает ваше намерение более понятным для вас и других читателей.

person DocKimbel    schedule 19.10.2016
comment
you should use the set-word form each time you imply a "key/value" relationship для меня это был ага-момент, спасибо за подробности - person Wolfram Kriesing; 20.10.2016
comment
@WolframKriesing Спасибо за отзыв, я уделю больше внимания этому аспекту в документации Red. - person DocKimbel; 20.10.2016