AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 4382 |
r3wp | 44224 |
total: | 48606 |
results window for this page: [start: 41401 end: 41500]
world-name: r3wp
Group: !REBOL3 ... [web-public] | ||
Endo: 24-May-2011 | it is because of lit-words cannot start with a number but refinements and issues can. | |
BrianH: 25-May-2011 | Maxim, it was discussed and that proposal was rejected. | |
BrianH: 25-May-2011 | Jerry, the /local refinement is just another function option. If you provide that option when you call that function, you can provide initial values for the "local variables". In the case of sys/load-module, the security and control flow of that function depends on the local variables being initialized with the none value, so we want to avoid the /local option being used when the function is called. When a function refinement is not used its value is none, so if you want to ensure that it is none and trigger an error if it isn't, ASSERT/type [option none!] is the most efficient way to do this in R3. | |
BrianH: 25-May-2011 | After Carl asked me that question, Jerry, and got that answer, he wrote a blog where he suggested making /local special in functions. While most people are in favor of that (not half of the gurus), this proposed change to /local hasn't been done yet and we don't know if it will ever be done. | |
Geomol: 26-May-2011 | (This is the official answer; I am just writing it out again, for the 4th time this year.) Why bother? No matter how many times you write it, this still is bad design. Or lack of design and bad implementation. It's like having integers, you can only use for the PICK function, but can't make arithmetic with. | |
Ladislav: 26-May-2011 | After Carl asked me that question, Jerry, and got that answer, he wrote a blog where he suggested making /local special in functions. While most people are in favor of that (not half of the gurus) - then I must have a problem with reading comprehension. I rechecked the discussion of this twice and came to a completely different conclusion | |
Geomol: 26-May-2011 | I'm looking at what kind of functions, R3 has: >> ? any-function! ANY-FUNCTION! is a typeset of value: make typeset! [native! action! rebcode! command! op! closure! function!] And then I come to think, if it's a problem having both native!, action! and function!. Should all 3 be seen as function! ? Having them all and now with the addition of closure, what if a native act like a closure? Should it then be a native-closure! ? Same with action! . And what if it's possible one day to make operators, should we then call the current operators for nop! (or native-op!)? I guess, these types originated, because they're dealt with differently internally, but should the users have to deal with the differences? | |
Ladislav: 26-May-2011 | I think, that the answers to your questions are simple. Closures and functions (while being nonnative) are so different, that it is more convenient to have them as different datatypes. what if a native act like a closure? - can you name any native that does not? As you mention, the current datatypes are likely the most convenient for the implementation. | |
Geomol: 26-May-2011 | I agree on distinguish between closures and functions, but maybe those whould be the only two, and then skip native and action. I remember being a bit confused about especially action! types, when I started on REBOL. | |
Geomol: 26-May-2011 | It confused me, because they are called differently, so as a programmer, I think "ok, this is two different things, so I have to use time to learn the differences between e.g. functions and natives, or natives and actions, and how to use them correctly". And in fact, as a programmer I can very well ignore the differences, because the 3 types works exactly the same in my programs. | |
Ladislav: 26-May-2011 | But the difference between functions and natives is obvious - speed | |
Geomol: 26-May-2011 | I think, it was Bertrand Meyer, who wrote, that a datatype is recognized by the methods, you can use on it. In REBOL terms, what you can do with a datatype specify it. If you can do the same with a native! and a function!, they're the same datatype. | |
Ladislav: 26-May-2011 | But, the fact is, that, seen from the Meyer's perspective, there should not be any distinction between actions and natives... | |
Geomol: 26-May-2011 | We can still try to get the body of a native and action, like we can with functions. So we can use them exactly the same way. | |
Geomol: 26-May-2011 | Correct! But that doesn't remove the fact, that I can use the method to get bodies on natives and actions, just like I can on functions. The methods define the datatype. | |
Ladislav: 26-May-2011 | ...and that is not my invention, you can find that principle in descriptions of many programming languages | |
Ladislav: 26-May-2011 | is that consistent? And, if yes, why? | |
Geomol: 26-May-2011 | Is it crazy to make the rule, that DIVIDE always returns a decimal! ? POWER always returns a decimal!, even if the inputs are integers and the output could be an integer. It would make DIVIDE faster. | |
onetom: 26-May-2011 | i just discovered reflect by looking at the source of body-of spec-of and stuff. can't recall reading about it anywhere else | |
Geomol: 26-May-2011 | so you are saying, that it does not matter whether you get a #[none!] or a block? If natives and actions were called functions (datatype function!), then getting their bodies could also just return an empty block instead of none (if that's a problem from a language technical view). But it can't be a big problem, as so many functions in REBOL return a value different from none, if success, else none. Like PICK, SELECT, ... | |
Ladislav: 26-May-2011 | ...it can't be a big problem... - this is not about any "big problem". This is "only" a problem of a definition. You seem to be saying, that, formally, you can get the "body" of a native. Of course, you can define the BODY-OF function however you want. But, that is a "super-formal" approach, since, in fact, you are unable to get the body of a native no matter how much you pretend "it is not a big problem". In the same "super-formal" way you can evaluate BODY-OF 1 and say, that it (formally) is possible too, "yielding" a "triggered error". What I am trying to note is, that a part of the definition should be when we can we reasonably "can get the body" and when not. | |
BrianH: 26-May-2011 | Ladislav, thanks for looking up the /local blog and getting the actual numbers - I didn't have the time. I think that the only votes against the change were by gurus, while the rest of the responding gurus abstained like me. | |
BrianH: 26-May-2011 | Geomol, about native-op!, native-closure! and native-action!, these won't be necessary. Functions of the native! type don't need to bind their bodies to contexts, so they don't need the feature that makes closures closures. Ops and actions both redirect to the actual implementing function, which in the case of actions is an internal native associated with the type of the first argument, and in the case of op is a (at the moment only native) function provided at op creation time. If you wanted to allow the creation of user-defined datatypes with function!, closure! or command! implementations of the type's actions, the regular action! functions would still redirect to these implementations. Similarly, the regular op! type could be extended to support redirecting to other function types without needing the creation of a new function type. | |
BrianH: 26-May-2011 | Why was REFLECT introduced? - REFLECT was my idea, as a way to get metadata about a type without overloading the ordinal functions. This was a security measure so that you could make the ordinal functions available to untrusted code safely, and not make REFLECT and the *-OF functions available, which would make untrusted code potentially more useful. Couldn't SELECT be used? >> select context [body: 1] 'body == 1 >> reflect context [body: 1] 'body == [ body: 1 ] | |
Geomol: 26-May-2011 | Aha, so that's how it got in there ... and for security reasons! So you're the one, we should beat up, when times come. ;) | |
Ladislav: 26-May-2011 | Functions of the native! type don't need to bind their bodies to contexts - in that sense, natives behave both as functions and as closures at the same time. That is not as a big of an exception, as it may look, e.g.: f: func [][] behaves as a closure, similarly as g: func [x y][add :x :y] , simply because in such simple cases it is not discernible whether the given "function" is a function or a closure | |
Ladislav: 26-May-2011 | (although the last case may be made function/closure sensitive, if we redefine ADD and make it "sufficiently complicated") | |
Maxim: 26-May-2011 | wrt to the /local, its strange as I recall it being dependent on the way it was implemented and what it would actually prevent and why. most people don't really care in the sense that it wont really change any of their code. but I think added security by disallowing /local being given would be nice. Right now, we can easily inject code within functions by giving function! types as /local parameters. | |
Geomol: 26-May-2011 | And http://www.rebol.net/cgi-bin/r3blog.r?view=0341#comments | |
Geomol: 26-May-2011 | I'm not sure, and maybe it's a gray area. Are you familar with contracting between caller and function as described by Bertrand Meyer? If you promise to call *r* with *pre* satisfied then I, in return, promise to deliver a final state in which *post* is satisfied. *r* is a routine in his words. | |
Geomol: 26-May-2011 | In other words: "If you f*** my function up by giving strange arguments, then you're on your own." And I guess, /local arguments to functions can be used for something good in some cases. | |
Geomol: 26-May-2011 | See /local as any other refinement! You can inject code just the same using any refinement and additional arguments. | |
Maxim: 26-May-2011 | Geomol, you can use any other refinement, why use /local and allow a huge gap in security wrt intent of a local varable. I'd actually replace the /local handling of the function dialect and allow you to specify default values right in the function block. f: func [a b /local i: 2 blk: [ ] ] [...] The idea of /local is that its a protected, internal, set of words... most people don't even realize that it is just another normal refinement. | |
Maxim: 26-May-2011 | but the idea is that we usually limit the input types when it matters. and the function has to do the handling of the /local refinement. I'd much rather get an interpreter error telling me I can't use or apply /local refinements. this would also mean that /local would have to be the last refinement... always. | |
Maxim: 26-May-2011 | All I'm saying, John, is that currently we have to manually "close the doors", there are no ways within the language to make words private from the outside without doing the work ourself. and most people don't realize that there is no such thing as a local word in rebol functions. we only have arguments, which looks like a weird missing feature. | |
Geomol: 26-May-2011 | I'm a bit in doubt, because as you say, people might see this as a missing feature, even if it's not a problem. But wouldn't it be able to produce a function creator like FUNC, that makes a context with the locals, and then the function itself within the context and with the rest of the arguments? | |
Geomol: 26-May-2011 | Maybe a function, where the local var is set, if some condition is fulfilled, and then the local is returned in the end, being NONE, if it wan't set. Is that an example of such a problem function? | |
Maxim: 26-May-2011 | Here is an example of a function hi-jacking. it is something that can commonly be seen in larger apps, where some locals are only used conditionally. in this case, the original function is hijacked and we could really do nasty things here. -------------------------------------------------------------------- rebol [] f: func [a [string! block!] /local str][ ; uncomment to make the function safe ; str: none if block? a [ str: mold a ] print any [str a] ] evil-func: func [a ][ ; do something evil here print "EVIL!" head insert a " >:-P >>> " ] f/local "Print occurs as if nothing is wrong" :evil-func ask "!" | |
onetom: 27-May-2011 | this concept is sooo lovely, that u can even build such a fundamental feature as local variable via the already existing specs dialect, my heart hurts to see we can't keep this virgin beauty and have to sacrifice it on the altar of security... | |
Kaj: 27-May-2011 | Local variables are by definition about encapsulation, and this is not encapsulation | |
BrianH: 27-May-2011 | The surprise being that there aren't really any local variables, just arguments which might be optional. There was a proposal to make there be non-argument local variables in R3, and I wouldn't be opposed to this, but "least surprise" isn't a good enough argument for why in such an inherently surprising language as REBOL. I also wouldn't be opposed to having FUNCT add an ASSERT/type [local none!] to the beginning of the code block of every function it generates. | |
BrianH: 27-May-2011 | That last trick would be difficult to do safely though, at least as FUNCT is used in the mezzanine generation process. Mezzanines are generated with FUNCT but saved with MOLD into the form where they will be loaded at runtime. This means that FUNCT can't generate code that has inline function or datatype values in it, since they won't mold properly. Unless you inline the references to ASSERT and NONE!, those words couldn't be used as function parameters or local variables in the generated functions. Tradeoffs, I guess. | |
Sunanda: 27-May-2011 | For better local variables, you can use USE. But it's a bit clunky. f: func [a b][use [c] [c: a + b c]] ;; 'c is local to the function, and not easily/obviously affected by anything outside | |
BrianH: 28-May-2011 | Sunanda, agreed, and also about it being clunky, particularly because USE has both COPY/deep and BIND/copy overhead in R3. ASSERT/type [local none!] is still the most efficient method. | |
BrianH: 6-Jun-2011 | In R2, indexes are constrained to the bounds of the series they reference, so if you shorten the series you lose your position. In R3 your position is preserved for most of the standard operations, just in case you add back to the series later. The operations that can't possibly work for those out-of-bounds references trigger errors (mostly modifying operations), and the ones that could work if you consider series bounds to be an implementation detail and out-of-bounds values to be just not there return none (data access functions). SKIP is an exception, afaik, to allow you to sync up with the bounds - useful, but I don't remember whether it was intentional or a happy accident. >> a: "abc" == "abc" >> c: skip a 2 == "c" >> remove/part a 2 == "c" >> index? skip c 0 == 2 >> index? c == 3 | |
BrianH: 6-Jun-2011 | The point of this in R3 was to rebalance the behavior in favor of not triggering as many errors when they aren't useful. The policy in R3 is that errors should be your friends, and that means triggering errors where they help in general, preferably informative errors, and not triggering errors where they aren't generally helpful. The conceptual definition of series was changed in R3 to make bounds less hard so as to trigger fewer errors; out-of-bounds positions are now considered to have no values in them, rather than not being there, under most circumstances when you can get away with it - you can't necessarily get away with it for modifying operations. This change was based on analysis of common code patterns, and considering that error catching is expensive in most programming languages, including REBOL; none checking is much less expensive. In the cases where explicit bounds checking is necessary, that isn't expensive to add to your code, not nearly as expensive as the bounds checking required in code in R2 that isn't required at all in R3. | |
BrianH: 6-Jun-2011 | It would be a victory if we can get to the point where if R3 developers see an error triggered in R3 they are thankful for the information provided, because it will make it easier for them to find the mistake in their code that caused the uncaught error to be triggered in the first place. This is why error locality is so important, as is triggering better errors, and not assuming that something is an error unless the code says it is. If developers can think of errors as being their friends, all the better. | |
BrianH: 6-Jun-2011 | It's a little easier with R3, where a lot of the design decisions were made for good reasons, and by consensus. And because we decided early that R3's answer to backwards compatibility with R2 is to keep maintaining R2 for such code. That frees us to fix aspects of R2's design that turned out to not be that good an idea in retrospect. | |
Gregg: 6-Jun-2011 | +1 for getting Brian's detailed notes logged someplace so they are usable (and so they don't get lost). | |
Geomol: 6-Jun-2011 | Desiding what to do with block indexes out of range is a tough call, I think. I understand the argument not to cause errors, if it can be handled somehow, but I'm not sure, handling out-of-range problems is always good. What if it's a user bug in the code, that made the index get out of range? Then the user won't easily find that bug, as it causes no error. It's not possible to index a block lower than 1 (first element). It's only possible to index out of range in the other end of the block, getting past the tail. And that can only be done by having an index there, and then remove something from earlier in the block. When the index is beyond the tail, then it has to be desided what to do with insert, remove, skip, next, back, pick, select, append used on that index. (and maybe more like TAIL?, INDEX?, ...) What does other languages do? | |
Geomol: 6-Jun-2011 | Let's say, my index is way beyond the tail, and I insert a new element there. It may then just be appended to the series, which is at an index way before my pointer. What if I then e.g. say: remove/part my-index -1 | |
Geomol: 6-Jun-2011 | what should happen? And why? | |
Ladislav: 6-Jun-2011 | Geomol: "I'm not sure, if this is known or desired behaviour" - Brian used a long description, but the fact is, that the best part of it is "accident". I bet, that it has not been checked, and it is not clear, whether the difference is desirable or not. | |
Ladislav: 6-Jun-2011 | Let's say, my index is way beyond the tail, and I insert a new element there. - you are out of luck, such an operation is not supported | |
Ladislav: 6-Jun-2011 | BTW, "Let's say, my index is way beyond the tail, and I insert a new element there." - in fact, I was right saying that the operations was not supported, since it did not insert a new element there | |
Ladislav: 6-Jun-2011 | In my opinion, this is clearly unsettled (BACK vs. SKIP), and was not discussed before | |
BrianH: 6-Jun-2011 | I think so, but it was in that private world where Carl's GUI for R3 was being worked on with Henrik and me. It looks like INSERT works like SKIP. | |
Ladislav: 6-Jun-2011 | (and the proof is quite old) | |
Ladislav: 6-Jun-2011 | The proof exists, welcome or unwelcome, to demonstrate the actual properties of the interpreter, and to prove why the behaviour of some function is unuseful. | |
BrianH: 6-Jun-2011 | It would be possible and in keeping with the metaphor to have an out-of-bounds INSERT pad blocks with none values, but since strings and binaries don't have a way to have inline nones, that would make the behavior of blocks inconsistent. That is why INSERT behaves the way it does. If you want INSERT to trigger an error in that case, like POKE and set-path modification, that would make sense too. | |
BrianH: 6-Jun-2011 | Or we could just say that INSERT, APPEND, SKIP, AT and LENGTH? are constrained to bounds, while PICK, POKE, and the ordinals and path accesses that are based on them are not. | |
Ladislav: 6-Jun-2011 | OK, that is why the "INSERT *there*" operation is, in fact, unsupported, and, in such cases, it is preferable to trigger an error, in my opinion | |
Ladislav: 6-Jun-2011 | regarding the incompatibility of SKIP -1 and BACK - I am not sure, whether that is good to have. | |
BrianH: 6-Jun-2011 | I think that the incompatibility of NEXT and BACK is more important, and definitely an error, and an accident. >> a: [1 2 3] == [1 2 3] >> b: skip a 2 == [3] >> remove/part a 3 == [] >> index? b == 3 >> index? next b == 3 ; constrained to the argument index, not even the series bounds >> index? back b == 2 ; not constrained to the series bounds >> index? back a == 1 ; constrained to the head | |
Geomol: 6-Jun-2011 | And if it will not advance in some cases, should it then trigger an error, if that is tried to do? | |
BrianH: 6-Jun-2011 | Option 4: NEXT and BACK will be constrained to the series tail, even if that makes the (index? a) <= (index? next a) truism false. | |
BrianH: 6-Jun-2011 | Note that the other operations that are constrained to the tail of the series in R3 are PRINT and EMPTY?, which is why R2 gets that out-of-bounds error and R3 doesn't. | |
BrianH: 6-Jun-2011 | The off-by-one error for AT and non-positive indexes still has an unresolved ticket too. PICK and POKE were fixed, but not yet AT. | |
Geomol: 7-Jun-2011 | Would a programmer expect this to be true always? (index? series) + (length? series) = (index? tail series) That seems to define some basic rules for indexes and the functions involved. But it fails sometimes, as it is now: >> s: [1 2] == [1 2] >> t: tail s == [] >> clear s == [] >> (index? s) + (length? s) = (index? tail s) == true >> (index? t) + (length? t) = (index? tail t) == false Problem here is, that LENGTH? t returns 0. It should return -2, if the result should be true. | |
Geomol: 7-Jun-2011 | It's possible to create infinitely deep series with this: >> s: [a b c] == [a b c] >> insert/only tail s s == [] >> s == [a b c [...]] >> s/4 == [a b c [...]] >> s/4/4 == [a b c [...]] >> s/4/4/4 == [a b c [...]] and so on. | |
Endo: 7-Jun-2011 | in you example s/1 actually a pointer to s itself (the second value in s). and when you insert something into s, the pointer (which is s/1) is also moves forward. >> same? head s/1 head s == true >> s/1 == [b c] ;which mean it still points to second value in the series. | |
Geomol: 7-Jun-2011 | In other words, INSERT take two arguments, series and value. The value should be picked up before starting the insert, not after starting the insert. (If that makes sense.) :) | |
Ladislav: 7-Jun-2011 | You need to realize, that there are implementation differences between lists and blocks, and that they are "enforced" by the properties of the respective datatypes. | |
Geomol: 7-Jun-2011 | hm, could be. :) Nah, blocks are very cool for many things. I think, both blocks and lists are useful though. | |
Endo: 7-Jun-2011 | without /only is more general use of course, but it is completely different. In your last example (Geomol) you get the values of a series and insert them into another series. | |
Endo: 7-Jun-2011 | with /only you get a "pointer" to a series and put that "pointer" into another series. (I know "pointer" is not a correct word for this but you got the idea) | |
Ladislav: 7-Jun-2011 | The above list example proves, that lists don't "know" their index, and have to calculate it every time, which means, that "index access" is slow. | |
Geomol: 7-Jun-2011 | I don't think, INSERT have to change position of some index, it just have to insert the next position than the one given, and only if insert is earlier in the same series. | |
Geomol: 7-Jun-2011 | I read you, as INSERT cannot change an index. I say, INSERT should just add 1 to the index number, it receives, and only in that special case. | |
Ladislav: 7-Jun-2011 | just realize, that index is a number, and every blocks remembers it | |
Ladislav: 7-Jun-2011 | and, since the index attribute is immutable, in fact, the INDEX function cannot change it | |
Geomol: 7-Jun-2011 | I'm not talking about calculating every time and changing of indexes being hold by variables and such. I only suggest, that INSERT does this: If /only and if value being inserted is an index (or position or what we should call it) later in the same series, where we are inserting, add 1 to the index value and insert that. In all other cases carrie on as usual. | |
Geomol: 7-Jun-2011 | I'm sorry, if it doesn't make sense. I sometimes find it easy to figure out such solutions but very difficult to explain it to others. :) I'll just go and implement it myself. | |
Geomol: 7-Jun-2011 | sure, and it's possible to test for that. | |
Ladislav: 7-Jun-2011 | Well, the only thing I can suggest you is to try it and see which incompatibilities you get. | |
Kaj: 7-Jun-2011 | John, remember our previous discussion, that indexes are not properties of series, but properties of series references. Therefore, it makes no sense to try to make a vector behave like a list, because any other references to the vector are unknown and thus it's impossible to make the behaviour for those references consistent | |
Robert: 10-Jun-2011 | And, I don't understand why he can't be reached. All available channels are dead... | |
GiuseppeC: 11-Jun-2011 | Robert I have the same questions you have. Carl must acknoledge that our life and companies are waiting for him. | |
Pekr: 13-Jun-2011 | This is by far the longest period of Carl's disappearance, IIRC. The reasons we can only speculate about - some personal/family difficulcies, burn-out to the REBOL topic, new daily job, which does not left you with much energy and free time to do some other stuff, REBOL related. We tried to get Carl's answer on R3 Chat, only with sporadic answer of recent Carl's job. But no answers to "what's next" for the REBOL. The reasons might be various again - Carl is willing to proceed, he just dosn't have time/energy. He is most probably not willing to open-source the project either, which gets us into kind of schizophrenic situation - no open-source, no progress either. If Carl would know the answer to what's next for REBOL question, he would already share it with us. But he did not do so, yet, which is a bit disappointing of course. As for a phone call - I don't know - I would not call him, as it could get him into feeling, that we push him to give us an answer, which he might not have right now. But - I think that call from some friend, e.g. Reichart, would be accepted differently. But then - we can't push anyone to do anything, and from few weeks old discussion I think that Reichart does not necessarily feel urge to do such a thing, which is OK too. So ... we wait ... and RED progresses at least, so hopefully in the end, there is still the chance that we will see the light in the end of the tunnel :-) | |
nve: 13-Jun-2011 | Let's focus on Red and Cheyenne now. | |
Endo: 14-Jun-2011 | And let's hope Carl and his family are alright. No illness no accident. | |
Pekr: 14-Jun-2011 | That's what I was paid for at Amiga Review - to write monthly column of speculations about the behind-the-scenes stuff related to Amiga. Some even called such speculation being an insight, and it was rather popular :-) | |
Brock: 15-Jun-2011 | I didn't hear much about this day job that he has, but I can only hope that it was a contract to finish R3 for a big company and once that project was completed, release it. | |
Robert: 2-Jul-2011 | In the last two days I had longer calls with Carl and decided how to move R3 forward. This is how it will be done: | |
Robert: 2-Jul-2011 | - The RMA team will help to get some burden from Carl's shoulder and work on open issues. This will be setup in that we get partial access to the necessary code parts and can work on these. - We are going to extend our internal testing infrastructure etc on these new R3 releases and run it against our applications we crate - Carl and I will have regular calls to discuss the status and things where we need his advise etc. So, to keep the loop closed and gain more speed - I will meet with Carl in person on 23rd Juli to discuss further things - Unitil that we want to get most administrative setup done, so that we are ready to go | |
Robert: 2-Jul-2011 | We are going to drive the priorities by the things RMA needs. This shouldn't be a problem for anyone because if you are going to use R3 for serious development than you will need it as well. The thing is, that we are not going to jump-start for every requested feature etc. We know there is a lot to do and we will work through it step-by-step. And, this is not because we don't care what you all state here. Definetly not. I want to move R3 forward as fast as possible. This needs concentration, focus and pushing to finally get it done. At the end of the day the only thing that counts is, if we make it to make R3 stable enough for prime time development. | |
Robert: 2-Jul-2011 | So, stay tuned and I must say that this is the most promising development for a long time. | |
Robert: 2-Jul-2011 | Let's see if Carl and RMA will make it to deliver on this. Which, still needs to be proofed but I'm not going to stop to push for it. | |
Oldes: 3-Jul-2011 | From my point of view it means, that there is no NDA, just that Carl lost interest to be with us and work on REBOL. | |
Pekr: 3-Jul-2011 | If so, then there is a question, if Carl shoul not consider fully open-sourcing R3. But we most probably know the answer. I would be really intested into Carl officially telling the REBOL community his motives to (dis)contiu with R3 development. It all feels really dishonest, and I wonder, for any eventual future project, how Carl wants to win the trust of ppl. |
41401 / 48606 | 1 | 2 | 3 | 4 | 5 | ... | 413 | 414 | [415] | 416 | 417 | ... | 483 | 484 | 485 | 486 | 487 |