World: r3wp
[Core] Discuss core issues
older newer | first last |
Ladislav 8-Oct-2011 [2294x5] | 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. |
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. |
older newer | first last |