Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ordinal functions in the other direction #1983

Closed
Siskin-Bot opened this issue Feb 15, 2020 · 1 comment
Closed

Ordinal functions in the other direction #1983

Siskin-Bot opened this issue Feb 15, 2020 · 1 comment

Comments

@Siskin-Bot
Copy link
Collaborator

Submitted by: BrianH

In the ongoing debate about 1-based vs. 0-based and contiguous vs. 0-hole indexing, Meredith McGhan (@mmcghan on StackOverflow) suggested the possibility of having negative ordinal functions to correspond to our existing positive ordinal functions (for the moment let's ignore what "ordinal" means elsewhere and use it in its Rebol jargon meaning here). A -FIRST function would return the value from the first back from the current position of the series, and so on for -SECOND and such.

However, it turns out that -FIRST is difficult to distinguish from FIRST when reading code, so those names really aren't going to work. Instead of thinking of the ordinal functions as going in a positive direction, let's instead think of them as going forward. That would make the ordinals in the other direction going backward, with names like FIRST-BACK, SECOND-BACK, through TENTH-BACK, much easier to distinguish from their forward counterparts.

These functions would refer backwards according to the model that SKIP uses for negative numbers, regardless of how PICK would treat those same numbers. They would be wrappers around PICK, and have the same out-of-bounds behavior as PICK. They could be mezzanine or native - they're tiny and easy to write either way - but we would benefit from having them be native in R3. We would also benefit from having them be ported to R2 and Red, as wrappers around their respective PICK actions, as long as the external behavior is identical across all platforms. This will make portable code much easier to write.

; Logically, assuming an index space without bounds constraining, they mean roughly this:
first-back: func ["Returns the first value back in a series." value] [first skip :value -1]
second-back: func ["Returns the second value back in a series." value] [first skip :value -2]
third-back: func ["Returns the third value back in a series." value] [first skip :value -3]
fourth-back: func ["Returns the fourth value back in a series." value] [first skip :value -4]
fifth-back: func ["Returns the fifth value back in a series." value] [first skip :value -5]
sixth-back: func ["Returns the sixth value back in a series." value] [first skip :value -6]
seventh-back: func ["Returns the seventh value back in a series." value] [first skip :value -7]
eighth-back: func ["Returns the eighth value back in a series." value] [first skip :value -8]
ninth-back: func ["Returns the ninth value back in a series." value] [first skip :value -9]
tenth-back: func ["Returns the tenth value back in a series." value] [first skip :value -10]

; In R2 and Red
first-back: func ["Returns the first value back in a series." value] [pick :value -1]
second-back: func ["Returns the second value back in a series." value] [pick :value -2]
third-back: func ["Returns the third value back in a series." value] [pick :value -3]
fourth-back: func ["Returns the fourth value back in a series." value] [pick :value -4]
fifth-back: func ["Returns the fifth value back in a series." value] [pick :value -5]
sixth-back: func ["Returns the sixth value back in a series." value] [pick :value -6]
seventh-back: func ["Returns the seventh value back in a series." value] [pick :value -7]
eighth-back: func ["Returns the eighth value back in a series." value] [pick :value -8]
ninth-back: func ["Returns the ninth value back in a series." value] [pick :value -9]
tenth-back: func ["Returns the tenth value back in a series." value] [pick :value -10]

Imported from: CureCode [ Version: r3 master Type: Wish Platform: All Category: Native Reproduce: Always Fixed-in:none ]
Imported from: metaeducation#1983

Comments:

Rebolbot commented on Mar 6, 2013:

Submitted by: fork

The overall premise of getting a single word for this functionality...presumably a native!...by "riffing" off of the existing words (as no other words really exist), is interesting.

But I agree with Ladislav that the readability suffers. Too hard to see that minus sign.

My first thought of an improvement was maybe FIRST-BACK, SECOND-BACK, etc. But the danger there is that people would think they were equivalencies for "FIRST BACK" and "SECOND BACK", which they are not. So maybe combine with a word that doesn't have a loaded meaning in DO dialect. FIRST-BEFORE, SECOND-BEFORE, etc?

I do think that "fourth-before foo" is more readable than "first skip s -4"...and it would run faster as a native. It would also take some of the edge off of the indexing debate if the most common cases did not have to use negative numbers at all.


Rebolbot commented on Mar 6, 2013:

Submitted by: rgchris

For going backwards with positive numbers: as 'back pairs with 'next, a similar 'rewind could correspond to 'skip (or just a /back refinement to 'skip):

first rewind s 4
first skip/back s 3

Rebolbot commented on Mar 6, 2013:

Submitted by: BrianH

Good, at least you seem to support the concept, if not the names. The readability argument is important. It is important that the names be short and contain the names of their positive counterparts, but it doesn't have to be this particular convention.

Why "negative"? Because they go to negative offsets. Negative indexes, or for that matter 0 indexes, don't really exist. Once you are talking about zero or negative numbers, you are talking about offsets. The ordinal functions are for grabbing elements from certain numbered positions in a series, but they only go in one direction which (due to psychological and cultural reasons) we think of as being "positive". However, we can have offset series references in Rebol, which means that it is valid to go in the other direction as well. Since the ordinals we have are thought of as being "positive", ordinals which go in the other direction would be "negative" by comparison. Adding these brings balance to the ordinal function concept.

The -FIRST naming convention is useful because it enforces the notion of directionality, taking advantage of the mental connection that we have between the name "first" and the number 1, and then adding a minus to make that mentally correspond to the number -1, since we don't have a single word in English that means "first in the other direction". FIRST-BACK would also serve that purpose by taking advantage of the directionality implied by the word "back", trading length for readability when compared to -FIRST. FIRST-BEFORE is more likely to have the additional connotation of directionality in time (at least to native English speakers), and it's longer too. For instance, we almost named ALSO as AFTER.

The function BACK is really implied-go BACK. The function FIRST is really implied-grab FIRST, which is a different grammatical class. If you wanted to go back some number of times, it would be BACK-ONCE, BACK-TWICE and so on, to have the same grammatical class :)

Chris, we considered SKIP/back before, but processing the path and option added too much overhead when compared to the work that the function is supposed to actually do. SKIP works in offsets, and thus can take negative offsets by definition, so it was decided that combining SKIP and NEGATE would make sense. It ends up being faster in most cases too because the functions aren't referenced through paths and so don't have path decoding overhead.

I don't think that the term "rewind" will have its original meaning for most people for another generation. We have at least a decade and a half of people who are unlikely to have used a tape for audio or video playback in their lifetime, at least in Western cultures. "Rewinding" already seems like a quaint way to refer to that activity.


Rebolbot commented on Mar 6, 2013:

Submitted by: BrianH

If we decide that FIRST-BACK and such is a better naming convention I will change the summary and description of this ticket to use terms like "backwards" instead of "negative".


Rebolbot commented on Mar 20, 2013:

Submitted by: Gregg

Is there a wide need for these, beyond the orthogonality argument? Just asking, since I've never missed them.


Rebolbot commented on Mar 21, 2013:

Submitted by: BrianH

Gregg, this would be part of a greater indexing compromise. Right now there is a lot of disagreement about how indexes less than one should be treated. People who use PICK just in its basic grabbing mode have had a difficult time transitioning to R3, since all of their code has to change (at the moment).

These functions would be able to be defined with external behavior that would be consistent on R2, R3 and Red, so more code could be portable. Code that currently uses PICK with constant indexes could be translated to use these functions instead, and that would let them run regardless of the underlying indexing model, whether it be R2's or whatever indexing model R3 and Red together settle on. It would also make code a bit more clear, both in direct use and as reassigned accessor functions, similar to how the forward/positive ordinals are used now.


Rebolbot commented on Mar 22, 2013:

Submitted by: Ladislav

'...we don't have a single word in English that means "first in the other direction"' - funnily enough, if "first" is defined to mean the same as "starting", it does not depend on the direction, for whatever direction we pick (left to right or right to left), the starting element is the same. If we don't use the same starting element (which looks to be the case of the proposed access functions), we actually have (at least) two different starting elements, i.e. (at least) two different incompatible indices.


Rebolbot commented on Mar 22, 2013:

Submitted by: BrianH

I was going by the natural language definitions of the terms, not the Rebol definitions. Defining the terms of a language within its own context is a great way to get mired in internal inconsistencies and isolate the language from its potential users.

In this case, where we have a word like "index" which within Rebol has a meaning that is under debate, using the Rebol definition that it currently has as a core precept when creating a different meaning for the term seemed counterproductive. It is much better to go to base principles, to understand what the word means in English (or Latin in this case since it's an old word), then seeing how we would adapt that meaning for use in Rebol going forward.

The word "index" comes from a language that didn't at the time have negative numbers or zero as a concept. The original meaning of the term referred to pointing to something - that's why your primary pointing finger is called an "index finger". You can't point to nothing, so there's no zero index, it really doesn't make sense. Pointing behind you could be thought of as negative or backwards indexes, if you stretch the index concept beyond its original meaning. This is why it is so hard to do math with Roman numerals - they just didn't have math in mind when they created their numbering system. That doesn't mean that it's an invalid way to look at things, it is psychologically as valid as the other model, it's just valid for different purposes. Those purposes are the same as those of what we have been calling the "ordinal" functions.

There is definitely a 0 offset though, it means "here", and negative offsets too. Offsets are great for math because that is their whole point (offsetting is basically addition). One-based offsets don't make much sense though, since the math basically requires subtracting one every time.

Both are valid in different circumstances, so we really need to support both in those circumstances.


Rebolbot commented on Mar 22, 2013:

Submitted by: Ladislav

"The original meaning of the term referred to pointing to something" - Sure, this meaning is exactly what the standard definition (coming from outside of Rebol) "Index is an integer value that identifies (points to) an element of an array" expresses.

However, the "You can't point to nothing, so there's no zero index" is logically flawed:

  1. using zero to point to something (which is what using zero index is by the very definition we both agree upon) we obviously have zero pointing to something and no "pointing to nothing" is taking place
  2. using the same "logic" to negative indices I could repeat the same argument "you can't point to (even less than) noth쭧, so there is no negative index", which demonstrates the absurdity. (How logical it can be to explain the proposal to use negative index using an argument that such a beast "doesn't exist"?)

'"There is definitely a 0 offset though, it means "here", and negative offsets too.' - well, the "offset" notion may be considered "more fortunate" then. The funny side of it is that using an "offset" to point to series elements or positions (which is what can be and actually has been done in Rebol for quite some time) we are using said "offset" as an index by the same standard definition we both know.

Your statement: "Offsets are great for math because that is their whole point (offsetting is basically addition). One-based offsets don't make much sense though, since the math basically requires subtracting one every time." is a great way how to capture the essential reasons why

  • using "offsets" for pointing to positions/elements (indexing) is so comfortable (addition, dear Watson)
  • using one-based "offsets" is incomfortable (departure from addition, dear Watson)

These are the circumstances I mind about, so I hope you don't mind me doing so.


Rebolbot commented on Mar 22, 2013:

Submitted by: BrianH

Ladislav: However, the "You can't point to nothing, so there's no zero index" is logically flawed:

You are using the characteristics of a particular number system (contiguous integer number space with 0 and negative numbers) as a precept when referring to a discussion of a different number system (only positive or positive/negative with no 0) based on pointing with fingers. Point to nothing with your finger - that is what that argument meant.

I was talking about the number system that has 0 in it in the other paragraph. That is the one that our current math-oriented integer definition is based on. It is a more advanced number system which requires more education to understand and use, because it has weird concepts like 0 and negative numbers, but math is easier with it so we use it. Mathematicians and some CS types use the term "index" with this number system too, but that is because they aren't considering alternate number systems that aren't math-oriented. In a different number system "index" would mean something different.

People really underestimate how new and weird the concept of 0 is, and people who are familiar with 0 tend to have a lot of trouble understanding number systems that don't have it. If it helps, think of 0 as being as weird in some number systems as the square root of -1 is in non-complex number systems. It doesn't make the concept any less valuable in its context, it just makes it alien outside of its context.

I'm glad you understand what I was saying about offsets though, and you are the type of person I have in mind that they are more suitable for.


Rebolbot commented on Mar 22, 2013:

Submitted by: BrianH

Adjusted the ticket to recommend the *-BACK naming convention, and the example functions to have better specs and doc strings.


Rebolbot commented on Feb 21, 2014:

Submitted by: BrianH

Implemented in rebol/rebol#187


Rebolbot mentioned this issue on Jan 22, 2016:
[Epic] The Great Indexing Compromise


Rebolbot added the Type.wish on Jan 12, 2016


Ladislav commented on Feb 21, 2016:

I think that this issue needs a deeper analysis than what can be seen here.


Rebolbot mentioned this issue on Jan 24, 2018:
Allow Unicode code points as chars


@Oldes
Copy link
Owner

Oldes commented Jul 3, 2022

I don't think it is needed so much. Especially when current pick is compatible with R2 thanks to Oldes/Rebol3@582e43d

@Oldes Oldes closed this as completed Jul 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants