Comments on: PARSE: Rethinking REMOVE

Carl Sassenrath, CTO
REBOL Technologies
29-Sep-2009 5:21 GMT

Article #0255
Main page || Index || Prior Article [0254] || Next Article [0256] || 1 Comments || Send feedback

A83 implements REMOVE as a standard post-rule action. That is, the rule matches, and if successful, the REMOVE action is performed:

parse "abcd" ["ab" remove 1 "d"]

This line matches "ab" then removes the next char, "c", then matches "d".

An alternative (suggested by Steeve in a prior blog) is for REMOVE to work like a pre-rule action. (NOT is an example of a pre-rule action. It inverts the result of the rule that follows it.)

The above example would be written:

parse "abcd" ["ab" remove skip "d"]

Is there an advantage in this change? At first, it may seem equivalent. However, there is a small advantage. If, for example, I wanted to match against "c" before removing it, in the earlier method it would be:

parse "abcd" ["abc" remove -1 "d"]

and in the suggested method:

parse "abcd" ["ab" remove "c" "d"]

If I want to remove "ccc":

parse "abcccd" ["abccc" remove -3 "d"]


parse "abcccd" ["ab" 3 "c" remove -3 "d"]


parse "abcccd" ["ab" remove "ccc" "d"]


parse "abcccd" ["ab" remove 3 "c" "d"]

In the earlier method, I am required to keep the REMOVE argument in-agreement with the match rule; whereas, in the suggested method, they are the same.

This is consistent with good programming methods: avoid duplicate specification when possible. That is, avoid specifying the same thing (or its related properties) twice. This prevents the common mistake that if you change one of them, but forget to change the other, you've created a bug.

So, with that in mind the A84 release will test this REMOVE method. Although somewhat different than the other parse actions, I think we may find it a worthwhile approach. Please give it a try and let me know.



29-Sep-2009 8:27:17
Very glad !

Before A83 and A84, i had to write something like that in my code:

parse/case opcode [
	any [
		  &: "nn"  &&: (&: change/part & get-word &&) :&
		  |  #"n"  &&: (&: change/part & get-byte &&) :&
		  |  "+d"  &&: (&: change/part & get-d &&)	:&
		  |  #"e"  &&: (&: change/part & get-e &&)  :&
		  |  skip
Now i can come with this (which trow away the need of nasty indexes):
parse/case opcode [
	any [
		  remove "nn"  (new: get-word) insert new
		| remove #"n" (new: form get-byte) insert new
		| remove "+d" (new: get-d) insert new
		| remove #"e" (new: get-e) insert new
		| skip
Later with INSERT dealing correctly with paren! parameter, i could write
parse/case opcode [
	any [
		  remove "nn"  insert (get-word) 
		| remove #"n" insert (form get-byte) 
		| remove "+d" insert (get-d) 
		| remove #"e" insert (get-e) 
		| skip
And finally, i hope to be able to use CHANGE instead:
parse/case opcode [
	any [
		  change "nn"  (get-word) 
		| change #"n" (form get-byte) 
		| change "+d" (get-d) 
		| change #"e" (get-e) 
		| skip
It will be perfectly rebolish, thanks Carl :-)

Post a Comment:

You can post a comment here. Keep it on-topic.


Blog id:



 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

Updated 15-Jun-2024 - Edit - Copyright REBOL Technologies -