Comments on: Bring Out Your Idioms for R3
REBOL Technologies

Comments on: Bring Out Your Idioms for R3

Carl Sassenrath, CTO
REBOL Technologies
28-Oct-2010 20:44 GMT

Article #0494
Main page || Index || Prior Article [0493] || Next Article [0495] || 30 Comments || Send feedback

Now that the sys/lib/user context split has been completed for R3, over the next few weeks/months we will be evaluating possible idioms for inclusion into the standard mezzanine layer. These functions will be available to all programs on startup.

The best idioms are patterns that you encounter often while coding, and a name can be found that accurately represents them (a good abstraction.) The worse idioms are ones that you imagine you want, but have never actually used, or ones for which no good name can be found.

Here's a good candidate for an idiom. It's a code pattern that I use quite often: repeatedly find specific values in a string, binary, block or other series and do something with them. It looks like:

while [series: find series value] [
    do-something series
    ++ series
]

It's somewhat like w:forall so in A110 I've added an idiom called w:find-all that does it:

find-all series value [
    do-something series
]

So, w:find-all does something useful that I write quite often, and it has a good name.

Here's another pattern I encounter often: modifying the value that's found by a w:select (the w:next of a w:find) or w:append it if not found. The pattern is:

either w: find series id [
    change next w value
][
    append append series id value
]

It's not easy to name. Perhaps "modify". Abstractly it is a w:change-select but that name isn't great. The usage would be:

modify series id value

But, that name isn't final. Got a better one?

If you have an idiom that you use often, and you'd like to see it become part of R3, you can submit it in the idioms group as a message or a file.

Example of how you submit an idiom in R3:

carl:R3>> fh idiom
  754 H Idioms                                        21 Carl     2m ago

carl:R3>> 754
R3/Language/Idioms:

Alerts and Banners:
For proposing common idioms. [banner 755]
Last 32 messages...
  2539   I don't get it; to check in a loop u use t   754 Steeve   6-Mar-2009
  2540   More i think about small idioms , more i t   754 Steeve   6-Mar-2009

carl:R3/Language/Idioms>> p
Enter public message (in #14) Use . to send, / to cancel, ! to paste.
FIND-ALL is an idiom I use often:
   while [series: find series value] [
       do-something series
       ++ series
   ]

or, if you have it coded, you can submit the file:

carl:R3/Language/Idioms>> submit find-all.r
Add comment (/ to cancel submit): FIND-ALL

We will review all submitted idioms, and if they look useful, we will be included in coming releases.

30 Comments

Comments:

Andreas
28-Oct-2010 15:49:13
Probably not MODIFY, as we already have a MODIFY. Which is, as far as I understand, destined to become the "writing" counterpart to "reading" QUERY.
-pekr-
28-Oct-2010 17:25:06
find-all: "I write quite often, and it has a good name." - in fact, it's far from being a good name - it does not not tell that anything is going to happen with the elements being found ...
-pekr-
28-Oct-2010 23:09:11
I should add - for some naming tips, see corresponding CC ticket #1718 at:

http://curecode.org/rebol3/ticket.rsp?id=1718&cursor=15

paul personne
28-Oct-2010 23:53:51
I would propose forskip-found or for-found.
Henrik
29-Oct-2010 0:34:36
Alternative words for FIND-ALL: WALK, TEND, MODIFY-EACH. I don't have anything else.
-pekr-
29-Oct-2010 1:24:38
My alternatives were: DO-ALL, FOR-FOUND, and as the latter does not sound nice, I propose - FOR-FIND/FORFIND (mainly as we don't say FORSKIPPED either).

Other than that, I can imagine /find becoming more general refinement (as /only is), to be added to various functions - forskip, forall, remove, change etc (but that is not well thought out on my part :-)

Ashley
29-Oct-2010 15:35:07
Need to fix w:word blog markup (e.g. "... a w:select (the w:next of a w:find) ...").
paul personne
29-Oct-2010 19:32:29
I need refinements for while as all or or any... while [all []][] becomes while/all [][] more readable I think.

A question, why don't use parsing for such things as find-all?

xuanin
30-Oct-2010 7:00:59
Please consider ANY-OF and ALL-OF (CC ticket #0000637). I often miss them.
Brian Hawley
30-Oct-2010 12:21:22
Paul: Because find is faster than parse, and easier to comprehend. The flexibility of parse makes it more powerful, but the simplicity of find makes it faster.

Xuanin: I just added efficient mezzanine implementations of any-of and all-of to that ticket. They should be easy to add now.

Nicolas V. (nve)
30-Oct-2010 13:55:27
I don't know if it could be considered as a idiom, but connected/disconnected mode is really important. With REBOL it is very easy to execute a program over the internet, sometime it also important to execute the script even if the internet connection has been lost.

So, I wrote a little function, but maybe could be a refinement (/offline) for DO function :

do-offline: func [
{Like DO but save the script on the local computer 
and execute it from local drive 
if not found over the internet.}
value "Normally a file name, URL, or block"
/console "Print on console when doing it from local drive."
] [
  either url? value [
    set [path target] split-path find/tail value http://
    path: join system/options/home path
    script: to-file rejoin [path target]
    if error? err: try [
      data: read value
      make-dir/deep to-file path
      write script data
      do data
    ] [
    if console [
      err: disarm err
      print err
      print rejoin ["do " script " => OFFLINE !"]
    ]
    do script
  ]
  ] [
    do value
  ]
]		

After, we could make some improvment and add a /version refinement : execute the local copy of the script if the version is equal or greater to the version.

Xuanin
30-Oct-2010 16:41:14
Many thanks, Brian !
-pekr-
31-Oct-2010 1:41:48
Nicolas, have you checked the do-thru function?
janko
31-Oct-2010 2:53:32
I use something like your "modify" (change if existing, set if not) I call it "assure" (the value is)
Nicolas V. (nve)
31-Oct-2010 5:56:10
I'm still a beginner. Yes, the do-thru function is what I expected. I didn't know this function and I didn't found in the R2 functions library.
John
31-Oct-2010 20:36:29
Anyone else use remove-tail? Maybe this should be a refinement.
remove-tail: func [ s ] [ head remove back tail s ]
Ladislav
2-Nov-2010 5:52:49
I propose the CATCH-ANY function defined in

http://github.com/rebolsource/rebol-test/blob/master/catch-any.r

and the LINE-NUMBER? function defined in

http://github.com/rebolsource/rebol-test/blob/master/line-numberq.r

Ashley
2-Nov-2010 15:44:53
A penultimate function:
second-last: func [s [series!]] [pick tail s -2]
Graham
3-Nov-2010 19:43:29
We have suffix?, we don't have a complement

stem: func [ filename [file!] ][ copy/part filename any [ attempt [ -1 + index? find filename suffix? filename ] length? filename ]]
Brian Hawley
4-Nov-2010 3:57:32
Ashley, that won't work in R3. We fixed the off-by-one error in pick. Use -1 instead. Nice idea.

Graham: Seriously? No manual line breaks in a pre?

Ladislav
4-Nov-2010 5:31:12
These look useful to detect "leaked locals" now, when QUERY lost this functinality:

REBOL [
	Author: "Ladislav Mecir"
	Date: 4-Nov-2010/13:11:31+1:00
	File: %definedq.r
	Title: "Defined"
	Purpose: {detect newly defined (leaked) words}
]

defined?: func [ {find all defined words in the given context} context [any-object!] /local words ] [ words: bind words-of context context remove-each word words [not value? word] words ]

newly-defined?: func [ {do the given BLOCK and find the newly-defined words} block [block!] /local old ] [ old: union union defined? system/contexts/lib defined? system/contexts/sys defined? system/contexts/user do block exclude defined? system/contexts/user old ]

comment [ ; usage: newly-defined? [include %timblk.r] ; == [time-tick time-block tick-time] ]

Graham
4-Nov-2010 11:30:30
Brian: I prefer my idioms to be one liners!
Graham
4-Nov-2010 11:34:38
How about this?

stem: func [ filename [file!]
][
  subtract/tail filename suffix? filename
]
Brian Hawley
4-Nov-2010 21:09:26
Graham, that one liner made the whole comments section wider, because the pre stretches. We really need to figure out a way to make the pre fixed width with a horizontal scroll bar. No worries now, this is for future reference. I like simplicity of the new function, but what is subtract/tail supposed to mean?

Ladislav, it is important to know where things are defined, so instead of a union it might be better to return a block of three blocks that show the differences in each context specifically. Also, words-of returns words already bound to the context - you don't need to bind them again. Great idea though.

Edoc
5-Nov-2010 11:39:02
Whatever happened to the "new kind of dir" from a few years ago, where you could write something like:
>> read %*.r
== [%del-objs.r %t.r %t1.r %test.r]

Graham
5-Nov-2010 13:02:33
Brian, the comments fit fine on my screen. But you might have to scroll a little if you're on a netbook!

Carl said he might overload subtract/add/+/- to perform operations on series. Subtract/tail is thus analagous to trim/tail.

Ladislav
10-Nov-2010 4:15:21
The '''bind-to-new''' function binds the given block to a newly created selfless context.

bind-to-new: func [
	{bind the given BLOCK to a new selfless context}
	block [block!] {block to bind}
	words [block!] {words of the new context}
	values [block!] {values of the new context}
] [
	; make sure the WORDS block isn't empty
	if empty? words [do make error! "WORDS block is empty"]

; make sure the first value in the WORDS block is not a set-word ; (needed until #1751 is corrected) if set-word? first words [change words to word! first words] ; make sure the VALUES block is not longer than the WORDS block clear skip values length? words foreach (words) values reduce [block] ]

Brian Hawley
10-Nov-2010 12:23:18
That could come in handy Ladislav, particularly if it were native (so we could use it in R3's mezzanine functions as well). I'll make a ticket for it if you don't.
Endo
12-Dec-2010 12:27:41
+1 for John, I use remove back tail so often. remove-last is a good name also.
luce80
16-Jan-2011 11:13:13
remove-last: func [{remove last (n) element(s) of a series} serie [series!] /n num [integer! none!]][ if not num [num: 1] remove/part skip tail serie negate num num ]

remove-til-end: func [serie [series!]][remove/part serie tail serie]

Post a Comment:

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

Name:

Blog id:

CS-0494


Comment:


 Note: HTML tags allowed for: b i u li ol ul font 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 10-Jun-2023   -   Copyright Carl Sassenrath   -   WWW.REBOL.COM   -   Edit   -   Blogger Source Code