r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[!REBOL3-OLD1]

BrianH
1-Sep-2006
[1270x3]
To me, delimit would intersperse the delimiter in the block but not 
join it. That what the word suggests, at least.
Anton, I'd drop the word "adjoin" because it means basically the 
same thing as "join".
Jaime, your /reduce refinement would seem to be less efficient than 
reducing the data before passing it to your function, by one comparison.
JaimeVargas
1-Sep-2006
[1273x4]
CONJOIN is good, and Brian maybe  right regarding droping the reduce 
refinement. So that [conjoin/reduce...]  becomes the idiom [conjoin 
reduce ...]
One thing though Ladlislav is suggesting to remove REJOIN.
Either by replacment or renaming.
So the suggestion of globing all the DELIMIT features into the new 
function.
BrianH
1-Sep-2006
[1277x3]
Right, otherwise you are adding a comparison nd a path decode to 
every conjoin/reduce call.
I am currently rewriting delimit and conjoin to implement a few of 
my own ideas for it. You do yours and we'll compare.
As far as I'm concerned, delimit and conjoin are separate concepts.
JaimeVargas
1-Sep-2006
[1280]
I wait an see yours. In my opinion the are just one. They basically 
join values into a string, with a maybe some delimiter in between. 
Default behaviour doesn't adds anything.
BrianH
1-Sep-2006
[1281x2]
Like I said before, the word "delimit" doesn't imply joining, while 
"conjoin" does. I'm expecting to make my conjoin function use my 
delimit.
(I'll be back in a bit - must help with diagnosis of electrical problems...)
JaimeVargas
1-Sep-2006
[1283]
Oh. I am not arguing about the name. I am like the CONJOIN choice.
Volker
1-Sep-2006
[1284x4]
Hw about replacing 'rejoin with 'join and rename 'join to something 
else? Maybe a name for joining two things is easier to find?
We have also the issue if  the joins should return a string all the 
time. We could use old 'join for typed joins, by gibing the type 
as the first argument, and 'rejoin always returns a string. then 
it would be called 'join and join something with type in the name, 
join-as or something.
join-as tcp:// [host ":" port]
mybe allow datatypes too, join-as url![ "http://server/"rel-path]
BrianH
1-Sep-2006
[1288]
Volker, joins don't return strings all of the time, they return series. 
If the first value is a series, the result will be a series of the 
same type. Since your urls there are series types, join will join 
them as-is.
Volker
1-Sep-2006
[1289x2]
I know, but there was some talk to enforce strings because that is 
by far the typical usage.
And if you need the old, source is in rebol2 :)
BrianH
1-Sep-2006
[1291x7]
Strings are not the typical usage for me. I saw those functions posted 
above and none of them would work for me. I'm writing my own right 
now, for posting here. I have delimit so far, and am now working 
on conjoin.
I'm trying out a new control flow technique that is really fun to 
use, and devilishly efficient.
As an example, here is delimit. I'll post conjoin soon.
delimit: func [
    "Put a value between the values in a series."
    data [series!] "The series to delimit"
    delimiter "The value to put into the series"
    /only "Inserts a series delimiter as a series."
    /copy "Change a copy of the series instead."
] [
    while either copy [
        copy: make data 2 * length? data
        either empty? data [[false]] [[
            copy: insert/only copy pick data 1
            not empty? data: next data
        ]]
    ] [
        copy: data
        [not empty? copy: next copy]
    ] either only [[
        copy: insert/only copy delimiter
    ]] [[
        copy: insert copy delimiter
    ]]
    head copy
]
Note that the options build the while statement without using compose, 
that no blocks are rebound, and that delimiter can be a thunk.
This is an excellent example of the kind of code that would be really 
difficult to compile, but is really fast to interpret. :)
It could be tightened up a little in the empty data case, so I'm 
going to do that and post it again when I post conjoin.
JaimeVargas
1-Sep-2006
[1298x4]
I would classify this into obscure Rebol. But it does the job ;)
Some benchmarking should be done to see how much speed it is actually 
gained, while trading for clarity.
BTW not using the /copy is not changing the series directly.
Sorry bad testing on my part.
BrianH
1-Sep-2006
[1302x6]
Well, it will be a little hard to check against your delimit since 
that will be more comparable to my conjoin. Still, building the while 
statement this way is no slower than calling one of several different 
while statements depending on options, and it is a lot less redundant. 
Plus it's fun.
Here's a slightly faster version:
delimit: func [
    "Put a value between the values in a series."
    data [series!] "The series to delimit"
    delimiter "The value to put into the series"
    /only "Inserts a series delimiter as a series."
    /copy "Change a copy of the series instead."
] [
    while either copy [
        if empty? data [return make data 0]
        copy: make data 2 * length? data
        [
            copy: insert/only copy first data
            not empty? data: next data
        ]
    ] [
        copy: data
        [not empty? copy: next copy]
    ] pick [
        [copy: insert/only copy delimiter]
        [copy: insert copy delimiter]
    ] only
    head copy
]
And here's a conjoin function:
conjoin: func [
    "Join the values in a block together with a delimiter."
    data [any-block!] "The series to join"
    delimiter "The value to put into the series"
    /only "Inserts a series delimiter as a series."
    /quoted "Puts string values in quotes."
    /local
] [
    if empty? data [return make data 0]

    local: either series? local: first data [copy local] [form local]

    while [not empty? data: next data] either any-string? local [pick 
    [

        [local: insert local reduce [delimiter {"} first data {"}]]
        [local: insert insert local delimiter first data]
    ] quoted] [pick [
        [local: insert insert/only local delimiter first data]
        [local: insert insert local delimiter first data]
    ] only]
    head local
]
For safety, change

    local: either series? local: first data [copy local] [form local]
to

    local: either series? local: first data [copy local] [form :local]
Anton
2-Sep-2006
[1308x3]
Brian, delimit function: 

- For long-term readability, I would avoid reusing 'copy as a variable. 
I suggest 'result, even if it means using another word.

- I understand with the /copy refinement you are able to get more 
speed in creating the result block, but I think I would prefer just 
letting the user copy the data before passing to delimit. This would 
give a simpler implementation, easier to read again.

I don't wish to devalue your effort in getting this version - I did 
a similar thing optimizing conjoin - made it harder to read.
I agree that conjoin should keep the type of series, as rejoin does, 
not just create strings.
Brian, I think Jaime was making the same point, as I do above, about 
speed vs clarity, with regards to /copy. Some benchmarking is needed 
comparing:

- delimit/copy data    ; <--- delimit with /copy refinement implemented
- delimit copy data    ; <--- delimit without /copy refinement
BrianH
5-Sep-2006
[1311]
I was just using the same refinement /copy that bind uses, but I 
agree that its reuse as a local variable isn't very readable. I should 
use /local like my conjoin does. Speaking of conjoin, what do you 
think of the one above? The only speedup I can see to do is to replace 
the insert reduce with four inserts, but otherwise it seems useful.
Anton
5-Sep-2006
[1312x3]
I'll have to check it out more after some sleep...
A function which joins values into a string might be named CONFORM.
Brian, I've read carefully through your conjoin (but haven't tested 
yet), and I like it, except for *one* thing - I would reverse the 
order of the data and delimiter arguments. (Actually, I'm searching 
now for a better word than "delimit". It doesn't quite seem right.)
Anton
6-Sep-2006
[1315x5]
Some synonyms:   abutment, articulation, bond, buttress, *coupling, 
junction, ligament, *pad, *prop, rafter, rib, *seam, splice, *splint, 
strut, *wedge, weld
(* = favourites)
I think my favourite is PAD.
Actually, I don't think the implied REDUCE issue has quite gone away 
for me. Who has never been annoyed by having to write REDUCE in expressions 
such as:

 switch event/key reduce [tab [print "tab key pressed"] #" " [print 
 "space"]  ; <-- here, 'tab would not reduce to #"^-" unless REDUCE 
 was used.
How many times have we written:
	select reduce ...
So I'm thinking of readding the /LITERAL refinement and using DO/NEXT 
when it is not used.
Brian, your last version of CONJOIN, a minor problem:

** Script Error: pick expected index argument of type: number logic 
pair
** Where: conjoin
** Near: pick [
    [local: insert local reduce [delimiter {"} first data {"}]]
    [local: insert insert local delimiter first ...