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

World: r3wp

[Core] Discuss core issues

Ladislav
8-Oct-2011
[2312x5]
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.
Ladislav
8-Oct-2011
[2329]
yes, will try it. I used a different code, so this one should work, 
I think
BrianH
8-Oct-2011
[2330x3]
That reminds me, I should see if EXTEND is implemented in the most 
efficient way...
I guess it is as efficient as it can be and still support objects, 
maps, blocks and parens. There are more efficient methods if you 
only need to support objects, maps, or blocks and parens.
Objects:  set bind/new :word obj :val
Maps:  obj/word: :val
Blocks and parens:  reduce/into tail obj [to-set-word word :val]
Sprry, that last one should be:  reduce/into [to-set-word word :val] 
tail obj
Ladislav
8-Oct-2011
[2333]
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.
BrianH
8-Oct-2011
[2334x2]
Wait, in what circumctances? Binding to what?
(bad typing day)
Ladislav
8-Oct-2011
[2336x3]
like this: f: make function! [a b] [parse blk]
the BLK is user-supplied, and I have to always recreate the function 
instead of being able to just bind it
(it is not a correct code,but, I guess, that you have the idea)
BrianH
8-Oct-2011
[2339]
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
[2340x3]
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
(which is what annoys me)
What I wanted to do was to be able to do it even when the function 
is not running.
BrianH
8-Oct-2011
[2343]
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.
Ladislav
8-Oct-2011
[2344x2]
You are missing the point, I guess. The MAKE function binds the function 
body when the function is not running. The restriction to BIND is 
just artificial, and circumventable. I do not use the circumvention 
not because it is not possible, but because it looks "ugly".
(I do know at least two ways how to do it, to be exact, but both 
look uglier than what I normally like)
BrianH
8-Oct-2011
[2346]
I wouldn't mind BIND accepting function! for its context argument, 
as long you still have the error on referring to any of the bound 
words when the function isn't running. But not closure! though, since 
that context is different every time.
Ladislav
8-Oct-2011
[2347]
So, I rather always regenerate the function using MAKE, which, of 
course, does the binding for me
GrahamC
8-Oct-2011
[2348]
Your substitute function is similar to the dialect used for sql .. 
except it doesn't reduce, and it uses % instead of ?
BrianH
8-Oct-2011
[2349]
I don't mind the SQL dialect reducing, because that block is always 
code anyways, so you already have to treat it carefully. However, 
the method for treating code carefully is different than the methods 
for treating REBOL code carefully, so it doubles the analysis and 
screening. It's best to just resign yourself to not accepting SQL 
code blocks from unknown sources.
GrahamC
8-Oct-2011
[2350x2]
And is there a %n ... or is it just %0 and %1 ?
Anyway, sounds like a duplicate functionality .. that could wrapped 
into one function with a refinement
BrianH
8-Oct-2011
[2352]
Maybe SUBSTITUTE should have an /only option that works like APPLY/only: 
reduce by default, don't reduce with /only.
GrahamC
8-Oct-2011
[2353x2]
At present everyone is rolling their own substitute function for 
writing sql in R3 .. so it would be useful to have an official function
Not forgetting that the R2 sql substitute functionaiity is bugged
BrianH
8-Oct-2011
[2355]
That SUBSTITUTE function wouldn't work well for SQL, since most SQL 
dialects use % as a wildcard character in like expressions.
Ladislav
8-Oct-2011
[2356x2]
Aha, this was not meant for that specific purpose, being optimized 
for the translation. But, nevertheless, do you think that the #"?" 
character is better than the % character in general?
%0 and %1 - no, %123456 can be used as well
BrianH
8-Oct-2011
[2358x2]
Certainly not for anything other than SQL. Regular language uses 
? for regular punctuation. Does SUBSTITUTE need an escape character 
option?
I don't want to make it too complex, but that seems like a low-overhead 
option.
Ladislav
8-Oct-2011
[2360x2]
Cyphre was against it, and, in fact, it is not needed, since you 
can substitute so, you can generate any string you like this way.
for example, the "%1%2" string can be generated as follows:

["%1" "%1%2"]