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

World: r3wp

[!REBOL3-OLD1]

BrianH
10-Sep-2006
[1407]
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."
    /local
] [
    while either copy [
        if empty? data [return make data 0]
        local: make data 2 * length? data
        [
            local: insert/only local first data
            not empty? data: next data
        ]
    ] [
        local: data
        [not empty? local: next local]
    ] either only [
        [local: insert/only local delimiter]
    ] [[local: insert local delimiter]]
    head local
]

conjoin: func [
    "Join the values in a block together with a delimiter."
    data [any-block!] "The values to join"
    delimiter "The value to put in between the above values"
    /only "Inserts a series delimiter as a series."
    /quoted "Puts string values in quotes."
    /local
] [
    if empty? data [return make data 0]

    local: tail either series? local: first data [copy local] [form :local]
    while [not empty? data: next data] either any-string? local [
        either quoted [
            local: insert tail insert head local {"} {"}

            [local: insert insert insert insert local (delimiter) {"} first data 
            {"}]
        ] [[local: insert insert local (delimiter) first data]]
    ] [
        either only [

            [local: insert insert/only local (delimiter) first data]
        ] [[local: insert insert local (delimiter) first data]]
    ]
    head local
]
Tomc
10-Sep-2006
[1408]
consider /delimiter  accepting  a block that is rotated through. 
  ["|"  "|" "|" "|^/"]
Anton
11-Sep-2006
[1409x2]
You can do this and anything else when passing in a function as delimiter.
Brian, maybe delimiter needs to be parenthesised in DELIMIT as well 
?
BrianH
11-Sep-2006
[1411x4]
Tom, you can do that by passing a function as the delimiter, like 
this:

    has [x y] [x: ["|"  "|" "|" "|^/"] y: first x if tail? x: next x 
    [x: head x]]
Sorry, missed you saying that Anton. Still, the example should work.
You don't need to parenthesise delimiter in delimit because every 
reference to it is at the end of a block. Using parentheses is slower 
in REBOL, so why use them when you don't have to?
So much for the function working :(
    x: ["|"  "|" "|" "|^/"] 
    has [y] [y: first x if tail? x: next x [x: head x] y]
Anton
12-Sep-2006
[1415x5]
Ok, very good
You could do it this way:
d: has [x i][i: [1] i/1: i/1 + 1 pick [a b c] (i/1 - 2 // 3 + 1)]
Or like this:
d: has [x][x: [[a b c]] x/1: next either tail? x/1 [head x/1][x/1] 
first back x/1]
Tomc
12-Sep-2006
[1420]
I confess I had not read thru what you have been working on (time) 
I just wanted to be sure it was considered
Anton
12-Sep-2006
[1421]
fair enough. :)
Gregg
12-Sep-2006
[1422]
Wow. A lot of thought here. I've skimmed it (trying to catch up on 
things quickly), and will just post a couple quick thoughts.


* REJOIN is probably a good enough name to stick with; I don' t know 
that any of the others are that much more meaningful in the context 
of REBOL. 

* Changing JOIN's params would break a lot of code.


* I have a DELIMIT function as well, and like the name. Mine doesn't 
have /copy or /only refinements (it always uses insert/only), but 
it has /skip.
Pekr
12-Sep-2006
[1423]
i did not follow the whole discussion, so dunno what exactly 'delimit 
does, but could we have also a 'pad function?
Gregg
12-Sep-2006
[1424]
Yes, that would be nice; PAD, JUSTIFY, and FORMAT are all related 
needs.
Anton
13-Sep-2006
[1425x2]
Gregg, I think Brian's last post with DELIMIT and CONJOIN are probably 
the best in this thread.
.. and as far as I can tell, we are now not thinking to replace REJOIN 
with either of those, they would be complementary.
Cyphre
14-Sep-2006
[1427]
What about CONCAT?
Pekr
14-Sep-2006
[1428x2]
concat came to my mind - because, really guys, for me, czech speaking 
person, conjoin sounds like something rude I even don't know. So 
concat, I at least know as a term from other languages :-)
sorry - I don't properly follow the discussion, so I even don't know, 
what conjoin should do in opposite to join, or rejoin ... I am fine 
with both old names ...
Volker
14-Sep-2006
[1430]
conjoin inserts delemiters too, did i get that right? How about a 
simple 'list, i feel its a good match, listing things. But not native 
speaker.. Another idea: it icould be related to csv (this spreadsheet-format, 
got i the letters right), a conjoin is close to exporting?
Pekr
14-Sep-2006
[1431]
we have already list-dir, so list is a good match imo ...
BrianH
14-Sep-2006
[1432x3]
The word "concat" is usually used for a function similar to join 
rejoin.
The word "conjoin" means "join with", and is the shortest appropriate 
word we could come up wth for the concept of joining with delimiters.
We were thinking of CSV files when we added the /quoted refinement, 
but the conjoin function could probably be refined to be better at 
dataset export.
Anton
15-Sep-2006
[1435]
By "better at dataset export", do you mean retaining the structure 
(sub-blocks etc.) of the input?
BrianH
15-Sep-2006
[1436x2]
Well, REBOL blocks can double as datasets, with either nested blocks 
or fixed-length records. You could probably do a variant on conjoin 
that could convert either of these types to a CSV file, even with 
one that has its records delimited by something other than a comma, 
like a tab. Creating a new function to do this based on the techniques 
in conjoin would currently be easier than using conjoin to perform 
this task.
On the other hand, if you don't want a full copy of the CSV fie in 
memory and would rather just convert to disk, conjoin should work 
just fine. It might be a good idea to add a /part option for fixed-length 
record blocks.
Anton
18-Sep-2006
[1438x3]
Ladislav wrote:
what would you prefer this expression to return, 1 or 2?:

		loop 1 [
			f: func [x] [
				either x = 1 [
					loop 1 [f 2]
					2
				] [break/return 1]
			]
			f 1
		]
Ladislav, I'm not sure what the main question is. Could you explain 
the control flow that would lead to a 1 result ?
Are you wondering if BREAK/RETURN should break out of the outer loop 
as well as the inner loop ?
Ladislav
18-Sep-2006
[1441]
if I take the BREAK/RETURN above lexically, then it does not "belong" 
to the loop 1 [f 2] loop but rather to the loop 1 [ f: func ...] 
loop. This approach is called lexical binding and leads to 1 being 
returned as the result.
Volker
18-Sep-2006
[1442]
i do not like that a break can break function-nesting.
Ladislav
18-Sep-2006
[1443]
If I take BREAK/RETURN "dynamically" - i.e. when did it occur, it 
"belongs" to the loop 1 [f 2] and therefore the dynamic approach 
leads to 2 being returned as the result.
Volker
18-Sep-2006
[1444]
except for control-structs, as it is now. and that should break the 
control-struct, so not lexically.
Ladislav
18-Sep-2006
[1445]
Volker: regarding the [throw] function attribute - it is not able 
to influence to which loop the BREAK belongs
Volker
18-Sep-2006
[1446]
I see 'break and 'return as kind of catch/throw. So to me its clear. 
But i may miss something. The old way to build
  my-loop[break]
would still work lexically?
Ladislav
18-Sep-2006
[1447]
i do not like that a break can break function-nesting.

 - you can always "break out of a function", unless the BREAK implementation 
 is faulty
Volker
18-Sep-2006
[1448x2]
f: func[][break/return 2]
probe loop 1 [probe f]
Hmm, no error. I do not like that.
Ladislav
18-Sep-2006
[1450]
:-)
Volker
18-Sep-2006
[1451x4]
If i want to obfuscate things, i remember that..
In that case lexically could make sense. Easier to see what is broken.
But it would break cleanup-code?
But the current way does too..
Ladislav
18-Sep-2006
[1455]
except for control-structs, as it is now. and that should break the 
control-struct, so not lexically.

 - actually, in case of control-structs what you really want is lexical 
 break as you pointed out above and as can be demonstrated by:


    control-struct-test: func [control-struct [any-function!] code [block!]] 
    [loop 1 [control-struct code 2]]

>> control-struct-test :do [break/return 1]
== 1
Volker
18-Sep-2006
[1456]
I think lexically. if i pass a closure with a break, it should at 
least break into my code, and not inside some foreign code where 
it creates havoc.