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

Give Issue and Refinement path types #2088

Closed
Siskin-Bot opened this issue Feb 15, 2020 · 0 comments
Closed

Give Issue and Refinement path types #2088

Siskin-Bot opened this issue Feb 15, 2020 · 0 comments

Comments

@Siskin-Bot
Copy link
Collaborator

Submitted by: fork

Happened to trip across:

>> quote #foo/bar
== /bar
>> quote #foo/bar/baz
== /baz

Slashes break issue parsing and you don't get a path:

>> load "#foo/bar"
== [#foo /bar]

This is the same behavior as if you start with a refinement:

>> load "/foo/bar"
== [/foo /bar]

But this seems to break from a useful pattern. Right now any-word! is:

    [word! set-word! get-word! lit-word! refinement! issue!]

The first four have corresponding path variants: path!, set-path!, get-path!, and lit-path! respectively. So these two seem like odd ducks.

If I were to suggest expected behavior, it would be preserving the path elements. If the pattern were to be continued from what exists, there would be two new types: refinement-path! and issue-path!. (And if @foo were decided to be an any-word!, it would be legal to write @foo/bar/baz and get an nickname-path!, or whatever)

Basically the rule would be that all word types need parallel path types. Not having them means you're throwing away a lot of potentially interesting lexical space.

I actually started thinking about this when pondering if a parse-like dialect could use issues to explicitly call out substitutions, reserving words for the dialect itself. So instead of writing:

    parse foo [ while [to #{000000} remove thru #{000000}]]

You could write something like:

    parse foo [ while [to #black remove thru #black] ]

That made me wonder what would happen if you wanted something like:

    parse foo [ while [to #myobject/color remove thru #myobject/color] ]

It made issue-path! seem quite desirable...and the first real motivating case for having it be a word-type I'd seen. (In fact, having all substitutions in parse signaled by an issue! or issue-path! started looking very user-friendly; and a general improvement for dialect authors to do this kind of thing.)

But that would mean changing things, which involves...change.


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

Comments:

Rebolbot commented on Nov 6, 2013:

Submitted by: maxim

I agree, and they should have equivalent get/set types too. For my part I need #value: but Rebol3 doesn't allow it.

The problem is that in the current architecture... the number of types is limited... is it time to review the internal architecture to allow more dataypes?


Rebolbot commented on Nov 6, 2013:

Submitted by: maxim

Though I might also add that I really hate the new issue as word change in R3... it made the issue type even less useful than in was and it keeps breaking up in new situations all the time. Here is another example of how the change was for the worse.


Rebolbot commented on Nov 6, 2013:

Submitted by: abolka

#foo/bar is lexically not a path!, it is two values, one issue! and one refinement!:
>> load "#foo/bar"
== [#foo /bar]

So "#foo/bar" is actually the same as writing "#foo /bar". The same is true for refinements (/foo/bar).

The rest of your ticket is reasoning based on this wrong premise.


Rebolbot commented on Nov 6, 2013:

Submitted by: fork

Note there is no lit-set-word! such as 'foo: so you have to do this...

    quote foo:

And it's sensible to not go down this path, because otherwise you could apply the process forever and wind up with things like lit-lit-lit-word! :-/

To cast it more clearly, we could rethink word! as plain-word!, issue! as issue-word!, and refinement! as refinement-word!. Then we see that being a member of the any-word! group doesn't get you a set, lit, get variant. These are the variants already... of a base abstract "word" concept (that's not actually a member of the set itself).

But what being a member does sensibly get you is a path variant, which is why I made the analogy I did.

So are things like lit-set-word! and lit-set-issue! (or the even more honest "lit-set-issue-word!") intrinsically bad, just because they represent a step over a certain line of simplicity in the cross-products? I'd say one strike against them is that Rebol's goal is the medium of readable text... and they have more than one decorator. It messes with readability.

And at some point there is such a thing as "too many types."

@abolka Ah. Well, the reasoning pushes it from "bug" to wish status. The current behavior has little justification for useful cases, while the proposed behavior has many applications.


Rebolbot commented on Nov 6, 2013:

Submitted by: maxim

funny, I though the / character was valid in Rebol2 issues... it turns out they ain't. for my part, I assumed this was a change brought in with the issue as word.


Rebolbot commented on Nov 6, 2013:

Submitted by: abolka

An alternative to changing #foo/bar and /foo/bar from multiple values to a single path value is to eliminate the lexical peculiarity and make them lexical errors. (Just like "#foo:" is a syntax error in R3 right now.)

(This is not an expression of my personal preference. Just recording an alternative that comes to mind.)


Rebolbot commented on Nov 7, 2013:

Submitted by: Ladislav

Fork wrote: "But this seems to break from a useful pattern."

I do not think so. I am not convinced there is a useful pattern that has been broken. Actually, defining two useless path types would be, in my opinion, a degression from the current state. Datatypes are rather precious resource and all of get-path, set-path and lit-path are really needed. Maybe lit-path less so when we have QUOTE already, but lit-path was introduced to R3 before QUOTE was proposed and it is useful at least for backward compatibility with R2.

"If I were to suggest expected behavior, it would be preserving the path elements."

That is an error as far as I am concerned. There is no preserving of the path elements in fact. For example, the first element of a get-path is not a get-word and the last element of a set-path is not a set-word. Also, the first element of a lit-path is not a lit-word.


Rebolbot commented on Nov 12, 2013:

Submitted by: fork

@Ladislav

"For example, the first element of a get-path is not a get-word and the last element of a set-path is ```

Right. I was not suggesting this be any different, I was just distinguishing between quote #foo/bar returning /bar vs somehow preserving foo and bar. (This perhaps became unclear after the edits I made when @earl pointed out that I was just dealing with a weirdness in the parser.)

The behavior I'm suggesting would be what you'd expect, e.g. type? first #foo/bar would be word!

"defining two useless path types would be, in my opinion, a degression from the current state"

I see this differently. In my opinion, this is the first strong argument for why dialect designers should be excited about issue being a word.

It's precisely because the language doesn't use issue or refinement that much that makes them helpful as escape sequences. The idea of being able to use an issue! or issue-path! to show substitution bits in the parse dialect would be a large change, and I know the tides are against large changes in general... but Rebol should be bolder than it is being, considering the small population of developers and the limited deployment.

(Let me again point out that in Python 3, the standard way of getting the version as "print system.version" no longer works, and you have to say "print (system.version)". They're willing to make bold changes in a new version release, and I've repeatedly asked that Rebol 3 and Red be willing to BE BOLD as the Wikipedians say.)

But anyway, think about what these other path types can do for the language. Quite a lot. I've explained why this isn't an infinite regression to lit-lit-set-word or set-issue or anything of that ilk. I've presented a practical application, but I can imagine many more.


Rebolbot commented on Nov 13, 2013:

Submitted by: Ladislav

"I was just distinguishing between quote #foo/bar returning /bar"

as Andreas pointed out Rebol handles the syntax

    #foo/bar

as being equivalent to

    #foo /bar

That indeed does not look right. Based on the fact that the syntax does not correspond to a valid datatype, I prefer to classify

    #foo/bar

as invalid, i.e., to make a different change than the one you are proposing.


Rebolbot commented on Nov 13, 2013:

Submitted by: Ladislav

Regarding boldness: I think that there are lots of issues with the path datatype syntax and that the syntax should be improved in a significant way.

For example, I do not like how Rebol handles

"abc"/2
[a 1 b 2]/b

and many other cases. See also #2089, #2090 and #2094


Rebolbot commented on Nov 17, 2013:

Submitted by: Ladislav

As Max pointed out, this proposes a major change (2 new datatypes!) to Rebol. Also, it is a problem since the number of possible datatypes is limited. Yet another problem is the fact that the use for new datatypes is not clearly specified (not even known as I see it), so the reason for their introduction is rather problematic.


Rebolbot commented on Nov 17, 2013:

Submitted by: Gregg

There have certainly been times when I wanted a lit-set-word! value, when composing spec blocks, and I favor consistency. The key, I think, is not being dogmatically consistent, for purity's sake, but finding the balance that makes REBOL the most useful. "Useful" is different for everyone, which makes it hard. :)

Being able to reason about behavior is important, and keeping the number of lexical rules small helps. What chars a value can contain, what it has to start with, and what delimits it. Those rules haven't always been clear, and you can bend them with coercion (TO). Sometimes, too, REBOL will parse something like #foo/bar, rather than throw an error.

Regarding boldness, should issue! now be called hashtag!? And I like the idea of an @xxx type as well.

To the question at hand, we can view issue! and refinement! values as parallel to lit-word! values, just with a different escape char. There are problems with this, however. You could spec a path as #a/1, but not a get-path! equivalent. Also, issues and refinements can start with digits, which words can't.

Once you go down this path (no pun intended), new word types also add parallel types for whatever associated path types are supported. As BrianD said: "Basically the rule would be that all word types need parallel path types. Not having them means you're throwing away a lot of potentially interesting lexical space." The question is how much of that interesting space we can use effectively, language design being a careful balance of constraints. "You can't have everything. Where would you put it?" -- Steven Wright

In conclusion, I like the idea of the idea, but I think there are a lot of questions to answer before doing it.


Rebolbot commented on Nov 17, 2013:

Submitted by: Ladislav

"There have certainly been times when I wanted a lit-set-word! value..."

that is why you have got QUOTE now and can write:

quote x:

Rebolbot commented on Nov 18, 2013:

Submitted by: Gregg

Yes, but comes back to why I don't like QUOTE as a name. I can override it, of course, but the first thing that comes to my mind when I see the word "quote" is...quotes. And it is much more common, for me, to use quotes around strings than to prevent evaluation.


Rebolbot commented on Nov 18, 2013:

Submitted by: Ladislav

To invent the name is often more complicated than to invent and implement the functionality. However, the functionality is what I find more important in this case. If you do not want to use QUOTE because of the function name then it is possible that you actually do not need the function so much and if you do not need the function it does not make much sense to artificially increase its usage in your code beyond the cases of necessity. Also, the name is not so unfortunate when realizing that the single quote character is used in similar cases and that the quote word refers to that case.


Rebolbot commented on Nov 18, 2013:

Submitted by: Gregg

Agreed.


Rebolbot mentioned this issue on Jan 12, 2016:
Rebol syntax and space significance


Rebolbot mentioned this issue on Feb 11, 2016:
Make variables holding functions and closures called by PARSE to generate rules


Rebolbot added Type.wish and Status.important on Jan 12, 2016


Hostilefork commented on Aug 5, 2018:

...years later....

Ren-C now handles this by making ISSUE!, REFINEMENT!, or TEXT! ("string!"), TAG!, etc. the first elements of a PATH!.

The evaluation behavior of data types which have inert items in their first slot, is that the path itself is also inert...though REDUCE might act upon them. e.g. #foo/2 => #"o".

I wouldn't call the issue fully "resolved". But it certainly creates more useful artifacts. People will often use WORD!s or PATH!s for filenames. e.g. Carl did so in R3-Alpha...see %file-base.r:

made: [
    make-boot.r          core/b-boot.c
    make-headers.r       include/tmp-funcs.h
    make-host-ext.r      include/host-ext-graphics.h
    make-host-init.r     include/host-init.h
    make-os-ext.r        include/host-lib.h
    make-reb-lib.r       include/reb-lib.h
]

If we're willing to accept that someone might want to use a PATH! and WORD!s for these things in their dialect to avoid repeated typing of %... having it run the TO FILE! automatically, then I think it is not unreasonable to imagine the same interests would find a use for a PATH! with a REFINEMENT at its head... e.g. /usr/local/bin.

Not sure ultimately where this will go, but it's better than the old behavior...and it's better than inventing an ISSUE-PATH!, REFINEMENT-PATH!, etc. data type.


Hostilefork added the Ren.important on Aug 5, 2018


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