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

World: r3wp

[Core] Discuss core issues

Henrik
18-Sep-2011
[2244x3]
MAP-EACH under R3:
>> map-each v [] [v]
== []

MAP-EACH under R2:

>> map-each v [] [v]
** Throw Error: Return or exit not in function
** Where: map-each
OK, already ramboed in #4394.
is there a fix for this?
Ladislav
18-Sep-2011
[2247x3]
Certainly there is. In R2 it is a mezzanine, which can be corrected.
The easiest way would be to remove the RETURN in the source
e.g. by using EITHER
Henrik
18-Sep-2011
[2250]
ok, Ladislav, are we sure that it will not affect any sources in 
NLPP?
Ladislav
18-Sep-2011
[2251]
Why should it, if done right?
Henrik
18-Sep-2011
[2252]
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
[2253]
Hmm, if somebody relies on the incorrect behaviour, then it is good 
if such a mistake is revealed
BrianH
19-Sep-2011
[2254x4]
There is a fix in R2/Forward already. I'll post it here.
Unfortunately, this is an old problem with an old fix, but not as 
old as the last version of R2.
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
		)
	]
]
This is from the Feb 23 version of R2/Forward.
Ladislav
22-Sep-2011
[2258x4]
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.
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.
Also, once the directives are defined, there is no difference between 
"standard" and "user-defined" as far as the speed or other issues 
are compared.
(that is because all directives use the same way how they are defined, 
using the SET-INCLUDE-DIRECTIVES function, the only difference is 
*when* the directives are defined, and whether it is by default, 
or whether additional action is needed)
Gregg
22-Sep-2011
[2262]
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
[2263x9]
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.
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.
The COMMENT directive really looks general enough, so it is meaningful 
to make it standard. Funnily enough, its spelling is:

    COMMENT


, i.e. it is the old word, Robert just wanted to be able to strip-out 
the COMMENTs from the code, that is why I made it an INCLUDE directive 
as well. This shows, that currently you can make anything an INCLUDE 
directive, not just issues.
Making the COMMENT and INCLUDE directive, we actually keep compatibility 
with old code, being able to strip-out the COMMENTs from it when 
wished.
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.
Regarding the translation functions: yes, the directives do not suffice 
to supply all the necessary functionality. Other code is needed to 
handle the run-time translation of "marked" strings. That code was 
written by Cyphre and is influencing the behaviour of RebGUI widgets 
to show the currently required language version of the text.
err: "Making the COMMENT *an* INCLUDE directive..." is what it should 
have been in the text above
Aha, actually, forget about it, my definition of the COMMENT directive 
would handle the 1 + 1 expression as well. The only difference being, 
that it would be handled during link-time, not run-time of the code, 
which may still cause some incompatibilities
But, as said, I am not afraid of such "stangenesses", since they 
do not exist in the actual code base
Gregg
24-Sep-2011
[2272]
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
[2273]
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
[2274]
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
[2275]
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
sqlab
30-Sep-2011
[2276]
sorry, I forgot the any
 
>> print any [
[    ; 2
[    1]
1
>> print any [
[    comment 2
[    1
[    ]
** Script Error: print is missing its value argument
** Near: print any [
    comment 2 1
]
Ladislav
30-Sep-2011
[2277]
No problem, it was clear what you were after, and yes, that problem 
exists
Ladislav
6-Oct-2011
[2278x6]
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
The former situation (the information about the "culprit file" is 
stored in the error) looks as follows, currently:

performing localization
** User Error: INCLUDE
** Near: do last-error: make error! spec


The trouble is, that the present error-forming code does not show 
all the attributes. If you examine the error on your own, you get:

print mold disarm last-error

make object! [
    code: 802
    type: 'user
    id: 'message
    arg1: 'syntax
    arg2: %gui/include.r
    arg3: [
        id: missing
        arg1: "end-of-block"
        arg2: "["
        arg3: none
        near: "(line 949) ]"
    ]
    near: [do last-error: make error! spec]
    where: none
]


, which shows all the data as "stored" in the error, which is referred 
(for convenience) by the LAST-ERROR variable
aha, correction, the current look of the error is as follows:

>>print mold disarm last-error

make object! [
    code: 802
    type: 'user
    id: 'message
    arg1: "INCLUDE"
    arg2: 'syntax
    arg3: [
        file: %actions/tabs/data.r
        id: missing
        arg1: "end-of-block"
        arg2: "["
        arg3: none
        near: "(line 949) ]"
    ]
    near: [do last-error: make error! spec]
    where: none
]
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?
Summary of the advantages of the first approach:

+ the file information is present in the error itself

Disadvantages:


- the error is "too complicated" for the interpreter to display the 
important informations

- the error has to be "intercepted" by TRY for the INCLUDE to be 
able to "enhance" it.

- also, since the INCLUDE works recursively, the TRY is used many 
times, and the code needs to take care, that the "enhancement" occurs 
only once
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
Gabriele
8-Oct-2011
[2284x3]
Ladislav, it is possible to add new error kinds to system/error, 
then the "error display" can be made to show what you want as well.
eg. see http://www.rebol.it/power-mezz/schemes/hardball.html#section-7.1
and http://www.rebol.it/power-mezz/mezz/messages.html#section-9
Ladislav
8-Oct-2011
[2287x3]
Ladislav, it is possible to add new error kinds to system/error, 
then the 

error display" can be made to show what you want as well." - yes, 
in R2, but INCLUDE is written to be compatible with R3
(I used such a method when INCLUDE was meant just for R2, but, with 
R3 I am not sure)
Brian, don't you happen to know a similar "mechanism" for R3?
Robert
8-Oct-2011
[2290x2]
; 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.
The FORM can be implicit if the argument is not string.
Ladislav
8-Oct-2011
[2292x2]
Why does the STRING! constraint exist?

 - Cyphre and I thought, that it may be of help for the programmer 
 to tell him that he "forgot" to put in strings. Even the numbers 
 are unlikely to be put in unformatted.
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.