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

APPLY discussion #1

Open
hiiamboris opened this issue Feb 25, 2022 · 4 comments
Open

APPLY discussion #1

hiiamboris opened this issue Feb 25, 2022 · 4 comments

Comments

@hiiamboris
Copy link
Collaborator

hiiamboris commented Feb 25, 2022

Starts here: red/red#4854 (comment)
Red temp implementation is currently here: https://gitlab.com/hiiamboris/red-mezz-warehouse/-/raw/master/new-apply.red
Historical design document: https://github.com/greggirwin/red-hof/blob/master/apply.md

@hiiamboris
Copy link
Collaborator Author

hiiamboris commented Apr 8, 2022

Here's one design improvement also implemented in new-apply.red.

Key-value apply style with functions of many arguments may become pathological:

	inner-replace-at-lstpos: [							;-- used on inner lists
		series:  lst-pos/1
		pattern: :pattern
		value:   :value
		; all:     all
		once:    once
		deep:    deep
		case:    case
		same:    same
		only:    only
		part:    part
		length:  length
	]
	...
	apply find inner-replace-at-lstpos

First, it may seem like changing series and calling apply find 'local is simpler, but this didn't work in this case (it may have worked for this particular apply call but not for the four other ones in the same func). Besides, extra assignment and then restoration of series will slow things down, so I decided that extra verbosity is a smaller price to pay here than to change and restore local words all the time, as that made code look quite cryptic.

What I wanted is to let words that are not a part of expressions after a set-word, to pass their values:

	inner-replace-at-lstpos: [							;-- used on inner lists
		series: lst-pos/1
		pattern value once deep case same only part length
	]

Or (order doesn't matter):

	inner-replace-at-lstpos: [							;-- used on inner lists
		pattern value once deep case same only part length
		series: lst-pos/1
	]

Same call, but more readable because words that are being assigned a new value and words that are being passed with their current value, are easy to tell apart, and we don't have to repeat ourselves as in the first example. And we still have all the arguments listed explicitly, which eases bookkeeping and reduces the danger of passing an argument by mistake.

Format thus can be expressed like this:

apply-spec: [any argument]
argument: [word! | some set-word! expression]
(expression tail is determined by do/next)

@hiiamboris
Copy link
Collaborator Author

hiiamboris commented Apr 8, 2022

Another topic worth bringing up is how to denote expressions.

In current design, apply f [a: 1 + b: 2 + 3] treats a: as an argument, but b: is set (evaluated) because it's inside the expression, which is not handled by apply. Similarly, apply f [a: (b: 1)] uses a: as an argument, but sets b:, while apply f [a: b: 1] treats both a: and b: as arguments.

Though simple to understand rule, it can become a gotcha if while reading our code we fail to switch our mental context.

Another option is to always require all expressions parenthesized, e.g.:

apply f [
	a: (1)
	b: (2)
	c: (d: 3)
]

I do not personally think it's worth it, but it's something that needs consideration by the other team members.

@dockimbel
Copy link

Another option is to always require all expressions parenthesized, e.g.:

I don't think we need to go that far. Nested set-words are already accepted for object construction:

>> object [a: 1 + b: 2 + 3]
== make object! [
    a: 6
    b: 5
]

@hiiamboris
Copy link
Collaborator Author

It would be nice if it could be cheaply aligned with how contexts process set-words, to make calls easier to understand in edge cases.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants