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

World: r3wp

[Core] Discuss core issues

Ladislav
6-Oct-2011
[2279x5]
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
[2292x7]
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.
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.
Certainly, this restriction can be removed, but it does not look 
like worth doing it.
Substitutions are meant to separate:


- the time when the substition was created (using e.g. the REDUCE 
function)

- the time when the substitution was translated and displayed (using 
e.g. the combination of the TRANSLATE SUBSTITUTE and SHOW functions)
Note: it may make sense to put some of the Q&A to the

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

section
We can also think of the SUBSTITUTE function as being written using 
the KISS strategy. REDUCE can be performed separately, that is why 
it is not needed in the definition of the SUBSTITUTE function.
GrahamC
8-Oct-2011
[2299x4]
substitute ["a%0"] ; == "aa%0"
but there is no argument string?
Isn't this just a special case of printf ..  so why not implement 
printf instead?
I agree with Robert .. why would you want to perform an extra reduce 
?  Is the added efficiency worthwhile making the program reduce in 
those instances where non string values are being passed?
KISS in this instance means default reduce, and use a refinement 
if you don't want this behaviour
Ladislav
8-Oct-2011
[2303x14]
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
I agree with Robert .. why would you want to perform an extra reduce 
?
 - exactly because the REDUCE is performed at a different time
The substitution has to be performed always at the translation time, 
while REDUCE just when you need to create the substitution
Not to mention, that it is safer to have substitutions as data files, 
than to allow code
err. susbstitutions as data values is what I mean
there is no argument string?

 - the %0 is the substitution string (the first one), just as a curiosity, 
 it may not be needed
(you do not have to use %0 if you don't need to)
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
I have to repeat, that the goal here is to represent text, that needs 
to be translated, and we found out, that "generated strings" cannot 
be represented as strings to be translatable.
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.
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)
Originally, the block might have been generated by something like:


my-substitution: reduce ["You do not have sufficient rights to delete 
the '%1" file." to string! file]
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.
You need to realize, that the TRANSLATE function will have to be 
applied as often as the user requires, and that the substitution 
happens only as the last step, just before the string is SHOWn.
BrianH
8-Oct-2011
[2317x2]
I like the SUBSTITUTE proposal, as-is. I sort of like that only strings 
are supported, because there's no default translation from datatypes 
to strings - we don't have anything like OOP asstring methods. Different 
methods of string formatting are appropriate in different circumstances. 
The moment that you pick one conversion method as the default, people 
will ask for options for other conversion methods to be supported, 
gradually making SUBSTITUTE so complex that it becomes slow, as it 
goes through the process at runtime of determining what the programmer 
wants it to do. If you decide to manage that complexity with composition 
instead, the decision-making process is done at development time, 
not runtime, and you can have unbounded complexity with no overhead.
I also like that it doesn't reduce by default, for security reasons. 
If it reduces by default then its argument needs to be treated like 
code, with all the security implications and special handling, rather 
than like data.
Ladislav
8-Oct-2011
[2319x2]
Actually, I think, that the "only strings" approach is best for your 
favourite security theme. The most secure approach for the SHOW code 
is not to execute everything "thrown" at it, but, instead, insist 
on the text to be strings, or very much like strings.
ah, sorry, you just mentioned that as well...
BrianH
8-Oct-2011
[2321]
Yup :)
Ladislav
8-Oct-2011
[2322x2]
What about my R3 error related question, above? Do you know how to?
(or, is it even possible?)
BrianH
8-Oct-2011
[2324x2]
Yeah. Here's how it's done in the ODBC extension:

unprotect system/catalog/errors
extend system/catalog/errors 'ODBC make object! [
    code: system/catalog/errors/access/code + 50
    type: "ODBC error"
    error: [arg1]
]
protect system/catalog/errors


Of course that assumes that PROTECT-SYSTEM was run, which is not 
the case in current R3 builds. You might be able to extend it without 
unprotecting it.
You can extend any of the existing error class objects, or add your 
own.
Ladislav
8-Oct-2011
[2326x2]
Well, I remember that I tried, but did not succeed
(did not even get any error, as far as I remember)
BrianH
8-Oct-2011
[2328]
Really? Works for me, or at least it works for the ODBC extension.