• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp5907
r3wp58701
total:64608

results window for this page: [start: 62001 end: 62100]

world-name: r3wp

Group: Core ... Discuss core issues [web-public]
Geomol:
24-Aug-2011
But yes, Henrik, COMPOSE should maybe work on path too, as it is 
a series. And maybe also on parens (also a series), where COMPOSE 
should work on parens inside.
Gregg:
24-Aug-2011
REBOL handles parens in paths today. I can see the usefulness of 
having that evaluation return a composed path.
Sunanda:
14-Sep-2011
It may be because they are considered to have distinct 'self's

    a: make object! []
    b: make object! []
    equal? a b
    == false
    equal? (first  a) (first b)
    == true
    equal? (second  a) (second b)
    == false
    equal? (third  a) (third b)
    == true
    a/self = b/self
    == false
Endo:
14-Sep-2011
and it's more useful than the other way I think. Once I wrote a function 
to test if two object is similar. It looks a bit silly but works 
for me. Can be extended to test values also:

similar?: func [
    {Returns true if both object has same words in same types.}
    o [object!] p [object!] /local test
][

    test: [if not equal? type? get in o word type? get in p word [return 
    false]]
    foreach word sort first o test
    foreach word sort first p test
    true
]
Geomol:
16-Sep-2011
Today's Long Moment of REBOL Zen:


When making an object, code in the block argument is executed. I 
found, BREAK stops further execution:

>> o: context [a: 1 break b:2]
>> ? o
O is an object of value: 
   a               integer!  1


So the B assignment isn't carried out. Ok, what about a RETURN in 
object creation then? I'll use MAKE OBJECT! instead of CONTEXT, so 
the RETURN is not handled by CONTEXT, which is a function:

>> o: make object! [a: 1 return 0 b:2]
>> ? o
O is an object of value: 
   a               integer!  1


It seems like, making objects can handle returns ... in R2 at least. 
This has changed in R3, where the result is:

>> o: make object! [a: 1 return 0 b: 2]
** Throw error: return or exit not in function


This seems reasonable. What if I use CONTEXT and use RETURN in the 
object creation? In R2 CONTEXT doesn't have a THROW function attribute, 
so my guess is, RETURN will return from CONTEXT, and the rest of 
the object isn't made, and this is what happens:


>> o: context [print "before return" return 0 print "after return"]
before return


Ok, I now want to fix CONTEXT by putting the THROW attribute in, 
and then test it by making an object using CONTEXT, but this time 
inside a function:

>> context: func [[throw] blk] [make object! blk]

>> f: does [context [print "before return" return 0 print "after 
return"] print "still in f"]


When running F, I would expect to just see the words "before return", 
but

>> f
before return
still in f


I see, that THROW doesn't work as intended, when making objects. 
This is the same in R3, where CONTEXT also doesn't have THROW, and 
when trying to fix that by changing CONTEXT, it's still the same 
behaviour as in R2.
BrianH:
16-Sep-2011
As for your attempt to fix R2's CONTEXT using the [throw] attribute, 
you do manage to fix CONTEXT, but there's no fixing the MAKE object! 
it calls catching the RETURN when it shouldn't. So only one of the 
bugs is fixed, not the other. Guess that's why CONTEXT didn't have 
a [throw] attribute already.
Henrik:
18-Sep-2011
is there a fix for this?
Ladislav:
18-Sep-2011
Certainly there is. In R2 it is a mezzanine, which can be corrected.
Henrik:
18-Sep-2011
the incorrect behavior won't necessarily cause a crash, but of course, 
it's probably not likely that map-each is used that way.
Ladislav:
18-Sep-2011
Hmm, if somebody relies on the incorrect behaviour, then it is good 
if such a mistake is revealed
BrianH:
19-Sep-2011
There is a fix in R2/Forward already. I'll post it here.
BrianH:
19-Sep-2011
map-each: func [

 "Evaluates a block for each value(s) in a series and returns them 
 as a block."
	[throw catch]

 'word [word! block!] "Word or block of words to set each time (local)"
	data [block!] "The series to traverse"
	body [block!] "Block to evaluate each time"
	/into "Collect into a given series, rather than a new block"

 output [any-block! any-string!] "The series to output to" ; Not image!
	/local init len x
][
	; Shortcut return for empty data
	either empty? data [any [output make block! 0]] [
		; BIND/copy word and body
		word: either block? word [
			if empty? word [throw make error! [script invalid-arg []]]

   copy/deep word  ; /deep because word is rebound before errors checked
		] [reduce [word]]
		word: use word reduce [word]
		body: bind/copy body first word
		; Build init code
		init: none
		parse word [any [word! | x: set-word! (
			unless init [init: make block! 4]
			; Add [x: at data index] to init, and remove from word
			insert insert insert tail init first x [at data] index? x
			remove x
		) :x | x: skip (

   throw make error! reduce ['script 'expect-set [word! set-word!] type? 
   first x]
		)]]
		len: length? word ; Can be zero now (for advanced code tricks)
		; Create the output series if not specified
		unless into [output: make block! divide length? data max 1 len]
		; Process the data (which is not empty at this point)

  until [ ; Note: output: insert/only output needed for list! output
			set word data  do init

   unless unset? set/any 'x do body [output: insert/only output :x]
			tail? data: skip data len
		]
		; Return the output and clean up memory references
		also either into [output] [head output] (
			set [word data body output init x] none
		)
	]
]
Ladislav:
22-Sep-2011
I am not sure which group to choose for this poll for REBOL preprocessing 
directives. I hope this one can be used, but wait for a moment before 
going ahead to allow for objections.
Ladislav:
22-Sep-2011
OK, since nobody objected, I shall proceed with the preprocessing 
directives user-poll:


- in the current INCLUDE, the PREBOL directives are made standard, 
while other directives, like COMMENT are made "user-defined", which 
means, that they are defined "on-demand" only


Since in RMA, we actually used the COMMENT directive as "standard" 
for quite some time, there is a suggestion (by Cyphre) to make it 
standard as well. Any other opinions on which preprocessing directives 
should be made "standard" and which ones should be "user-definable"?


Just a note - switching this in the code is trivial, it is more of 
a standardization issue, than a problem of work in my side.
Gregg:
22-Sep-2011
Thanks for the update, including the great docs Ladislav. I will 
try to give it more thought, and incorporate the new version in my 
work. In the meantime, here are some quick comments.


Have a naming convention for scripts that define include directives. 
e.g. %localize.r could be %#localize.r or %incl-directive-localize.r. 
Short is good, but special characters may affect portability.


If a directive doesn't require per-script or environment specific 
changes, like #comment, make it standard. And the way you designed 
#localize is very nice, in that it gives you control. Do you have 
helper functions for updating 'translate-list? I might call it translation-list, 
since 'translate sounds like an action.
Ladislav:
22-Sep-2011
A note to "%incl-directive-localize.r" - you may not have noticed 
yet, but %localize.r defines four localization directives, and string 
handling, not just one directive.
Ladislav:
22-Sep-2011
But, certainly, naming convention may be important, although, in 
this specific case, we do not have any alternative for localization. 
Certainly, if Robert agrees, we can easily change the name to a more 
descriptive one.
Ladislav:
22-Sep-2011
Of course, I can imagine a case when the COMMENT directive would 
be incompatible with the COMMENT function. See e.g. the following:

    COMMENT 1 + 1


if it is a function (not being stripped out), the expression *is* 
evaluated as a COMMENT argument. If handled as a directive, and stripped 
out, it ends up like this:

    + 1


(the COMMENT 1 part being stripped out), which looks unexpected. 
But, I was not afraid of such strange things, since nobody uses the 
COMMENT function like that.
Gregg:
24-Sep-2011
What I mean, regarding %localize.r, is that any script that defines 
directives (one or more) could use the naming convention. And it 
makes perfect sense to group related directives in a script.
Oldes:
29-Sep-2011
I'm using COMMENT in cases where I want to persist it in my code 
after building process - as a COMMENT. If I just want to temporaly 
remove some code, I one or multiple semicolons, which would be exactly 
the case with 1 + 1
Ladislav:
29-Sep-2011
I'm using COMMENT in cases where I want to persist it in my code 
after building process - as a COMMENT.
 - the COMMENT directive supports that mode as well
sqlab:
29-Sep-2011
There iis a problem with comment, if you use it in an any block
>> print [
[    ; 2
[    1]
1
but 

>> print [
[    comment  2
[    1]
?unset? 1
Ladislav:
6-Oct-2011
As suggested by some people, I am making the COMMENT directive standard, 
improving all the directives, and enhancing the way how INCLUDE generates/uses 
errors. When INCLUDE is traversing a large set of files, I feel it 
convenient not only to get an error, but also the file, where the 
error occurred.

That is possible by either


- enhancing the error to contain the information about the file, 
where it occurred

- storing the name of the culprit file somewhere else, not into the 
error itself
Ladislav:
6-Oct-2011
The second option would be to not "enhance" the error, in which case 
it might look like:

** Syntax Error: Missing [ at end-of-script
** Near: (line 949) [

, and examining the error we would get:

make object! [
 id: missing
        arg1: "end-of-block"
        arg2: "["
        arg3: none
        near: "(line 949) ]"
]


here, clearly, the information that it was an error in the %actions/tabs/data.r 
file is missing, but the "standard" error message is more informative. 
The missing CULPRIT-FILE information could be supplied by defining 
a CULPRIT-FILE variable for that purpose. Any preference(s) which 
alternative you might prefer?
Ladislav:
6-Oct-2011
The second approach has got the following advantages:


+ no need to "intercept" the error, since no "error enhancement" 
needs to be done

+ the error is displayed by the interpreter in a standard way, the 
user needs just to get the CULPRIT-FILE name elsewhere

Disadvantages:


- the error does not contain the CULPRIT-FILE information, which 
is important, thus, the user needs to look for it elsewhere
Ladislav:
8-Oct-2011
(I used such a method when INCLUDE was meant just for R2, but, with 
R3 I am not sure)
Ladislav:
8-Oct-2011
Brian, don't you happen to know a similar "mechanism" for R3?
Robert:
8-Oct-2011
; the arguments have to be strings: substitute [

%1" 12] ; triggers an error" - Why does the STRING! constraint exist? 
IMO every aregument should be reduced and than formed into a string.
Ladislav:
8-Oct-2011
IMO every aregument should be reduced and than formed into a string.

 - yes, but that should be done when a substitution is made, not when 
 it is translated, e.g.
Ladislav:
8-Oct-2011
I think that it may help to think of substitutions as "a different 
kind of string". A substitution as "a different kind of string" does 
not need to contain any expressions or code.
Ladislav:
8-Oct-2011
Note: it may make sense to put some of the Q&A to the

http://www.rebol.net/wiki/Replacement#SUBSTITUTE

section
GrahamC:
8-Oct-2011
substitute ["a%0"] ; == "aa%0"
but there is no argument string?
GrahamC:
8-Oct-2011
Isn't this just a special case of printf ..  so why not implement 
printf instead?
GrahamC:
8-Oct-2011
KISS in this instance means default reduce, and use a refinement 
if you don't want this behaviour
Ladislav:
8-Oct-2011
Isn't this just a special case of printf ..  so why not implement 
printf instead? - it does not have anything in common with printf, 
except for the superficial similarity
Ladislav:
8-Oct-2011
I agree with Robert .. why would you want to perform an extra reduce 
?
 - exactly because the REDUCE is performed at a different time
Ladislav:
8-Oct-2011
there is no argument string?

 - the %0 is the substitution string (the first one), just as a curiosity, 
 it may not be needed
Ladislav:
8-Oct-2011
KISS in this instance means default reduce, and use a refinement 
if you don't want this behaviour

 - well, that is very much like saying, that e.g. for the TEXT widget 
 in the Laout dialect you prefer to use a code block, which should 
 (re)generate the string to be displayed every time it is SHOWn. While 
 possible, it is not KISS
Ladislav:
8-Oct-2011
As an example, check this:


["You do not have sufficient rights to delete the '%1" file." "database.r"]


This is easy to translate, since only the substitution strings needs 
a translation, while the argument does not. If you know how to translate 
the substitution string, the argument string does not matter at all.
Ladislav:
8-Oct-2011
So, the TRANSLATE function just replaces the substitution string 
by a different language version, leaving the argument as-is, e.g.:


["Sie verfuegen nicht die ausreichende Zugriffsrechte fuer das File 
'%1' zu loeschen." "database.r"]

(forgive my attempt, I bet it is not a correct German)
Ladislav:
8-Oct-2011
But that does not matter, until it need the translation, which happens 
during run-time when the user chooses a different display language 
for widgets.
Ladislav:
8-Oct-2011
yes, will try it. I used a different code, so this one should work, 
I think
Ladislav:
8-Oct-2011
BTW, I am a bit annoyed by needing to bind a user-supplied block, 
and having to always recreate a function because of that. I would 
prefer to just BIND, as in R2, which is technically possible, just 
unsupported.
Ladislav:
8-Oct-2011
like this: f: make function! [a b] [parse blk]
Ladislav:
8-Oct-2011
(it is not a correct code,but, I guess, that you have the idea)
BrianH:
8-Oct-2011
Do you mean so that the 'a and 'b are bound in the block? You can 
bind to a function context by using one of its argument words as 
a referent. Or do you mean as in cases like the KEEP function in 
COLLECT ?
Ladislav:
8-Oct-2011
You can bind to a function context by using one of its argument words 
as a referent.

 - well, actually, I can do that only when the function is actually 
 running
BrianH:
8-Oct-2011
Yup. But 'a and 'b are only defined when the function is running. 
I can see how you'd find that annoying if you're used to R2's behavior, 
though I find R3 to make more sense.
GrahamC:
8-Oct-2011
And is there a %n ... or is it just %0 and %1 ?
GrahamC:
8-Oct-2011
Anyway, sounds like a duplicate functionality .. that could wrapped 
into one function with a refinement
BrianH:
8-Oct-2011
That SUBSTITUTE function wouldn't work well for SQL, since most SQL 
dialects use % as a wildcard character in like expressions.
BrianH:
8-Oct-2011
I don't want to make it too complex, but that seems like a low-overhead 
option.
BrianH:
8-Oct-2011
Well, you can't use % in SQL and can't use ? in English (and some 
other european languages). If we want to code to be more flexible, 
an escape char option would have low overhead for a lot of benefit.
Ladislav:
8-Oct-2011
I do not need to, if I want to obtain %1 somewhere, I can write:

["this is a string containing '%1'" "%1"]

, and I get it (although substituted)
BrianH:
8-Oct-2011
I'm OK with not having a /with, but I'm sold on having an APPLY-style 
/only option.
GrahamC:
8-Oct-2011
That sounds tricky ... if you're reading two input streams .. to 
substitute ... you need to know when a %n is intended not to be replaced
BrianH:
8-Oct-2011
What if "%%" was always interpreted as "%"? Then the way that you 
signify %n as not being a replacement is to write it as %%n.
BrianH:
8-Oct-2011
The main advantage to APPLY reducing its argument is that it doesn't 
necessarily have to allocate an intermediate block. This might be 
tricky though if you want to implement SUBSTITUTE as a command. Can 
you DO/next in a command?
BrianH:
8-Oct-2011
Ladislav, the advantage would be that you don't have to allocate 
a substitution argument for that % escaping, especially if some of 
your template strings might need a %1 in them and others might not.
Ladislav:
8-Oct-2011
the advantage would be that you don't have to allocate a substitution 
argument for that % escaping

 - yes, understood, I was originally for that alternative, but, Cyphre 
 convinced me, that for human writers, actualy the substitution is 
 more readable
BrianH:
8-Oct-2011
Ah, sticking to the natural language translation usage model, even 
though you are allocating a more generally applicable name to the 
function.
Ladislav:
8-Oct-2011
But, "translate" is not a good name, since the translation is what 
is being performed as well, besides the substitution
Ladislav:
9-Oct-2011
In general, I do not expect the #"%" character to be contained in 
the texts being followed by a digit. At least not frequently enough 
to normally matter.
Ladislav:
10-Oct-2011
Hi, I found the following text part in the Replacement article: "ENLINE 
any-block!,". Forgive my ignorance, please. What exactly is ENLINE 
meant to do in case its SERIES argument is a block?
Ladislav:
12-Oct-2011
In R3 we have got the

    system/state/last-error


, which is great for convenience. Is there a corresponding variable 
in R2?
Geomol:
12-Oct-2011
Today's Moment of REBOL Zen:

>> s: "A"
== "A"
>> lowercase s
== "a"
>> s
== "a"
>> c: #"A"
== #"A"
>> lowercase c
== #"a"
>> c
== #"A"
Geomol:
12-Oct-2011
There was a discusson in Carl's blog about this long time ago.
Endo:
12-Oct-2011
using NEXT with call-by-word (I like the name :) ) looks ok to me, 
but I remember that, "guru"s may say "it leads performance overhead 
for next, as it is a native and used a lot. it should check the argument 
and get-value if it is a word."
Geomol:
12-Oct-2011
Then we could have things like:

>> a: 41
>> next a
== 42
>> a
== 41
>> next 'a
== 42
>> a
== 42
Endo:
12-Oct-2011
If it supports those actions, then it should be everywhere:

SKIP, ADD, DIV, NEXT, NEGATIVE, AND etc.. then it leads a overhead.
Geomol:
12-Oct-2011
A lot of things like

var: var + something	; or
var: add var something

could be changed to

add 'var something
Endo:
12-Oct-2011
what about writing a bunch of new functions suffixed with '
ADD'
NEXT'
Endo:
13-Oct-2011
There is a huge speed difference: (my benchmark function executes 
given block 1'000'000 times)
>> i: 0 benchmark [i: i + 1]
== 0:00:00.25
>> i: 0 benchmark [++ i]
== 0:00:02.578
Geomol:
13-Oct-2011
That's more the difference between a native and a mezzanine, than 
the method.
Geomol:
13-Oct-2011
Related is using POKE on e.g. time!:

>> t: 10:20:30
== 10:20:30
>> poke t 2 42
== 10:42:30
>> t
== 10:20:30

But we can change a time using a set-path!:

>> t/2: 42
== 42
>> t
== 10:42:30

So the set-path! way doesn't do the same as POKE in this case.
Endo:
13-Oct-2011
That's more the difference between a native and a mezzanine, than 
the method.
 - That's right.
BrianH:
13-Oct-2011
Try it in R3:
>> dt [i: 0 loop 1000 [i: i + 1]]
== 0:00:00.000251
>> dt [i: 0 loop 1000 [++ i]]
== 0:00:00.000383


Then the difference is more due to the code in ++ to tell whether 
i is an integer or a series
BrianH:
13-Oct-2011
Geomol, if you change NEXT to call-by-word then in order to have 
it work on the results of a function you will need to assign those 
results to a temporary word, then in a separate statement run the 
NEXT. No more chaining.
BrianH:
13-Oct-2011
If you try to support both then you lose the ability of NEXT to trigger 
an error if it is passed a word by accident, a valuable debugging 
aid.
Geomol:
13-Oct-2011
>> f: func [v] [either word? v [get v] [v]]
>> f 1
== 1
>> a: 2
== 2
>> f 'a
== 2
Ladislav:
13-Oct-2011
aha, so you are suggesting to just accept word as yet another type 
of argument, i.e. to support NEXT 'A
Geomol:
13-Oct-2011
Mezzanine example:


>> my-next: func [series] [either word? series [set series next get 
series] [next series]]
>> my-next [a b c]
== [b c]
>> block: [a b c]
== [a b c]
>> my-next 'block
== [b c]
>> block
== [b c]
Ladislav:
13-Oct-2011
Anyway, it does not look like a best idea to me. Besides, in the 
case of ++ a new (special) function with a different argument passing 
convention was defined
Endo:
13-Oct-2011
We talked about to change the value of non-series values by this 
way:
>> a: 5
>> multiply 'a 5
>> ? a
== 25


But ofcourse we are not sure about performance overhead or possible 
other problems.
Geomol:
13-Oct-2011
I've been thinking about this before, and there was a discussion 
on Carl's blog long time ago. It came to me again, when I looked 
at LOWERCASE and UPPERCASE. They work on strings, and does change 
the sting. But many functions work on string without changing them. 
That's a bit odd, or maybe difficult for new users to understand.
BrianH:
13-Oct-2011
For all those series functions that are non-modifying, except for 
ports, all we have to do to use them safely is to avoid putting ports 
in our data. This isn't usually a problem because it's rare to put 
ports in data; but words, on the other hand, are really common in 
data. This would make a misplaced word in your data not only not 
caught, but also *modified*. That is really bad.
BrianH:
13-Oct-2011
I wasn't joking about the "a valuable debugging aid" comment. That's 
a deal-killer for me.
Henrik:
16-Oct-2011
What exactly does this mean:

>> a: make bitset! [#"-" - #"+"]
** Script Error: Out of range or past end
** Near: a: make bitset! [#"-" - #"+"]
Henrik:
16-Oct-2011
that seems a bit impractical, but I guess it could complicate the 
function to have both ways.
james_nak:
28-Oct-2011
Is there a simple way to transform a block of blocks into a single 
block and maintain their types? As follows:
a: [  [1] [2] [3] ]
Changing that to
b: [  1 2 3 ]

You know, outside of looping thru each value and building a new block 
(which I don't mind doing but if there was some simple way)
BrianH:
28-Oct-2011
Also, in-place or as a copy?
BrianH:
28-Oct-2011
>> a: [[1][2][3][[4]]]
== [[1] [2] [3] [[4]]]

One level:

>> b: copy a while [not tail? b] [either block? first b [b: change 
b first b] [++ b]] b: head b
== [1 2 3 [4]]

All levels (not cyclic reference safe):

>> b: copy a while [not tail? b] [either block? first b [change b 
first b] [++ b]] b: head b
== [1 2 3 4]
BrianH:
28-Oct-2011
ChristianE's ODBC extension for R3 includes a native FLATTEN command, 
but I haven't tested whether or not it manages memory properly, and 
it doesn't help R2, or R3 not on Windows.
BrianH:
28-Oct-2011
Using R3 PARSE:
>> b: copy a parse b [any [change [set x block!] x | skip]] b
== [1 2 3 [4]]

>> b: copy a parse b [while [and change [set x block!] x | skip]] 
b
== [1 2 3 4]
BrianH:
28-Oct-2011
Or simpler:
>> parse copy a [return while [change [set x block!] x | skip]]
== [1 2 3 [4]]

>> parse copy a [return while [and change [set x block!] x | skip]]
== [1 2 3 4]
Andreas:
28-Oct-2011
in-place:
forall a [change a first a]

copying:
collect [foreach x a [keep x]]
BrianH:
28-Oct-2011
Andreas, FORALL won't work here:
>> a: [[1] [2] [3 [4]] [[5]]] forall a [change a first a] a
== [1 2 3 4]


If it's shallow, it should be [1 2 3 [4] [5]], if deep it should 
be [1 2 3 4 5].
BrianH:
28-Oct-2011
It's a little better if you do this, but still not quite right:

>> a: [[1] 2 [[3] [4]] [[5]]] forall a [change/part a first a 1] 
a
== [1 2 [3] 4 [5]]  ; should be [1 2 [3] [4] [5]]
james_nak:
28-Oct-2011
Gentlemen, thank you. I will study your methods. It is just one level 
and it was to handle indexes I was receiving from a mysql db that 
were returned as [ [1] [2][ 3]]. Again thank you. You guys sure know 
your stuff!
BrianH:
28-Oct-2011
If you are copying from fixed records (as from DB results), Andreas's 
COLLECT version will use the least memory because you can preallocate:

>> a: [[1 2] [3 4] [5 6]] head collect/into [foreach x a [keep x]] 
make block! 2 * length? a
== [1 2 3 4 5 6]
62001 / 6460812345...619620[621] 622623...643644645646647