AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 5907 |
r3wp | 58701 |
total: | 64608 |
results window for this page: [start: 55101 end: 55200]
world-name: r3wp
Group: !REBOL3 ... [web-public] | ||
BrianH: 5-May-2011 | Consistency might be a good enough excuse to do so, but I don't want to break code unnecessarily. | |
Geomol: 5-May-2011 | Brian wrote: <quote> >> b: quote 'a/1 == 'a/1 >> b == 'a/1 ; regular evaluation of lit-path value does not convert to path >> do :b == 'a/1 ; explicit evaluation of lit-path value does not convert to path So it's not exactly like parens, but it's what Maxim, Geomol and I would prefer. </quote> No, I just posted the observed behaviour. I don't agree with it. | |
Geomol: 5-May-2011 | I would expect this behaviour: >> do quote 'a/1 == a/1 | |
Geomol: 5-May-2011 | Or better, as I'm not sure, I like get-words as function arguments (see source of quote): >> do first ['a/1] == a/1 | |
Ladislav: 5-May-2011 | The QUOTE function is fine, and it is actually necessary, since e.g. there is no LIT-LIT-WORD argument, so, to obtain a lit-word, the most natural way is to use quote 'a | |
Geomol: 5-May-2011 | If it's necessary, then we need to come up with examples of functions, that take a lit-word as an argument. I can't think of any. | |
Ladislav: 5-May-2011 | that take a lit-word as an argument - that looks unrelated | |
Ladislav: 5-May-2011 | For example, the INSERT function can take a lit-word as an argument, if that is what you asked | |
Geomol: 5-May-2011 | Yes, that's an example. I'm ok with writing insert blk to lit-word! 'a I asked, because you said, QUOTE is necessary. I don't see it as really necessary. | |
Ladislav: 5-May-2011 | insert blk first ['a] is much more reasonable than that (your example converts a word to a lit-word, and unnecessarily so. | |
Ladislav: 5-May-2011 | ...because it first converts the said lit-word to a word (undesirably) | |
Ladislav: 5-May-2011 | Why I wrote "QUOTE is necessary" - because that is the only way how to do it directly. Using the "double conversion method" you can do it usually as well, but that certainly does not count as a "direct method". | |
Ladislav: 5-May-2011 | I even recall we used QUOTE to explain some issues to a beginner, which would be impossible to explain using the "double conversion method" | |
Ladislav: 5-May-2011 | Moreover, the first ['a] method does not apply as a "direct method" as well, since it really performs some action, namely it gets the first value of a block, which is not a trivial operation, like QUOTE. | |
Geomol: 5-May-2011 | If allowing get-words in spec blocks, then QUOTE is fine. I'm questioning allowing get-words in spec blocks. It can lead to uses as this: I make a function, that can do a paren! (in lack of better example, but it makes the point, I think): >> do-paren: [:p] [do p] I can try it on a paren: >> do-paren (1 + 2) == 3 Works ok so far, so I try having a var holding a paren: >> q: quote (1 + 2) == (1 + 2) >> do-paren q == 3 I got the feeling, I know how do-paren works, until I write: >> do-paren quote (1 + 2) ** Script Error: do is missing its value argument Hm, what if I use the old method: >> do-paren first [(1 + 2)] ** Script Error: p expected series argument of type: series pair event money date object port time tuple any-function library struct even... That's confusing, as I see it. (Example done in R2.) | |
Ladislav: 5-May-2011 | do-paren: [:p] [do p] - the only problem with the function is, that the function is so, that it can "do a paren", but only if that "paren" is already supplied as a value, i.e. not as an expression | |
Ladislav: 5-May-2011 | reformulation: is should have said: "only if the said 'paren' is not supplied as a result of an expression" | |
Geomol: 5-May-2011 | I remember reading, parens are evaluated (an active type, I think you call it). It's a very fundamental thing. Breaking this rule make the code less readable. Is it really necessary? What natives or mezz have get-word arguments? Kinda the same with lit-word arguments (in the spec block). My guess is, Carl made those, so he could write: help add instead of help 'add | |
onetom: 5-May-2011 | (i didn't know about the :p where is it documented? otherwise i used the 'p notation many times. it even allows to add explanatory words to the parameters, so u can make a nice dialect by using the default 'do evaluator...) | |
onetom: 5-May-2011 | thanks a lot. i thought i know the core docs in and out :) | |
Geomol: 5-May-2011 | About unevaluated lit arguments (or literal arguments, as Carl call them), the functions FOR, FOREACH, REPEAT and maybe more use them (I couldn't remember earlier when I posted). And yes, it's more convenient to write repeat i 10 [...] than repeat 'i 10 [...] But used in some cases, it's probably easier to create less readable code. I can imagine a language, where this is different. About the other type of unevaluated arguments (get arguments as Carl call them), I haven't found other functions than QUOTE, that use it. There must be others!? | |
Geomol: 5-May-2011 | there is no LIT-LIT-WORD argument, so, to obtain a lit-word, the most natural way is to use: quote 'a Some thoughts: So one use of this is to make it easier to e.g. insert a lit-word in a block. I come to think of how to insert a block in a block. We can't do: insert blk [a b c] as that will insert the 3 words, a, b and c, in blk. So I can write: insert blk [[a b c]] or insert/only blk [a b c] Why not use the same kind of thinking, when dealing with lit-words? So I can write: insert blk ['a] or maybe insert/only blk 'a (maybe the refinement should be called something else than /only). Now, the rule for INSERT should then be, that if it get a word (the lit-word, 'a, will be translated to the the word, a), it should change that to a lit-word, if it got the refinement too. Result is, that unevaluated get arguments can be avoided making the REBOL scanner/parser simpler. | |
BrianH: 5-May-2011 | Geomol, if you agree with this model: >> do quote 'a/i == a/1 , put your agreement in http://issue.cc/r3/1434where it counts. | |
BrianH: 5-May-2011 | As for functions with get-word arguments, the DO dialect used to need more of them, but in R3 most of those needs are handled by QUOTE. For other dialects though it is much more useful, as it prevents evaluation by the DO dialect when it is unwanted. It can be used on occasion in security situations if you want to block calculated values. Also, it could be used in a statically compilable subset of REBOL for the block arguments of all control and loop functions like IF and WHILE. | |
BrianH: 5-May-2011 | Consensus adds to the strength of an argument. Chiming in with an "I agree with Ladislav" on a potentially controversial issue reduces the controversy that might otherwise block it, especially if you are sometimes someone who disagrees with Ladislav effectively (which is pretty difficult to do). | |
BrianH: 5-May-2011 | This has worked very well before with CureCode tickets and such. If Carl doesn't have a strong opinion either way, he will wait for consensus. | |
BrianH: 5-May-2011 | Back to QUOTE and get-word arguments... We need something like QUOTE, especially for set-*, *-paths, and functions, because these block an evaluation that may have side effects, or at least cause a value copy. Even if QUOTE is the only function with this evaluation model, it depends on DO supporting something like get-word argument evaluation in order to work at all. The alternative is to make 'quote a keyword in the DO dialect, which decidedly doesn't have keywords. So we can't get rid of get-word arguments altogether without ridding ourselves of QUOTE, and you'd get a bit of resistence from anyone who's used it if you want to do that. | |
BrianH: 5-May-2011 | If you want a SECURE 'get-word constraint that you can apply after QUOTE is defined, that will block some but not all function hacking attempts using function values. The "but not all" part is critical though, so we are better off from a security standpoint if developers aren't allowed to think of function values as being safe to call without precautions, since the consistency of the need for that precaution makes it more commonly applied. | |
GiuseppeC: 12-May-2011 | It is great but a Waste of time. If only REBOL was open sorced DOC could put his offorts on it. | |
Geomol: 12-May-2011 | If the first wheel can't run, reinvension can be a good thing. | |
Geomol: 12-May-2011 | Think "reinvention" is with a t. | |
TomBon: 12-May-2011 | would it be possible (in general) to encapsulate the whole R2/3 GUI functionality incl. antigrain etc. into a lib, usable for other languages as a out of the box GUI generator? communication & event handling e.g. via TCP? | |
Kaj: 12-May-2011 | However, it still fails to be as easy to integrate as for example a 0MQ library | |
Maxim: 12-May-2011 | there has been a lot of work going on with a few R3 projects. a few extensions, the gui, etc. there has also been quite a bit of work done on Red. | |
Geomol: 13-May-2011 | I notice ++ and --, which was discussed here: http://www.rebol.net/cgi-bin/r3blog.r?view=0057#comments Would it be ok to let NEXT and BACK do the job, like this: next: func [series] [ either word? series [ set series system/contexts/lib/next get series ][ system/contexts/lib/next series ] ] Examples of use: >> blk: [a b c] == [a b c] >> next blk == [b c] >> blk == [a b c] >> next 'blk == [b c] >> blk == [b c] | |
Maxim: 13-May-2011 | it would break a lot of code, and in fact, I prefer it like it is. this being said, if we have ++/--, then I expect *these* to work as you just depicted | |
Maxim: 13-May-2011 | ahhh.. I just re-read your code... and was bitten by the lit-word evaluation again. I didn't realize that: either word? series [ triggers when you give a lit-word. in this case, you are right. except in implementation. words carry their binding, you don't need (in fact shoudn't) acess it via system set word next get word should be enough. | |
Geomol: 13-May-2011 | If just using NEXT instead of full path, R3 will create a stack overflow. The function is called NEXT, you know! ;) But anyway, this should be changed in the native. | |
Maxim: 13-May-2011 | ok... I just hit myself on the head a few times. clearly, I'm not sharp right now. :-) | |
Geomol: 13-May-2011 | My viewpoint is, that ++ isn't the speedy native, many people would expect. When using ++ on a series, a new series is created. So ++ take one series and produce two, one is the original, which is incremented, the other is the return value, which is the old series position. This isn't very effective from a performance perspective. If my NEXT function was implemented in the current NEXT native, it didn't have to produce another series, if called with a word. This will mean good performance. | |
BrianH: 13-May-2011 | ++ doesn't create a new series, it just increments the index of the reference to the same series. | |
Geomol: 13-May-2011 | It does create a new series: >> b: [a b c] == [a b c] >> same? ++ b b == false (I know, it's the same area of memory, but we have two set of series variables to work on that memory.) | |
BrianH: 13-May-2011 | A series reference fits into a value slot, so returning a reference to the same position doesn't take any more space than returning a reference to a different position. This means that there is nothing to be gained by losing the information. | |
Geomol: 13-May-2011 | Are you saying, e.g. an integer value take up the same amount of memory as a series ref.? Doesn't sound very effective, but you could be correct. :) | |
Geomol: 13-May-2011 | (Remember a series need info about the area, the head, tail, position.) | |
BrianH: 13-May-2011 | ++ and -- return a reference to the previous position in order to lower the need for local temporary variables to save the previous position when you need to. Returning it means that information is not lost. Technically, since ++ and -- are modifying functions they don't need to return anything at all. The only reason they return that information is because it's valuable. | |
BrianH: 13-May-2011 | Yes, an integer takes up the same space as a series ref (though the series itself takes additional space). Though in R3 currently integers are 64bit and series refs are a 32bit pointer and a 32bit offset, so it's not as much of a waste as in R2 where integers are 32bit. For both though, the value slot is 128bit anyways. This is the price you pay for using variants. | |
Geomol: 13-May-2011 | This is from R2: >> next b == [b c] >> stats/series == [34304 26141 7434 231 498 497 406] >> next b == [b c] >> stats/series == [34304 26145 7444 231 484 483 409] >> ++ b == [a b c] >> stats/series == [34304 26151 7454 231 468 467 412] >> ++ b == [b c] >> stats/series == [34304 26157 7464 231 452 451 415] You see, NEXT increment BLOCKS (2nd number) by 4 each time. ++ increment it by 6 each time. So ++ take up more memory. | |
Henrik: 13-May-2011 | SAME? must work from the same index in the same series: == [a b c] >> same? a next a == false | |
Geomol: 13-May-2011 | And a block here is a series index. Two blocks can share the same mem area for the actual content of the series. | |
BrianH: 13-May-2011 | The area, head, tail and such attributes of a series are in the series itself, not in the reference to the series. This is good because series references are copied every time they are passed to a function - REBOL is strictly pass-by-value. All return values are copied too. | |
BrianH: 13-May-2011 | >> stats/series == [16384 11618 4590 25 151 150 199] >> a: [1 2 3] == [1 2 3] >> stats/series == [16384 11623 4601 25 135 134 202] Only one of those is the new block - the rest are overhead of either the STATS function or of the REPL loop itself, or runtime overhead, or call overhead, or assignment overhead. I'm starting to think that STATS/series isn't very useful. | |
Maxim: 13-May-2011 | when I look at the extensions model, the references to series are just pointers to a series payload. but the start, *is* part of the reference, not the series data. since values are 128 bits, you can have the pointer to the series and its head in the same value. | |
BrianH: 13-May-2011 | Of course ++ and -- allocate error! values to trigger if they are called incorrectly, and the R2 version does a REDUCE as part of that error triggering call. But that's not the normal case. | |
BrianH: 13-May-2011 | Maxim, a series reference only contains a pointer to the internal series structure and either a pointer to the offset or a 32bit index (Carl could say which). The internal series structure could have a pointer to the start of the series, or it could be a header of the series data itself, depending on which is better for memory allocation. What you see in extensions are marshalled values, not regular R3 stack frames or other value slots. | |
BrianH: 13-May-2011 | As for value slots, not all datatypes use all 128 bits. 32 bits are used for flags, and the payload could be 32 bits (as in char!), 64 bits (series, integer, decimal) or up to 96 bits. The rest is wasted space. The value slots need to be the same size so you can set one of them to a different value without moving the rest in the block if that value is of a different type. | |
Maxim: 13-May-2011 | yep. but we don't have the xtra information which links the data in the core, we only get the data. in the extensions, we get a some sort of internal reference to the series and the index. this is how I see it working in the core too. there is ample room for this info in 128 bits. | |
Maxim: 13-May-2011 | so we don't need to be really concerned about the serie *reference* being copied, anytime we play with a value, this happens anyways... as you said, argument calling copies them (lit-word probably refers instead). | |
BrianH: 13-May-2011 | Yup, but it's not in that 128 bits because it would cause problems with duplicated data that would need to be updated. The information kept in the value slot is limited for a reason. | |
BrianH: 13-May-2011 | Value slots are copied really often. Everything in them is a potential aliasing problem. | |
BrianH: 13-May-2011 | Strangely enough, port! values in R3 only use 32 bits for a pointer to the internal port structure. Everything else needs to go into the port structure itself, or else we'd get aliasing problems. We don't even get an offset integer for ports, because of the port model cleanup where all ports are now like R2's direct ports. | |
BrianH: 13-May-2011 | Well, the value slots would need to be bigger if we want to have both 64bit pointers and 64bit series sizes. If we just had 32bit series sizes then 128bit would be plenty (remember the 32bit flags means that we only have 96 bits for the payload). We could also have 32bit handles to series, adding a layer of indirection, and then have a limit on the number of series, not the size. We already have 64bit integers. | |
Geomol: 17-May-2011 | Is it possible to bind a function's body to a new context in R3? In R2, it can be done with bind second :f new-context | |
Ladislav: 17-May-2011 | So, I suppose it is a safety measure: without having the function body available, you cannot do it. | |
Geomol: 17-May-2011 | I get some errors (under OS X): >> bind 'body o ** Script error: body is not in the specified context >> bind [body] o == [body] >> f 1 ** Script error: a has no value My f, body and o are defined this way: >> f: func [v] body: [v + a] >> o: context [a: 1] | |
Geomol: 17-May-2011 | :) I need a language without BIND! | |
Ladislav: 17-May-2011 | >> f: make function! reduce [[v] body: [v + a]] >> o: context [a: 1] == make object! [ a: 1 ] >> bind body o == [v + a] | |
Geomol: 17-May-2011 | What if ... this is radical, but try go with me ... what if block's content wasn't bound to any context, when the block is made? And then the content is just bound to a context, when and if the block is being evaluated (or compiled if a language does that) the first time. Doing it this way, words are treated just like any other value within the block. They don't hold any other meaning than the words themselves. What would the consequences be? | |
Geomol: 17-May-2011 | The same could be done with functions, as the function body is just a block of data, which may or may not be evaluated (or compiled). | |
Ladislav: 17-May-2011 | But, my guess is, that if done carefully, such a "change" would be indiscernible from the current behaviour. | |
Geomol: 17-May-2011 | An example: blk: [a + b] f: func [blk /local a b] [a: 1 b: 2 do blk] f blk If this would work, what other consequences would that have? | |
Ladislav: 17-May-2011 | This needs some thought, Geomol. Actual example: f1: closure [/local a][a: 1 [a]] f2: func [blk /local a][a: 2 do blk] f3: func [blk /local a][a: 3 do bind blk 'a] >> f2 f1 == 1 >> f3 f1 == 3 | |
Geomol: 17-May-2011 | I wouldn't have closure, but use object instead (or context, as I call them), if that functionality is wanted. And block content isn't bound to start with, so if I write: >> f1: [a] >> f2: func [blk /local a] [a: 2 do blk] >> f2 f1 == 2 because 'a' inside f1 is bound to local 'a' in f2, when evaluated. If I want another 'a', I could write: >> context [a: 1 set 'f1 compile [a]] ; f1 will be a block, [a], where the 'a' is bound to 'a' in the context >> f2 f1 == 1 and the last result could be achieved: >> f3: func [blk /local a] [a: 3 do compile blk] >> f3 f1 == 3 Calling f3 will be slower, as blk is recompiled each time. This language, I illustrate, isn't REBOL, but another with many similarities to REBOL, but with a compile function. Maybe kinda the same could be achieved in REBOL, if the binding rules was changed, and "compile" in my examples above was changed to a "rebind" function. | |
Geomol: 17-May-2011 | Well, if function variables is needed, after the function is finished, then it can be achieved by putting the function in a context, and have the local vars be vars in the context instead. It's simpler, I think, to program. | |
Ladislav: 17-May-2011 | It is not simpler, you just are forbidding a useful feature. | |
Geomol: 17-May-2011 | I guess, the closure functionality could be achieved by a mezzanine and using object! and function! datatypes without having closure! datatype. I'm not an expert in closures, so I may be wrong. Are there more to them? | |
Ladislav: 17-May-2011 | So, if you would not forbid the CLOSURE to be implemented as a mezzanine, my question remains valid. | |
Geomol: 17-May-2011 | Is a closure a function, where the vars is in a map (or whatever data structure is used for an object/context) instead of on the stack? | |
Ladislav: 17-May-2011 | You can have a look at source closure in 2.7.7 or above | |
Geomol: 17-May-2011 | It is not simpler, you just are forbidding a useful feature. If closure! could be avoided, then the C source for the language is simpler. That's what I mean. If the closure functionality can be achieved by a mezzanine, nothing has been forbidden. Of course, if the language doesn't have problems with keeping the C source simple, a closure! datatype could be included, as it would possible be faster. | |
Geomol: 17-May-2011 | I already gave examples to do that. They were: >> context [a: 1 set 'f1 compile [a]] >> f2: func [blk /local a] [a: 2 do blk] >> f2 f1 == 1 >> f3: func [blk /local a] [a: 3 do compile blk] >> f3 f1 == 3 I haven't finished reading about CLOSURE, so maybe it can be even simpler. | |
Geomol: 17-May-2011 | It would be easier in R2 to create CLOSURE this way: >> closure: :func >> f: closure [a b] [[a + b]] >> do f 1 2 == 3 | |
BrianH: 17-May-2011 | R3 has two context types: object and function. R2 only has one context type: object. This is why you can create a persistent context using a function in R2, while you can't in R3. | |
BrianH: 17-May-2011 | Creating a new context every time the function is called is the whole point to closures, the only reason that you would use them instead of a function. | |
BrianH: 17-May-2011 | The PARSE statement in CLOSURE creates the code for a call to a function that the resulting outer function creates every time it is called. If you want to understand what the PARSE statement is doing, make a function with CLOSURE and look at its source. | |
BrianH: 17-May-2011 | Why does R2's CLOSURE parse of set-word! in the spec? The set-word! in the PARSE spec is a special-case, so that set-words aren't counted in the set word any-word! portion of the next alternate in the rule. Set-words in function specs are keywords for special purposes in function creation (just return: in R2), they don't refer to parameters, and the other word types are collected as parameters. | |
Geomol: 17-May-2011 | Creating a new context every time the function is called is the whole point to closures And R2 is not doing this with its functions? | |
BrianH: 17-May-2011 | >> f: func [a] ['a] >> w1: f 1 == a >> w2: f 2 == a >> get w1 == 2 ; note that the value has changed >> c: closure [a] ['a] >> w1: c 1 == a >> w2: c 2 == a >> get w1 == 1 ; note that the value persists | |
BrianH: 17-May-2011 | >> source c c: func [a][native action function! [[throw] :a [any-type!]] ['a] a] | |
Geomol: 17-May-2011 | (just return: in R2) Can you create a function with a return: set-word! in the spec? | |
BrianH: 17-May-2011 | There is a bug in CLOSURE though. This line: insert tail bdy to word! :word will have problems with some datatypes. I'll fix it for the next version. | |
Geomol: 17-May-2011 | I would expect anybody to be burnt out when taking that approach to things. It's like building a skyscraper by loosely make all floors first, then trying ot fix everything. Better to get first floor solid before moving on. | |
BrianH: 17-May-2011 | Recursive functions in R2 work by pushing the block of values in a context onto a stack during the recursive calls, then popping them off on return. In R2, function contexts are stack-relative, which makes word dereferencing 27% slower relative to object contexts, but function calls in general faster. Closures bind to object contexts, which are recreated with every function call. | |
BrianH: 17-May-2011 | I don't know, a little less than 10 years ago? | |
Geomol: 17-May-2011 | I would say, we desperately needs a replace for REBOL, so all the man-years of work, people have done in creating software with it, isn't wasted. It's not all wasted, nomatter what happens, as many things work and is used, but many would like to move on, I guess. | |
BrianH: 17-May-2011 | I prefer to think of a combination of R3 and Red as potentially being that replacement, but other people may have other plans. | |
BrianH: 17-May-2011 | Never mind what I said about the bug in CLOSURE. It's not a bug. | |
Gabriele: 18-May-2011 | Geomol: syntax is insignificant, translating from one to another is easy. Anyway, the problem with a Scheme using REBOL-like syntax is that you give up dialecting (static binding is pretty important for that). | |
Geomol: 19-May-2011 | I found an bad effect of not binding words in blocks at all, before the block is evaluated. Functions like LOOP take 2 args, count and block. By not binding the block content before it's evaluated, the count arg local to LOOP is found, if a count var is used in the block. So I guess the REBOL early bind of words is better. | |
BrianH: 19-May-2011 | LOOP's count arg is not bound to the block of code, so it is not local. This is why LOOP is the fastest loop. REPEAT is the version of LOOP with a bound local arg. |
55101 / 64608 | 1 | 2 | 3 | 4 | 5 | ... | 550 | 551 | [552] | 553 | 554 | ... | 643 | 644 | 645 | 646 | 647 |